2727#include <net/netfilter/nf_conntrack_ecache.h>
2828#include <net/netfilter/nf_conntrack_timeout.h>
2929
30- /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
31- closely. They're more complex. --RR
32-
33- And so for me for SCTP :D -Kiran */
34-
3530static const char * const sctp_conntrack_names [] = {
36- "NONE" ,
37- "CLOSED" ,
38- "COOKIE_WAIT" ,
39- "COOKIE_ECHOED" ,
40- "ESTABLISHED" ,
41- "SHUTDOWN_SENT" ,
42- "SHUTDOWN_RECD" ,
43- "SHUTDOWN_ACK_SENT" ,
44- "HEARTBEAT_SENT" ,
45- "HEARTBEAT_ACKED" ,
31+ [SCTP_CONNTRACK_NONE ] = "NONE" ,
32+ [SCTP_CONNTRACK_CLOSED ] = "CLOSED" ,
33+ [SCTP_CONNTRACK_COOKIE_WAIT ] = "COOKIE_WAIT" ,
34+ [SCTP_CONNTRACK_COOKIE_ECHOED ] = "COOKIE_ECHOED" ,
35+ [SCTP_CONNTRACK_ESTABLISHED ] = "ESTABLISHED" ,
36+ [SCTP_CONNTRACK_SHUTDOWN_SENT ] = "SHUTDOWN_SENT" ,
37+ [SCTP_CONNTRACK_SHUTDOWN_RECD ] = "SHUTDOWN_RECD" ,
38+ [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT ] = "SHUTDOWN_ACK_SENT" ,
39+ [SCTP_CONNTRACK_HEARTBEAT_SENT ] = "HEARTBEAT_SENT" ,
4640};
4741
4842#define SECS * HZ
@@ -54,13 +48,11 @@ static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = {
5448 [SCTP_CONNTRACK_CLOSED ] = 10 SECS ,
5549 [SCTP_CONNTRACK_COOKIE_WAIT ] = 3 SECS ,
5650 [SCTP_CONNTRACK_COOKIE_ECHOED ] = 3 SECS ,
57- [SCTP_CONNTRACK_ESTABLISHED ] = 5 DAYS ,
51+ [SCTP_CONNTRACK_ESTABLISHED ] = 210 SECS ,
5852 [SCTP_CONNTRACK_SHUTDOWN_SENT ] = 300 SECS / 1000 ,
5953 [SCTP_CONNTRACK_SHUTDOWN_RECD ] = 300 SECS / 1000 ,
6054 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT ] = 3 SECS ,
6155 [SCTP_CONNTRACK_HEARTBEAT_SENT ] = 30 SECS ,
62- [SCTP_CONNTRACK_HEARTBEAT_ACKED ] = 210 SECS ,
63- [SCTP_CONNTRACK_DATA_SENT ] = 30 SECS ,
6456};
6557
6658#define SCTP_FLAG_HEARTBEAT_VTAG_FAILED 1
@@ -74,8 +66,6 @@ static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = {
7466#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
7567#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
7668#define sHS SCTP_CONNTRACK_HEARTBEAT_SENT
77- #define sHA SCTP_CONNTRACK_HEARTBEAT_ACKED
78- #define sDS SCTP_CONNTRACK_DATA_SENT
7969#define sIV SCTP_CONNTRACK_MAX
8070
8171/*
@@ -98,10 +88,6 @@ SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
9888CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
9989 the SHUTDOWN chunk. Connection is closed.
10090HEARTBEAT_SENT - We have seen a HEARTBEAT in a new flow.
101- HEARTBEAT_ACKED - We have seen a HEARTBEAT-ACK/DATA/SACK in the direction
102- opposite to that of the HEARTBEAT/DATA chunk. Secondary connection
103- is established.
104- DATA_SENT - We have seen a DATA/SACK in a new flow.
10591*/
10692
10793/* TODO
@@ -115,38 +101,36 @@ cookie echoed to closed.
115101*/
116102
117103/* SCTP conntrack state transitions */
118- static const u8 sctp_conntracks [2 ][12 ][SCTP_CONNTRACK_MAX ] = {
104+ static const u8 sctp_conntracks [2 ][11 ][SCTP_CONNTRACK_MAX ] = {
119105 {
120106/* ORIGINAL */
121- /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA, sDS */
122- /* init */ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sCW , sHA , sCW },
123- /* init_ack */ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sCL , sHA , sCL },
124- /* abort */ {sCL , sCL , sCL , sCL , sCL , sCL , sCL , sCL , sCL , sCL , sCL },
125- /* shutdown */ {sCL , sCL , sCW , sCE , sSS , sSS , sSR , sSA , sCL , sSS , sCL },
126- /* shutdown_ack */ {sSA , sCL , sCW , sCE , sES , sSA , sSA , sSA , sSA , sHA , sSA },
127- /* error */ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sCL , sHA , sCL },/* Can't have Stale cookie*/
128- /* cookie_echo */ {sCL , sCL , sCE , sCE , sES , sSS , sSR , sSA , sCL , sHA , sCL },/* 5.2.4 - Big TODO */
129- /* cookie_ack */ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sCL , sHA , sCL },/* Can't come in orig dir */
130- /* shutdown_comp*/ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sCL , sCL , sHA , sCL },
131- /* heartbeat */ {sHS , sCL , sCW , sCE , sES , sSS , sSR , sSA , sHS , sHA , sDS },
132- /* heartbeat_ack*/ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sHS , sHA , sDS },
133- /* data/sack */ {sDS , sCL , sCW , sCE , sES , sSS , sSR , sSA , sHS , sHA , sDS }
107+ /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS */
108+ /* init */ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sCW },
109+ /* init_ack */ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sCL },
110+ /* abort */ {sCL , sCL , sCL , sCL , sCL , sCL , sCL , sCL , sCL },
111+ /* shutdown */ {sCL , sCL , sCW , sCE , sSS , sSS , sSR , sSA , sCL },
112+ /* shutdown_ack */ {sSA , sCL , sCW , sCE , sES , sSA , sSA , sSA , sSA },
113+ /* error */ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sCL },/* Can't have Stale cookie*/
114+ /* cookie_echo */ {sCL , sCL , sCE , sCE , sES , sSS , sSR , sSA , sCL },/* 5.2.4 - Big TODO */
115+ /* cookie_ack */ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sCL },/* Can't come in orig dir */
116+ /* shutdown_comp*/ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sCL , sCL },
117+ /* heartbeat */ {sHS , sCL , sCW , sCE , sES , sSS , sSR , sSA , sHS },
118+ /* heartbeat_ack*/ {sCL , sCL , sCW , sCE , sES , sSS , sSR , sSA , sHS },
134119 },
135120 {
136121/* REPLY */
137- /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA, sDS */
138- /* init */ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sSA , sIV , sHA , sIV },/* INIT in sCL Big TODO */
139- /* init_ack */ {sIV , sCW , sCW , sCE , sES , sSS , sSR , sSA , sIV , sHA , sIV },
140- /* abort */ {sIV , sCL , sCL , sCL , sCL , sCL , sCL , sCL , sIV , sCL , sIV },
141- /* shutdown */ {sIV , sCL , sCW , sCE , sSR , sSS , sSR , sSA , sIV , sSR , sIV },
142- /* shutdown_ack */ {sIV , sCL , sCW , sCE , sES , sSA , sSA , sSA , sIV , sHA , sIV },
143- /* error */ {sIV , sCL , sCW , sCL , sES , sSS , sSR , sSA , sIV , sHA , sIV },
144- /* cookie_echo */ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sSA , sIV , sHA , sIV },/* Can't come in reply dir */
145- /* cookie_ack */ {sIV , sCL , sCW , sES , sES , sSS , sSR , sSA , sIV , sHA , sIV },
146- /* shutdown_comp*/ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sCL , sIV , sHA , sIV },
147- /* heartbeat */ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sSA , sHS , sHA , sHA },
148- /* heartbeat_ack*/ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sSA , sHA , sHA , sHA },
149- /* data/sack */ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sSA , sHA , sHA , sHA },
122+ /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS */
123+ /* init */ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sSA , sIV },/* INIT in sCL Big TODO */
124+ /* init_ack */ {sIV , sCW , sCW , sCE , sES , sSS , sSR , sSA , sIV },
125+ /* abort */ {sIV , sCL , sCL , sCL , sCL , sCL , sCL , sCL , sIV },
126+ /* shutdown */ {sIV , sCL , sCW , sCE , sSR , sSS , sSR , sSA , sIV },
127+ /* shutdown_ack */ {sIV , sCL , sCW , sCE , sES , sSA , sSA , sSA , sIV },
128+ /* error */ {sIV , sCL , sCW , sCL , sES , sSS , sSR , sSA , sIV },
129+ /* cookie_echo */ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sSA , sIV },/* Can't come in reply dir */
130+ /* cookie_ack */ {sIV , sCL , sCW , sES , sES , sSS , sSR , sSA , sIV },
131+ /* shutdown_comp*/ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sCL , sIV },
132+ /* heartbeat */ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sSA , sHS },
133+ /* heartbeat_ack*/ {sIV , sCL , sCW , sCE , sES , sSS , sSR , sSA , sES },
150134 }
151135};
152136
@@ -160,8 +144,8 @@ static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
160144
161145#define for_each_sctp_chunk (skb , sch , _sch , offset , dataoff , count ) \
162146for ((offset) = (dataoff) + sizeof(struct sctphdr), (count) = 0; \
163- (offset) < ( skb)->len && \
164- (( sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))) ; \
147+ ((sch) = skb_header_pointer(( skb), (offset), sizeof(_sch), &(_sch))) && \
148+ (sch)->length ; \
165149 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
166150
167151/* Some validity checks to make sure the chunks are fine */
@@ -258,11 +242,6 @@ static int sctp_new_state(enum ip_conntrack_dir dir,
258242 pr_debug ("SCTP_CID_HEARTBEAT_ACK" );
259243 i = 10 ;
260244 break ;
261- case SCTP_CID_DATA :
262- case SCTP_CID_SACK :
263- pr_debug ("SCTP_CID_DATA/SACK" );
264- i = 11 ;
265- break ;
266245 default :
267246 /* Other chunks like DATA or SACK do not change the state */
268247 pr_debug ("Unknown chunk type, Will stay in %s\n" ,
@@ -316,9 +295,7 @@ sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
316295 ih -> init_tag );
317296
318297 ct -> proto .sctp .vtag [IP_CT_DIR_REPLY ] = ih -> init_tag ;
319- } else if (sch -> type == SCTP_CID_HEARTBEAT ||
320- sch -> type == SCTP_CID_DATA ||
321- sch -> type == SCTP_CID_SACK ) {
298+ } else if (sch -> type == SCTP_CID_HEARTBEAT ) {
322299 pr_debug ("Setting vtag %x for secondary conntrack\n" ,
323300 sh -> vtag );
324301 ct -> proto .sctp .vtag [IP_CT_DIR_ORIGINAL ] = sh -> vtag ;
@@ -404,42 +381,49 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
404381
405382 if (!sctp_new (ct , skb , sh , dataoff ))
406383 return - NF_ACCEPT ;
407- } else {
408- /* Check the verification tag (Sec 8.5) */
409- if (! test_bit ( SCTP_CID_INIT , map ) &&
410- !test_bit (SCTP_CID_SHUTDOWN_COMPLETE , map ) &&
411- !test_bit (SCTP_CID_COOKIE_ECHO , map ) &&
412- !test_bit (SCTP_CID_ABORT , map ) &&
413- !test_bit (SCTP_CID_SHUTDOWN_ACK , map ) &&
414- !test_bit (SCTP_CID_HEARTBEAT , map ) &&
415- !test_bit (SCTP_CID_HEARTBEAT_ACK , map ) &&
416- sh -> vtag != ct -> proto . sctp . vtag [ dir ]) {
417- pr_debug ( "Verification tag check failed\n" );
418- goto out ;
419- }
384+ }
385+
386+ /* Check the verification tag (Sec 8.5) */
387+ if ( !test_bit (SCTP_CID_INIT , map ) &&
388+ !test_bit (SCTP_CID_SHUTDOWN_COMPLETE , map ) &&
389+ !test_bit (SCTP_CID_COOKIE_ECHO , map ) &&
390+ !test_bit (SCTP_CID_ABORT , map ) &&
391+ !test_bit (SCTP_CID_SHUTDOWN_ACK , map ) &&
392+ !test_bit (SCTP_CID_HEARTBEAT , map ) &&
393+ ! test_bit ( SCTP_CID_HEARTBEAT_ACK , map ) &&
394+ sh -> vtag != ct -> proto . sctp . vtag [ dir ]) {
395+ pr_debug ( "Verification tag check failed\n" ) ;
396+ goto out ;
420397 }
421398
422399 old_state = new_state = SCTP_CONNTRACK_NONE ;
423400 spin_lock_bh (& ct -> lock );
424401 for_each_sctp_chunk (skb , sch , _sch , offset , dataoff , count ) {
425402 /* Special cases of Verification tag check (Sec 8.5.1) */
426403 if (sch -> type == SCTP_CID_INIT ) {
427- /* Sec 8.5.1 (A) */
404+ /* (A) vtag MUST be zero */
428405 if (sh -> vtag != 0 )
429406 goto out_unlock ;
430407 } else if (sch -> type == SCTP_CID_ABORT ) {
431- /* Sec 8.5.1 (B) */
432- if (sh -> vtag != ct -> proto .sctp .vtag [dir ] &&
433- sh -> vtag != ct -> proto .sctp .vtag [!dir ])
408+ /* (B) vtag MUST match own vtag if T flag is unset OR
409+ * MUST match peer's vtag if T flag is set
410+ */
411+ if ((!(sch -> flags & SCTP_CHUNK_FLAG_T ) &&
412+ sh -> vtag != ct -> proto .sctp .vtag [dir ]) ||
413+ ((sch -> flags & SCTP_CHUNK_FLAG_T ) &&
414+ sh -> vtag != ct -> proto .sctp .vtag [!dir ]))
434415 goto out_unlock ;
435416 } else if (sch -> type == SCTP_CID_SHUTDOWN_COMPLETE ) {
436- /* Sec 8.5.1 (C) */
437- if (sh -> vtag != ct -> proto .sctp .vtag [dir ] &&
438- sh -> vtag != ct -> proto .sctp .vtag [!dir ] &&
439- sch -> flags & SCTP_CHUNK_FLAG_T )
417+ /* (C) vtag MUST match own vtag if T flag is unset OR
418+ * MUST match peer's vtag if T flag is set
419+ */
420+ if ((!(sch -> flags & SCTP_CHUNK_FLAG_T ) &&
421+ sh -> vtag != ct -> proto .sctp .vtag [dir ]) ||
422+ ((sch -> flags & SCTP_CHUNK_FLAG_T ) &&
423+ sh -> vtag != ct -> proto .sctp .vtag [!dir ]))
440424 goto out_unlock ;
441425 } else if (sch -> type == SCTP_CID_COOKIE_ECHO ) {
442- /* Sec 8.5.1 (D) */
426+ /* (D) vtag must be same as init_vtag as found in INIT_ACK */
443427 if (sh -> vtag != ct -> proto .sctp .vtag [dir ])
444428 goto out_unlock ;
445429 } else if (sch -> type == SCTP_CID_HEARTBEAT ) {
@@ -476,11 +460,6 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
476460 } else if (ct -> proto .sctp .flags & SCTP_FLAG_HEARTBEAT_VTAG_FAILED ) {
477461 ct -> proto .sctp .flags &= ~SCTP_FLAG_HEARTBEAT_VTAG_FAILED ;
478462 }
479- } else if (sch -> type == SCTP_CID_DATA || sch -> type == SCTP_CID_SACK ) {
480- if (ct -> proto .sctp .vtag [dir ] == 0 ) {
481- pr_debug ("Setting vtag %x for dir %d\n" , sh -> vtag , dir );
482- ct -> proto .sctp .vtag [dir ] = sh -> vtag ;
483- }
484463 }
485464
486465 old_state = ct -> proto .sctp .state ;
@@ -518,8 +497,12 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
518497 }
519498
520499 ct -> proto .sctp .state = new_state ;
521- if (old_state != new_state )
500+ if (old_state != new_state ) {
522501 nf_conntrack_event_cache (IPCT_PROTOINFO , ct );
502+ if (new_state == SCTP_CONNTRACK_ESTABLISHED &&
503+ !test_and_set_bit (IPS_ASSURED_BIT , & ct -> status ))
504+ nf_conntrack_event_cache (IPCT_ASSURED , ct );
505+ }
523506 }
524507 spin_unlock_bh (& ct -> lock );
525508
@@ -533,14 +516,6 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
533516
534517 nf_ct_refresh_acct (ct , ctinfo , skb , timeouts [new_state ]);
535518
536- if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
537- dir == IP_CT_DIR_REPLY &&
538- new_state == SCTP_CONNTRACK_ESTABLISHED ) {
539- pr_debug ("Setting assured bit\n" );
540- set_bit (IPS_ASSURED_BIT , & ct -> status );
541- nf_conntrack_event_cache (IPCT_ASSURED , ct );
542- }
543-
544519 return NF_ACCEPT ;
545520
546521out_unlock :
@@ -701,7 +676,6 @@ sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
701676 [CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT ] = { .type = NLA_U32 },
702677 [CTA_TIMEOUT_SCTP_HEARTBEAT_SENT ] = { .type = NLA_U32 },
703678 [CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED ] = { .type = NLA_U32 },
704- [CTA_TIMEOUT_SCTP_DATA_SENT ] = { .type = NLA_U32 },
705679};
706680#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
707681
0 commit comments