Blame view

net/netfilter/nf_conntrack_proto_sctp.c 21.5 KB
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
1
2
  /*
   * Connection tracking protocol helper module for SCTP.
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
3
4
   *
   * SCTP is defined in RFC 2960. References to various sections in this code
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
5
   * are to this RFC.
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
6
   *
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
7
8
9
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
10
11
12
   */
  
  #include <linux/types.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
13
14
15
16
17
18
19
20
  #include <linux/timer.h>
  #include <linux/netfilter.h>
  #include <linux/module.h>
  #include <linux/in.h>
  #include <linux/ip.h>
  #include <linux/sctp.h>
  #include <linux/string.h>
  #include <linux/seq_file.h>
40a839fdb   Yasuyuki Kozakai   [NETFILTER]: nf_c...
21
22
  #include <linux/spinlock.h>
  #include <linux/interrupt.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
23
24
  
  #include <net/netfilter/nf_conntrack.h>
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
25
  #include <net/netfilter/nf_conntrack_l4proto.h>
f61801218   Martin Josefsson   [NETFILTER]: nf_c...
26
  #include <net/netfilter/nf_conntrack_ecache.h>
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
27

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
28
  /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
29
     closely.  They're more complex. --RR
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
30
31
  
     And so for me for SCTP :D -Kiran */
12c33aa20   Jan Engelhardt   [NETFILTER]: nf_c...
32
  static const char *const sctp_conntrack_names[] = {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  	"NONE",
  	"CLOSED",
  	"COOKIE_WAIT",
  	"COOKIE_ECHOED",
  	"ESTABLISHED",
  	"SHUTDOWN_SENT",
  	"SHUTDOWN_RECD",
  	"SHUTDOWN_ACK_SENT",
  };
  
  #define SECS  * HZ
  #define MINS  * 60 SECS
  #define HOURS * 60 MINS
  #define DAYS  * 24 HOURS
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
47
48
49
50
51
52
53
54
55
  static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
  	[SCTP_CONNTRACK_CLOSED]			= 10 SECS,
  	[SCTP_CONNTRACK_COOKIE_WAIT]		= 3 SECS,
  	[SCTP_CONNTRACK_COOKIE_ECHOED]		= 3 SECS,
  	[SCTP_CONNTRACK_ESTABLISHED]		= 5 DAYS,
  	[SCTP_CONNTRACK_SHUTDOWN_SENT]		= 300 SECS / 1000,
  	[SCTP_CONNTRACK_SHUTDOWN_RECD]		= 300 SECS / 1000,
  	[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT]	= 3 SECS,
  };
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
56
57
58
59
60
61
62
63
64
65
  
  #define sNO SCTP_CONNTRACK_NONE
  #define	sCL SCTP_CONNTRACK_CLOSED
  #define	sCW SCTP_CONNTRACK_COOKIE_WAIT
  #define	sCE SCTP_CONNTRACK_COOKIE_ECHOED
  #define	sES SCTP_CONNTRACK_ESTABLISHED
  #define	sSS SCTP_CONNTRACK_SHUTDOWN_SENT
  #define	sSR SCTP_CONNTRACK_SHUTDOWN_RECD
  #define	sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
  #define	sIV SCTP_CONNTRACK_MAX
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
66
  /*
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
67
  	These are the descriptions of the states:
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
68
  NOTE: These state names are tantalizingly similar to the states of an
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
69
  SCTP endpoint. But the interpretation of the states is a little different,
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
70
  considering that these are the states of the connection and not of an end
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
71
72
73
  point. Please note the subtleties. -Kiran
  
  NONE              - Nothing so far.
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
74
75
  COOKIE WAIT       - We have seen an INIT chunk in the original direction, or also
  		    an INIT_ACK chunk in the reply direction.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
76
77
78
79
80
  COOKIE ECHOED     - We have seen a COOKIE_ECHO chunk in the original direction.
  ESTABLISHED       - We have seen a COOKIE_ACK in the reply direction.
  SHUTDOWN_SENT     - We have seen a SHUTDOWN chunk in the original direction.
  SHUTDOWN_RECD     - We have seen a SHUTDOWN chunk in the reply directoin.
  SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
81
82
83
  		    to that of the SHUTDOWN chunk.
  CLOSED            - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
  		    the SHUTDOWN chunk. Connection is closed.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
84
85
86
  */
  
  /* TODO
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
87
   - I have assumed that the first INIT is in the original direction.
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
88
89
   This messes things when an INIT comes in the reply direction in CLOSED
   state.
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
90
   - Check the error type in the reply dir before transitioning from
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
91
92
93
94
95
96
  cookie echoed to closed.
   - Sec 5.2.4 of RFC 2960
   - Multi Homing support.
  */
  
  /* SCTP conntrack state transitions */
