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