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