a5e73c29d   Patrick McHardy   [NETFILTER]: nf_c...
97
  static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
98
99
100
101
102
103
104
105
  	{
  /*	ORIGINAL	*/
  /*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
  /* init         */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
  /* init_ack     */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
  /* abort        */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
  /* shutdown     */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
  /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
25985edce   Lucas De Marchi   Fix common misspe...
106
  /* error        */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't have Stale cookie*/
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
107
  /* cookie_echo  */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
25985edce   Lucas De Marchi   Fix common misspe...
108
  /* cookie_ack   */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in orig dir */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
109
110
111
112
113
114
115
116
117
118
119
  /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
  	},
  	{
  /*	REPLY	*/
  /*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
  /* init         */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
  /* init_ack     */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
  /* abort        */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
  /* shutdown     */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
  /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
  /* error        */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
25985edce   Lucas De Marchi   Fix common misspe...
120
  /* cookie_echo  */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in reply dir */
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
121
122
123
124
  /* cookie_ack   */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
  /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
  	}
  };
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
125
126
  static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
  			      struct nf_conntrack_tuple *tuple)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
127
  {
12c33aa20   Jan Engelhardt   [NETFILTER]: nf_c...
128
129
  	const struct sctphdr *hp;
  	struct sctphdr _hdr;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
130

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
131
132
133
  	/* Actually only need first 8 bytes. */
  	hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
  	if (hp == NULL)
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
134
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
135
136
137
  
  	tuple->src.u.sctp.port = hp->source;
  	tuple->dst.u.sctp.port = hp->dest;
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
138
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
139
  }
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
140
141
  static bool sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
  			      const struct nf_conntrack_tuple *orig)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
142
  {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
143
144
  	tuple->src.u.sctp.port = orig->dst.u.sctp.port;
  	tuple->dst.u.sctp.port = orig->src.u.sctp.port;
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
145
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
146
147
148
149
150
151
  }
  
  /* Print out the per-protocol part of the tuple. */
  static int sctp_print_tuple(struct seq_file *s,
  			    const struct nf_conntrack_tuple *tuple)
  {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
152
153
154
155
156
157
  	return seq_printf(s, "sport=%hu dport=%hu ",
  			  ntohs(tuple->src.u.sctp.port),
  			  ntohs(tuple->dst.u.sctp.port));
  }
  
  /* Print out the private part of the conntrack. */
440f0d588   Patrick McHardy   netfilter: nf_con...
158
  static int sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
159
160
  {
  	enum sctp_conntrack state;
440f0d588   Patrick McHardy   netfilter: nf_con...
161
  	spin_lock_bh(&ct->lock);
112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
162
  	state = ct->proto.sctp.state;
440f0d588   Patrick McHardy   netfilter: nf_con...
163
  	spin_unlock_bh(&ct->lock);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
164
165
166
167
168
  
  	return seq_printf(s, "%s ", sctp_conntrack_names[state]);
  }
  
  #define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count)	\
