27
27
#include <net/netfilter/nf_conntrack_ecache.h>
28
28
#include <net/netfilter/nf_conntrack_timeout.h>
29
29
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
-
35
30
static 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" ,
46
40
};
47
41
48
42
#define SECS * HZ
@@ -54,13 +48,11 @@ static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = {
54
48
[SCTP_CONNTRACK_CLOSED ] = 10 SECS ,
55
49
[SCTP_CONNTRACK_COOKIE_WAIT ] = 3 SECS ,
56
50
[SCTP_CONNTRACK_COOKIE_ECHOED ] = 3 SECS ,
57
- [SCTP_CONNTRACK_ESTABLISHED ] = 5 DAYS ,
51
+ [SCTP_CONNTRACK_ESTABLISHED ] = 210 SECS ,
58
52
[SCTP_CONNTRACK_SHUTDOWN_SENT ] = 300 SECS / 1000 ,
59
53
[SCTP_CONNTRACK_SHUTDOWN_RECD ] = 300 SECS / 1000 ,
60
54
[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT ] = 3 SECS ,
61
55
[SCTP_CONNTRACK_HEARTBEAT_SENT ] = 30 SECS ,
62
- [SCTP_CONNTRACK_HEARTBEAT_ACKED ] = 210 SECS ,
63
- [SCTP_CONNTRACK_DATA_SENT ] = 30 SECS ,
64
56
};
65
57
66
58
#define SCTP_FLAG_HEARTBEAT_VTAG_FAILED 1
@@ -74,8 +66,6 @@ static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = {
74
66
#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
75
67
#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
76
68
#define sHS SCTP_CONNTRACK_HEARTBEAT_SENT
77
- #define sHA SCTP_CONNTRACK_HEARTBEAT_ACKED
78
- #define sDS SCTP_CONNTRACK_DATA_SENT
79
69
#define sIV SCTP_CONNTRACK_MAX
80
70
81
71
/*
@@ -98,10 +88,6 @@ SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
98
88
CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
99
89
the SHUTDOWN chunk. Connection is closed.
100
90
HEARTBEAT_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.
105
91
*/
106
92
107
93
/* TODO
@@ -115,38 +101,36 @@ cookie echoed to closed.
115
101
*/
116
102
117
103
/* 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 ] = {
119
105
{
120
106
/* 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 },
134
119
},
135
120
{
136
121
/* 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 },
150
134
}
151
135
};
152
136
@@ -160,8 +144,8 @@ static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
160
144
161
145
#define for_each_sctp_chunk (skb , sch , _sch , offset , dataoff , count ) \
162
146
for ((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 ; \
165
149
(offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
166
150
167
151
/* Some validity checks to make sure the chunks are fine */
@@ -258,11 +242,6 @@ static int sctp_new_state(enum ip_conntrack_dir dir,
258
242
pr_debug ("SCTP_CID_HEARTBEAT_ACK" );
259
243
i = 10 ;
260
244
break ;
261
- case SCTP_CID_DATA :
262
- case SCTP_CID_SACK :
263
- pr_debug ("SCTP_CID_DATA/SACK" );
264
- i = 11 ;
265
- break ;
266
245
default :
267
246
/* Other chunks like DATA or SACK do not change the state */
268
247
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,
316
295
ih -> init_tag );
317
296
318
297
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 ) {
322
299
pr_debug ("Setting vtag %x for secondary conntrack\n" ,
323
300
sh -> vtag );
324
301
ct -> proto .sctp .vtag [IP_CT_DIR_ORIGINAL ] = sh -> vtag ;
@@ -404,42 +381,49 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
404
381
405
382
if (!sctp_new (ct , skb , sh , dataoff ))
406
383
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 ;
420
397
}
421
398
422
399
old_state = new_state = SCTP_CONNTRACK_NONE ;
423
400
spin_lock_bh (& ct -> lock );
424
401
for_each_sctp_chunk (skb , sch , _sch , offset , dataoff , count ) {
425
402
/* Special cases of Verification tag check (Sec 8.5.1) */
426
403
if (sch -> type == SCTP_CID_INIT ) {
427
- /* Sec 8.5.1 (A) */
404
+ /* (A) vtag MUST be zero */
428
405
if (sh -> vtag != 0 )
429
406
goto out_unlock ;
430
407
} 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 ]))
434
415
goto out_unlock ;
435
416
} 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 ]))
440
424
goto out_unlock ;
441
425
} 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 */
443
427
if (sh -> vtag != ct -> proto .sctp .vtag [dir ])
444
428
goto out_unlock ;
445
429
} else if (sch -> type == SCTP_CID_HEARTBEAT ) {
@@ -476,11 +460,6 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
476
460
} else if (ct -> proto .sctp .flags & SCTP_FLAG_HEARTBEAT_VTAG_FAILED ) {
477
461
ct -> proto .sctp .flags &= ~SCTP_FLAG_HEARTBEAT_VTAG_FAILED ;
478
462
}
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
- }
484
463
}
485
464
486
465
old_state = ct -> proto .sctp .state ;
@@ -518,8 +497,12 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
518
497
}
519
498
520
499
ct -> proto .sctp .state = new_state ;
521
- if (old_state != new_state )
500
+ if (old_state != new_state ) {
522
501
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
+ }
523
506
}
524
507
spin_unlock_bh (& ct -> lock );
525
508
@@ -533,14 +516,6 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
533
516
534
517
nf_ct_refresh_acct (ct , ctinfo , skb , timeouts [new_state ]);
535
518
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
-
544
519
return NF_ACCEPT ;
545
520
546
521
out_unlock :
@@ -701,7 +676,6 @@ sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
701
676
[CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT ] = { .type = NLA_U32 },
702
677
[CTA_TIMEOUT_SCTP_HEARTBEAT_SENT ] = { .type = NLA_U32 },
703
678
[CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED ] = { .type = NLA_U32 },
704
- [CTA_TIMEOUT_SCTP_DATA_SENT ] = { .type = NLA_U32 },
705
679
};
706
680
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
707
681
0 commit comments