sctp: handle ootb packet in chunk order as defined
authorShan Wei <shanwei@cn.fujitsu.com>
Tue, 19 Apr 2011 21:30:01 +0000 (21:30 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 20 Apr 2011 08:51:04 +0000 (01:51 -0700)
Changed the order of processing SHUTDOWN ACK and COOKIE ACK
refer to section 8.4:Handle "Out of the Blue" Packets.

SHUTDOWN ACK chunk should be processed before processing
"Stale Cookie" ERROR or a COOKIE ACK.

Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>
Signed-off-by: Shan Wei <shanwei@cn.fujitsu.com>
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sctp/input.c
net/sctp/sm_statefuns.c

index 30cec77..3a8eb79 100644 (file)
@@ -661,7 +661,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb)
 {
        sctp_chunkhdr_t *ch;
        __u8 *ch_end;
-       sctp_errhdr_t *err;
 
        ch = (sctp_chunkhdr_t *) skb->data;
 
@@ -697,20 +696,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb)
                if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data)
                        goto discard;
 
-               /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR
-                * or a COOKIE ACK the SCTP Packet should be silently
-                * discarded.
-                */
-               if (SCTP_CID_COOKIE_ACK == ch->type)
-                       goto discard;
-
-               if (SCTP_CID_ERROR == ch->type) {
-                       sctp_walk_errors(err, ch) {
-                               if (SCTP_ERROR_STALE_COOKIE == err->cause)
-                                       goto discard;
-                       }
-               }
-
                ch = (sctp_chunkhdr_t *) ch_end;
        } while (ch_end < skb_tail_pointer(skb));
 
index 194d5ec..ad3b43b 100644 (file)
@@ -3332,8 +3332,10 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
        struct sctp_chunk *chunk = arg;
        struct sk_buff *skb = chunk->skb;
        sctp_chunkhdr_t *ch;
+       sctp_errhdr_t *err;
        __u8 *ch_end;
        int ootb_shut_ack = 0;
+       int ootb_cookie_ack = 0;
 
        SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
 
@@ -3358,6 +3360,23 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
                if (SCTP_CID_ABORT == ch->type)
                        return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+               /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR
+                * or a COOKIE ACK the SCTP Packet should be silently
+                * discarded.
+                */
+
+               if (SCTP_CID_COOKIE_ACK == ch->type)
+                       ootb_cookie_ack = 1;
+
+               if (SCTP_CID_ERROR == ch->type) {
+                       sctp_walk_errors(err, ch) {
+                               if (SCTP_ERROR_STALE_COOKIE == err->cause) {
+                                       ootb_cookie_ack = 1;
+                                       break;
+                               }
+                       }
+               }
+
                /* Report violation if chunk len overflows */
                ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
                if (ch_end > skb_tail_pointer(skb))
@@ -3369,6 +3388,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
 
        if (ootb_shut_ack)
                return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
+       else if (ootb_cookie_ack)
+               return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
        else
                return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 }