diff options
author | Erik Hugne <erik.hugne@ericsson.com> | 2013-10-18 01:23:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-18 13:20:43 -0400 |
commit | bbfbe47cc99ce093708aaf28b7f2c08d28045c67 (patch) | |
tree | d12bae2180f77b4dc48580bf5a85b995f1f4909c /net/tipc | |
parent | 636c0371a737c27510df867161fb8100c2f086bd (diff) |
tipc: simplify the link lookup routine
When checking statistics or changing parameters on a link, the
link_find_link function is used to locate the link with a given
name. The complex method of deconstructing the name into local
and remote address/interface is error prone and may fail if the
interface names contains special characters. We change the lookup
method to iterate over the list of nodes and compare the link
names.
Signed-off-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/link.c | 110 |
1 files changed, 13 insertions, 97 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index 223bbc87e451..e8153f64d2d6 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -75,20 +75,6 @@ static const char *link_unk_evt = "Unknown link event "; | |||
75 | */ | 75 | */ |
76 | #define START_CHANGEOVER 100000u | 76 | #define START_CHANGEOVER 100000u |
77 | 77 | ||
78 | /** | ||
79 | * struct tipc_link_name - deconstructed link name | ||
80 | * @addr_local: network address of node at this end | ||
81 | * @if_local: name of interface at this end | ||
82 | * @addr_peer: network address of node at far end | ||
83 | * @if_peer: name of interface at far end | ||
84 | */ | ||
85 | struct tipc_link_name { | ||
86 | u32 addr_local; | ||
87 | char if_local[TIPC_MAX_IF_NAME]; | ||
88 | u32 addr_peer; | ||
89 | char if_peer[TIPC_MAX_IF_NAME]; | ||
90 | }; | ||
91 | |||
92 | static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, | 78 | static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, |
93 | struct sk_buff *buf); | 79 | struct sk_buff *buf); |
94 | static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf); | 80 | static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf); |
@@ -160,72 +146,6 @@ int tipc_link_is_active(struct tipc_link *l_ptr) | |||
160 | } | 146 | } |
161 | 147 | ||
162 | /** | 148 | /** |
163 | * link_name_validate - validate & (optionally) deconstruct tipc_link name | ||
164 | * @name: ptr to link name string | ||
165 | * @name_parts: ptr to area for link name components (or NULL if not needed) | ||
166 | * | ||
167 | * Returns 1 if link name is valid, otherwise 0. | ||
168 | */ | ||
169 | static int link_name_validate(const char *name, | ||
170 | struct tipc_link_name *name_parts) | ||
171 | { | ||
172 | char name_copy[TIPC_MAX_LINK_NAME]; | ||
173 | char *addr_local; | ||
174 | char *if_local; | ||
175 | char *addr_peer; | ||
176 | char *if_peer; | ||
177 | char dummy; | ||
178 | u32 z_local, c_local, n_local; | ||
179 | u32 z_peer, c_peer, n_peer; | ||
180 | u32 if_local_len; | ||
181 | u32 if_peer_len; | ||
182 | |||
183 | /* copy link name & ensure length is OK */ | ||
184 | name_copy[TIPC_MAX_LINK_NAME - 1] = 0; | ||
185 | /* need above in case non-Posix strncpy() doesn't pad with nulls */ | ||
186 | strncpy(name_copy, name, TIPC_MAX_LINK_NAME); | ||
187 | if (name_copy[TIPC_MAX_LINK_NAME - 1] != 0) | ||
188 | return 0; | ||
189 | |||
190 | /* ensure all component parts of link name are present */ | ||
191 | addr_local = name_copy; | ||
192 | if_local = strchr(addr_local, ':'); | ||
193 | if (if_local == NULL) | ||
194 | return 0; | ||
195 | *(if_local++) = 0; | ||
196 | addr_peer = strchr(if_local, '-'); | ||
197 | if (addr_peer == NULL) | ||
198 | return 0; | ||
199 | *(addr_peer++) = 0; | ||
200 | if_local_len = addr_peer - if_local; | ||
201 | if_peer = strchr(addr_peer, ':'); | ||
202 | if (if_peer == NULL) | ||
203 | return 0; | ||
204 | *(if_peer++) = 0; | ||
205 | if_peer_len = strlen(if_peer) + 1; | ||
206 | |||
207 | /* validate component parts of link name */ | ||
208 | if ((sscanf(addr_local, "%u.%u.%u%c", | ||
209 | &z_local, &c_local, &n_local, &dummy) != 3) || | ||
210 | (sscanf(addr_peer, "%u.%u.%u%c", | ||
211 | &z_peer, &c_peer, &n_peer, &dummy) != 3) || | ||
212 | (z_local > 255) || (c_local > 4095) || (n_local > 4095) || | ||
213 | (z_peer > 255) || (c_peer > 4095) || (n_peer > 4095) || | ||
214 | (if_local_len <= 1) || (if_local_len > TIPC_MAX_IF_NAME) || | ||
215 | (if_peer_len <= 1) || (if_peer_len > TIPC_MAX_IF_NAME)) | ||
216 | return 0; | ||
217 | |||
218 | /* return link name components, if necessary */ | ||
219 | if (name_parts) { | ||
220 | name_parts->addr_local = tipc_addr(z_local, c_local, n_local); | ||
221 | strcpy(name_parts->if_local, if_local); | ||
222 | name_parts->addr_peer = tipc_addr(z_peer, c_peer, n_peer); | ||
223 | strcpy(name_parts->if_peer, if_peer); | ||
224 | } | ||
225 | return 1; | ||
226 | } | ||
227 | |||
228 | /** | ||
229 | * link_timeout - handle expiration of link timer | 149 | * link_timeout - handle expiration of link timer |
230 | * @l_ptr: pointer to link | 150 | * @l_ptr: pointer to link |
231 | * | 151 | * |
@@ -2580,25 +2500,21 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window) | |||
2580 | static struct tipc_link *link_find_link(const char *name, | 2500 | static struct tipc_link *link_find_link(const char *name, |
2581 | struct tipc_node **node) | 2501 | struct tipc_node **node) |
2582 | { | 2502 | { |
2583 | struct tipc_link_name link_name_parts; | ||
2584 | struct tipc_bearer *b_ptr; | ||
2585 | struct tipc_link *l_ptr; | 2503 | struct tipc_link *l_ptr; |
2504 | struct tipc_node *n_ptr; | ||
2505 | int i; | ||
2586 | 2506 | ||
2587 | if (!link_name_validate(name, &link_name_parts)) | 2507 | list_for_each_entry(n_ptr, &tipc_node_list, list) { |
2588 | return NULL; | 2508 | for (i = 0; i < MAX_BEARERS; i++) { |
2589 | 2509 | l_ptr = n_ptr->links[i]; | |
2590 | b_ptr = tipc_bearer_find_interface(link_name_parts.if_local); | 2510 | if (l_ptr && !strcmp(l_ptr->name, name)) |
2591 | if (!b_ptr) | 2511 | goto found; |
2592 | return NULL; | 2512 | } |
2593 | 2513 | } | |
2594 | *node = tipc_node_find(link_name_parts.addr_peer); | 2514 | l_ptr = NULL; |
2595 | if (!*node) | 2515 | n_ptr = NULL; |
2596 | return NULL; | 2516 | found: |
2597 | 2517 | *node = n_ptr; | |
2598 | l_ptr = (*node)->links[b_ptr->identity]; | ||
2599 | if (!l_ptr || strcmp(l_ptr->name, name)) | ||
2600 | return NULL; | ||
2601 | |||
2602 | return l_ptr; | 2518 | return l_ptr; |
2603 | } | 2519 | } |
2604 | 2520 | ||