|
@@ -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);
|
|
@@ -160,72 +145,6 @@ int tipc_link_is_active(struct tipc_link *l_ptr)
|
|
|
(l_ptr->owner->active_links[1] == 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,
|