e79ec50b9   Jan Engelhardt   [NETFILTER]: Pare...
169
170
171
172
  for ((offset) = (dataoff) + sizeof(sctp_sctphdr_t), (count) = 0;	\
  	(offset) < (skb)->len &&					\
  	((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch)));	\
  	(offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
173
174
  
  /* Some validity checks to make sure the chunks are fine */
112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
175
  static int do_basic_checks(struct nf_conn *ct,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
176
177
  			   const struct sk_buff *skb,
  			   unsigned int dataoff,
35c6d3cbe   Patrick McHardy   [NETFILTER]: nf_c...
178
  			   unsigned long *map)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
179
180
181
182
  {
  	u_int32_t offset, count;
  	sctp_chunkhdr_t _sch, *sch;
  	int flag;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
183
184
185
  	flag = 0;
  
  	for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
186
187
  		pr_debug("Chunk Num: %d  Type: %d
  ", count, sch->type);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
188

5447d4777   Patrick McHardy   [NETFILTER]: nf_c...
189
190
191
  		if (sch->type == SCTP_CID_INIT ||
  		    sch->type == SCTP_CID_INIT_ACK ||
  		    sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
192
  			flag = 1;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
193

e17df688f   Patrick McHardy   [NETFILTER] SCTP ...
194
195
196
197
198
  		/*
  		 * Cookie Ack/Echo chunks not the first OR
  		 * Init / Init Ack / Shutdown compl chunks not the only chunks
  		 * OR zero-length.
  		 */
5447d4777   Patrick McHardy   [NETFILTER]: nf_c...
199
200
201
202
  		if (((sch->type == SCTP_CID_COOKIE_ACK ||
  		      sch->type == SCTP_CID_COOKIE_ECHO ||
  		      flag) &&
  		     count != 0) || !sch->length) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
203
204
  			pr_debug("Basic checks failed
  ");
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
205
206
  			return 1;
  		}
5447d4777   Patrick McHardy   [NETFILTER]: nf_c...
207
  		if (map)
35c6d3cbe   Patrick McHardy   [NETFILTER]: nf_c...
208
  			set_bit(sch->type, map);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
209
  	}
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
210
211
  	pr_debug("Basic checks passed
  ");
dd7271feb   Patrick McHardy   [NETFILTER]: SCTP...
212
  	return count == 0;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
213
  }
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
214
215
216
  static int sctp_new_state(enum ip_conntrack_dir dir,
  			  enum sctp_conntrack cur_state,
  			  int chunk_type)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
217
218
  {
  	int i;
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
219
220
  	pr_debug("Chunk type: %d
  ", chunk_type);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
221
222
  
  	switch (chunk_type) {
5447d4777   Patrick McHardy   [NETFILTER]: nf_c...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
  	case SCTP_CID_INIT:
  		pr_debug("SCTP_CID_INIT
  ");
  		i = 0;
  		break;
  	case SCTP_CID_INIT_ACK:
  		pr_debug("SCTP_CID_INIT_ACK
  ");
  		i = 1;
  		break;
  	case SCTP_CID_ABORT:
  		pr_debug("SCTP_CID_ABORT
  ");
  		i = 2;
  		break;
  	case SCTP_CID_SHUTDOWN:
  		pr_debug("SCTP_CID_SHUTDOWN
  ");
  		i = 3;
  		break;
  	case SCTP_CID_SHUTDOWN_ACK:
  		pr_debug("SCTP_CID_SHUTDOWN_ACK
  ");
  		i = 4;
  		break;
  	case SCTP_CID_ERROR:
  		pr_debug("SCTP_CID_ERROR
  ");
  		i = 5;
  		break;
  	case SCTP_CID_COOKIE_ECHO:
  		pr_debug("SCTP_CID_COOKIE_ECHO
  ");
  		i = 6;
  		break;
  	case SCTP_CID_COOKIE_ACK:
  		pr_debug("SCTP_CID_COOKIE_ACK
  ");
  		i = 7;
  		break;
  	case SCTP_CID_SHUTDOWN_COMPLETE:
  		pr_debug("SCTP_CID_SHUTDOWN_COMPLETE
  ");
  		i = 8;
  		break;
  	default:
  		/* Other chunks like DATA, SACK, HEARTBEAT and
  		its ACK do not cause a change in state */
  		pr_debug("Unknown chunk type, Will stay in %s
  ",
  			 sctp_conntrack_names[cur_state]);
  		return cur_state;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
275
  	}
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
276
277
278
279
  	pr_debug("dir: %d   cur_state: %s  chunk_type: %d  new_state: %s
  ",
  		 dir, sctp_conntrack_names[cur_state], chunk_type,
  		 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
280
281
282
  
  	return sctp_conntracks[dir][i][cur_state];
  }
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
283
  /* Returns verdict for packet, or -NF_ACCEPT for invalid. */
112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
284
  static int sctp_packet(struct nf_conn *ct,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
285
286
287
  		       const struct sk_buff *skb,
  		       unsigned int dataoff,
  		       enum ip_conntrack_info ctinfo,
76108cea0   Jan Engelhardt   netfilter: Use un...
288
  		       u_int8_t pf,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
289
290
  		       unsigned int hooknum)
  {
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
291
  	enum sctp_conntrack new_state, old_state;
8528819ad   Patrick McHardy   [NETFILTER]: nf_c...
292
  	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
12c33aa20   Jan Engelhardt   [NETFILTER]: nf_c...
293
294
295
296
  	const struct sctphdr *sh;
  	struct sctphdr _sctph;
  	const struct sctp_chunkhdr *sch;
  	struct sctp_chunkhdr _sch;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
297
  	u_int32_t offset, count;
35c6d3cbe   Patrick McHardy   [NETFILTER]: nf_c...
298
  	unsigned long map[256 / sizeof(unsigned long)] = { 0 };
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
299

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
300
301
  	sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
  	if (sh == NULL)
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
302
  		goto out;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
303

112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
304
  	if (do_basic_checks(ct, skb, dataoff, map) != 0)
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
305
  		goto out;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
306
307
  
  	/* Check the verification tag (Sec 8.5) */
35c6d3cbe   Patrick McHardy   [NETFILTER]: nf_c...
308
309
310
311
312
  	if (!test_bit(SCTP_CID_INIT, map) &&
  	    !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) &&
  	    !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
  	    !test_bit(SCTP_CID_ABORT, map) &&
  	    !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
8528819ad   Patrick McHardy   [NETFILTER]: nf_c...
313
  	    sh->vtag != ct->proto.sctp.vtag[dir]) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
314
315
  		pr_debug("Verification tag check failed
  ");
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
316
  		goto out;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
317
  	}
328bd8997   Patrick McHardy   netfilter: nf_con...
318
  	old_state = new_state = SCTP_CONNTRACK_NONE;
440f0d588   Patrick McHardy   netfilter: nf_con...
319
  	spin_lock_bh(&ct->lock);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
320
  	for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
321
322
323
  		/* Special cases of Verification tag check (Sec 8.5.1) */
  		if (sch->type == SCTP_CID_INIT) {
  			/* Sec 8.5.1 (A) */
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
324
325
  			if (sh->vtag != 0)
  				goto out_unlock;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
326
327
  		} else if (sch->type == SCTP_CID_ABORT) {
  			/* Sec 8.5.1 (B) */
8528819ad   Patrick McHardy   [NETFILTER]: nf_c...
328
  			if (sh->vtag != ct->proto.sctp.vtag[dir] &&
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
329
330
  			    sh->vtag != ct->proto.sctp.vtag[!dir])
  				goto out_unlock;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
331
332
  		} else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
  			/* Sec 8.5.1 (C) */
8528819ad   Patrick McHardy   [NETFILTER]: nf_c...
333
334
  			if (sh->vtag != ct->proto.sctp.vtag[dir] &&
  			    sh->vtag != ct->proto.sctp.vtag[!dir] &&
9b1c2cfd7   Patrick McHardy   [NETFILTER]: nf_c...
335
  			    sch->flags & SCTP_CHUNK_FLAG_T)
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
336
  				goto out_unlock;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
337
338
  		} else if (sch->type == SCTP_CID_COOKIE_ECHO) {
  			/* Sec 8.5.1 (D) */
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
339
340
  			if (sh->vtag != ct->proto.sctp.vtag[dir])
  				goto out_unlock;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
341
  		}
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
342
343
  		old_state = ct->proto.sctp.state;
  		new_state = sctp_new_state(dir, old_state, sch->type);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
344
345
  
  		/* Invalid */
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
346
  		if (new_state == SCTP_CONNTRACK_MAX) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
347
348
349
  			pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
  				 "conntrack=%u
  ",
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
350
  				 dir, sch->type, old_state);
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
351
  			goto out_unlock;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
352
353
354
  		}
  
  		/* If it is an INIT or an INIT ACK note down the vtag */
5447d4777   Patrick McHardy   [NETFILTER]: nf_c...
355
356
  		if (sch->type == SCTP_CID_INIT ||
  		    sch->type == SCTP_CID_INIT_ACK) {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
357
358
359
  			sctp_inithdr_t _inithdr, *ih;
  
  			ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
360
  						sizeof(_inithdr), &_inithdr);
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
361
362
  			if (ih == NULL)
  				goto out_unlock;
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
363
364
  			pr_debug("Setting vtag %x for dir %d
  ",
8528819ad   Patrick McHardy   [NETFILTER]: nf_c...
365
366
  				 ih->init_tag, !dir);
  			ct->proto.sctp.vtag[!dir] = ih->init_tag;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
367
  		}
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
368
369
  		ct->proto.sctp.state = new_state;
  		if (old_state != new_state)
a71996fcc   Alexey Dobriyan   netfilter: netns ...
370
  			nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
371
  	}
440f0d588   Patrick McHardy   netfilter: nf_con...
372
  	spin_unlock_bh(&ct->lock);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
373

86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
374
  	nf_ct_refresh_acct(ct, ctinfo, skb, sctp_timeouts[new_state]);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
375

efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
376
  	if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
8528819ad   Patrick McHardy   [NETFILTER]: nf_c...
377
  	    dir == IP_CT_DIR_REPLY &&
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
378
  	    new_state == SCTP_CONNTRACK_ESTABLISHED) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
379
380
  		pr_debug("Setting assured bit
  ");
112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
381
  		set_bit(IPS_ASSURED_BIT, &ct->status);
858b31330   Patrick McHardy   netfilter: nf_con...
382
  		nf_conntrack_event_cache(IPCT_ASSURED, ct);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
383
384
385
  	}
  
  	return NF_ACCEPT;
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
386
387
  
  out_unlock:
440f0d588   Patrick McHardy   netfilter: nf_con...
388
  	spin_unlock_bh(&ct->lock);
b37e933ac   Patrick McHardy   [NETFILTER]: nf_c...
389
390
  out:
  	return -NF_ACCEPT;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
391
392
393
  }
  
  /* Called when a new connection for this protocol found. */
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
394
395
  static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
  		     unsigned int dataoff)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
396
  {
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
397
  	enum sctp_conntrack new_state;
12c33aa20   Jan Engelhardt   [NETFILTER]: nf_c...
398
399
400
401
  	const struct sctphdr *sh;
  	struct sctphdr _sctph;
  	const struct sctp_chunkhdr *sch;
  	struct sctp_chunkhdr _sch;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
402
  	u_int32_t offset, count;
35c6d3cbe   Patrick McHardy   [NETFILTER]: nf_c...
403
  	unsigned long map[256 / sizeof(unsigned long)] = { 0 };
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
404

9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
405
406
  	sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
  	if (sh == NULL)
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
407
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
408

112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
409
  	if (do_basic_checks(ct, skb, dataoff, map) != 0)
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
410
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
411
412
  
  	/* If an OOTB packet has any of these chunks discard (Sec 8.4) */
35c6d3cbe   Patrick McHardy   [NETFILTER]: nf_c...
413
414
415
  	if (test_bit(SCTP_CID_ABORT, map) ||
  	    test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
  	    test_bit(SCTP_CID_COOKIE_ACK, map))
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
416
  		return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
417

e5fc9e7a6   Changli Gao   netfilter: nf_con...
418
  	memset(&ct->proto.sctp, 0, sizeof(ct->proto.sctp));
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
419
  	new_state = SCTP_CONNTRACK_MAX;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
420
421
  	for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
  		/* Don't need lock here: this conntrack not in circulation yet */
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
422
423
  		new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
  					   SCTP_CONNTRACK_NONE, sch->type);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
424
425
  
  		/* Invalid: delete conntrack */
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
426
427
  		if (new_state == SCTP_CONNTRACK_NONE ||
  		    new_state == SCTP_CONNTRACK_MAX) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
428
429
  			pr_debug("nf_conntrack_sctp: invalid new deleting.
  ");
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
430
  			return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
431
432
433
434
435
436
437
438
  		}
  
  		/* Copy the vtag into the state info */
  		if (sch->type == SCTP_CID_INIT) {
  			if (sh->vtag == 0) {
  				sctp_inithdr_t _inithdr, *ih;
  
  				ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
601e68e10   YOSHIFUJI Hideaki   [NETFILTER]: Fix ...
439
  							sizeof(_inithdr), &_inithdr);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
440
  				if (ih == NULL)
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
441
  					return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
442

0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
443
444
445
  				pr_debug("Setting vtag %x for new conn
  ",
  					 ih->init_tag);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
446

112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
447
  				ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
448
449
450
  								ih->init_tag;
  			} else {
  				/* Sec 8.5.1 (A) */
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
451
  				return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
452
453
454
455
456
  			}
  		}
  		/* If it is a shutdown ack OOTB packet, we expect a return
  		   shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
  		else {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
457
458
459
  			pr_debug("Setting vtag %x for new conn OOTB
  ",
  				 sh->vtag);
112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
460
  			ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
461
  		}
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
462
  		ct->proto.sctp.state = new_state;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
463
  	}
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
464
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
465
  }
c0cd11566   Igor Maravić   net:netfilter: us...
466
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
467
468
469
470
471
  
  #include <linux/netfilter/nfnetlink.h>
  #include <linux/netfilter/nfnetlink_conntrack.h>
  
  static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
440f0d588   Patrick McHardy   netfilter: nf_con...
472
  			  struct nf_conn *ct)
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
473
474
  {
  	struct nlattr *nest_parms;
440f0d588   Patrick McHardy   netfilter: nf_con...
475
  	spin_lock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
476
477
478
479
480
481
482
483
  	nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP | NLA_F_NESTED);
  	if (!nest_parms)
  		goto nla_put_failure;
  
  	NLA_PUT_U8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state);
  
  	NLA_PUT_BE32(skb,
  		     CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
5547cd0ae   Patrick McHardy   netfilter: nf_con...
484
  		     ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
485
486
487
  
  	NLA_PUT_BE32(skb,
  		     CTA_PROTOINFO_SCTP_VTAG_REPLY,
5547cd0ae   Patrick McHardy   netfilter: nf_con...
488
  		     ct->proto.sctp.vtag[IP_CT_DIR_REPLY]);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
489

440f0d588   Patrick McHardy   netfilter: nf_con...
490
  	spin_unlock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
491
492
493
494
495
496
  
  	nla_nest_end(skb, nest_parms);
  
  	return 0;
  
  nla_put_failure:
440f0d588   Patrick McHardy   netfilter: nf_con...
497
  	spin_unlock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
  	return -1;
  }
  
  static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = {
  	[CTA_PROTOINFO_SCTP_STATE]	    = { .type = NLA_U8 },
  	[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]  = { .type = NLA_U32 },
  	[CTA_PROTOINFO_SCTP_VTAG_REPLY]     = { .type = NLA_U32 },
  };
  
  static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
  {
  	struct nlattr *attr = cda[CTA_PROTOINFO_SCTP];
  	struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1];
  	int err;
  
  	/* updates may not contain the internal protocol info, skip parsing */
  	if (!attr)
  		return 0;
  
  	err = nla_parse_nested(tb,
  			       CTA_PROTOINFO_SCTP_MAX,
  			       attr,
  			       sctp_nla_policy);
  	if (err < 0)
  		return err;
  
  	if (!tb[CTA_PROTOINFO_SCTP_STATE] ||
  	    !tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] ||
  	    !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])
  		return -EINVAL;
440f0d588   Patrick McHardy   netfilter: nf_con...
528
  	spin_lock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
529
530
  	ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
  	ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
5547cd0ae   Patrick McHardy   netfilter: nf_con...
531
  		nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
532
  	ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
5547cd0ae   Patrick McHardy   netfilter: nf_con...
533
  		nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
440f0d588   Patrick McHardy   netfilter: nf_con...
534
  	spin_unlock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
535
536
537
  
  	return 0;
  }
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
538
539
540
541
542
543
  
  static int sctp_nlattr_size(void)
  {
  	return nla_total_size(0)	/* CTA_PROTOINFO_SCTP */
  		+ nla_policy_len(sctp_nla_policy, CTA_PROTOINFO_SCTP_MAX + 1);
  }
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
544
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
545
  #ifdef CONFIG_SYSCTL
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
546
547
548
  static unsigned int sctp_sysctl_table_users;
  static struct ctl_table_header *sctp_sysctl_header;
  static struct ctl_table sctp_sysctl_table[] = {
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
549
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
550
  		.procname	= "nf_conntrack_sctp_timeout_closed",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
551
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
552
553
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
554
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
555
556
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
557
  		.procname	= "nf_conntrack_sctp_timeout_cookie_wait",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
558
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
559
560
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
561
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
562
563
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
564
  		.procname	= "nf_conntrack_sctp_timeout_cookie_echoed",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
565
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
566
567
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
568
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
569
570
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
571
  		.procname	= "nf_conntrack_sctp_timeout_established",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
572
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
573
574
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
575
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
576
577
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
578
  		.procname	= "nf_conntrack_sctp_timeout_shutdown_sent",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
579
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
580
581
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
582
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
583
584
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
585
  		.procname	= "nf_conntrack_sctp_timeout_shutdown_recd",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
586
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
587
588
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
589
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
590
591
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
592
  		.procname	= "nf_conntrack_sctp_timeout_shutdown_ack_sent",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
593
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
594
595
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
596
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
597
  	},
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
598
  	{ }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
599
  };
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
600
601
602
603
  
  #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  static struct ctl_table sctp_compat_sysctl_table[] = {
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
604
  		.procname	= "ip_conntrack_sctp_timeout_closed",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
605
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
606
607
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
608
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
609
610
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
611
  		.procname	= "ip_conntrack_sctp_timeout_cookie_wait",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
612
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
613
614
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
615
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
616
617
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
618
  		.procname	= "ip_conntrack_sctp_timeout_cookie_echoed",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
619
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
620
621
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
622
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
623
624
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
625
  		.procname	= "ip_conntrack_sctp_timeout_established",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
626
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
627
628
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
629
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
630
631
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
632
  		.procname	= "ip_conntrack_sctp_timeout_shutdown_sent",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
633
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
634
635
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
636
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
637
638
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
639
  		.procname	= "ip_conntrack_sctp_timeout_shutdown_recd",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
640
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
641
642
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
643
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
644
645
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
646
  		.procname	= "ip_conntrack_sctp_timeout_shutdown_ack_sent",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
647
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
648
649
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
650
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
651
  	},
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
652
  	{ }
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
653
654
  };
  #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
