diff options
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r-- | net/tipc/msg.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 00fbb5c4b2ef..f48e5857210f 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -525,6 +525,10 @@ bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err) | |||
525 | if (hlen == SHORT_H_SIZE) | 525 | if (hlen == SHORT_H_SIZE) |
526 | hlen = BASIC_H_SIZE; | 526 | hlen = BASIC_H_SIZE; |
527 | 527 | ||
528 | /* Don't return data along with SYN+, - sender has a clone */ | ||
529 | if (msg_is_syn(_hdr) && err == TIPC_ERR_OVERLOAD) | ||
530 | dlen = 0; | ||
531 | |||
528 | /* Allocate new buffer to return */ | 532 | /* Allocate new buffer to return */ |
529 | *skb = tipc_buf_acquire(hlen + dlen, GFP_ATOMIC); | 533 | *skb = tipc_buf_acquire(hlen + dlen, GFP_ATOMIC); |
530 | if (!*skb) | 534 | if (!*skb) |
@@ -552,6 +556,22 @@ exit: | |||
552 | return false; | 556 | return false; |
553 | } | 557 | } |
554 | 558 | ||
559 | bool tipc_msg_skb_clone(struct sk_buff_head *msg, struct sk_buff_head *cpy) | ||
560 | { | ||
561 | struct sk_buff *skb, *_skb; | ||
562 | |||
563 | skb_queue_walk(msg, skb) { | ||
564 | _skb = skb_clone(skb, GFP_ATOMIC); | ||
565 | if (!_skb) { | ||
566 | __skb_queue_purge(cpy); | ||
567 | pr_err_ratelimited("Failed to clone buffer chain\n"); | ||
568 | return false; | ||
569 | } | ||
570 | __skb_queue_tail(cpy, _skb); | ||
571 | } | ||
572 | return true; | ||
573 | } | ||
574 | |||
555 | /** | 575 | /** |
556 | * tipc_msg_lookup_dest(): try to find new destination for named message | 576 | * tipc_msg_lookup_dest(): try to find new destination for named message |
557 | * @skb: the buffer containing the message. | 577 | * @skb: the buffer containing the message. |