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