655
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
656

61075af51   Patrick McHardy   [NETFILTER]: nf_c...
657
  static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
658
659
660
661
662
663
664
665
666
667
  	.l3proto		= PF_INET,
  	.l4proto 		= IPPROTO_SCTP,
  	.name 			= "sctp",
  	.pkt_to_tuple 		= sctp_pkt_to_tuple,
  	.invert_tuple 		= sctp_invert_tuple,
  	.print_tuple 		= sctp_print_tuple,
  	.print_conntrack	= sctp_print_conntrack,
  	.packet 		= sctp_packet,
  	.new 			= sctp_new,
  	.me 			= THIS_MODULE,
c0cd11566   Igor Maravić   net:netfilter: us...
668
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
669
  	.to_nlattr		= sctp_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
670
  	.nlattr_size		= sctp_nlattr_size,
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
671
  	.from_nlattr		= nlattr_to_sctp,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
672
  	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
673
  	.nlattr_tuple_size	= nf_ct_port_nlattr_tuple_size,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
674
675
676
  	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
  	.nla_policy		= nf_ct_port_nla_policy,
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
677
678
679
680
  #ifdef CONFIG_SYSCTL
  	.ctl_table_users	= &sctp_sysctl_table_users,
  	.ctl_table_header	= &sctp_sysctl_header,
  	.ctl_table		= sctp_sysctl_table,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
