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