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.c493
1 files changed, 170 insertions, 323 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 0cc3d9015c5d..69cd9bf3f561 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
*
@@ -485,15 +404,9 @@ static void link_release_outqueue(struct tipc_link *l_ptr)
*/
void tipc_link_reset_fragments(struct tipc_link *l_ptr)
{
- struct sk_buff *buf = l_ptr->defragm_buf;
- struct sk_buff *next;
-
- while (buf) {
- next = buf->next;
- kfree_skb(buf);
- buf = next;
- }
- l_ptr->defragm_buf = NULL;
+ kfree_skb(l_ptr->reasm_head);
+ l_ptr->reasm_head = NULL;
+ l_ptr->reasm_tail = NULL;
}
/**
@@ -1065,8 +978,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 +992,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 +1032,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 +1043,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 +1064,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 +1116,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 +1192,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 */
@@ -1592,15 +1501,15 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
/* Ensure bearer is still enabled */
if (unlikely(!b_ptr->active))
- goto cont;
+ goto discard;
/* Ensure message is well-formed */
if (unlikely(!link_recv_buf_validate(buf)))
- goto cont;
+ goto discard;
/* Ensure message data is a single contiguous unit */
if (unlikely(skb_linearize(buf)))
- goto cont;
+ goto discard;
/* Handle arrival of a non-unicast link message */
msg = buf_msg(buf);
@@ -1616,20 +1525,18 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
/* Discard unicast link messages destined for another node */
if (unlikely(!msg_short(msg) &&
(msg_destnode(msg) != tipc_own_addr)))
- goto cont;
+ goto discard;
/* Locate neighboring node that sent message */
n_ptr = tipc_node_find(msg_prevnode(msg));
if (unlikely(!n_ptr))
- goto cont;
+ goto discard;
tipc_node_lock(n_ptr);
/* Locate unicast link endpoint that should handle message */
l_ptr = n_ptr->links[b_ptr->identity];
- if (unlikely(!l_ptr)) {
- tipc_node_unlock(n_ptr);
- goto cont;
- }
+ if (unlikely(!l_ptr))
+ goto unlock_discard;
/* Verify that communication with node is currently allowed */
if ((n_ptr->block_setup & WAIT_PEER_DOWN) &&
@@ -1639,10 +1546,8 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
!msg_redundant_link(msg))
n_ptr->block_setup &= ~WAIT_PEER_DOWN;
- if (n_ptr->block_setup) {
- tipc_node_unlock(n_ptr);
- goto cont;
- }
+ if (n_ptr->block_setup)
+ goto unlock_discard;
/* Validate message sequence number info */
seq_no = msg_seqno(msg);
@@ -1678,98 +1583,100 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *b_ptr)
/* Now (finally!) process the incoming message */
protocol_check:
- if (likely(link_working_working(l_ptr))) {
- if (likely(seq_no == mod(l_ptr->next_in_no))) {
- l_ptr->next_in_no++;
- if (unlikely(l_ptr->oldest_deferred_in))
- head = link_insert_deferred_queue(l_ptr,
- head);
-deliver:
- if (likely(msg_isdata(msg))) {
- tipc_node_unlock(n_ptr);
- tipc_port_recv_msg(buf);
- continue;
- }
- switch (msg_user(msg)) {
- int ret;
- case MSG_BUNDLER:
- l_ptr->stats.recv_bundles++;
- l_ptr->stats.recv_bundled +=
- msg_msgcnt(msg);
- tipc_node_unlock(n_ptr);
- tipc_link_recv_bundle(buf);
- continue;
- case NAME_DISTRIBUTOR:
- n_ptr->bclink.recv_permitted = true;
- tipc_node_unlock(n_ptr);
- tipc_named_recv(buf);
- continue;
- case BCAST_PROTOCOL:
- tipc_link_recv_sync(n_ptr, buf);
- tipc_node_unlock(n_ptr);
- continue;
- case CONN_MANAGER:
- tipc_node_unlock(n_ptr);
- tipc_port_recv_proto_msg(buf);
- continue;
- case MSG_FRAGMENTER:
- l_ptr->stats.recv_fragments++;
- ret = tipc_link_recv_fragment(
- &l_ptr->defragm_buf,
- &buf, &msg);
- if (ret == 1) {
- l_ptr->stats.recv_fragmented++;
- goto deliver;
- }
- if (ret == -1)
- l_ptr->next_in_no--;
- break;
- case CHANGEOVER_PROTOCOL:
- type = msg_type(msg);
- if (link_recv_changeover_msg(&l_ptr,
- &buf)) {
- msg = buf_msg(buf);
- seq_no = msg_seqno(msg);
- if (type == ORIGINAL_MSG)
- goto deliver;
- goto protocol_check;
- }
- break;
- default:
- kfree_skb(buf);
- buf = NULL;
- break;
- }
+ if (unlikely(!link_working_working(l_ptr))) {
+ if (msg_user(msg) == LINK_PROTOCOL) {
+ link_recv_proto_msg(l_ptr, buf);
+ head = link_insert_deferred_queue(l_ptr, head);
+ tipc_node_unlock(n_ptr);
+ continue;
+ }
+
+ /* Traffic message. Conditionally activate link */
+ link_state_event(l_ptr, TRAFFIC_MSG_EVT);
+
+ if (link_working_working(l_ptr)) {
+ /* Re-insert buffer in front of queue */
+ buf->next = head;
+ head = buf;
tipc_node_unlock(n_ptr);
- tipc_net_route_msg(buf);
continue;
}
+ goto unlock_discard;
+ }
+
+ /* Link is now in state WORKING_WORKING */
+ if (unlikely(seq_no != mod(l_ptr->next_in_no))) {
link_handle_out_of_seq_msg(l_ptr, buf);
head = link_insert_deferred_queue(l_ptr, head);
tipc_node_unlock(n_ptr);
continue;
}
-
- /* Link is not in state WORKING_WORKING */
- if (msg_user(msg) == LINK_PROTOCOL) {
- link_recv_proto_msg(l_ptr, buf);
+ l_ptr->next_in_no++;
+ if (unlikely(l_ptr->oldest_deferred_in))
head = link_insert_deferred_queue(l_ptr, head);
+deliver:
+ if (likely(msg_isdata(msg))) {
tipc_node_unlock(n_ptr);
+ tipc_port_recv_msg(buf);
continue;
}
-
- /* Traffic message. Conditionally activate link */
- link_state_event(l_ptr, TRAFFIC_MSG_EVT);
-
- if (link_working_working(l_ptr)) {
- /* Re-insert buffer in front of queue */
- buf->next = head;
- head = buf;
+ switch (msg_user(msg)) {
+ int ret;
+ case MSG_BUNDLER:
+ l_ptr->stats.recv_bundles++;
+ l_ptr->stats.recv_bundled += msg_msgcnt(msg);
+ tipc_node_unlock(n_ptr);
+ tipc_link_recv_bundle(buf);
+ continue;
+ case NAME_DISTRIBUTOR:
+ n_ptr->bclink.recv_permitted = true;
+ tipc_node_unlock(n_ptr);
+ tipc_named_recv(buf);
+ continue;
+ case BCAST_PROTOCOL:
+ tipc_link_recv_sync(n_ptr, buf);
+ tipc_node_unlock(n_ptr);
+ continue;
+ case CONN_MANAGER:
+ tipc_node_unlock(n_ptr);
+ tipc_port_recv_proto_msg(buf);
+ continue;
+ case MSG_FRAGMENTER:
+ l_ptr->stats.recv_fragments++;
+ ret = tipc_link_recv_fragment(&l_ptr->reasm_head,
+ &l_ptr->reasm_tail,
+ &buf);
+ if (ret == LINK_REASM_COMPLETE) {
+ l_ptr->stats.recv_fragmented++;
+ msg = buf_msg(buf);
+ goto deliver;
+ }
+ if (ret == LINK_REASM_ERROR)
+ tipc_link_reset(l_ptr);
tipc_node_unlock(n_ptr);
continue;
+ case CHANGEOVER_PROTOCOL:
+ type = msg_type(msg);
+ if (link_recv_changeover_msg(&l_ptr, &buf)) {
+ msg = buf_msg(buf);
+ seq_no = msg_seqno(msg);
+ if (type == ORIGINAL_MSG)
+ goto deliver;
+ goto protocol_check;
+ }
+ break;
+ default:
+ kfree_skb(buf);
+ buf = NULL;
+ break;
}
tipc_node_unlock(n_ptr);
-cont:
+ tipc_net_route_msg(buf);
+ continue;
+unlock_discard:
+
+ tipc_node_unlock(n_ptr);
+discard:
kfree_skb(buf);
}
read_unlock_bh(&tipc_net_lock);
@@ -2432,114 +2339,48 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
}
/*
- * A pending message being re-assembled must store certain values
- * to handle subsequent fragments correctly. The following functions
- * help storing these values in unused, available fields in the
- * pending message. This makes dynamic memory allocation unnecessary.
- */
-static void set_long_msg_seqno(struct sk_buff *buf, u32 seqno)
-{
- msg_set_seqno(buf_msg(buf), seqno);
-}
-
-static u32 get_fragm_size(struct sk_buff *buf)
-{
- return msg_ack(buf_msg(buf));
-}
-
-static void set_fragm_size(struct sk_buff *buf, u32 sz)
-{
- msg_set_ack(buf_msg(buf), sz);
-}
-
-static u32 get_expected_frags(struct sk_buff *buf)
-{
- return msg_bcast_ack(buf_msg(buf));
-}
-
-static void set_expected_frags(struct sk_buff *buf, u32 exp)
-{
- msg_set_bcast_ack(buf_msg(buf), exp);
-}
-
-/*
* tipc_link_recv_fragment(): Called with node lock on. Returns
* the reassembled buffer if message is complete.
*/
-int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb,
- struct tipc_msg **m)
-{
- struct sk_buff *prev = NULL;
- struct sk_buff *fbuf = *fb;
- struct tipc_msg *fragm = buf_msg(fbuf);
- struct sk_buff *pbuf = *pending;
- u32 long_msg_seq_no = msg_long_msgno(fragm);
-
- *fb = NULL;
-
- /* Is there an incomplete message waiting for this fragment? */
- while (pbuf && ((buf_seqno(pbuf) != long_msg_seq_no) ||
- (msg_orignode(fragm) != msg_orignode(buf_msg(pbuf))))) {
- prev = pbuf;
- pbuf = pbuf->next;
- }
-
- if (!pbuf && (msg_type(fragm) == FIRST_FRAGMENT)) {
- struct tipc_msg *imsg = (struct tipc_msg *)msg_data(fragm);
- u32 msg_sz = msg_size(imsg);
- u32 fragm_sz = msg_data_sz(fragm);
- u32 exp_fragm_cnt;
- u32 max = TIPC_MAX_USER_MSG_SIZE + NAMED_H_SIZE;
-
- if (msg_type(imsg) == TIPC_MCAST_MSG)
- max = TIPC_MAX_USER_MSG_SIZE + MCAST_H_SIZE;
- if (fragm_sz == 0 || msg_size(imsg) > max) {
- kfree_skb(fbuf);
- return 0;
- }
- exp_fragm_cnt = msg_sz / fragm_sz + !!(msg_sz % fragm_sz);
- pbuf = tipc_buf_acquire(msg_size(imsg));
- if (pbuf != NULL) {
- pbuf->next = *pending;
- *pending = pbuf;
- skb_copy_to_linear_data(pbuf, imsg,
- msg_data_sz(fragm));
- /* Prepare buffer for subsequent fragments. */
- set_long_msg_seqno(pbuf, long_msg_seq_no);
- set_fragm_size(pbuf, fragm_sz);
- set_expected_frags(pbuf, exp_fragm_cnt - 1);
- } else {
- pr_debug("Link unable to reassemble fragmented message\n");
- kfree_skb(fbuf);
- return -1;
- }
- kfree_skb(fbuf);
- return 0;
- } else if (pbuf && (msg_type(fragm) != FIRST_FRAGMENT)) {
- u32 dsz = msg_data_sz(fragm);
- u32 fsz = get_fragm_size(pbuf);
- u32 crs = ((msg_fragm_no(fragm) - 1) * fsz);
- u32 exp_frags = get_expected_frags(pbuf) - 1;
- skb_copy_to_linear_data_offset(pbuf, crs,
- msg_data(fragm), dsz);
- kfree_skb(fbuf);
-
- /* Is message complete? */
- if (exp_frags == 0) {
- if (prev)
- prev->next = pbuf->next;
- else
- *pending = pbuf->next;
- msg_reset_reroute_cnt(buf_msg(pbuf));
- *fb = pbuf;
- *m = buf_msg(pbuf);
- return 1;
- }
- set_expected_frags(pbuf, exp_frags);
+int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail,
+ struct sk_buff **fbuf)
+{
+ struct sk_buff *frag = *fbuf;
+ struct tipc_msg *msg = buf_msg(frag);
+ u32 fragid = msg_type(msg);
+ bool headstolen;
+ int delta;
+
+ skb_pull(frag, msg_hdr_sz(msg));
+ if (fragid == FIRST_FRAGMENT) {
+ if (*head || skb_unclone(frag, GFP_ATOMIC))
+ goto out_free;
+ *head = frag;
+ skb_frag_list_init(*head);
return 0;
+ } else if (*head &&
+ skb_try_coalesce(*head, frag, &headstolen, &delta)) {
+ kfree_skb_partial(frag, headstolen);
+ } else {
+ if (!*head)
+ goto out_free;
+ if (!skb_has_frag_list(*head))
+ skb_shinfo(*head)->frag_list = frag;
+ else
+ (*tail)->next = frag;
+ *tail = frag;
+ (*head)->truesize += frag->truesize;
+ }
+ if (fragid == LAST_FRAGMENT) {
+ *fbuf = *head;
+ *tail = *head = NULL;
+ return LINK_REASM_COMPLETE;
}
- kfree_skb(fbuf);
return 0;
+out_free:
+ pr_warn_ratelimited("Link unable to reassemble fragmented message\n");
+ kfree_skb(*fbuf);
+ return LINK_REASM_ERROR;
}
static void link_set_supervision_props(struct tipc_link *l_ptr, u32 tolerance)
@@ -2585,25 +2426,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 +2483,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 +2506,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 +2519,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 +2539,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,