diff options
author | Shan Wei <shanwei@cn.fujitsu.com> | 2011-04-19 17:30:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-20 04:51:04 -0400 |
commit | 85c5ed4e44a262344ce43b4bf23204107923ca95 (patch) | |
tree | 1b494d271d2e08a4f316bbf8cbeb677eed11b939 /net | |
parent | deb85a6ecc432a4f342004a6ac2a0dad7cba6846 (diff) |
sctp: handle ootb packet in chunk order as defined
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/sctp/input.c | 15 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 21 |
2 files changed, 21 insertions, 15 deletions
diff --git a/net/sctp/input.c b/net/sctp/input.c index 30cec7732e80..3a8eb79eb78b 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -661,7 +661,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb) | |||
661 | { | 661 | { |
662 | sctp_chunkhdr_t *ch; | 662 | sctp_chunkhdr_t *ch; |
663 | __u8 *ch_end; | 663 | __u8 *ch_end; |
664 | sctp_errhdr_t *err; | ||
665 | 664 | ||
666 | ch = (sctp_chunkhdr_t *) skb->data; | 665 | ch = (sctp_chunkhdr_t *) skb->data; |
667 | 666 | ||
@@ -697,20 +696,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb) | |||
697 | if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data) | 696 | if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data) |
698 | goto discard; | 697 | goto discard; |
699 | 698 | ||
700 | /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR | ||
701 | * or a COOKIE ACK the SCTP Packet should be silently | ||
702 | * discarded. | ||
703 | */ | ||
704 | if (SCTP_CID_COOKIE_ACK == ch->type) | ||
705 | goto discard; | ||
706 | |||
707 | if (SCTP_CID_ERROR == ch->type) { | ||
708 | sctp_walk_errors(err, ch) { | ||
709 | if (SCTP_ERROR_STALE_COOKIE == err->cause) | ||
710 | goto discard; | ||
711 | } | ||
712 | } | ||
713 | |||
714 | ch = (sctp_chunkhdr_t *) ch_end; | 699 | ch = (sctp_chunkhdr_t *) ch_end; |
715 | } while (ch_end < skb_tail_pointer(skb)); | 700 | } while (ch_end < skb_tail_pointer(skb)); |
716 | 701 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 194d5ecab5c3..ad3b43bb75cc 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -3332,8 +3332,10 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3332 | struct sctp_chunk *chunk = arg; | 3332 | struct sctp_chunk *chunk = arg; |
3333 | struct sk_buff *skb = chunk->skb; | 3333 | struct sk_buff *skb = chunk->skb; |
3334 | sctp_chunkhdr_t *ch; | 3334 | sctp_chunkhdr_t *ch; |
3335 | sctp_errhdr_t *err; | ||
3335 | __u8 *ch_end; | 3336 | __u8 *ch_end; |
3336 | int ootb_shut_ack = 0; | 3337 | int ootb_shut_ack = 0; |
3338 | int ootb_cookie_ack = 0; | ||
3337 | 3339 | ||
3338 | SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); | 3340 | SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES); |
3339 | 3341 | ||
@@ -3358,6 +3360,23 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3358 | if (SCTP_CID_ABORT == ch->type) | 3360 | if (SCTP_CID_ABORT == ch->type) |
3359 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | 3361 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); |
3360 | 3362 | ||
3363 | /* RFC 8.4, 7) If the packet contains a "Stale cookie" ERROR | ||
3364 | * or a COOKIE ACK the SCTP Packet should be silently | ||
3365 | * discarded. | ||
3366 | */ | ||
3367 | |||
3368 | if (SCTP_CID_COOKIE_ACK == ch->type) | ||
3369 | ootb_cookie_ack = 1; | ||
3370 | |||
3371 | if (SCTP_CID_ERROR == ch->type) { | ||
3372 | sctp_walk_errors(err, ch) { | ||
3373 | if (SCTP_ERROR_STALE_COOKIE == err->cause) { | ||
3374 | ootb_cookie_ack = 1; | ||
3375 | break; | ||
3376 | } | ||
3377 | } | ||
3378 | } | ||
3379 | |||
3361 | /* Report violation if chunk len overflows */ | 3380 | /* Report violation if chunk len overflows */ |
3362 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); | 3381 | ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length)); |
3363 | if (ch_end > skb_tail_pointer(skb)) | 3382 | if (ch_end > skb_tail_pointer(skb)) |
@@ -3369,6 +3388,8 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep, | |||
3369 | 3388 | ||
3370 | if (ootb_shut_ack) | 3389 | if (ootb_shut_ack) |
3371 | return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); | 3390 | return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands); |
3391 | else if (ootb_cookie_ack) | ||
3392 | return sctp_sf_pdiscard(ep, asoc, type, arg, commands); | ||
3372 | else | 3393 | else |
3373 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); | 3394 | return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); |
3374 | } | 3395 | } |