aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-02-13 17:29:05 -0500
committerDavid S. Miller <davem@davemloft.net>2014-02-13 17:57:05 -0500
commit03b92017933bd22a3dca6830048877dd3162f872 (patch)
treeb4632236d0c8dd6a325bc0787486fba3ab6bcb52 /net/tipc
parentb3f0f5c357e60b7a366d2c8d739b47452451868b (diff)
tipc: stricter behavior of message reassembly function
The function tipc_link_recv_fragment(struct sk_buff **buf) currently leaves the value of the input buffer pointer undefined when it returns, except when the return code indicates that the reassembly is complete. This despite the fact that it always consumes the input buffer. Here, we enforce a stricter behavior by this function, ensuring that the returned buffer pointer is non-NULL if and only if the reassembly is complete. This makes it possible to test for the buffer pointer as criteria for successful reassembly. We also rename the function to tipc_link_frag_rcv(), which is both shorter and more in line with common naming practice in the network subsystem. Apart from the new name, these changes have no impact on current users of the function, but makes it more practical for use in some planned future commits. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c6
-rw-r--r--net/tipc/link.c16
-rw-r--r--net/tipc/link.h6
3 files changed, 15 insertions, 13 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index bf860d9e75af..af35f76c6b29 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -481,9 +481,9 @@ receive:
481 tipc_link_recv_bundle(buf); 481 tipc_link_recv_bundle(buf);
482 } else if (msg_user(msg) == MSG_FRAGMENTER) { 482 } else if (msg_user(msg) == MSG_FRAGMENTER) {
483 int ret; 483 int ret;
484 ret = tipc_link_recv_fragment(&node->bclink.reasm_head, 484 ret = tipc_link_frag_rcv(&node->bclink.reasm_head,
485 &node->bclink.reasm_tail, 485 &node->bclink.reasm_tail,
486 &buf); 486 &buf);
487 if (ret == LINK_REASM_ERROR) 487 if (ret == LINK_REASM_ERROR)
488 goto unlock; 488 goto unlock;
489 spin_lock_bh(&bc_lock); 489 spin_lock_bh(&bc_lock);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index d4b5de41b682..17fbd15fcad8 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1584,9 +1584,9 @@ deliver:
1584 continue; 1584 continue;
1585 case MSG_FRAGMENTER: 1585 case MSG_FRAGMENTER:
1586 l_ptr->stats.recv_fragments++; 1586 l_ptr->stats.recv_fragments++;
1587 ret = tipc_link_recv_fragment(&l_ptr->reasm_head, 1587 ret = tipc_link_frag_rcv(&l_ptr->reasm_head,
1588 &l_ptr->reasm_tail, 1588 &l_ptr->reasm_tail,
1589 &buf); 1589 &buf);
1590 if (ret == LINK_REASM_COMPLETE) { 1590 if (ret == LINK_REASM_COMPLETE) {
1591 l_ptr->stats.recv_fragmented++; 1591 l_ptr->stats.recv_fragmented++;
1592 msg = buf_msg(buf); 1592 msg = buf_msg(buf);
@@ -2277,12 +2277,11 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf)
2277 return dsz; 2277 return dsz;
2278} 2278}
2279 2279
2280/* 2280/* tipc_link_frag_rcv(): Called with node lock on. Returns
2281 * tipc_link_recv_fragment(): Called with node lock on. Returns
2282 * the reassembled buffer if message is complete. 2281 * the reassembled buffer if message is complete.
2283 */ 2282 */
2284int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail, 2283int tipc_link_frag_rcv(struct sk_buff **head, struct sk_buff **tail,
2285 struct sk_buff **fbuf) 2284 struct sk_buff **fbuf)
2286{ 2285{
2287 struct sk_buff *frag = *fbuf; 2286 struct sk_buff *frag = *fbuf;
2288 struct tipc_msg *msg = buf_msg(frag); 2287 struct tipc_msg *msg = buf_msg(frag);
@@ -2296,6 +2295,7 @@ int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail,
2296 goto out_free; 2295 goto out_free;
2297 *head = frag; 2296 *head = frag;
2298 skb_frag_list_init(*head); 2297 skb_frag_list_init(*head);
2298 *fbuf = NULL;
2299 return 0; 2299 return 0;
2300 } else if (*head && 2300 } else if (*head &&
2301 skb_try_coalesce(*head, frag, &headstolen, &delta)) { 2301 skb_try_coalesce(*head, frag, &headstolen, &delta)) {
@@ -2315,10 +2315,12 @@ int tipc_link_recv_fragment(struct sk_buff **head, struct sk_buff **tail,
2315 *tail = *head = NULL; 2315 *tail = *head = NULL;
2316 return LINK_REASM_COMPLETE; 2316 return LINK_REASM_COMPLETE;
2317 } 2317 }
2318 *fbuf = NULL;
2318 return 0; 2319 return 0;
2319out_free: 2320out_free:
2320 pr_warn_ratelimited("Link unable to reassemble fragmented message\n"); 2321 pr_warn_ratelimited("Link unable to reassemble fragmented message\n");
2321 kfree_skb(*fbuf); 2322 kfree_skb(*fbuf);
2323 *fbuf = NULL;
2322 return LINK_REASM_ERROR; 2324 return LINK_REASM_ERROR;
2323} 2325}
2324 2326
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 3b6aa65b608c..8addc5ec5fc6 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -239,9 +239,9 @@ int tipc_link_send_sections_fast(struct tipc_port *sender,
239 struct iovec const *msg_sect, 239 struct iovec const *msg_sect,
240 unsigned int len, u32 destnode); 240 unsigned int len, u32 destnode);
241void tipc_link_recv_bundle(struct sk_buff *buf); 241void tipc_link_recv_bundle(struct sk_buff *buf);
242int tipc_link_recv_fragment(struct sk_buff **reasm_head, 242int tipc_link_frag_rcv(struct sk_buff **reasm_head,
243 struct sk_buff **reasm_tail, 243 struct sk_buff **reasm_tail,
244 struct sk_buff **fbuf); 244 struct sk_buff **fbuf);
245void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, int prob, 245void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, int prob,
246 u32 gap, u32 tolerance, u32 priority, 246 u32 gap, u32 tolerance, u32 priority,
247 u32 acked_mtu); 247 u32 acked_mtu);