diff options
-rw-r--r-- | net/l2tp/l2tp_core.c | 54 |
1 files changed, 34 insertions, 20 deletions
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 6984c3a353cd..5ca29659171d 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -542,6 +542,38 @@ static inline int l2tp_verify_udp_checksum(struct sock *sk, | |||
542 | return __skb_checksum_complete(skb); | 542 | return __skb_checksum_complete(skb); |
543 | } | 543 | } |
544 | 544 | ||
545 | /* If packet has sequence numbers, queue it if acceptable. Returns 0 if | ||
546 | * acceptable, else non-zero. | ||
547 | */ | ||
548 | static int l2tp_recv_data_seq(struct l2tp_session *session, struct sk_buff *skb) | ||
549 | { | ||
550 | if (session->reorder_timeout != 0) { | ||
551 | /* Packet reordering enabled. Add skb to session's | ||
552 | * reorder queue, in order of ns. | ||
553 | */ | ||
554 | l2tp_recv_queue_skb(session, skb); | ||
555 | } else { | ||
556 | /* Packet reordering disabled. Discard out-of-sequence | ||
557 | * packets | ||
558 | */ | ||
559 | if (L2TP_SKB_CB(skb)->ns != session->nr) { | ||
560 | atomic_long_inc(&session->stats.rx_seq_discards); | ||
561 | l2tp_dbg(session, L2TP_MSG_SEQ, | ||
562 | "%s: oos pkt %u len %d discarded, waiting for %u, reorder_q_len=%d\n", | ||
563 | session->name, L2TP_SKB_CB(skb)->ns, | ||
564 | L2TP_SKB_CB(skb)->length, session->nr, | ||
565 | skb_queue_len(&session->reorder_q)); | ||
566 | goto discard; | ||
567 | } | ||
568 | skb_queue_tail(&session->reorder_q, skb); | ||
569 | } | ||
570 | |||
571 | return 0; | ||
572 | |||
573 | discard: | ||
574 | return 1; | ||
575 | } | ||
576 | |||
545 | /* Do receive processing of L2TP data frames. We handle both L2TPv2 | 577 | /* Do receive processing of L2TP data frames. We handle both L2TPv2 |
546 | * and L2TPv3 data frames here. | 578 | * and L2TPv3 data frames here. |
547 | * | 579 | * |
@@ -757,26 +789,8 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, | |||
757 | * enabled. Saved L2TP protocol info is stored in skb->sb[]. | 789 | * enabled. Saved L2TP protocol info is stored in skb->sb[]. |
758 | */ | 790 | */ |
759 | if (L2TP_SKB_CB(skb)->has_seq) { | 791 | if (L2TP_SKB_CB(skb)->has_seq) { |
760 | if (session->reorder_timeout != 0) { | 792 | if (l2tp_recv_data_seq(session, skb)) |
761 | /* Packet reordering enabled. Add skb to session's | 793 | goto discard; |
762 | * reorder queue, in order of ns. | ||
763 | */ | ||
764 | l2tp_recv_queue_skb(session, skb); | ||
765 | } else { | ||
766 | /* Packet reordering disabled. Discard out-of-sequence | ||
767 | * packets | ||
768 | */ | ||
769 | if (L2TP_SKB_CB(skb)->ns != session->nr) { | ||
770 | atomic_long_inc(&session->stats.rx_seq_discards); | ||
771 | l2tp_dbg(session, L2TP_MSG_SEQ, | ||
772 | "%s: oos pkt %u len %d discarded, waiting for %u, reorder_q_len=%d\n", | ||
773 | session->name, L2TP_SKB_CB(skb)->ns, | ||
774 | L2TP_SKB_CB(skb)->length, session->nr, | ||
775 | skb_queue_len(&session->reorder_q)); | ||
776 | goto discard; | ||
777 | } | ||
778 | skb_queue_tail(&session->reorder_q, skb); | ||
779 | } | ||
780 | } else { | 794 | } else { |
781 | /* No sequence numbers. Add the skb to the tail of the | 795 | /* No sequence numbers. Add the skb to the tail of the |
782 | * reorder queue. This ensures that it will be | 796 | * reorder queue. This ensures that it will be |