aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorErik Hugne <erik.hugne@ericsson.com>2013-10-18 01:23:21 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-18 13:20:43 -0400
commitbbfbe47cc99ce093708aaf28b7f2c08d28045c67 (patch)
treed12bae2180f77b4dc48580bf5a85b995f1f4909c /net/tipc
parent636c0371a737c27510df867161fb8100c2f086bd (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.c110
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 */
85struct 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
92static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr, 78static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
93 struct sk_buff *buf); 79 struct sk_buff *buf);
94static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf); 80static 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 */
169static 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)
2580static struct tipc_link *link_find_link(const char *name, 2500static 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; 2516found:
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