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