Blame view

net/netfilter/nf_conntrack_proto_sctp.c 21.6 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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  	{
  /*	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},
  /* error        */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have Stale cookie*/
  /* cookie_echo  */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
  /* cookie_ack   */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in orig dir */
  /* 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},
  /* cookie_echo  */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in reply dir */
  /* 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

efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
418
  	new_state = SCTP_CONNTRACK_MAX;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
419
420
  	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...
421
422
  		new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
  					   SCTP_CONNTRACK_NONE, sch->type);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
423
424
  
  		/* Invalid: delete conntrack */
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
425
426
  		if (new_state == SCTP_CONNTRACK_NONE ||
  		    new_state == SCTP_CONNTRACK_MAX) {
0d53778e8   Patrick McHardy   [NETFILTER]: Conv...
427
428
  			pr_debug("nf_conntrack_sctp: invalid new deleting.
  ");
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
429
  			return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
430
431
432
433
434
435
436
437
  		}
  
  		/* 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 ...
438
  							sizeof(_inithdr), &_inithdr);
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
439
  				if (ih == NULL)
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
440
  					return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
441

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

112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
446
  				ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
447
448
449
  								ih->init_tag;
  			} else {
  				/* Sec 8.5.1 (A) */
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
450
  				return false;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
451
452
453
454
455
  			}
  		}
  		/* 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...
456
457
458
  			pr_debug("Setting vtag %x for new conn OOTB
  ",
  				 sh->vtag);
112f35c9c   Patrick McHardy   [NETFILTER]: nf_c...
459
  			ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
460
  		}
efe9f68af   Patrick McHardy   [NETFILTER]: nf_c...
461
  		ct->proto.sctp.state = new_state;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
462
  	}
09f263cd3   Jan Engelhardt   [NETFILTER]: nf_c...
463
  	return true;
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
464
  }
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
465
466
467
468
469
470
  #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
  
  #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...
471
  			  struct nf_conn *ct)
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
472
473
  {
  	struct nlattr *nest_parms;
440f0d588   Patrick McHardy   netfilter: nf_con...
474
  	spin_lock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
475
476
477
478
479
480
481
482
  	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...
483
  		     ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
484
485
486
  
  	NLA_PUT_BE32(skb,
  		     CTA_PROTOINFO_SCTP_VTAG_REPLY,
5547cd0ae   Patrick McHardy   netfilter: nf_con...
487
  		     ct->proto.sctp.vtag[IP_CT_DIR_REPLY]);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
488

440f0d588   Patrick McHardy   netfilter: nf_con...
489
  	spin_unlock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
490
491
492
493
494
495
  
  	nla_nest_end(skb, nest_parms);
  
  	return 0;
  
  nla_put_failure:
440f0d588   Patrick McHardy   netfilter: nf_con...
496
  	spin_unlock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
497
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
  	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...
527
  	spin_lock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
528
529
  	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...
530
  		nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
531
  	ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
5547cd0ae   Patrick McHardy   netfilter: nf_con...
532
  		nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
440f0d588   Patrick McHardy   netfilter: nf_con...
533
  	spin_unlock_bh(&ct->lock);
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
534
535
536
  
  	return 0;
  }
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
537
538
539
540
541
542
  
  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...
543
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
544
  #ifdef CONFIG_SYSCTL
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
545
546
547
  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 ...
548
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
549
  		.procname	= "nf_conntrack_sctp_timeout_closed",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
550
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
551
552
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
553
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
554
555
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
556
  		.procname	= "nf_conntrack_sctp_timeout_cookie_wait",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
557
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
558
559
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
560
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
561
562
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
563
  		.procname	= "nf_conntrack_sctp_timeout_cookie_echoed",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
564
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
565
566
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
567
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
568
569
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
570
  		.procname	= "nf_conntrack_sctp_timeout_established",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
571
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
572
573
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
574
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
575
576
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
577
  		.procname	= "nf_conntrack_sctp_timeout_shutdown_sent",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
578
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
579
580
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
581
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
582
583
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
584
  		.procname	= "nf_conntrack_sctp_timeout_shutdown_recd",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
585
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
586
587
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
588
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
589
590
  	},
  	{
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
591
  		.procname	= "nf_conntrack_sctp_timeout_shutdown_ack_sent",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
592
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
593
594
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
595
  		.proc_handler	= proc_dointvec_jiffies,
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
596
  	},
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
597
  	{ }
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
598
  };
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
599
600
601
602
  
  #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  static struct ctl_table sctp_compat_sysctl_table[] = {
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
603
  		.procname	= "ip_conntrack_sctp_timeout_closed",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
604
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
605
606
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
607
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
608
609
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
610
  		.procname	= "ip_conntrack_sctp_timeout_cookie_wait",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
611
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
612
613
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
614
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
615
616
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
617
  		.procname	= "ip_conntrack_sctp_timeout_cookie_echoed",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
618
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
619
620
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
621
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
622
623
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
624
  		.procname	= "ip_conntrack_sctp_timeout_established",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
625
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
626
627
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
628
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
629
630
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
631
  		.procname	= "ip_conntrack_sctp_timeout_shutdown_sent",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
632
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
633
634
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
635
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
636
637
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
638
  		.procname	= "ip_conntrack_sctp_timeout_shutdown_recd",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
639
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
640
641
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
642
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
643
644
  	},
  	{
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
645
  		.procname	= "ip_conntrack_sctp_timeout_shutdown_ack_sent",
86c0bf409   Patrick McHardy   [NETFILTER]: nf_c...
646
  		.data		= &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
647
648
  		.maxlen		= sizeof(unsigned int),
  		.mode		= 0644,
6d9f239a1   Alexey Dobriyan   net: '&' redux
649
  		.proc_handler	= proc_dointvec_jiffies,
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
650
  	},
f8572d8f2   Eric W. Biederman   sysctl net: Remov...
651
  	{ }
a999e6837   Patrick McHardy   [NETFILTER]: nf_c...
652
653
  };
  #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
654
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
655

61075af51   Patrick McHardy   [NETFILTER]: nf_c...
656
  static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
657
658
659
660
661
662
663
664
665
666
  	.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,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
667
  #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
668
  	.to_nlattr		= sctp_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
669
  	.nlattr_size		= sctp_nlattr_size,
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
670
  	.from_nlattr		= nlattr_to_sctp,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
671
  	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
672
  	.nlattr_tuple_size	= nf_ct_port_nlattr_tuple_size,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
673
674
675
  	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
  	.nla_policy		= nf_ct_port_nla_policy,
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
676
677
678
679
  #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...
680
681
682
  #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
  	.ctl_compat_table	= sctp_compat_sysctl_table,
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
683
  #endif
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
684
  };
61075af51   Patrick McHardy   [NETFILTER]: nf_c...
685
  static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
686
687
688
689
690
691
692
693
694
695
  	.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,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
696
  #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
697
  	.to_nlattr		= sctp_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
698
  	.nlattr_size		= sctp_nlattr_size,
a258860e0   Pablo Neira Ayuso   netfilter: ctnetl...
699
  	.from_nlattr		= nlattr_to_sctp,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
700
  	.tuple_to_nlattr	= nf_ct_port_tuple_to_nlattr,
a400c30ed   Holger Eitzenberger   netfilter: nf_con...
701
  	.nlattr_tuple_size	= nf_ct_port_nlattr_tuple_size,
c7212e9d3   Pablo Neira Ayuso   [NETFILTER]: nf_c...
702
703
704
  	.nlattr_to_tuple	= nf_ct_port_nlattr_to_tuple,
  	.nla_policy		= nf_ct_port_nla_policy,
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
705
706
707
708
  #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 ...
709
  #endif
933a41e7e   Patrick McHardy   [NETFILTER]: nf_c...
710
  };
9fb9cbb10   Yasuyuki Kozakai   [NETFILTER]: Add ...
711

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