aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c167
1 files changed, 44 insertions, 123 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 0cc3d9015c5d..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 ";
*/
#define START_CHANGEOVER 100000u
-/**
- * struct tipc_link_name - deconstructed link name
- * @addr_local: network address of node at this end
- * @if_local: name of interface at this end
- * @addr_peer: network address of node at far end
- * @if_peer: name of interface at far end
- */
-struct tipc_link_name {
- u32 addr_local;
- char if_local[TIPC_MAX_IF_NAME];
- u32 addr_peer;
- char if_peer[TIPC_MAX_IF_NAME];
-};
-
static void link_handle_out_of_seq_msg(struct tipc_link *l_ptr,
struct sk_buff *buf);
static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf);
@@ -97,8 +83,7 @@ static int link_recv_changeover_msg(struct tipc_link **l_ptr,
static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance);
static int link_send_sections_long(struct tipc_port *sender,
struct iovec const *msg_sect,
- u32 num_sect, unsigned int total_len,
- u32 destnode);
+ unsigned int len, u32 destnode);
static void link_state_event(struct tipc_link *l_ptr, u32 event);
static void link_reset_statistics(struct tipc_link *l_ptr);
static void link_print(struct tipc_link *l_ptr, const char *str);
@@ -161,72 +146,6 @@ int tipc_link_is_active(struct tipc_link *l_ptr)
}
/**
- * link_name_validate - validate & (optionally) deconstruct tipc_link name
- * @name: ptr to link name string
- * @name_parts: ptr to area for link name components (or NULL if not needed)
- *
- * Returns 1 if link name is valid, otherwise 0.
- */
-static int link_name_validate(const char *name,
- struct tipc_link_name *name_parts)
-{
- char name_copy[TIPC_MAX_LINK_NAME];
- char *addr_local;
- char *if_local;
- char *addr_peer;
- char *if_peer;
- char dummy;
- u32 z_local, c_local, n_local;
- u32 z_peer, c_peer, n_peer;
- u32 if_local_len;
- u32 if_peer_len;
-
- /* copy link name & ensure length is OK */
- name_copy[TIPC_MAX_LINK_NAME - 1] = 0;
- /* need above in case non-Posix strncpy() doesn't pad with nulls */
- strncpy(name_copy, name, TIPC_MAX_LINK_NAME);
- if (name_copy[TIPC_MAX_LINK_NAME - 1] != 0)
- return 0;
-
- /* ensure all component parts of link name are present */
- addr_local = name_copy;
- if_local = strchr(addr_local, ':');
- if (if_local == NULL)
- return 0;
- *(if_local++) = 0;
- addr_peer = strchr(if_local, '-');
- if (addr_peer == NULL)
- return 0;
- *(addr_peer++) = 0;
- if_local_len = addr_peer - if_local;
- if_peer = strchr(addr_peer, ':');
- if (if_peer == NULL)
- return 0;
- *(if_peer++) = 0;
- if_peer_len = strlen(if_peer) + 1;
-
- /* validate component parts of link name */
- if ((sscanf(addr_local, "%u.%u.%u%c",
- &z_local, &c_local, &n_local, &dummy) != 3) ||
- (sscanf(addr_peer, "%u.%u.%u%c",
- &z_peer, &c_peer, &n_peer, &dummy) != 3) ||
- (z_local > 255) || (c_local > 4095) || (n_local > 4095) ||
- (z_peer > 255) || (c_peer > 4095) || (n_peer > 4095) ||
- (if_local_len <= 1) || (if_local_len > TIPC_MAX_IF_NAME) ||
- (if_peer_len <= 1) || (if_peer_len > TIPC_MAX_IF_NAME))
- return 0;
-
- /* return link name components, if necessary */
- if (name_parts) {
- name_parts->addr_local = tipc_addr(z_local, c_local, n_local);
- strcpy(name_parts->if_local, if_local);
- name_parts->addr_peer = tipc_addr(z_peer, c_peer, n_peer);
- strcpy(name_parts->if_peer, if_peer);
- }
- return 1;
-}
-
-/**
* link_timeout - handle expiration of link timer
* @l_ptr: pointer to link
*
@@ -1065,8 +984,7 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
*/
int tipc_link_send_sections_fast(struct tipc_port *sender,
struct iovec const *msg_sect,
- const u32 num_sect, unsigned int total_len,
- u32 destaddr)
+ unsigned int len, u32 destaddr)
{
struct tipc_msg *hdr = &sender->phdr;
struct tipc_link *l_ptr;
@@ -1080,8 +998,7 @@ again:
* Try building message using port's max_pkt hint.
* (Must not hold any locks while building message.)
*/
- res = tipc_msg_build(hdr, msg_sect, num_sect, total_len,
- sender->max_pkt, &buf);
+ res = tipc_msg_build(hdr, msg_sect, len, sender->max_pkt, &buf);
/* Exit if build request was invalid */
if (unlikely(res < 0))
return res;
@@ -1121,8 +1038,7 @@ exit:
if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
goto again;
- return link_send_sections_long(sender, msg_sect,
- num_sect, total_len,
+ return link_send_sections_long(sender, msg_sect, len,
destaddr);
}
tipc_node_unlock(node);
@@ -1133,8 +1049,8 @@ exit:
if (buf)
return tipc_reject_msg(buf, TIPC_ERR_NO_NODE);
if (res >= 0)
- return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
- total_len, TIPC_ERR_NO_NODE);
+ return tipc_port_reject_sections(sender, hdr, msg_sect,
+ len, TIPC_ERR_NO_NODE);
return res;
}
@@ -1154,18 +1070,17 @@ exit:
*/
static int link_send_sections_long(struct tipc_port *sender,
struct iovec const *msg_sect,
- u32 num_sect, unsigned int total_len,
- u32 destaddr)
+ unsigned int len, u32 destaddr)
{
struct tipc_link *l_ptr;
struct tipc_node *node;
struct tipc_msg *hdr = &sender->phdr;
- u32 dsz = total_len;
+ u32 dsz = len;
u32 max_pkt, fragm_sz, rest;
struct tipc_msg fragm_hdr;
struct sk_buff *buf, *buf_chain, *prev;
u32 fragm_crs, fragm_rest, hsz, sect_rest;
- const unchar *sect_crs;
+ const unchar __user *sect_crs;
int curr_sect;
u32 fragm_no;
int res = 0;
@@ -1207,7 +1122,7 @@ again:
if (!sect_rest) {
sect_rest = msg_sect[++curr_sect].iov_len;
- sect_crs = (const unchar *)msg_sect[curr_sect].iov_base;
+ sect_crs = msg_sect[curr_sect].iov_base;
}
if (sect_rest < fragm_rest)
@@ -1283,8 +1198,8 @@ reject:
buf = buf_chain->next;
kfree_skb(buf_chain);
}
- return tipc_port_reject_sections(sender, hdr, msg_sect, num_sect,
- total_len, TIPC_ERR_NO_NODE);
+ return tipc_port_reject_sections(sender, hdr, msg_sect,
+ len, TIPC_ERR_NO_NODE);
}
/* Append chain of fragments to send queue & send them */
@@ -2585,25 +2500,21 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
static struct tipc_link *link_find_link(const char *name,
struct tipc_node **node)
{
- struct tipc_link_name link_name_parts;
- struct tipc_bearer *b_ptr;
struct tipc_link *l_ptr;
+ struct tipc_node *n_ptr;
+ int i;
- if (!link_name_validate(name, &link_name_parts))
- return NULL;
-
- b_ptr = tipc_bearer_find_interface(link_name_parts.if_local);
- if (!b_ptr)
- return NULL;
-
- *node = tipc_node_find(link_name_parts.addr_peer);
- if (!*node)
- return NULL;
-
- l_ptr = (*node)->links[b_ptr->identity];
- if (!l_ptr || strcmp(l_ptr->name, name))
- return NULL;
-
+ list_for_each_entry(n_ptr, &tipc_node_list, list) {
+ for (i = 0; i < MAX_BEARERS; i++) {
+ l_ptr = n_ptr->links[i];
+ if (l_ptr && !strcmp(l_ptr->name, name))
+ goto found;
+ }
+ }
+ l_ptr = NULL;
+ n_ptr = NULL;
+found:
+ *node = n_ptr;
return l_ptr;
}
@@ -2646,6 +2557,7 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
struct tipc_link *l_ptr;
struct tipc_bearer *b_ptr;
struct tipc_media *m_ptr;
+ int res = 0;
l_ptr = link_find_link(name, &node);
if (l_ptr) {
@@ -2668,9 +2580,12 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
case TIPC_CMD_SET_LINK_WINDOW:
tipc_link_set_queue_limits(l_ptr, new_value);
break;
+ default:
+ res = -EINVAL;
+ break;
}
tipc_node_unlock(node);
- return 0;
+ return res;
}
b_ptr = tipc_bearer_find(name);
@@ -2678,15 +2593,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
switch (cmd) {
case TIPC_CMD_SET_LINK_TOL:
b_ptr->tolerance = new_value;
- return 0;
+ break;
case TIPC_CMD_SET_LINK_PRI:
b_ptr->priority = new_value;
- return 0;
+ break;
case TIPC_CMD_SET_LINK_WINDOW:
b_ptr->window = new_value;
- return 0;
+ break;
+ default:
+ res = -EINVAL;
+ break;
}
- return -EINVAL;
+ return res;
}
m_ptr = tipc_media_find(name);
@@ -2695,15 +2613,18 @@ static int link_cmd_set_value(const char *name, u32 new_value, u16 cmd)
switch (cmd) {
case TIPC_CMD_SET_LINK_TOL:
m_ptr->tolerance = new_value;
- return 0;
+ break;
case TIPC_CMD_SET_LINK_PRI:
m_ptr->priority = new_value;
- return 0;
+ break;
case TIPC_CMD_SET_LINK_WINDOW:
m_ptr->window = new_value;
- return 0;
+ break;
+ default:
+ res = -EINVAL;
+ break;
}
- return -EINVAL;
+ return res;
}
struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space,