681
682
683
  #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  	.ctl_compat_table	= sctp_compat_sysctl_table,
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
684
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
685
  };
61075af51   Patrick McHardy   [NETFILTER]: nf_c...
686
  static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
687
688
689
690
691
692
693
694
695
696
  	.l3proto		= PF_INET6,
  	.l4proto 		= IPPROTO_SCTP,
  	.name 			= "sctp",
  	.pkt_to_tuple 		= sctp_pkt_to_tuple,
  	.invert_tuple 		= sctp_invert_tuple,
  	.print_tuple 		= sctp_print_tuple,
  	.print_conntrack	= sctp_print_conntrack,
  	.packet 		= sctp_packet,
  	.new 			= sctp_new,
  	.me 			= THIS_MODULE,
c0cd11566   Igor Maravić   net:netfilter: us...
697
  #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
698
  	.to_nlattr		= sctp_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
699
  	.nlattr_size		= sctp_nlattr_size,
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
700
  	.from_nlattr		= nlattr_to_sctp,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
701
  	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
702
  	.nlattr_tuple_size	= nf_ct_port_nlattr_tuple_size,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
703
704
705
  	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
  	.nla_policy		= nf_ct_port_nla_policy,
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
706
707
708
709
  #ifdef CONFIG_SYSCTL
  	.ctl_table_users	= &sctp_sysctl_table_users,
  	.ctl_table_header	= &sctp_sysctl_header,
  	.ctl_table		= sctp_sysctl_table,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
