netfilter: nf_ct_ipv6: add namespace support
[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
9fb9cbb1 28/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
601e68e1 29 closely. They're more complex. --RR
9fb9cbb1
YK
30
31 And so for me for SCTP :D -Kiran */
32
12c33aa2 33static const char *const sctp_conntrack_names[] = {
9fb9cbb1
YK
34 "NONE",
35 "CLOSED",
36 "COOKIE_WAIT",
37 "COOKIE_ECHOED",
38 "ESTABLISHED",
39 "SHUTDOWN_SENT",
40 "SHUTDOWN_RECD",
41 "SHUTDOWN_ACK_SENT",
42};
43
44#define SECS * HZ
45#define MINS * 60 SECS
46#define HOURS * 60 MINS
47#define DAYS * 24 HOURS
48
86c0bf40
PM
49static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
50 [SCTP_CONNTRACK_CLOSED] = 10 SECS,
51 [SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS,
52 [SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS,
53 [SCTP_CONNTRACK_ESTABLISHED] = 5 DAYS,
54 [SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000,
55 [SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000,
56 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS,
57};
9fb9cbb1
YK
58
59#define sNO SCTP_CONNTRACK_NONE
60#define sCL SCTP_CONNTRACK_CLOSED
61#define sCW SCTP_CONNTRACK_COOKIE_WAIT
62#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
63#define sES SCTP_CONNTRACK_ESTABLISHED
64#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
65#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
66#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
67#define sIV SCTP_CONNTRACK_MAX
68
601e68e1 69/*
9fb9cbb1
YK
70 These are the descriptions of the states:
71
601e68e1 72NOTE: These state names are tantalizingly similar to the states of an
9fb9cbb1 73SCTP endpoint. But the interpretation of the states is a little different,
601e68e1 74considering that these are the states of the connection and not of an end
9fb9cbb1
YK
75point. Please note the subtleties. -Kiran
76
77NONE - Nothing so far.
601e68e1
YH
78COOKIE WAIT - We have seen an INIT chunk in the original direction, or also
79 an INIT_ACK chunk in the reply direction.
9fb9cbb1
YK
80COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direction.
81ESTABLISHED - We have seen a COOKIE_ACK in the reply direction.
82SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original direction.
83SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin.
84SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
601e68e1
YH
85 to that of the SHUTDOWN chunk.
86CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
87 the SHUTDOWN chunk. Connection is closed.
9fb9cbb1
YK
88*/
89
90/* TODO
601e68e1 91 - I have assumed that the first INIT is in the original direction.
9fb9cbb1
YK
92 This messes things when an INIT comes in the reply direction in CLOSED
93 state.
601e68e1 94 - Check the error type in the reply dir before transitioning from
9fb9cbb1
YK
95cookie echoed to closed.
96 - Sec 5.2.4 of RFC 2960
97 - Multi Homing support.
98*/
99
100/* SCTP conntrack state transitions */
a5e73c29 101static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
9fb9cbb1
YK
102 {
103/* ORIGINAL */
104/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
105/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
106/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
107/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
108/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
109/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
25985edc 110/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't have Stale cookie*/
9fb9cbb1 111/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
25985edc 112/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in orig dir */
9fb9cbb1
YK
113/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
114 },
115 {
116/* REPLY */
117/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
118/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
119/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
120/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
121/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
122/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
123/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
25985edc 124/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in reply dir */
9fb9cbb1
YK
125/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
126/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
127 }
128};
129
09f263cd
JE
130static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
131 struct nf_conntrack_tuple *tuple)
9fb9cbb1 132{
12c33aa2
JE
133 const struct sctphdr *hp;
134 struct sctphdr _hdr;
9fb9cbb1 135
9fb9cbb1
YK
136 /* Actually only need first 8 bytes. */
137 hp = skb_header_pointer(skb, dataoff, 8, &_hdr);
138 if (hp == NULL)
09f263cd 139 return false;
9fb9cbb1
YK
140
141 tuple->src.u.sctp.port = hp->source;
142 tuple->dst.u.sctp.port = hp->dest;
09f263cd 143 return true;
9fb9cbb1
YK
144}
145
09f263cd
JE
146static bool sctp_invert_tuple(struct nf_conntrack_tuple *tuple,
147 const struct nf_conntrack_tuple *orig)
9fb9cbb1 148{
9fb9cbb1
YK
149 tuple->src.u.sctp.port = orig->dst.u.sctp.port;
150 tuple->dst.u.sctp.port = orig->src.u.sctp.port;
09f263cd 151 return true;
9fb9cbb1
YK
152}
153
154/* Print out the per-protocol part of the tuple. */
155static int sctp_print_tuple(struct seq_file *s,
156 const struct nf_conntrack_tuple *tuple)
157{
9fb9cbb1
YK
158 return seq_printf(s, "sport=%hu dport=%hu ",
159 ntohs(tuple->src.u.sctp.port),
160 ntohs(tuple->dst.u.sctp.port));
161}
162
163/* Print out the private part of the conntrack. */
440f0d58 164static int sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
9fb9cbb1
YK
165{
166 enum sctp_conntrack state;
167
440f0d58 168 spin_lock_bh(&ct->lock);
112f35c9 169 state = ct->proto.sctp.state;
440f0d58 170 spin_unlock_bh(&ct->lock);
9fb9cbb1
YK
171
172 return seq_printf(s, "%s ", sctp_conntrack_names[state]);
173}
174
175#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
e79ec50b
JE
176for ((offset) = (dataoff) + sizeof(sctp_sctphdr_t), (count) = 0; \
177 (offset) < (skb)->len && \
178 ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \
179 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
9fb9cbb1
YK
180
181/* Some validity checks to make sure the chunks are fine */
112f35c9 182static int do_basic_checks(struct nf_conn *ct,
9fb9cbb1
YK
183 const struct sk_buff *skb,
184 unsigned int dataoff,
35c6d3cb 185 unsigned long *map)
9fb9cbb1
YK
186{
187 u_int32_t offset, count;
188 sctp_chunkhdr_t _sch, *sch;
189 int flag;
190
9fb9cbb1
YK
191 flag = 0;
192
193 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
0d53778e 194 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type);
9fb9cbb1 195
5447d477
PM
196 if (sch->type == SCTP_CID_INIT ||
197 sch->type == SCTP_CID_INIT_ACK ||
198 sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
9fb9cbb1 199 flag = 1;
9fb9cbb1 200
e17df688
PM
201 /*
202 * Cookie Ack/Echo chunks not the first OR
203 * Init / Init Ack / Shutdown compl chunks not the only chunks
204 * OR zero-length.
205 */
5447d477
PM
206 if (((sch->type == SCTP_CID_COOKIE_ACK ||
207 sch->type == SCTP_CID_COOKIE_ECHO ||
208 flag) &&
209 count != 0) || !sch->length) {
0d53778e 210 pr_debug("Basic checks failed\n");
9fb9cbb1
YK
211 return 1;
212 }
213
5447d477 214 if (map)
35c6d3cb 215 set_bit(sch->type, map);
9fb9cbb1
YK
216 }
217
0d53778e 218 pr_debug("Basic checks passed\n");
dd7271fe 219 return count == 0;
9fb9cbb1
YK
220}
221
efe9f68a
PM
222static int sctp_new_state(enum ip_conntrack_dir dir,
223 enum sctp_conntrack cur_state,
224 int chunk_type)
9fb9cbb1
YK
225{
226 int i;
227
0d53778e 228 pr_debug("Chunk type: %d\n", chunk_type);
9fb9cbb1
YK
229
230 switch (chunk_type) {
5447d477
PM
231 case SCTP_CID_INIT:
232 pr_debug("SCTP_CID_INIT\n");
233 i = 0;
234 break;
235 case SCTP_CID_INIT_ACK:
236 pr_debug("SCTP_CID_INIT_ACK\n");
237 i = 1;
238 break;
239 case SCTP_CID_ABORT:
240 pr_debug("SCTP_CID_ABORT\n");
241 i = 2;
242 break;
243 case SCTP_CID_SHUTDOWN:
244 pr_debug("SCTP_CID_SHUTDOWN\n");
245 i = 3;
246 break;
247 case SCTP_CID_SHUTDOWN_ACK:
248 pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
249 i = 4;
250 break;
251 case SCTP_CID_ERROR:
252 pr_debug("SCTP_CID_ERROR\n");
253 i = 5;
254 break;
255 case SCTP_CID_COOKIE_ECHO:
256 pr_debug("SCTP_CID_COOKIE_ECHO\n");
257 i = 6;
258 break;
259 case SCTP_CID_COOKIE_ACK:
260 pr_debug("SCTP_CID_COOKIE_ACK\n");
261 i = 7;
262 break;
263 case SCTP_CID_SHUTDOWN_COMPLETE:
264 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
265 i = 8;
266 break;
267 default:
268 /* Other chunks like DATA, SACK, HEARTBEAT and
269 its ACK do not cause a change in state */
270 pr_debug("Unknown chunk type, Will stay in %s\n",
271 sctp_conntrack_names[cur_state]);
272 return cur_state;
9fb9cbb1
YK
273 }
274
0d53778e
PM
275 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
276 dir, sctp_conntrack_names[cur_state], chunk_type,
277 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
9fb9cbb1
YK
278
279 return sctp_conntracks[dir][i][cur_state];
280}
281
2c8503f5
PNA
282static unsigned int *sctp_get_timeouts(struct net *net)
283{
284 return sctp_timeouts;
285}
286
b37e933a 287/* Returns verdict for packet, or -NF_ACCEPT for invalid. */
112f35c9 288static int sctp_packet(struct nf_conn *ct,
9fb9cbb1
YK
289 const struct sk_buff *skb,
290 unsigned int dataoff,
291 enum ip_conntrack_info ctinfo,
76108cea 292 u_int8_t pf,
2c8503f5
PNA
293 unsigned int hooknum,
294 unsigned int *timeouts)
9fb9cbb1 295{
efe9f68a 296 enum sctp_conntrack new_state, old_state;
8528819a 297 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
12c33aa2
JE
298 const struct sctphdr *sh;
299 struct sctphdr _sctph;
300 const struct sctp_chunkhdr *sch;
301 struct sctp_chunkhdr _sch;
9fb9cbb1 302 u_int32_t offset, count;
35c6d3cb 303 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
9fb9cbb1 304
9fb9cbb1
YK
305 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
306 if (sh == NULL)
b37e933a 307 goto out;
9fb9cbb1 308
112f35c9 309 if (do_basic_checks(ct, skb, dataoff, map) != 0)
b37e933a 310 goto out;
9fb9cbb1
YK
311
312 /* Check the verification tag (Sec 8.5) */
35c6d3cb
PM
313 if (!test_bit(SCTP_CID_INIT, map) &&
314 !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) &&
315 !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
316 !test_bit(SCTP_CID_ABORT, map) &&
317 !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
8528819a 318 sh->vtag != ct->proto.sctp.vtag[dir]) {
0d53778e 319 pr_debug("Verification tag check failed\n");
b37e933a 320 goto out;
9fb9cbb1
YK
321 }
322
328bd899 323 old_state = new_state = SCTP_CONNTRACK_NONE;
440f0d58 324 spin_lock_bh(&ct->lock);
9fb9cbb1 325 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
9fb9cbb1
YK
326 /* Special cases of Verification tag check (Sec 8.5.1) */
327 if (sch->type == SCTP_CID_INIT) {
328 /* Sec 8.5.1 (A) */
b37e933a
PM
329 if (sh->vtag != 0)
330 goto out_unlock;
9fb9cbb1
YK
331 } else if (sch->type == SCTP_CID_ABORT) {
332 /* Sec 8.5.1 (B) */
8528819a 333 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
b37e933a
PM
334 sh->vtag != ct->proto.sctp.vtag[!dir])
335 goto out_unlock;
9fb9cbb1
YK
336 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
337 /* Sec 8.5.1 (C) */
8528819a
PM
338 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
339 sh->vtag != ct->proto.sctp.vtag[!dir] &&
9b1c2cfd 340 sch->flags & SCTP_CHUNK_FLAG_T)
b37e933a 341 goto out_unlock;
9fb9cbb1
YK
342 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
343 /* Sec 8.5.1 (D) */
b37e933a
PM
344 if (sh->vtag != ct->proto.sctp.vtag[dir])
345 goto out_unlock;
9fb9cbb1
YK
346 }
347
efe9f68a
PM
348 old_state = ct->proto.sctp.state;
349 new_state = sctp_new_state(dir, old_state, sch->type);
9fb9cbb1
YK
350
351 /* Invalid */
efe9f68a 352 if (new_state == SCTP_CONNTRACK_MAX) {
0d53778e
PM
353 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
354 "conntrack=%u\n",
efe9f68a 355 dir, sch->type, old_state);
b37e933a 356 goto out_unlock;
9fb9cbb1
YK
357 }
358
359 /* If it is an INIT or an INIT ACK note down the vtag */
5447d477
PM
360 if (sch->type == SCTP_CID_INIT ||
361 sch->type == SCTP_CID_INIT_ACK) {
9fb9cbb1
YK
362 sctp_inithdr_t _inithdr, *ih;
363
364 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
601e68e1 365 sizeof(_inithdr), &_inithdr);
b37e933a
PM
366 if (ih == NULL)
367 goto out_unlock;
0d53778e 368 pr_debug("Setting vtag %x for dir %d\n",
8528819a
PM
369 ih->init_tag, !dir);
370 ct->proto.sctp.vtag[!dir] = ih->init_tag;
9fb9cbb1
YK
371 }
372
efe9f68a
PM
373 ct->proto.sctp.state = new_state;
374 if (old_state != new_state)
a71996fc 375 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
9fb9cbb1 376 }
440f0d58 377 spin_unlock_bh(&ct->lock);
9fb9cbb1 378
2c8503f5 379 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
9fb9cbb1 380
efe9f68a 381 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
8528819a 382 dir == IP_CT_DIR_REPLY &&
efe9f68a 383 new_state == SCTP_CONNTRACK_ESTABLISHED) {
0d53778e 384 pr_debug("Setting assured bit\n");
112f35c9 385 set_bit(IPS_ASSURED_BIT, &ct->status);
858b3133 386 nf_conntrack_event_cache(IPCT_ASSURED, ct);
9fb9cbb1
YK
387 }
388
389 return NF_ACCEPT;
b37e933a
PM
390
391out_unlock:
440f0d58 392 spin_unlock_bh(&ct->lock);
b37e933a
PM
393out:
394 return -NF_ACCEPT;
9fb9cbb1
YK
395}
396
397/* Called when a new connection for this protocol found. */
09f263cd 398static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
2c8503f5 399 unsigned int dataoff, unsigned int *timeouts)
9fb9cbb1 400{
efe9f68a 401 enum sctp_conntrack new_state;
12c33aa2
JE
402 const struct sctphdr *sh;
403 struct sctphdr _sctph;
404 const struct sctp_chunkhdr *sch;
405 struct sctp_chunkhdr _sch;
9fb9cbb1 406 u_int32_t offset, count;
35c6d3cb 407 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
9fb9cbb1 408
9fb9cbb1
YK
409 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
410 if (sh == NULL)
09f263cd 411 return false;
9fb9cbb1 412
112f35c9 413 if (do_basic_checks(ct, skb, dataoff, map) != 0)
09f263cd 414 return false;
9fb9cbb1
YK
415
416 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
35c6d3cb
PM
417 if (test_bit(SCTP_CID_ABORT, map) ||
418 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
419 test_bit(SCTP_CID_COOKIE_ACK, map))
09f263cd 420 return false;
9fb9cbb1 421
e5fc9e7a 422 memset(&ct->proto.sctp, 0, sizeof(ct->proto.sctp));
efe9f68a 423 new_state = SCTP_CONNTRACK_MAX;
9fb9cbb1
YK
424 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
425 /* Don't need lock here: this conntrack not in circulation yet */
efe9f68a
PM
426 new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
427 SCTP_CONNTRACK_NONE, sch->type);
9fb9cbb1
YK
428
429 /* Invalid: delete conntrack */
efe9f68a
PM
430 if (new_state == SCTP_CONNTRACK_NONE ||
431 new_state == SCTP_CONNTRACK_MAX) {
0d53778e 432 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
09f263cd 433 return false;
9fb9cbb1
YK
434 }
435
436 /* Copy the vtag into the state info */
437 if (sch->type == SCTP_CID_INIT) {
438 if (sh->vtag == 0) {
439 sctp_inithdr_t _inithdr, *ih;
440
441 ih = skb_header_pointer(skb, offset + sizeof(sctp_chunkhdr_t),
601e68e1 442 sizeof(_inithdr), &_inithdr);
9fb9cbb1 443 if (ih == NULL)
09f263cd 444 return false;
9fb9cbb1 445
0d53778e
PM
446 pr_debug("Setting vtag %x for new conn\n",
447 ih->init_tag);
9fb9cbb1 448
112f35c9 449 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
9fb9cbb1
YK
450 ih->init_tag;
451 } else {
452 /* Sec 8.5.1 (A) */
09f263cd 453 return false;
9fb9cbb1
YK
454 }
455 }
456 /* If it is a shutdown ack OOTB packet, we expect a return
457 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
458 else {
0d53778e
PM
459 pr_debug("Setting vtag %x for new conn OOTB\n",
460 sh->vtag);
112f35c9 461 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
9fb9cbb1
YK
462 }
463
efe9f68a 464 ct->proto.sctp.state = new_state;
9fb9cbb1
YK
465 }
466
09f263cd 467 return true;
9fb9cbb1
YK
468}
469
c0cd1156 470#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
a258860e
PNA
471
472#include <linux/netfilter/nfnetlink.h>
473#include <linux/netfilter/nfnetlink_conntrack.h>
474
475static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
440f0d58 476 struct nf_conn *ct)
a258860e
PNA
477{
478 struct nlattr *nest_parms;
479
440f0d58 480 spin_lock_bh(&ct->lock);
a258860e
PNA
481 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP | NLA_F_NESTED);
482 if (!nest_parms)
483 goto nla_put_failure;
484
5e8d1eb5
DM
485 if (nla_put_u8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state) ||
486 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
487 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]) ||
488 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_REPLY,
489 ct->proto.sctp.vtag[IP_CT_DIR_REPLY]))
490 goto nla_put_failure;
a258860e 491
440f0d58 492 spin_unlock_bh(&ct->lock);
a258860e
PNA
493
494 nla_nest_end(skb, nest_parms);
495
496 return 0;
497
498nla_put_failure:
440f0d58 499 spin_unlock_bh(&ct->lock);
a258860e
PNA
500 return -1;
501}
502
503static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = {
504 [CTA_PROTOINFO_SCTP_STATE] = { .type = NLA_U8 },
505 [CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] = { .type = NLA_U32 },
506 [CTA_PROTOINFO_SCTP_VTAG_REPLY] = { .type = NLA_U32 },
507};
508
509static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
510{
511 struct nlattr *attr = cda[CTA_PROTOINFO_SCTP];
512 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1];
513 int err;
514
515 /* updates may not contain the internal protocol info, skip parsing */
516 if (!attr)
517 return 0;
518
519 err = nla_parse_nested(tb,
520 CTA_PROTOINFO_SCTP_MAX,
521 attr,
522 sctp_nla_policy);
523 if (err < 0)
524 return err;
525
526 if (!tb[CTA_PROTOINFO_SCTP_STATE] ||
527 !tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] ||
528 !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])
529 return -EINVAL;
530
440f0d58 531 spin_lock_bh(&ct->lock);
a258860e
PNA
532 ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
533 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
5547cd0a 534 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
a258860e 535 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
5547cd0a 536 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
440f0d58 537 spin_unlock_bh(&ct->lock);
a258860e
PNA
538
539 return 0;
540}
a400c30e
HE
541
542static int sctp_nlattr_size(void)
543{
544 return nla_total_size(0) /* CTA_PROTOINFO_SCTP */
545 + nla_policy_len(sctp_nla_policy, CTA_PROTOINFO_SCTP_MAX + 1);
546}
a258860e
PNA
547#endif
548
50978462
PNA
549#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
550
551#include <linux/netfilter/nfnetlink.h>
552#include <linux/netfilter/nfnetlink_cttimeout.h>
553
554static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[], void *data)
555{
556 unsigned int *timeouts = data;
557 int i;
558
559 /* set default SCTP timeouts. */
560 for (i=0; i<SCTP_CONNTRACK_MAX; i++)
561 timeouts[i] = sctp_timeouts[i];
562
563 /* there's a 1:1 mapping between attributes and protocol states. */
564 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
565 if (tb[i]) {
566 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
567 }
568 }
569 return 0;
570}
571
572static int
573sctp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
574{
575 const unsigned int *timeouts = data;
576 int i;
577
5e8d1eb5
DM
578 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
579 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
580 goto nla_put_failure;
581 }
50978462
PNA
582 return 0;
583
584nla_put_failure:
585 return -ENOSPC;
586}
587
588static const struct nla_policy
589sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
590 [CTA_TIMEOUT_SCTP_CLOSED] = { .type = NLA_U32 },
591 [CTA_TIMEOUT_SCTP_COOKIE_WAIT] = { .type = NLA_U32 },
592 [CTA_TIMEOUT_SCTP_COOKIE_ECHOED] = { .type = NLA_U32 },
593 [CTA_TIMEOUT_SCTP_ESTABLISHED] = { .type = NLA_U32 },
594 [CTA_TIMEOUT_SCTP_SHUTDOWN_SENT] = { .type = NLA_U32 },
595 [CTA_TIMEOUT_SCTP_SHUTDOWN_RECD] = { .type = NLA_U32 },
596 [CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT] = { .type = NLA_U32 },
597};
598#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
599
600
9fb9cbb1 601#ifdef CONFIG_SYSCTL
933a41e7
PM
602static unsigned int sctp_sysctl_table_users;
603static struct ctl_table_header *sctp_sysctl_header;
604static struct ctl_table sctp_sysctl_table[] = {
9fb9cbb1 605 {
9fb9cbb1 606 .procname = "nf_conntrack_sctp_timeout_closed",
86c0bf40 607 .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
9fb9cbb1
YK
608 .maxlen = sizeof(unsigned int),
609 .mode = 0644,
6d9f239a 610 .proc_handler = proc_dointvec_jiffies,
9fb9cbb1
YK
611 },
612 {
9fb9cbb1 613 .procname = "nf_conntrack_sctp_timeout_cookie_wait",
86c0bf40 614 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
9fb9cbb1
YK
615 .maxlen = sizeof(unsigned int),
616 .mode = 0644,
6d9f239a 617 .proc_handler = proc_dointvec_jiffies,
9fb9cbb1
YK
618 },
619 {
9fb9cbb1 620 .procname = "nf_conntrack_sctp_timeout_cookie_echoed",
86c0bf40 621 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
9fb9cbb1
YK
622 .maxlen = sizeof(unsigned int),
623 .mode = 0644,
6d9f239a 624 .proc_handler = proc_dointvec_jiffies,
9fb9cbb1
YK
625 },
626 {
9fb9cbb1 627 .procname = "nf_conntrack_sctp_timeout_established",
86c0bf40 628 .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
9fb9cbb1
YK
629 .maxlen = sizeof(unsigned int),
630 .mode = 0644,
6d9f239a 631 .proc_handler = proc_dointvec_jiffies,
9fb9cbb1
YK
632 },
633 {
9fb9cbb1 634 .procname = "nf_conntrack_sctp_timeout_shutdown_sent",
86c0bf40 635 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
9fb9cbb1
YK
636 .maxlen = sizeof(unsigned int),
637 .mode = 0644,
6d9f239a 638 .proc_handler = proc_dointvec_jiffies,
9fb9cbb1
YK
639 },
640 {
9fb9cbb1 641 .procname = "nf_conntrack_sctp_timeout_shutdown_recd",
86c0bf40 642 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
9fb9cbb1
YK
643 .maxlen = sizeof(unsigned int),
644 .mode = 0644,
6d9f239a 645 .proc_handler = proc_dointvec_jiffies,
9fb9cbb1
YK
646 },
647 {
9fb9cbb1 648 .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent",
86c0bf40 649 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
9fb9cbb1
YK
650 .maxlen = sizeof(unsigned int),
651 .mode = 0644,
6d9f239a 652 .proc_handler = proc_dointvec_jiffies,
9fb9cbb1 653 },
f8572d8f 654 { }
9fb9cbb1 655};
a999e683
PM
656
657#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
658static struct ctl_table sctp_compat_sysctl_table[] = {
659 {
a999e683 660 .procname = "ip_conntrack_sctp_timeout_closed",
86c0bf40 661 .data = &sctp_timeouts[SCTP_CONNTRACK_CLOSED],
a999e683
PM
662 .maxlen = sizeof(unsigned int),
663 .mode = 0644,
6d9f239a 664 .proc_handler = proc_dointvec_jiffies,
a999e683
PM
665 },
666 {
a999e683 667 .procname = "ip_conntrack_sctp_timeout_cookie_wait",
86c0bf40 668 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_WAIT],
a999e683
PM
669 .maxlen = sizeof(unsigned int),
670 .mode = 0644,
6d9f239a 671 .proc_handler = proc_dointvec_jiffies,
a999e683
PM
672 },
673 {
a999e683 674 .procname = "ip_conntrack_sctp_timeout_cookie_echoed",
86c0bf40 675 .data = &sctp_timeouts[SCTP_CONNTRACK_COOKIE_ECHOED],
a999e683
PM
676 .maxlen = sizeof(unsigned int),
677 .mode = 0644,
6d9f239a 678 .proc_handler = proc_dointvec_jiffies,
a999e683
PM
679 },
680 {
a999e683 681 .procname = "ip_conntrack_sctp_timeout_established",
86c0bf40 682 .data = &sctp_timeouts[SCTP_CONNTRACK_ESTABLISHED],
a999e683
PM
683 .maxlen = sizeof(unsigned int),
684 .mode = 0644,
6d9f239a 685 .proc_handler = proc_dointvec_jiffies,
a999e683
PM
686 },
687 {
a999e683 688 .procname = "ip_conntrack_sctp_timeout_shutdown_sent",
86c0bf40 689 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT],
a999e683
PM
690 .maxlen = sizeof(unsigned int),
691 .mode = 0644,
6d9f239a 692 .proc_handler = proc_dointvec_jiffies,
a999e683
PM
693 },
694 {
a999e683 695 .procname = "ip_conntrack_sctp_timeout_shutdown_recd",
86c0bf40 696 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD],
a999e683
PM
697 .maxlen = sizeof(unsigned int),
698 .mode = 0644,
6d9f239a 699 .proc_handler = proc_dointvec_jiffies,
a999e683
PM
700 },
701 {
a999e683 702 .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
86c0bf40 703 .data = &sctp_timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT],
a999e683
PM
704 .maxlen = sizeof(unsigned int),
705 .mode = 0644,
6d9f239a 706 .proc_handler = proc_dointvec_jiffies,
a999e683 707 },
f8572d8f 708 { }
a999e683
PM
709};
710#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
933a41e7 711#endif
9fb9cbb1 712
61075af5 713static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
933a41e7
PM
714 .l3proto = PF_INET,
715 .l4proto = IPPROTO_SCTP,
716 .name = "sctp",
717 .pkt_to_tuple = sctp_pkt_to_tuple,
718 .invert_tuple = sctp_invert_tuple,
719 .print_tuple = sctp_print_tuple,
720 .print_conntrack = sctp_print_conntrack,
721 .packet = sctp_packet,
2c8503f5 722 .get_timeouts = sctp_get_timeouts,
933a41e7
PM
723 .new = sctp_new,
724 .me = THIS_MODULE,
c0cd1156 725#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
a258860e 726 .to_nlattr = sctp_to_nlattr,
a400c30e 727 .nlattr_size = sctp_nlattr_size,
a258860e 728 .from_nlattr = nlattr_to_sctp,
c7212e9d 729 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
a400c30e 730 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
c7212e9d
PNA
731 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
732 .nla_policy = nf_ct_port_nla_policy,
733#endif
50978462
PNA
734#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
735 .ctnl_timeout = {
736 .nlattr_to_obj = sctp_timeout_nlattr_to_obj,
737 .obj_to_nlattr = sctp_timeout_obj_to_nlattr,
738 .nlattr_max = CTA_TIMEOUT_SCTP_MAX,
739 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
740 .nla_policy = sctp_timeout_nla_policy,
741 },
742#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
933a41e7
PM
743#ifdef CONFIG_SYSCTL
744 .ctl_table_users = &sctp_sysctl_table_users,
745 .ctl_table_header = &sctp_sysctl_header,
746 .ctl_table = sctp_sysctl_table,
a999e683
PM
747#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
748 .ctl_compat_table = sctp_compat_sysctl_table,
749#endif
933a41e7 750#endif
9fb9cbb1
YK
751};
752
61075af5 753static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
933a41e7
PM
754 .l3proto = PF_INET6,
755 .l4proto = IPPROTO_SCTP,
756 .name = "sctp",
757 .pkt_to_tuple = sctp_pkt_to_tuple,
758 .invert_tuple = sctp_invert_tuple,
759 .print_tuple = sctp_print_tuple,
760 .print_conntrack = sctp_print_conntrack,
761 .packet = sctp_packet,
2c8503f5 762 .get_timeouts = sctp_get_timeouts,
933a41e7
PM
763 .new = sctp_new,
764 .me = THIS_MODULE,
c0cd1156 765#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
a258860e 766 .to_nlattr = sctp_to_nlattr,
a400c30e 767 .nlattr_size = sctp_nlattr_size,
a258860e 768 .from_nlattr = nlattr_to_sctp,
c7212e9d 769 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
a400c30e 770 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
c7212e9d
PNA
771 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
772 .nla_policy = nf_ct_port_nla_policy,
50978462
PNA
773#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
774 .ctnl_timeout = {
775 .nlattr_to_obj = sctp_timeout_nlattr_to_obj,
776 .obj_to_nlattr = sctp_timeout_obj_to_nlattr,
777 .nlattr_max = CTA_TIMEOUT_SCTP_MAX,
778 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
779 .nla_policy = sctp_timeout_nla_policy,
780 },
781#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
c7212e9d 782#endif
933a41e7
PM
783#ifdef CONFIG_SYSCTL
784 .ctl_table_users = &sctp_sysctl_table_users,
785 .ctl_table_header = &sctp_sysctl_header,
786 .ctl_table = sctp_sysctl_table,
9fb9cbb1 787#endif
933a41e7 788};
9fb9cbb1 789
2f0d2f10 790static int __init nf_conntrack_proto_sctp_init(void)
9fb9cbb1
YK
791{
792 int ret;
793
2c352f44 794 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_sctp4);
9fb9cbb1 795 if (ret) {
654d0fbd 796 pr_err("nf_conntrack_l4proto_sctp4: protocol register failed\n");
9fb9cbb1
YK
797 goto out;
798 }
2c352f44 799 ret = nf_conntrack_l4proto_register(&init_net, &nf_conntrack_l4proto_sctp6);
9fb9cbb1 800 if (ret) {
654d0fbd 801 pr_err("nf_conntrack_l4proto_sctp6: protocol register failed\n");
9fb9cbb1
YK
802 goto cleanup_sctp4;
803 }
804
9fb9cbb1
YK
805 return ret;
806
9fb9cbb1 807 cleanup_sctp4:
2c352f44 808 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp4);
9fb9cbb1 809 out:
9fb9cbb1
YK
810 return ret;
811}
812
2f0d2f10 813static void __exit nf_conntrack_proto_sctp_fini(void)
9fb9cbb1 814{
2c352f44
G
815 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp6);
816 nf_conntrack_l4proto_unregister(&init_net, &nf_conntrack_l4proto_sctp4);
9fb9cbb1
YK
817}
818
65b4b4e8
AM
819module_init(nf_conntrack_proto_sctp_init);
820module_exit(nf_conntrack_proto_sctp_fini);
9fb9cbb1
YK
821
822MODULE_LICENSE("GPL");
823MODULE_AUTHOR("Kiran Kumar Immidi");
824MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
d2483dde 825MODULE_ALIAS("ip_conntrack_proto_sctp");
This page took 0.625504 seconds and 5 git commands to generate.