[NETFILTER]: Fix whitespace errors
[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.
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
601e68e1 48 closely. They're more complex. --RR
9fb9cbb1
YK
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
601e68e1 97/*
9fb9cbb1
YK
98 These are the descriptions of the states:
99
601e68e1 100NOTE: These state names are tantalizingly similar to the states of an
9fb9cbb1 101SCTP endpoint. But the interpretation of the states is a little different,
601e68e1 102considering that these are the states of the connection and not of an end
9fb9cbb1
YK
103point. Please note the subtleties. -Kiran
104
105NONE - Nothing so far.
601e68e1
YH
106COOKIE WAIT - We have seen an INIT chunk in the original direction, or also
107 an INIT_ACK chunk in the reply direction.
9fb9cbb1
YK
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
601e68e1
YH
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.
9fb9cbb1
YK
116*/
117
118/* TODO
601e68e1 119 - I have assumed that the first INIT is in the original direction.
9fb9cbb1
YK
120 This messes things when an INIT comes in the reply direction in CLOSED
121 state.
601e68e1 122 - Check the error type in the reply dir before transitioning from
9fb9cbb1
YK
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)); \
bff9a89b 220 offset += (ntohs(sch->length) + 3) & ~3, count++)
9fb9cbb1
YK
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
601e68e1 240 if (sch->type == SCTP_CID_INIT
9fb9cbb1
YK
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) {
601e68e1 280 case SCTP_CID_INIT:
9fb9cbb1
YK
281 DEBUGP("SCTP_CID_INIT\n");
282 i = 0; break;
601e68e1 283 case SCTP_CID_INIT_ACK:
9fb9cbb1
YK
284 DEBUGP("SCTP_CID_INIT_ACK\n");
285 i = 1; break;
601e68e1 286 case SCTP_CID_ABORT:
9fb9cbb1
YK
287 DEBUGP("SCTP_CID_ABORT\n");
288 i = 2; break;
601e68e1 289 case SCTP_CID_SHUTDOWN:
9fb9cbb1
YK
290 DEBUGP("SCTP_CID_SHUTDOWN\n");
291 i = 3; break;
601e68e1 292 case SCTP_CID_SHUTDOWN_ACK:
9fb9cbb1
YK
293 DEBUGP("SCTP_CID_SHUTDOWN_ACK\n");
294 i = 4; break;
601e68e1 295 case SCTP_CID_ERROR:
9fb9cbb1
YK
296 DEBUGP("SCTP_CID_ERROR\n");
297 i = 5; break;
601e68e1 298 case SCTP_CID_COOKIE_ECHO:
9fb9cbb1
YK
299 DEBUGP("SCTP_CID_COOKIE_ECHO\n");
300 i = 6; break;
601e68e1 301 case SCTP_CID_COOKIE_ACK:
9fb9cbb1
YK
302 DEBUGP("SCTP_CID_COOKIE_ACK\n");
303 i = 7; break;
601e68e1 304 case SCTP_CID_SHUTDOWN_COMPLETE:
9fb9cbb1
YK
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 */
601e68e1 310 DEBUGP("Unknown chunk type, Will stay in %s\n",
9fb9cbb1
YK
311 sctp_conntrack_names[cur_state]);
312 return cur_state;
313 }
314
601e68e1 315 DEBUGP("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
9fb9cbb1
YK
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
601e68e1 380 [1 - CTINFO2DIR(ctinfo)]
9fb9cbb1
YK
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 */
601e68e1 405 if (sch->type == SCTP_CID_INIT
9fb9cbb1
YK
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),
601e68e1 410 sizeof(_inithdr), &_inithdr);
9fb9cbb1
YK
411 if (ih == NULL) {
412 write_unlock_bh(&sctp_lock);
413 return -1;
414 }
601e68e1 415 DEBUGP("Setting vtag %x for dir %d\n",
9fb9cbb1
YK
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 */
601e68e1 469 newconntrack = new_state(IP_CT_DIR_ORIGINAL,
9fb9cbb1
YK
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),
601e68e1 484 sizeof(_inithdr), &_inithdr);
9fb9cbb1
YK
485 if (ih == NULL)
486 return 0;
487
601e68e1 488 DEBUGP("Setting vtag %x for new conn\n",
9fb9cbb1
YK
489 ih->init_tag);
490
601e68e1 491 conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =
9fb9cbb1
YK
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 {
601e68e1 501 DEBUGP("Setting vtag %x for new conn OOTB\n",
9fb9cbb1
YK
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
9fb9cbb1 512#ifdef CONFIG_SYSCTL
933a41e7
PM
513static unsigned int sctp_sysctl_table_users;
514static struct ctl_table_header *sctp_sysctl_header;
515static struct ctl_table sctp_sysctl_table[] = {
9fb9cbb1
YK
516 {
517 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
518 .procname = "nf_conntrack_sctp_timeout_closed",
519 .data = &nf_ct_sctp_timeout_closed,
520 .maxlen = sizeof(unsigned int),
521 .mode = 0644,
522 .proc_handler = &proc_dointvec_jiffies,
523 },
524 {
525 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
526 .procname = "nf_conntrack_sctp_timeout_cookie_wait",
527 .data = &nf_ct_sctp_timeout_cookie_wait,
528 .maxlen = sizeof(unsigned int),
529 .mode = 0644,
530 .proc_handler = &proc_dointvec_jiffies,
531 },
532 {
533 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
534 .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
535 .data = &nf_ct_sctp_timeout_cookie_echoed,
536 .maxlen = sizeof(unsigned int),
537 .mode = 0644,
538 .proc_handler = &proc_dointvec_jiffies,
539 },
540 {
541 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
542 .procname = "nf_conntrack_sctp_timeout_established",
543 .data = &nf_ct_sctp_timeout_established,
544 .maxlen = sizeof(unsigned int),
545 .mode = 0644,
546 .proc_handler = &proc_dointvec_jiffies,
547 },
548 {
549 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
550 .procname = "nf_conntrack_sctp_timeout_shutdown_sent",
551 .data = &nf_ct_sctp_timeout_shutdown_sent,
552 .maxlen = sizeof(unsigned int),
553 .mode = 0644,
554 .proc_handler = &proc_dointvec_jiffies,
555 },
556 {
557 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
558 .procname = "nf_conntrack_sctp_timeout_shutdown_recd",
559 .data = &nf_ct_sctp_timeout_shutdown_recd,
560 .maxlen = sizeof(unsigned int),
561 .mode = 0644,
562 .proc_handler = &proc_dointvec_jiffies,
563 },
564 {
565 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
566 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
567 .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
568 .maxlen = sizeof(unsigned int),
569 .mode = 0644,
570 .proc_handler = &proc_dointvec_jiffies,
571 },
9fb9cbb1 572 {
933a41e7
PM
573 .ctl_name = 0
574 }
9fb9cbb1 575};
a999e683
PM
576
577#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
578static struct ctl_table sctp_compat_sysctl_table[] = {
579 {
580 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
581 .procname = "ip_conntrack_sctp_timeout_closed",
582 .data = &nf_ct_sctp_timeout_closed,
583 .maxlen = sizeof(unsigned int),
584 .mode = 0644,
585 .proc_handler = &proc_dointvec_jiffies,
586 },
587 {
588 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
589 .procname = "ip_conntrack_sctp_timeout_cookie_wait",
590 .data = &nf_ct_sctp_timeout_cookie_wait,
591 .maxlen = sizeof(unsigned int),
592 .mode = 0644,
593 .proc_handler = &proc_dointvec_jiffies,
594 },
595 {
596 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
597 .procname = "ip_conntrack_sctp_timeout_cookie_echoed",
598 .data = &nf_ct_sctp_timeout_cookie_echoed,
599 .maxlen = sizeof(unsigned int),
600 .mode = 0644,
601 .proc_handler = &proc_dointvec_jiffies,
602 },
603 {
604 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
605 .procname = "ip_conntrack_sctp_timeout_established",
606 .data = &nf_ct_sctp_timeout_established,
607 .maxlen = sizeof(unsigned int),
608 .mode = 0644,
609 .proc_handler = &proc_dointvec_jiffies,
610 },
611 {
612 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
613 .procname = "ip_conntrack_sctp_timeout_shutdown_sent",
614 .data = &nf_ct_sctp_timeout_shutdown_sent,
615 .maxlen = sizeof(unsigned int),
616 .mode = 0644,
617 .proc_handler = &proc_dointvec_jiffies,
618 },
619 {
620 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
621 .procname = "ip_conntrack_sctp_timeout_shutdown_recd",
622 .data = &nf_ct_sctp_timeout_shutdown_recd,
623 .maxlen = sizeof(unsigned int),
624 .mode = 0644,
625 .proc_handler = &proc_dointvec_jiffies,
626 },
627 {
628 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
629 .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
630 .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
631 .maxlen = sizeof(unsigned int),
632 .mode = 0644,
633 .proc_handler = &proc_dointvec_jiffies,
634 },
635 {
636 .ctl_name = 0
637 }
638};
639#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
933a41e7 640#endif
9fb9cbb1 641
933a41e7
PM
642struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 = {
643 .l3proto = PF_INET,
644 .l4proto = IPPROTO_SCTP,
645 .name = "sctp",
646 .pkt_to_tuple = sctp_pkt_to_tuple,
647 .invert_tuple = sctp_invert_tuple,
648 .print_tuple = sctp_print_tuple,
649 .print_conntrack = sctp_print_conntrack,
650 .packet = sctp_packet,
651 .new = sctp_new,
652 .me = THIS_MODULE,
653#ifdef CONFIG_SYSCTL
654 .ctl_table_users = &sctp_sysctl_table_users,
655 .ctl_table_header = &sctp_sysctl_header,
656 .ctl_table = sctp_sysctl_table,
a999e683
PM
657#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
658 .ctl_compat_table = sctp_compat_sysctl_table,
659#endif
933a41e7 660#endif
9fb9cbb1
YK
661};
662
933a41e7
PM
663struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 = {
664 .l3proto = PF_INET6,
665 .l4proto = IPPROTO_SCTP,
666 .name = "sctp",
667 .pkt_to_tuple = sctp_pkt_to_tuple,
668 .invert_tuple = sctp_invert_tuple,
669 .print_tuple = sctp_print_tuple,
670 .print_conntrack = sctp_print_conntrack,
671 .packet = sctp_packet,
672 .new = sctp_new,
673 .me = THIS_MODULE,
674#ifdef CONFIG_SYSCTL
675 .ctl_table_users = &sctp_sysctl_table_users,
676 .ctl_table_header = &sctp_sysctl_header,
677 .ctl_table = sctp_sysctl_table,
9fb9cbb1 678#endif
933a41e7 679};
9fb9cbb1 680
65b4b4e8 681int __init nf_conntrack_proto_sctp_init(void)
9fb9cbb1
YK
682{
683 int ret;
684
605dcad6 685 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
9fb9cbb1 686 if (ret) {
605dcad6 687 printk("nf_conntrack_l4proto_sctp4: protocol register failed\n");
9fb9cbb1
YK
688 goto out;
689 }
605dcad6 690 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
9fb9cbb1 691 if (ret) {
605dcad6 692 printk("nf_conntrack_l4proto_sctp6: protocol register failed\n");
9fb9cbb1
YK
693 goto cleanup_sctp4;
694 }
695
9fb9cbb1
YK
696 return ret;
697
9fb9cbb1 698 cleanup_sctp4:
605dcad6 699 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
9fb9cbb1 700 out:
601e68e1 701 DEBUGP("SCTP conntrack module loading %s\n",
9fb9cbb1
YK
702 ret ? "failed": "succeeded");
703 return ret;
704}
705
65b4b4e8 706void __exit nf_conntrack_proto_sctp_fini(void)
9fb9cbb1 707{
605dcad6
MJ
708 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
709 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
9fb9cbb1
YK
710 DEBUGP("SCTP conntrack module unloaded\n");
711}
712
65b4b4e8
AM
713module_init(nf_conntrack_proto_sctp_init);
714module_exit(nf_conntrack_proto_sctp_fini);
9fb9cbb1
YK
715
716MODULE_LICENSE("GPL");
717MODULE_AUTHOR("Kiran Kumar Immidi");
718MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
d2483dde 719MODULE_ALIAS("ip_conntrack_proto_sctp");