710
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
711
  };
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
712

2f0d2f103   Stephen Hemminger   [NETFILTER]: conn...
713
  static int __init nf_conntrack_proto_sctp_init(void)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
714
715
  {
  	int ret;
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
716
  	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
717
  	if (ret) {
654d0fbdc   Stephen Hemminger   netfilter: cleanu...
718
719
  		pr_err("nf_conntrack_l4proto_sctp4: protocol register failed
  ");
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
720
721
  		goto out;
  	}
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
722
  	ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
723
  	if (ret) {
654d0fbdc   Stephen Hemminger   netfilter: cleanu...
724
725
  		pr_err("nf_conntrack_l4proto_sctp6: protocol register failed
  ");
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
726
727
  		goto cleanup_sctp4;
  	}
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
728
  	return ret;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
729
   cleanup_sctp4:
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
730
  	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
731
   out:
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
732
733
  	return ret;
  }
2f0d2f103   Stephen Hemminger   [NETFILTER]: conn...
734
  static void __exit nf_conntrack_proto_sctp_fini(void)
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
735
  {
605dcad6c   Martin Josefsson   [NETFILTER]: nf_c...
736
737
  	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
  	nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
738
  }
65b4b4e81   Andrew Morton   [NETFILTER]: Rena...
739
740
  module_init(nf_conntrack_proto_sctp_init);
  module_exit(nf_conntrack_proto_sctp_fini);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
741
742
743
744
  
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Kiran Kumar Immidi");
  MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
d2483ddef   Patrick McHardy   [NETFILTER]: nf_c...
745
  MODULE_ALIAS("ip_conntrack_proto_sctp");