[NETFILTER]: nf_conntrack_sctp: replace magic value by symbolic constant
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / netfilter / nf_conntrack_proto_sctp.c
CommitLineData
9fb9cbb1
YK
1/*
2 * Connection tracking protocol helper module for SCTP.
601e68e1
YH
3 *
4 * SCTP is defined in RFC 2960. References to various sections in this code
9fb9cbb1 5 * are to this RFC.
601e68e1 6 *
9fb9cbb1
YK
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
9fb9cbb1
YK
10 */
11
12#include <linux/types.h>
9fb9cbb1
YK
13#include <linux/timer.h>
14#include <linux/netfilter.h>
15#include <linux/module.h>
16#include <linux/in.h>
17#include <linux/ip.h>
18#include <linux/sctp.h>
19#include <linux/string.h>
20#include <linux/seq_file.h>
40a839fd
YK
21#include <linux/spinlock.h>
22#include <linux/interrupt.h>
9fb9cbb1
YK
23
24#include <net/netfilter/nf_conntrack.h>
605dcad6 25#include <net/netfilter/nf_conntrack_l4proto.h>
f6180121 26#include <net/netfilter/nf_conntrack_ecache.h>
9fb9cbb1 27
9fb9cbb1
YK
28/* Protects conntrack->proto.sctp */
29static DEFINE_RWLOCK(sctp_lock);
30
31/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
601e68e1 32 closely. They're more complex. --RR
9fb9cbb1
YK
33
34 And so for me for SCTP :D -Kiran */
35
36static const char *sctp_conntrack_names[] = {
37 "NONE",
38 "CLOSED",
39 "COOKIE_WAIT",
40 "COOKIE_ECHOED",
41 "ESTABLISHED",
42 "SHUTDOWN_SENT",
43 "SHUTDOWN_RECD",
44 "SHUTDOWN_ACK_SENT",
45};
46
47#define SECS * HZ
48#define MINS * 60 SECS
49#define HOURS * 60 MINS
50#define DAYS * 24 HOURS
51
94aec08e
BH
52static unsigned int nf_ct_sctp_timeout_closed __read_mostly = 10 SECS;
53static unsigned int nf_ct_sctp_timeout_cookie_wait __read_mostly = 3 SECS;
54static unsigned int nf_ct_sctp_timeout_cookie_echoed __read_mostly = 3 SECS;
55static unsigned int nf_ct_sctp_timeout_established __read_mostly = 5 DAYS;
56static unsigned int nf_ct_sctp_timeout_shutdown_sent __read_mostly = 300 SECS / 1000;
57static unsigned int nf_ct_sctp_timeout_shutdown_recd __read_mostly = 300 SECS / 1000;
58static unsigned int nf_ct_sctp_timeout_shutdown_ack_sent __read_mostly = 3 SECS;
9fb9cbb1 59
babbdb1a 60static unsigned int * sctp_timeouts[]
9fb9cbb1
YK
61= { NULL, /* SCTP_CONNTRACK_NONE */
62 &nf_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */
63 &nf_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */
64 &nf_ct_sctp_timeout_cookie_echoed, /* SCTP_CONNTRACK_COOKIE_ECHOED */
65 &nf_ct_sctp_timeout_established, /* SCTP_CONNTRACK_ESTABLISHED */
66 &nf_ct_sctp_timeout_shutdown_sent, /* SCTP_CONNTRACK_SHUTDOWN_SENT */
67 &nf_ct_sctp_timeout_shutdown_recd, /* SCTP_CONNTRACK_SHUTDOWN_RECD */
68 &nf_ct_sctp_timeout_shutdown_ack_sent /* SCTP_CONNTRACK_SHUTDOWN_ACK_SENT */
69 };
70
71#define sNO SCTP_CONNTRACK_NONE
72#define sCL SCTP_CONNTRACK_CLOSED
73#define sCW SCTP_CONNTRACK_COOKIE_WAIT
74#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
75#define sES SCTP_CONNTRACK_ESTABLISHED
76#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
77#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
78#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
79#define sIV SCTP_CONNTRACK_MAX
80
601e68e1 81/*
9fb9cbb1
YK
82 These are the descriptions of the states:
83
601e68e1 84NOTE: These state names are tantalizingly similar to the states of an
9fb9cbb1 85SCTP endpoint. But the interpretation of the states is a little different,
601e68e1 86considering that these are the states of the connection and not of an end
9fb9cbb1
YK
87point. Please note the subtleties. -Kiran
88
89NONE - Nothing so far.
601e68e1
YH
90COOKIE WAIT - We have seen an INIT chunk in the original direction, or also
91 an INIT_ACK chunk in the reply direction.
9fb9cbb1
YK
92COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direction.
93ESTABLISHED - We have seen a COOKIE_ACK in the reply direction.
94SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original direction.
95SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin.
96SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
601e68e1
YH
97 to that of the SHUTDOWN chunk.
98CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
99 the SHUTDOWN chunk. Connection is closed.
9fb9cbb1
YK
100*/
101
102/* TODO
601e68e1 103 - I have assumed that the first INIT is in the original direction.
9fb9cbb1
YK
104 This messes things when an INIT comes in the reply direction in CLOSED
105 state.
601e68e1 106 - Check the error type in the reply dir before transitioning from
9fb9cbb1
YK
107cookie echoed to closed.
108 - Sec 5.2.4 of RFC 2960
109 - Multi Homing support.
110*/
111
112/* SCTP conntrack state transitions */
a5e73c29 113static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
9fb9cbb1
YK
114 {
115/* ORIGINAL */
116/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
117/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
118/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
119/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
120/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
121/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
122/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have Stale cookie*/
123/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
124/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in orig dir */
125/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
126 },
127 {
128/* REPLY */
129/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
130/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
131/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
132/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
133/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
134/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
135/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
136/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come in reply dir */
137/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
138/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
139 }
140};
141
142static int sctp_pkt_to_tuple(const struct sk_buff *skb,
143 unsigned int dataoff,
144 struct nf_conntrack_tuple *tuple)
145{
146 sctp_sctphdr_t _hdr, *hp;
147
9fb9cbb1
YK
148 /* Actually only need first 8 bytes. */
149 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
150 if (hp == NULL)
151 return 0;
152
153 tuple->src.u.sctp.port = hp->source;
154 tuple->dst.u.sctp.port = hp->dest;
155 return 1;
156}
157
158static int sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
159 const struct nf_conntrack_tuple *orig)
160{
9fb9cbb1
YK
161 tuple->src.u.sctp.port = orig->dst.u.sctp.port;
162 tuple->dst.u.sctp.port = orig->src.u.sctp.port;
163 return 1;
164}
165
166/* Print out the per-protocol part of the tuple. */
167static int sctp_print_tuple(struct seq_file *s,
168 const struct nf_conntrack_tuple *tuple)
169{
9fb9cbb1
YK
170 return seq_printf(s, "sport=%hu dport=%hu ",
171 ntohs(tuple->src.u.sctp.port),
172 ntohs(tuple->dst.u.sctp.port));
173}
174
175/* Print out the private part of the conntrack. */
112f35c9 176static int sctp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
9fb9cbb1
YK
177{
178 enum sctp_conntrack state;
179
9fb9cbb1 180 read_lock_bh(&sctp_lock);
112f35c9 181 state = ct->proto.sctp.state;
9fb9cbb1
YK
182 read_unlock_bh(&sctp_lock);
183
184 return seq_printf(s, "%s ", sctp_conntrack_names[state]);
185}
186
187#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
e79ec50b
JE
188for ((offset) = (dataoff) + sizeof(sctp_sctphdr_t), (count) = 0; \
189 (offset) < (skb)->len && \
190 ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \
191 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
9fb9cbb1
YK
192
193/* Some validity checks to make sure the chunks are fine */
112f35c9 194static int do_basic_checks(struct nf_conn *ct,
9fb9cbb1
YK
195 const struct sk_buff *skb,
196 unsigned int dataoff,
35c6d3cb 197 unsigned long *map)
9fb9cbb1
YK
198{
199 u_int32_t offset, count;
200 sctp_chunkhdr_t _sch, *sch;
201 int flag;
202
9fb9cbb1
YK
203 flag = 0;
204
205 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
0d53778e 206 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type);
9fb9cbb1 207
5447d477
PM
208 if (sch->type == SCTP_CID_INIT ||
209 sch->type == SCTP_CID_INIT_ACK ||
210 sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
9fb9cbb1 211 flag = 1;
9fb9cbb1 212
e17df688
PM
213 /*
214 * Cookie Ack/Echo chunks not the first OR
215 * Init / Init Ack / Shutdown compl chunks not the only chunks
216 * OR zero-length.
217 */
5447d477
PM
218 if (((sch->type == SCTP_CID_COOKIE_ACK ||
219 sch->type == SCTP_CID_COOKIE_ECHO ||
220 flag) &&
221 count != 0) || !sch->length) {
0d53778e 222 pr_debug("Basic checks failed\n");
9fb9cbb1
YK
223 return 1;
224 }
225
5447d477 226 if (map)
35c6d3cb 227 set_bit(sch->type, map);
9fb9cbb1
YK
228 }
229
0d53778e 230 pr_debug("Basic checks passed\n");
dd7271fe 231 return count == 0;
9fb9cbb1
YK
232}
233
efe9f68a
PM
234static int sctp_new_state(enum ip_conntrack_dir dir,
235 enum sctp_conntrack cur_state,
236 int chunk_type)
9fb9cbb1
YK
237{
238 int i;
239
0d53778e 240 pr_debug("Chunk type: %d\n", chunk_type);
9fb9cbb1
YK
241
242 switch (chunk_type) {
5447d477
PM
243 case SCTP_CID_INIT:
244 pr_debug("SCTP_CID_INIT\n");
245 i = 0;
246 break;
247 case SCTP_CID_INIT_ACK:
248 pr_debug("SCTP_CID_INIT_ACK\n");
249 i = 1;
250 break;
251 case SCTP_CID_ABORT:
252 pr_debug("SCTP_CID_ABORT\n");
253 i = 2;
254 break;
255 case SCTP_CID_SHUTDOWN:
256 pr_debug("SCTP_CID_SHUTDOWN\n");
257 i = 3;
258 break;
259 case SCTP_CID_SHUTDOWN_ACK:
260 pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
261 i = 4;
262 break;
263 case SCTP_CID_ERROR:
264 pr_debug("SCTP_CID_ERROR\n");
265 i = 5;
266 break;
267 case SCTP_CID_COOKIE_ECHO:
268 pr_debug("SCTP_CID_COOKIE_ECHO\n");
269 i = 6;
270 break;
271 case SCTP_CID_COOKIE_ACK:
272 pr_debug("SCTP_CID_COOKIE_ACK\n");
273 i = 7;
274 break;
275 case SCTP_CID_SHUTDOWN_COMPLETE:
276 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
277 i = 8;
278 break;
279 default:
280 /* Other chunks like DATA, SACK, HEARTBEAT and
281 its ACK do not cause a change in state */
282 pr_debug("Unknown chunk type, Will stay in %s\n",
283 sctp_conntrack_names[cur_state]);
284 return cur_state;
9fb9cbb1
YK
285 }
286
0d53778e
PM
287 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
288 dir, sctp_conntrack_names[cur_state], chunk_type,
289 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
9fb9cbb1
YK
290
291 return sctp_conntracks[dir][i][cur_state];
292}
293
b37e933a 294/* Returns verdict for packet, or -NF_ACCEPT for invalid. */
112f35c9 295static int sctp_packet(struct nf_conn *ct,
9fb9cbb1
YK
296 const struct sk_buff *skb,
297 unsigned int dataoff,
298 enum ip_conntrack_info ctinfo,
299 int pf,
300 unsigned int hooknum)
301{
efe9f68a 302 enum sctp_conntrack new_state, old_state;
8528819a 303 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
9fb9cbb1
YK
304 sctp_sctphdr_t _sctph, *sh;
305 sctp_chunkhdr_t _sch, *sch;
306 u_int32_t offset, count;
35c6d3cb 307 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
9fb9cbb1 308
9fb9cbb1
YK
309 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
310 if (sh == NULL)
b37e933a 311 goto out;
9fb9cbb1 312
112f35c9 313 if (do_basic_checks(ct, skb, dataoff, map) != 0)
b37e933a 314 goto out;
9fb9cbb1
YK
315
316 /* Check the verification tag (Sec 8.5) */
35c6d3cb
PM
317 if (!test_bit(SCTP_CID_INIT, map) &&
318 !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) &&
319 !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
320 !test_bit(SCTP_CID_ABORT, map) &&
321 !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
8528819a 322 sh->vtag != ct->proto.sctp.vtag[dir]) {
0d53778e 323 pr_debug("Verification tag check failed\n");
b37e933a 324 goto out;
9fb9cbb1
YK
325 }
326
efe9f68a 327 old_state = new_state = SCTP_CONNTRACK_MAX;
4a64830a 328 write_lock_bh(&sctp_lock);
9fb9cbb1 329 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
9fb9cbb1
YK
330 /* Special cases of Verification tag check (Sec 8.5.1) */
331 if (sch->type == SCTP_CID_INIT) {
332 /* Sec 8.5.1 (A) */
b37e933a
PM
333 if (sh->vtag != 0)
334 goto out_unlock;
9fb9cbb1
YK
335 } else if (sch->type == SCTP_CID_ABORT) {
336 /* Sec 8.5.1 (B) */
8528819a 337 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
b37e933a
PM
338 sh->vtag != ct->proto.sctp.vtag[!dir])
339 goto out_unlock;
9fb9cbb1
YK
340 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
341 /* Sec 8.5.1 (C) */
8528819a
PM
342 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
343 sh->vtag != ct->proto.sctp.vtag[!dir] &&
9b1c2cfd 344 sch->flags & SCTP_CHUNK_FLAG_T)
b37e933a 345 goto out_unlock;
9fb9cbb1
YK
346 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
347 /* Sec 8.5.1 (D) */
b37e933a
PM
348 if (sh->vtag != ct->proto.sctp.vtag[dir])
349 goto out_unlock;
9fb9cbb1
YK
350 }
351
efe9f68a
PM
352 old_state = ct->proto.sctp.state;
353 new_state = sctp_new_state(dir, old_state, sch->type);
9fb9cbb1
YK
354
355 /* Invalid */
efe9f68a 356 if (new_state == SCTP_CONNTRACK_MAX) {
0d53778e
PM
357 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
358 "conntrack=%u\n",
efe9f68a 359 dir, sch->type, old_state);
b37e933a 360 goto out_unlock;
9fb9cbb1
YK
361 }
362
363 /* If it is an INIT or an INIT ACK note down the vtag */
5447d477
PM
364 if (sch->type == SCTP_CID_INIT ||
365 sch->type == SCTP_CID_INIT_ACK) {
9fb9cbb1
YK
366 sctp_inithdr_t _inithdr, *ih;
367
368 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
601e68e1 369 sizeof(_inithdr), &_inithdr);
b37e933a
PM
370 if (ih == NULL)
371 goto out_unlock;
0d53778e 372 pr_debug("Setting vtag %x for dir %d\n",
8528819a
PM
373 ih->init_tag, !dir);
374 ct->proto.sctp.vtag[!dir] = ih->init_tag;
9fb9cbb1
YK
375 }
376
efe9f68a
PM
377 ct->proto.sctp.state = new_state;
378 if (old_state != new_state)
9fb9cbb1 379 nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
9fb9cbb1 380 }
4a64830a 381 write_unlock_bh(&sctp_lock);
9fb9cbb1 382
efe9f68a 383 nf_ct_refresh_acct(ct, ctinfo, skb, *sctp_timeouts[new_state]);
9fb9cbb1 384
efe9f68a 385 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
8528819a 386 dir == IP_CT_DIR_REPLY &&
efe9f68a 387 new_state == SCTP_CONNTRACK_ESTABLISHED) {
0d53778e 388 pr_debug("Setting assured bit\n");
112f35c9 389 set_bit(IPS_ASSURED_BIT, &ct->status);
9fb9cbb1
YK
390 nf_conntrack_event_cache(IPCT_STATUS, skb);
391 }
392
393 return NF_ACCEPT;
b37e933a
PM
394
395out_unlock:
396 write_unlock_bh(&sctp_lock);
397out:
398 return -NF_ACCEPT;
9fb9cbb1
YK
399}
400
401/* Called when a new connection for this protocol found. */
112f35c9 402static int sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
9fb9cbb1
YK
403 unsigned int dataoff)
404{
efe9f68a 405 enum sctp_conntrack new_state;
9fb9cbb1
YK
406 sctp_sctphdr_t _sctph, *sh;
407 sctp_chunkhdr_t _sch, *sch;
408 u_int32_t offset, count;
35c6d3cb 409 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
9fb9cbb1 410
9fb9cbb1
YK
411 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
412 if (sh == NULL)
413 return 0;
414
112f35c9 415 if (do_basic_checks(ct, skb, dataoff, map) != 0)
9fb9cbb1
YK
416 return 0;
417
418 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
35c6d3cb
PM
419 if (test_bit(SCTP_CID_ABORT, map) ||
420 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
421 test_bit(SCTP_CID_COOKIE_ACK, map))
9fb9cbb1 422 return 0;
9fb9cbb1 423
efe9f68a 424 new_state = SCTP_CONNTRACK_MAX;
9fb9cbb1
YK
425 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
426 /* Don't need lock here: this conntrack not in circulation yet */
efe9f68a
PM
427 new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
428 SCTP_CONNTRACK_NONE, sch->type);
9fb9cbb1
YK
429
430 /* Invalid: delete conntrack */
efe9f68a
PM
431 if (new_state == SCTP_CONNTRACK_NONE ||
432 new_state == SCTP_CONNTRACK_MAX) {
0d53778e 433 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
9fb9cbb1
YK
434 return 0;
435 }
436
437 /* Copy the vtag into the state info */
438 if (sch->type == SCTP_CID_INIT) {
439 if (sh->vtag == 0) {
440 sctp_inithdr_t _inithdr, *ih;
441
442 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
601e68e1 443 sizeof(_inithdr), &_inithdr);
9fb9cbb1
YK
444 if (ih == NULL)
445 return 0;
446
0d53778e
PM
447 pr_debug("Setting vtag %x for new conn\n",
448 ih->init_tag);
9fb9cbb1 449
112f35c9 450 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
9fb9cbb1
YK
451 ih->init_tag;
452 } else {
453 /* Sec 8.5.1 (A) */
454 return 0;
455 }
456 }
457 /* If it is a shutdown ack OOTB packet, we expect a return
458 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
459 else {
0d53778e
PM
460 pr_debug("Setting vtag %x for new conn OOTB\n",
461 sh->vtag);
112f35c9 462 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
9fb9cbb1
YK
463 }
464
efe9f68a 465 ct->proto.sctp.state = new_state;
9fb9cbb1
YK
466 }
467
468 return 1;
469}
470
9fb9cbb1 471#ifdef CONFIG_SYSCTL
933a41e7
PM
472static unsigned int sctp_sysctl_table_users;
473static struct ctl_table_header *sctp_sysctl_header;
474static struct ctl_table sctp_sysctl_table[] = {
9fb9cbb1 475 {
9fb9cbb1
YK
476 .procname = "nf_conntrack_sctp_timeout_closed",
477 .data = &nf_ct_sctp_timeout_closed,
478 .maxlen = sizeof(unsigned int),
479 .mode = 0644,
480 .proc_handler = &proc_dointvec_jiffies,
481 },
482 {
9fb9cbb1
YK
483 .procname = "nf_conntrack_sctp_timeout_cookie_wait",
484 .data = &nf_ct_sctp_timeout_cookie_wait,
485 .maxlen = sizeof(unsigned int),
486 .mode = 0644,
487 .proc_handler = &proc_dointvec_jiffies,
488 },
489 {
9fb9cbb1
YK
490 .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
491 .data = &nf_ct_sctp_timeout_cookie_echoed,
492 .maxlen = sizeof(unsigned int),
493 .mode = 0644,
494 .proc_handler = &proc_dointvec_jiffies,
495 },
496 {
9fb9cbb1
YK
497 .procname = "nf_conntrack_sctp_timeout_established",
498 .data = &nf_ct_sctp_timeout_established,
499 .maxlen = sizeof(unsigned int),
500 .mode = 0644,
501 .proc_handler = &proc_dointvec_jiffies,
502 },
503 {
9fb9cbb1
YK
504 .procname = "nf_conntrack_sctp_timeout_shutdown_sent",
505 .data = &nf_ct_sctp_timeout_shutdown_sent,
506 .maxlen = sizeof(unsigned int),
507 .mode = 0644,
508 .proc_handler = &proc_dointvec_jiffies,
509 },
510 {
9fb9cbb1
YK
511 .procname = "nf_conntrack_sctp_timeout_shutdown_recd",
512 .data = &nf_ct_sctp_timeout_shutdown_recd,
513 .maxlen = sizeof(unsigned int),
514 .mode = 0644,
515 .proc_handler = &proc_dointvec_jiffies,
516 },
517 {
9fb9cbb1
YK
518 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
519 .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
520 .maxlen = sizeof(unsigned int),
521 .mode = 0644,
522 .proc_handler = &proc_dointvec_jiffies,
523 },
9fb9cbb1 524 {
933a41e7
PM
525 .ctl_name = 0
526 }
9fb9cbb1 527};
a999e683
PM
528
529#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
530static struct ctl_table sctp_compat_sysctl_table[] = {
531 {
a999e683
PM
532 .procname = "ip_conntrack_sctp_timeout_closed",
533 .data = &nf_ct_sctp_timeout_closed,
534 .maxlen = sizeof(unsigned int),
535 .mode = 0644,
536 .proc_handler = &proc_dointvec_jiffies,
537 },
538 {
a999e683
PM
539 .procname = "ip_conntrack_sctp_timeout_cookie_wait",
540 .data = &nf_ct_sctp_timeout_cookie_wait,
541 .maxlen = sizeof(unsigned int),
542 .mode = 0644,
543 .proc_handler = &proc_dointvec_jiffies,
544 },
545 {
a999e683
PM
546 .procname = "ip_conntrack_sctp_timeout_cookie_echoed",
547 .data = &nf_ct_sctp_timeout_cookie_echoed,
548 .maxlen = sizeof(unsigned int),
549 .mode = 0644,
550 .proc_handler = &proc_dointvec_jiffies,
551 },
552 {
a999e683
PM
553 .procname = "ip_conntrack_sctp_timeout_established",
554 .data = &nf_ct_sctp_timeout_established,
555 .maxlen = sizeof(unsigned int),
556 .mode = 0644,
557 .proc_handler = &proc_dointvec_jiffies,
558 },
559 {
a999e683
PM
560 .procname = "ip_conntrack_sctp_timeout_shutdown_sent",
561 .data = &nf_ct_sctp_timeout_shutdown_sent,
562 .maxlen = sizeof(unsigned int),
563 .mode = 0644,
564 .proc_handler = &proc_dointvec_jiffies,
565 },
566 {
a999e683
PM
567 .procname = "ip_conntrack_sctp_timeout_shutdown_recd",
568 .data = &nf_ct_sctp_timeout_shutdown_recd,
569 .maxlen = sizeof(unsigned int),
570 .mode = 0644,
571 .proc_handler = &proc_dointvec_jiffies,
572 },
573 {
a999e683
PM
574 .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
575 .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
576 .maxlen = sizeof(unsigned int),
577 .mode = 0644,
578 .proc_handler = &proc_dointvec_jiffies,
579 },
580 {
581 .ctl_name = 0
582 }
583};
584#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
933a41e7 585#endif
9fb9cbb1 586
61075af5 587static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
933a41e7
PM
588 .l3proto = PF_INET,
589 .l4proto = IPPROTO_SCTP,
590 .name = "sctp",
591 .pkt_to_tuple = sctp_pkt_to_tuple,
592 .invert_tuple = sctp_invert_tuple,
593 .print_tuple = sctp_print_tuple,
594 .print_conntrack = sctp_print_conntrack,
595 .packet = sctp_packet,
596 .new = sctp_new,
597 .me = THIS_MODULE,
c7212e9d
PNA
598#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
599 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
600 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
601 .nla_policy = nf_ct_port_nla_policy,
602#endif
933a41e7
PM
603#ifdef CONFIG_SYSCTL
604 .ctl_table_users = &sctp_sysctl_table_users,
605 .ctl_table_header = &sctp_sysctl_header,
606 .ctl_table = sctp_sysctl_table,
a999e683
PM
607#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
608 .ctl_compat_table = sctp_compat_sysctl_table,
609#endif
933a41e7 610#endif
9fb9cbb1
YK
611};
612
61075af5 613static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
933a41e7
PM
614 .l3proto = PF_INET6,
615 .l4proto = IPPROTO_SCTP,
616 .name = "sctp",
617 .pkt_to_tuple = sctp_pkt_to_tuple,
618 .invert_tuple = sctp_invert_tuple,
619 .print_tuple = sctp_print_tuple,
620 .print_conntrack = sctp_print_conntrack,
621 .packet = sctp_packet,
622 .new = sctp_new,
623 .me = THIS_MODULE,
c7212e9d
PNA
624#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
625 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
626 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
627 .nla_policy = nf_ct_port_nla_policy,
628#endif
933a41e7
PM
629#ifdef CONFIG_SYSCTL
630 .ctl_table_users = &sctp_sysctl_table_users,
631 .ctl_table_header = &sctp_sysctl_header,
632 .ctl_table = sctp_sysctl_table,
9fb9cbb1 633#endif
933a41e7 634};
9fb9cbb1 635
65b4b4e8 636int __init nf_conntrack_proto_sctp_init(void)
9fb9cbb1
YK
637{
638 int ret;
639
605dcad6 640 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
9fb9cbb1 641 if (ret) {
605dcad6 642 printk("nf_conntrack_l4proto_sctp4: protocol register failed\n");
9fb9cbb1
YK
643 goto out;
644 }
605dcad6 645 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
9fb9cbb1 646 if (ret) {
605dcad6 647 printk("nf_conntrack_l4proto_sctp6: protocol register failed\n");
9fb9cbb1
YK
648 goto cleanup_sctp4;
649 }
650
9fb9cbb1
YK
651 return ret;
652
9fb9cbb1 653 cleanup_sctp4:
605dcad6 654 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
9fb9cbb1 655 out:
9fb9cbb1
YK
656 return ret;
657}
658
65b4b4e8 659void __exit nf_conntrack_proto_sctp_fini(void)
9fb9cbb1 660{
605dcad6
MJ
661 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
662 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
9fb9cbb1
YK
663}
664
65b4b4e8
AM
665module_init(nf_conntrack_proto_sctp_init);
666module_exit(nf_conntrack_proto_sctp_fini);
9fb9cbb1
YK
667
668MODULE_LICENSE("GPL");
669MODULE_AUTHOR("Kiran Kumar Immidi");
670MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
d2483dde 671MODULE_ALIAS("ip_conntrack_proto_sctp");