[NETFILTER]: nf_conntrack_sctp: use proper types for bitops
[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. */
176static int sctp_print_conntrack(struct seq_file *s,
177 const struct nf_conn *conntrack)
178{
179 enum sctp_conntrack state;
180
9fb9cbb1
YK
181 read_lock_bh(&sctp_lock);
182 state = conntrack->proto.sctp.state;
183 read_unlock_bh(&sctp_lock);
184
185 return seq_printf(s, "%s ", sctp_conntrack_names[state]);
186}
187
188#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
e79ec50b
JE
189for ((offset) = (dataoff) + sizeof(sctp_sctphdr_t), (count) = 0; \
190 (offset) < (skb)->len && \
191 ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \
192 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
9fb9cbb1
YK
193
194/* Some validity checks to make sure the chunks are fine */
195static int do_basic_checks(struct nf_conn *conntrack,
196 const struct sk_buff *skb,
197 unsigned int dataoff,
35c6d3cb 198 unsigned long *map)
9fb9cbb1
YK
199{
200 u_int32_t offset, count;
201 sctp_chunkhdr_t _sch, *sch;
202 int flag;
203
9fb9cbb1
YK
204 flag = 0;
205
206 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
0d53778e 207 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type);
9fb9cbb1 208
5447d477
PM
209 if (sch->type == SCTP_CID_INIT ||
210 sch->type == SCTP_CID_INIT_ACK ||
211 sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
9fb9cbb1 212 flag = 1;
9fb9cbb1 213
e17df688
PM
214 /*
215 * Cookie Ack/Echo chunks not the first OR
216 * Init / Init Ack / Shutdown compl chunks not the only chunks
217 * OR zero-length.
218 */
5447d477
PM
219 if (((sch->type == SCTP_CID_COOKIE_ACK ||
220 sch->type == SCTP_CID_COOKIE_ECHO ||
221 flag) &&
222 count != 0) || !sch->length) {
0d53778e 223 pr_debug("Basic checks failed\n");
9fb9cbb1
YK
224 return 1;
225 }
226
5447d477 227 if (map)
35c6d3cb 228 set_bit(sch->type, map);
9fb9cbb1
YK
229 }
230
0d53778e 231 pr_debug("Basic checks passed\n");
dd7271fe 232 return count == 0;
9fb9cbb1
YK
233}
234
235static int new_state(enum ip_conntrack_dir dir,
236 enum sctp_conntrack cur_state,
237 int chunk_type)
238{
239 int i;
240
0d53778e 241 pr_debug("Chunk type: %d\n", chunk_type);
9fb9cbb1
YK
242
243 switch (chunk_type) {
5447d477
PM
244 case SCTP_CID_INIT:
245 pr_debug("SCTP_CID_INIT\n");
246 i = 0;
247 break;
248 case SCTP_CID_INIT_ACK:
249 pr_debug("SCTP_CID_INIT_ACK\n");
250 i = 1;
251 break;
252 case SCTP_CID_ABORT:
253 pr_debug("SCTP_CID_ABORT\n");
254 i = 2;
255 break;
256 case SCTP_CID_SHUTDOWN:
257 pr_debug("SCTP_CID_SHUTDOWN\n");
258 i = 3;
259 break;
260 case SCTP_CID_SHUTDOWN_ACK:
261 pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
262 i = 4;
263 break;
264 case SCTP_CID_ERROR:
265 pr_debug("SCTP_CID_ERROR\n");
266 i = 5;
267 break;
268 case SCTP_CID_COOKIE_ECHO:
269 pr_debug("SCTP_CID_COOKIE_ECHO\n");
270 i = 6;
271 break;
272 case SCTP_CID_COOKIE_ACK:
273 pr_debug("SCTP_CID_COOKIE_ACK\n");
274 i = 7;
275 break;
276 case SCTP_CID_SHUTDOWN_COMPLETE:
277 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
278 i = 8;
279 break;
280 default:
281 /* Other chunks like DATA, SACK, HEARTBEAT and
282 its ACK do not cause a change in state */
283 pr_debug("Unknown chunk type, Will stay in %s\n",
284 sctp_conntrack_names[cur_state]);
285 return cur_state;
9fb9cbb1
YK
286 }
287
0d53778e
PM
288 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
289 dir, sctp_conntrack_names[cur_state], chunk_type,
290 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
9fb9cbb1
YK
291
292 return sctp_conntracks[dir][i][cur_state];
293}
294
295/* Returns verdict for packet, or -1 for invalid. */
296static int sctp_packet(struct nf_conn *conntrack,
297 const struct sk_buff *skb,
298 unsigned int dataoff,
299 enum ip_conntrack_info ctinfo,
300 int pf,
301 unsigned int hooknum)
302{
303 enum sctp_conntrack newconntrack, oldsctpstate;
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)
311 return -1;
312
313 if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
314 return -1;
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) &&
5447d477 322 sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) {
0d53778e 323 pr_debug("Verification tag check failed\n");
9fb9cbb1
YK
324 return -1;
325 }
326
327 oldsctpstate = newconntrack = SCTP_CONNTRACK_MAX;
328 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
329 write_lock_bh(&sctp_lock);
330
331 /* Special cases of Verification tag check (Sec 8.5.1) */
332 if (sch->type == SCTP_CID_INIT) {
333 /* Sec 8.5.1 (A) */
334 if (sh->vtag != 0) {
335 write_unlock_bh(&sctp_lock);
336 return -1;
337 }
338 } else if (sch->type == SCTP_CID_ABORT) {
339 /* Sec 8.5.1 (B) */
5447d477
PM
340 if (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)] &&
341 sh->vtag != conntrack->proto.sctp.vtag[1 - CTINFO2DIR(ctinfo)]) {
9fb9cbb1
YK
342 write_unlock_bh(&sctp_lock);
343 return -1;
344 }
345 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
346 /* Sec 8.5.1 (C) */
5447d477
PM
347 if (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)] &&
348 sh->vtag != conntrack->proto.sctp.vtag[1 - CTINFO2DIR(ctinfo)] &&
349 (sch->flags & 1)) {
9fb9cbb1
YK
350 write_unlock_bh(&sctp_lock);
351 return -1;
352 }
353 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
354 /* Sec 8.5.1 (D) */
5447d477 355 if (sh->vtag != conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) {
9fb9cbb1
YK
356 write_unlock_bh(&sctp_lock);
357 return -1;
358 }
359 }
360
361 oldsctpstate = conntrack->proto.sctp.state;
362 newconntrack = new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch->type);
363
364 /* Invalid */
365 if (newconntrack == SCTP_CONNTRACK_MAX) {
0d53778e
PM
366 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
367 "conntrack=%u\n",
368 CTINFO2DIR(ctinfo), sch->type, oldsctpstate);
9fb9cbb1
YK
369 write_unlock_bh(&sctp_lock);
370 return -1;
371 }
372
373 /* If it is an INIT or an INIT ACK note down the vtag */
5447d477
PM
374 if (sch->type == SCTP_CID_INIT ||
375 sch->type == SCTP_CID_INIT_ACK) {
9fb9cbb1
YK
376 sctp_inithdr_t _inithdr, *ih;
377
378 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
601e68e1 379 sizeof(_inithdr), &_inithdr);
9fb9cbb1 380 if (ih == NULL) {
5447d477
PM
381 write_unlock_bh(&sctp_lock);
382 return -1;
9fb9cbb1 383 }
0d53778e
PM
384 pr_debug("Setting vtag %x for dir %d\n",
385 ih->init_tag, !CTINFO2DIR(ctinfo));
9fb9cbb1
YK
386 conntrack->proto.sctp.vtag[!CTINFO2DIR(ctinfo)] = ih->init_tag;
387 }
388
389 conntrack->proto.sctp.state = newconntrack;
390 if (oldsctpstate != newconntrack)
391 nf_conntrack_event_cache(IPCT_PROTOINFO, skb);
392 write_unlock_bh(&sctp_lock);
393 }
394
395 nf_ct_refresh_acct(conntrack, ctinfo, skb, *sctp_timeouts[newconntrack]);
396
5447d477
PM
397 if (oldsctpstate == SCTP_CONNTRACK_COOKIE_ECHOED &&
398 CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY &&
399 newconntrack == SCTP_CONNTRACK_ESTABLISHED) {
0d53778e 400 pr_debug("Setting assured bit\n");
9fb9cbb1
YK
401 set_bit(IPS_ASSURED_BIT, &conntrack->status);
402 nf_conntrack_event_cache(IPCT_STATUS, skb);
403 }
404
405 return NF_ACCEPT;
406}
407
408/* Called when a new connection for this protocol found. */
409static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
410 unsigned int dataoff)
411{
412 enum sctp_conntrack newconntrack;
413 sctp_sctphdr_t _sctph, *sh;
414 sctp_chunkhdr_t _sch, *sch;
415 u_int32_t offset, count;
35c6d3cb 416 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
9fb9cbb1 417
9fb9cbb1
YK
418 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
419 if (sh == NULL)
420 return 0;
421
422 if (do_basic_checks(conntrack, skb, dataoff, map) != 0)
423 return 0;
424
425 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
35c6d3cb
PM
426 if (test_bit(SCTP_CID_ABORT, map) ||
427 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
428 test_bit(SCTP_CID_COOKIE_ACK, map))
9fb9cbb1 429 return 0;
9fb9cbb1
YK
430
431 newconntrack = SCTP_CONNTRACK_MAX;
432 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
433 /* Don't need lock here: this conntrack not in circulation yet */
601e68e1 434 newconntrack = new_state(IP_CT_DIR_ORIGINAL,
9fb9cbb1
YK
435 SCTP_CONNTRACK_NONE, sch->type);
436
437 /* Invalid: delete conntrack */
99d24ede
PM
438 if (newconntrack == SCTP_CONNTRACK_NONE ||
439 newconntrack == SCTP_CONNTRACK_MAX) {
0d53778e 440 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
9fb9cbb1
YK
441 return 0;
442 }
443
444 /* Copy the vtag into the state info */
445 if (sch->type == SCTP_CID_INIT) {
446 if (sh->vtag == 0) {
447 sctp_inithdr_t _inithdr, *ih;
448
449 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
601e68e1 450 sizeof(_inithdr), &_inithdr);
9fb9cbb1
YK
451 if (ih == NULL)
452 return 0;
453
0d53778e
PM
454 pr_debug("Setting vtag %x for new conn\n",
455 ih->init_tag);
9fb9cbb1 456
601e68e1 457 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
9fb9cbb1
YK
458 ih->init_tag;
459 } else {
460 /* Sec 8.5.1 (A) */
461 return 0;
462 }
463 }
464 /* If it is a shutdown ack OOTB packet, we expect a return
465 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
466 else {
0d53778e
PM
467 pr_debug("Setting vtag %x for new conn OOTB\n",
468 sh->vtag);
9fb9cbb1
YK
469 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
470 }
471
472 conntrack->proto.sctp.state = newconntrack;
473 }
474
475 return 1;
476}
477
9fb9cbb1 478#ifdef CONFIG_SYSCTL
933a41e7
PM
479static unsigned int sctp_sysctl_table_users;
480static struct ctl_table_header *sctp_sysctl_header;
481static struct ctl_table sctp_sysctl_table[] = {
9fb9cbb1 482 {
9fb9cbb1
YK
483 .procname = "nf_conntrack_sctp_timeout_closed",
484 .data = &nf_ct_sctp_timeout_closed,
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_wait",
491 .data = &nf_ct_sctp_timeout_cookie_wait,
492 .maxlen = sizeof(unsigned int),
493 .mode = 0644,
494 .proc_handler = &proc_dointvec_jiffies,
495 },
496 {
9fb9cbb1
YK
497 .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
498 .data = &nf_ct_sctp_timeout_cookie_echoed,
499 .maxlen = sizeof(unsigned int),
500 .mode = 0644,
501 .proc_handler = &proc_dointvec_jiffies,
502 },
503 {
9fb9cbb1
YK
504 .procname = "nf_conntrack_sctp_timeout_established",
505 .data = &nf_ct_sctp_timeout_established,
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_sent",
512 .data = &nf_ct_sctp_timeout_shutdown_sent,
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_recd",
519 .data = &nf_ct_sctp_timeout_shutdown_recd,
520 .maxlen = sizeof(unsigned int),
521 .mode = 0644,
522 .proc_handler = &proc_dointvec_jiffies,
523 },
524 {
9fb9cbb1
YK
525 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
526 .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
527 .maxlen = sizeof(unsigned int),
528 .mode = 0644,
529 .proc_handler = &proc_dointvec_jiffies,
530 },
9fb9cbb1 531 {
933a41e7
PM
532 .ctl_name = 0
533 }
9fb9cbb1 534};
a999e683
PM
535
536#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
537static struct ctl_table sctp_compat_sysctl_table[] = {
538 {
a999e683
PM
539 .procname = "ip_conntrack_sctp_timeout_closed",
540 .data = &nf_ct_sctp_timeout_closed,
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_wait",
547 .data = &nf_ct_sctp_timeout_cookie_wait,
548 .maxlen = sizeof(unsigned int),
549 .mode = 0644,
550 .proc_handler = &proc_dointvec_jiffies,
551 },
552 {
a999e683
PM
553 .procname = "ip_conntrack_sctp_timeout_cookie_echoed",
554 .data = &nf_ct_sctp_timeout_cookie_echoed,
555 .maxlen = sizeof(unsigned int),
556 .mode = 0644,
557 .proc_handler = &proc_dointvec_jiffies,
558 },
559 {
a999e683
PM
560 .procname = "ip_conntrack_sctp_timeout_established",
561 .data = &nf_ct_sctp_timeout_established,
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_sent",
568 .data = &nf_ct_sctp_timeout_shutdown_sent,
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_recd",
575 .data = &nf_ct_sctp_timeout_shutdown_recd,
576 .maxlen = sizeof(unsigned int),
577 .mode = 0644,
578 .proc_handler = &proc_dointvec_jiffies,
579 },
580 {
a999e683
PM
581 .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
582 .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
583 .maxlen = sizeof(unsigned int),
584 .mode = 0644,
585 .proc_handler = &proc_dointvec_jiffies,
586 },
587 {
588 .ctl_name = 0
589 }
590};
591#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
933a41e7 592#endif
9fb9cbb1 593
61075af5 594static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
933a41e7
PM
595 .l3proto = PF_INET,
596 .l4proto = IPPROTO_SCTP,
597 .name = "sctp",
598 .pkt_to_tuple = sctp_pkt_to_tuple,
599 .invert_tuple = sctp_invert_tuple,
600 .print_tuple = sctp_print_tuple,
601 .print_conntrack = sctp_print_conntrack,
602 .packet = sctp_packet,
603 .new = sctp_new,
604 .me = THIS_MODULE,
c7212e9d
PNA
605#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
606 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
607 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
608 .nla_policy = nf_ct_port_nla_policy,
609#endif
933a41e7
PM
610#ifdef CONFIG_SYSCTL
611 .ctl_table_users = &sctp_sysctl_table_users,
612 .ctl_table_header = &sctp_sysctl_header,
613 .ctl_table = sctp_sysctl_table,
a999e683
PM
614#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
615 .ctl_compat_table = sctp_compat_sysctl_table,
616#endif
933a41e7 617#endif
9fb9cbb1
YK
618};
619
61075af5 620static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
933a41e7
PM
621 .l3proto = PF_INET6,
622 .l4proto = IPPROTO_SCTP,
623 .name = "sctp",
624 .pkt_to_tuple = sctp_pkt_to_tuple,
625 .invert_tuple = sctp_invert_tuple,
626 .print_tuple = sctp_print_tuple,
627 .print_conntrack = sctp_print_conntrack,
628 .packet = sctp_packet,
629 .new = sctp_new,
630 .me = THIS_MODULE,
c7212e9d
PNA
631#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
632 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
633 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
634 .nla_policy = nf_ct_port_nla_policy,
635#endif
933a41e7
PM
636#ifdef CONFIG_SYSCTL
637 .ctl_table_users = &sctp_sysctl_table_users,
638 .ctl_table_header = &sctp_sysctl_header,
639 .ctl_table = sctp_sysctl_table,
9fb9cbb1 640#endif
933a41e7 641};
9fb9cbb1 642
65b4b4e8 643int __init nf_conntrack_proto_sctp_init(void)
9fb9cbb1
YK
644{
645 int ret;
646
605dcad6 647 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
9fb9cbb1 648 if (ret) {
605dcad6 649 printk("nf_conntrack_l4proto_sctp4: protocol register failed\n");
9fb9cbb1
YK
650 goto out;
651 }
605dcad6 652 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
9fb9cbb1 653 if (ret) {
605dcad6 654 printk("nf_conntrack_l4proto_sctp6: protocol register failed\n");
9fb9cbb1
YK
655 goto cleanup_sctp4;
656 }
657
9fb9cbb1
YK
658 return ret;
659
9fb9cbb1 660 cleanup_sctp4:
605dcad6 661 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
9fb9cbb1 662 out:
9fb9cbb1
YK
663 return ret;
664}
665
65b4b4e8 666void __exit nf_conntrack_proto_sctp_fini(void)
9fb9cbb1 667{
605dcad6
MJ
668 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
669 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
9fb9cbb1
YK
670}
671
65b4b4e8
AM
672module_init(nf_conntrack_proto_sctp_init);
673module_exit(nf_conntrack_proto_sctp_fini);
9fb9cbb1
YK
674
675MODULE_LICENSE("GPL");
676MODULE_AUTHOR("Kiran Kumar Immidi");
677MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
d2483dde 678MODULE_ALIAS("ip_conntrack_proto_sctp");