aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/msg.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-10-15 14:52:43 -0400
committerDavid S. Miller <davem@davemloft.net>2015-10-16 02:55:21 -0400
commit8306f99a517b91ebf8fa94d017c2c84ca62e107c (patch)
treebbcdfbe08e36290dec053b7a155c5a4320987ee0 /net/tipc/msg.c
parent81204c492b05274ade680c54787cd8ba234dcfd7 (diff)
tipc: disallow packet duplicates in link deferred queue
After the previous commits, we are guaranteed that no packets of type LINK_PROTOCOL or with illegal sequence numbers will be attempted added to the link deferred queue. This makes it possible to make some simplifications to the sorting algorithm in the function tipc_skb_queue_sorted(). We also alter the function so that it will drop packets if one with the same seqeunce number is already present in the queue. This is necessary because we have identified weird packet sequences, involving duplicate packets, where a legitimate in-sequence packet may advance to the head of the queue without being detected and de-queued. Finally, we make this function outline, since it will now be called only in exceptional cases. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r--net/tipc/msg.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index c5ac436235e0..454f5ec275c8 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -590,3 +590,34 @@ error:
590 kfree_skb(head); 590 kfree_skb(head);
591 return NULL; 591 return NULL;
592} 592}
593
594/* tipc_skb_queue_sorted(); sort pkt into list according to sequence number
595 * @list: list to be appended to
596 * @seqno: sequence number of buffer to add
597 * @skb: buffer to add
598 */
599void __tipc_skb_queue_sorted(struct sk_buff_head *list, u16 seqno,
600 struct sk_buff *skb)
601{
602 struct sk_buff *_skb, *tmp;
603
604 if (skb_queue_empty(list) || less(seqno, buf_seqno(skb_peek(list)))) {
605 __skb_queue_head(list, skb);
606 return;
607 }
608
609 if (more(seqno, buf_seqno(skb_peek_tail(list)))) {
610 __skb_queue_tail(list, skb);
611 return;
612 }
613
614 skb_queue_walk_safe(list, _skb, tmp) {
615 if (more(seqno, buf_seqno(_skb)))
616 continue;
617 if (seqno == buf_seqno(_skb))
618 break;
619 __skb_queue_before(list, _skb, skb);
620 return;
621 }
622 kfree_skb(skb);
623}