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>
{
sctp_chunkhdr_t *ch;
__u8 *ch_end;
{
sctp_chunkhdr_t *ch;
__u8 *ch_end;
ch = (sctp_chunkhdr_t *) skb->data;
ch = (sctp_chunkhdr_t *) skb->data;
if (SCTP_CID_INIT == ch->type && (void *)ch != skb->data)
goto discard;
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));
ch = (sctp_chunkhdr_t *) ch_end;
} while (ch_end < skb_tail_pointer(skb));
struct sctp_chunk *chunk = arg;
struct sk_buff *skb = chunk->skb;
sctp_chunkhdr_t *ch;
struct sctp_chunk *chunk = arg;
struct sk_buff *skb = chunk->skb;
sctp_chunkhdr_t *ch;
__u8 *ch_end;
int ootb_shut_ack = 0;
__u8 *ch_end;
int ootb_shut_ack = 0;
+ int ootb_cookie_ack = 0;
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
if (SCTP_CID_ABORT == ch->type)
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
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))
/* Report violation if chunk len overflows */
ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
if (ch_end > skb_tail_pointer(skb))
if (ootb_shut_ack)
return sctp_sf_shut_8_4_5(ep, asoc, type, arg, commands);
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);
}
else
return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
}