Merge tag 'modules-for-v5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu...
[linux-block.git] / net / netfilter / nf_conntrack_proto_sctp.c
CommitLineData
d2912cb1 1// SPDX-License-Identifier: GPL-2.0-only
9fb9cbb1
YK
2/*
3 * Connection tracking protocol helper module for SCTP.
601e68e1 4 *
f229f6ce
PM
5 * Copyright (c) 2004 Kiran Kumar Immidi <immidi_kiran@yahoo.com>
6 * Copyright (c) 2004-2012 Patrick McHardy <kaber@trash.net>
7 *
601e68e1 8 * SCTP is defined in RFC 2960. References to various sections in this code
9fb9cbb1 9 * are to this RFC.
9fb9cbb1
YK
10 */
11
12#include <linux/types.h>
9fb9cbb1
YK
13#include <linux/timer.h>
14#include <linux/netfilter.h>
9fb9cbb1
YK
15#include <linux/in.h>
16#include <linux/ip.h>
17#include <linux/sctp.h>
18#include <linux/string.h>
19#include <linux/seq_file.h>
40a839fd
YK
20#include <linux/spinlock.h>
21#include <linux/interrupt.h>
cf6e007e 22#include <net/sctp/checksum.h>
9fb9cbb1 23
cf6e007e 24#include <net/netfilter/nf_log.h>
9fb9cbb1 25#include <net/netfilter/nf_conntrack.h>
605dcad6 26#include <net/netfilter/nf_conntrack_l4proto.h>
f6180121 27#include <net/netfilter/nf_conntrack_ecache.h>
c779e849 28#include <net/netfilter/nf_conntrack_timeout.h>
9fb9cbb1 29
9fb9cbb1 30/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
601e68e1 31 closely. They're more complex. --RR
9fb9cbb1
YK
32
33 And so for me for SCTP :D -Kiran */
34
12c33aa2 35static const char *const sctp_conntrack_names[] = {
9fb9cbb1
YK
36 "NONE",
37 "CLOSED",
38 "COOKIE_WAIT",
39 "COOKIE_ECHOED",
40 "ESTABLISHED",
41 "SHUTDOWN_SENT",
42 "SHUTDOWN_RECD",
43 "SHUTDOWN_ACK_SENT",
d7ee3519
MK
44 "HEARTBEAT_SENT",
45 "HEARTBEAT_ACKED",
9fb9cbb1
YK
46};
47
48#define SECS * HZ
49#define MINS * 60 SECS
50#define HOURS * 60 MINS
51#define DAYS * 24 HOURS
52
2c9e8637 53static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = {
86c0bf40
PM
54 [SCTP_CONNTRACK_CLOSED] = 10 SECS,
55 [SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS,
56 [SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS,
57 [SCTP_CONNTRACK_ESTABLISHED] = 5 DAYS,
58 [SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000,
59 [SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000,
60 [SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS,
d7ee3519
MK
61 [SCTP_CONNTRACK_HEARTBEAT_SENT] = 30 SECS,
62 [SCTP_CONNTRACK_HEARTBEAT_ACKED] = 210 SECS,
86c0bf40 63};
9fb9cbb1
YK
64
65#define sNO SCTP_CONNTRACK_NONE
66#define sCL SCTP_CONNTRACK_CLOSED
67#define sCW SCTP_CONNTRACK_COOKIE_WAIT
68#define sCE SCTP_CONNTRACK_COOKIE_ECHOED
69#define sES SCTP_CONNTRACK_ESTABLISHED
70#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT
71#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
72#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
d7ee3519
MK
73#define sHS SCTP_CONNTRACK_HEARTBEAT_SENT
74#define sHA SCTP_CONNTRACK_HEARTBEAT_ACKED
9fb9cbb1
YK
75#define sIV SCTP_CONNTRACK_MAX
76
601e68e1 77/*
9fb9cbb1
YK
78 These are the descriptions of the states:
79
601e68e1 80NOTE: These state names are tantalizingly similar to the states of an
9fb9cbb1 81SCTP endpoint. But the interpretation of the states is a little different,
601e68e1 82considering that these are the states of the connection and not of an end
9fb9cbb1
YK
83point. Please note the subtleties. -Kiran
84
85NONE - Nothing so far.
601e68e1
YH
86COOKIE WAIT - We have seen an INIT chunk in the original direction, or also
87 an INIT_ACK chunk in the reply direction.
9fb9cbb1
YK
88COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direction.
89ESTABLISHED - We have seen a COOKIE_ACK in the reply direction.
90SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original direction.
91SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin.
92SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
601e68e1
YH
93 to that of the SHUTDOWN chunk.
94CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
95 the SHUTDOWN chunk. Connection is closed.
d7ee3519
MK
96HEARTBEAT_SENT - We have seen a HEARTBEAT in a new flow.
97HEARTBEAT_ACKED - We have seen a HEARTBEAT-ACK in the direction opposite to
98 that of the HEARTBEAT chunk. Secondary connection is
99 established.
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
d7ee3519 109 - Full Multi Homing support.
9fb9cbb1
YK
110*/
111
112/* SCTP conntrack state transitions */
d7ee3519 113static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
9fb9cbb1
YK
114 {
115/* ORIGINAL */
d7ee3519
MK
116/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
117/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA, sCW, sHA},
118/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},
119/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
120/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL, sSS},
121/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA, sHA},
122/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* Can't have Stale cookie*/
123/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* 5.2.4 - Big TODO */
124/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* Can't come in orig dir */
125/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL, sHA},
126/* heartbeat */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
127/* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA}
9fb9cbb1
YK
128 },
129 {
130/* REPLY */
d7ee3519
MK
131/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
132/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},/* INIT in sCL Big TODO */
133/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},
134/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV, sCL},
135/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV, sSR},
136/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV, sHA},
137/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV, sHA},
138/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},/* Can't come in reply dir */
139/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV, sHA},
140/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV, sHA},
141/* heartbeat */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
142/* heartbeat_ack*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHA, sHA}
9fb9cbb1
YK
143 }
144};
145
ea48cc83 146#ifdef CONFIG_NF_CONNTRACK_PROCFS
9fb9cbb1 147/* Print out the private part of the conntrack. */
37246a58 148static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
9fb9cbb1 149{
a163f2cb 150 seq_printf(s, "%s ", sctp_conntrack_names[ct->proto.sctp.state]);
9fb9cbb1 151}
ea48cc83 152#endif
9fb9cbb1
YK
153
154#define for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) \
ae146d9b 155for ((offset) = (dataoff) + sizeof(struct sctphdr), (count) = 0; \
e79ec50b
JE
156 (offset) < (skb)->len && \
157 ((sch) = skb_header_pointer((skb), (offset), sizeof(_sch), &(_sch))); \
158 (offset) += (ntohs((sch)->length) + 3) & ~3, (count)++)
9fb9cbb1
YK
159
160/* Some validity checks to make sure the chunks are fine */
112f35c9 161static int do_basic_checks(struct nf_conn *ct,
9fb9cbb1
YK
162 const struct sk_buff *skb,
163 unsigned int dataoff,
35c6d3cb 164 unsigned long *map)
9fb9cbb1
YK
165{
166 u_int32_t offset, count;
922dbc5b 167 struct sctp_chunkhdr _sch, *sch;
9fb9cbb1
YK
168 int flag;
169
9fb9cbb1
YK
170 flag = 0;
171
172 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
0d53778e 173 pr_debug("Chunk Num: %d Type: %d\n", count, sch->type);
9fb9cbb1 174
5447d477
PM
175 if (sch->type == SCTP_CID_INIT ||
176 sch->type == SCTP_CID_INIT_ACK ||
177 sch->type == SCTP_CID_SHUTDOWN_COMPLETE)
9fb9cbb1 178 flag = 1;
9fb9cbb1 179
e17df688
PM
180 /*
181 * Cookie Ack/Echo chunks not the first OR
182 * Init / Init Ack / Shutdown compl chunks not the only chunks
183 * OR zero-length.
184 */
5447d477
PM
185 if (((sch->type == SCTP_CID_COOKIE_ACK ||
186 sch->type == SCTP_CID_COOKIE_ECHO ||
187 flag) &&
188 count != 0) || !sch->length) {
0d53778e 189 pr_debug("Basic checks failed\n");
9fb9cbb1
YK
190 return 1;
191 }
192
5447d477 193 if (map)
35c6d3cb 194 set_bit(sch->type, map);
9fb9cbb1
YK
195 }
196
0d53778e 197 pr_debug("Basic checks passed\n");
dd7271fe 198 return count == 0;
9fb9cbb1
YK
199}
200
efe9f68a
PM
201static int sctp_new_state(enum ip_conntrack_dir dir,
202 enum sctp_conntrack cur_state,
203 int chunk_type)
9fb9cbb1
YK
204{
205 int i;
206
0d53778e 207 pr_debug("Chunk type: %d\n", chunk_type);
9fb9cbb1
YK
208
209 switch (chunk_type) {
5447d477
PM
210 case SCTP_CID_INIT:
211 pr_debug("SCTP_CID_INIT\n");
212 i = 0;
213 break;
214 case SCTP_CID_INIT_ACK:
215 pr_debug("SCTP_CID_INIT_ACK\n");
216 i = 1;
217 break;
218 case SCTP_CID_ABORT:
219 pr_debug("SCTP_CID_ABORT\n");
220 i = 2;
221 break;
222 case SCTP_CID_SHUTDOWN:
223 pr_debug("SCTP_CID_SHUTDOWN\n");
224 i = 3;
225 break;
226 case SCTP_CID_SHUTDOWN_ACK:
227 pr_debug("SCTP_CID_SHUTDOWN_ACK\n");
228 i = 4;
229 break;
230 case SCTP_CID_ERROR:
231 pr_debug("SCTP_CID_ERROR\n");
232 i = 5;
233 break;
234 case SCTP_CID_COOKIE_ECHO:
235 pr_debug("SCTP_CID_COOKIE_ECHO\n");
236 i = 6;
237 break;
238 case SCTP_CID_COOKIE_ACK:
239 pr_debug("SCTP_CID_COOKIE_ACK\n");
240 i = 7;
241 break;
242 case SCTP_CID_SHUTDOWN_COMPLETE:
243 pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
244 i = 8;
245 break;
d7ee3519
MK
246 case SCTP_CID_HEARTBEAT:
247 pr_debug("SCTP_CID_HEARTBEAT");
248 i = 9;
249 break;
250 case SCTP_CID_HEARTBEAT_ACK:
251 pr_debug("SCTP_CID_HEARTBEAT_ACK");
252 i = 10;
253 break;
5447d477 254 default:
d7ee3519 255 /* Other chunks like DATA or SACK do not change the state */
5447d477
PM
256 pr_debug("Unknown chunk type, Will stay in %s\n",
257 sctp_conntrack_names[cur_state]);
258 return cur_state;
9fb9cbb1
YK
259 }
260
0d53778e
PM
261 pr_debug("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",
262 dir, sctp_conntrack_names[cur_state], chunk_type,
263 sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]);
9fb9cbb1
YK
264
265 return sctp_conntracks[dir][i][cur_state];
266}
267
9976fc6e
FW
268/* Don't need lock here: this conntrack not in circulation yet */
269static noinline bool
270sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
271 const struct sctphdr *sh, unsigned int dataoff)
272{
273 enum sctp_conntrack new_state;
274 const struct sctp_chunkhdr *sch;
275 struct sctp_chunkhdr _sch;
276 u32 offset, count;
277
278 memset(&ct->proto.sctp, 0, sizeof(ct->proto.sctp));
279 new_state = SCTP_CONNTRACK_MAX;
280 for_each_sctp_chunk(skb, sch, _sch, offset, dataoff, count) {
281 new_state = sctp_new_state(IP_CT_DIR_ORIGINAL,
282 SCTP_CONNTRACK_NONE, sch->type);
283
284 /* Invalid: delete conntrack */
285 if (new_state == SCTP_CONNTRACK_NONE ||
286 new_state == SCTP_CONNTRACK_MAX) {
287 pr_debug("nf_conntrack_sctp: invalid new deleting.\n");
288 return false;
289 }
290
291 /* Copy the vtag into the state info */
292 if (sch->type == SCTP_CID_INIT) {
293 struct sctp_inithdr _inithdr, *ih;
294 /* Sec 8.5.1 (A) */
295 if (sh->vtag)
296 return false;
297
298 ih = skb_header_pointer(skb, offset + sizeof(_sch),
299 sizeof(_inithdr), &_inithdr);
300 if (!ih)
301 return false;
302
303 pr_debug("Setting vtag %x for new conn\n",
304 ih->init_tag);
305
306 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = ih->init_tag;
307 } else if (sch->type == SCTP_CID_HEARTBEAT) {
308 pr_debug("Setting vtag %x for secondary conntrack\n",
309 sh->vtag);
310 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = sh->vtag;
311 } else {
312 /* If it is a shutdown ack OOTB packet, we expect a return
313 shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
314 pr_debug("Setting vtag %x for new conn OOTB\n",
315 sh->vtag);
316 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
317 }
318
319 ct->proto.sctp.state = new_state;
320 }
321
322 return true;
323}
324
0150ffba
FW
325static bool sctp_error(struct sk_buff *skb,
326 unsigned int dataoff,
327 const struct nf_hook_state *state)
328{
329 const struct sctphdr *sh;
330 const char *logmsg;
331
332 if (skb->len < dataoff + sizeof(struct sctphdr)) {
333 logmsg = "nf_ct_sctp: short packet ";
334 goto out_invalid;
335 }
336 if (state->hook == NF_INET_PRE_ROUTING &&
337 state->net->ct.sysctl_checksum &&
338 skb->ip_summed == CHECKSUM_NONE) {
86f04538 339 if (skb_ensure_writable(skb, dataoff + sizeof(*sh))) {
0150ffba
FW
340 logmsg = "nf_ct_sctp: failed to read header ";
341 goto out_invalid;
342 }
343 sh = (const struct sctphdr *)(skb->data + dataoff);
344 if (sh->checksum != sctp_compute_cksum(skb, dataoff)) {
345 logmsg = "nf_ct_sctp: bad CRC ";
346 goto out_invalid;
347 }
348 skb->ip_summed = CHECKSUM_UNNECESSARY;
349 }
350 return false;
351out_invalid:
352 nf_l4proto_log_invalid(skb, state->net, state->pf, IPPROTO_SCTP, "%s", logmsg);
353 return true;
354}
355
b37e933a 356/* Returns verdict for packet, or -NF_ACCEPT for invalid. */
a47c5404
FW
357int nf_conntrack_sctp_packet(struct nf_conn *ct,
358 struct sk_buff *skb,
359 unsigned int dataoff,
360 enum ip_conntrack_info ctinfo,
361 const struct nf_hook_state *state)
9fb9cbb1 362{
efe9f68a 363 enum sctp_conntrack new_state, old_state;
8528819a 364 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
12c33aa2
JE
365 const struct sctphdr *sh;
366 struct sctphdr _sctph;
367 const struct sctp_chunkhdr *sch;
368 struct sctp_chunkhdr _sch;
9fb9cbb1 369 u_int32_t offset, count;
c779e849 370 unsigned int *timeouts;
35c6d3cb 371 unsigned long map[256 / sizeof(unsigned long)] = { 0 };
9fb9cbb1 372
0150ffba
FW
373 if (sctp_error(skb, dataoff, state))
374 return -NF_ACCEPT;
375
9fb9cbb1
YK
376 sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
377 if (sh == NULL)
b37e933a 378 goto out;
9fb9cbb1 379
112f35c9 380 if (do_basic_checks(ct, skb, dataoff, map) != 0)
b37e933a 381 goto out;
9fb9cbb1 382
9976fc6e
FW
383 if (!nf_ct_is_confirmed(ct)) {
384 /* If an OOTB packet has any of these chunks discard (Sec 8.4) */
385 if (test_bit(SCTP_CID_ABORT, map) ||
386 test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) ||
387 test_bit(SCTP_CID_COOKIE_ACK, map))
388 return -NF_ACCEPT;
389
390 if (!sctp_new(ct, skb, sh, dataoff))
391 return -NF_ACCEPT;
392 }
393
9fb9cbb1 394 /* Check the verification tag (Sec 8.5) */
35c6d3cb
PM
395 if (!test_bit(SCTP_CID_INIT, map) &&
396 !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, map) &&
397 !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
398 !test_bit(SCTP_CID_ABORT, map) &&
399 !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
d7ee3519
MK
400 !test_bit(SCTP_CID_HEARTBEAT, map) &&
401 !test_bit(SCTP_CID_HEARTBEAT_ACK, map) &&
8528819a 402 sh->vtag != ct->proto.sctp.vtag[dir]) {
0d53778e 403 pr_debug("Verification tag check failed\n");
b37e933a 404 goto out;
9fb9cbb1
YK
405 }
406
328bd899 407 old_state = new_state = SCTP_CONNTRACK_NONE;
440f0d58 408 spin_lock_bh(&ct->lock);
9fb9cbb1 409 for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
9fb9cbb1
YK
410 /* Special cases of Verification tag check (Sec 8.5.1) */
411 if (sch->type == SCTP_CID_INIT) {
412 /* Sec 8.5.1 (A) */
b37e933a
PM
413 if (sh->vtag != 0)
414 goto out_unlock;
9fb9cbb1
YK
415 } else if (sch->type == SCTP_CID_ABORT) {
416 /* Sec 8.5.1 (B) */
8528819a 417 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
b37e933a
PM
418 sh->vtag != ct->proto.sctp.vtag[!dir])
419 goto out_unlock;
9fb9cbb1
YK
420 } else if (sch->type == SCTP_CID_SHUTDOWN_COMPLETE) {
421 /* Sec 8.5.1 (C) */
8528819a
PM
422 if (sh->vtag != ct->proto.sctp.vtag[dir] &&
423 sh->vtag != ct->proto.sctp.vtag[!dir] &&
9b1c2cfd 424 sch->flags & SCTP_CHUNK_FLAG_T)
b37e933a 425 goto out_unlock;
9fb9cbb1
YK
426 } else if (sch->type == SCTP_CID_COOKIE_ECHO) {
427 /* Sec 8.5.1 (D) */
b37e933a
PM
428 if (sh->vtag != ct->proto.sctp.vtag[dir])
429 goto out_unlock;
d7ee3519
MK
430 } else if (sch->type == SCTP_CID_HEARTBEAT ||
431 sch->type == SCTP_CID_HEARTBEAT_ACK) {
432 if (ct->proto.sctp.vtag[dir] == 0) {
433 pr_debug("Setting vtag %x for dir %d\n",
434 sh->vtag, dir);
435 ct->proto.sctp.vtag[dir] = sh->vtag;
436 } else if (sh->vtag != ct->proto.sctp.vtag[dir]) {
437 pr_debug("Verification tag check failed\n");
438 goto out_unlock;
439 }
9fb9cbb1
YK
440 }
441
efe9f68a
PM
442 old_state = ct->proto.sctp.state;
443 new_state = sctp_new_state(dir, old_state, sch->type);
9fb9cbb1
YK
444
445 /* Invalid */
efe9f68a 446 if (new_state == SCTP_CONNTRACK_MAX) {
0d53778e
PM
447 pr_debug("nf_conntrack_sctp: Invalid dir=%i ctype=%u "
448 "conntrack=%u\n",
efe9f68a 449 dir, sch->type, old_state);
b37e933a 450 goto out_unlock;
9fb9cbb1
YK
451 }
452
453 /* If it is an INIT or an INIT ACK note down the vtag */
5447d477
PM
454 if (sch->type == SCTP_CID_INIT ||
455 sch->type == SCTP_CID_INIT_ACK) {
4ae70c08 456 struct sctp_inithdr _inithdr, *ih;
9fb9cbb1 457
922dbc5b 458 ih = skb_header_pointer(skb, offset + sizeof(_sch),
601e68e1 459 sizeof(_inithdr), &_inithdr);
b37e933a
PM
460 if (ih == NULL)
461 goto out_unlock;
0d53778e 462 pr_debug("Setting vtag %x for dir %d\n",
8528819a
PM
463 ih->init_tag, !dir);
464 ct->proto.sctp.vtag[!dir] = ih->init_tag;
9fb9cbb1
YK
465 }
466
efe9f68a
PM
467 ct->proto.sctp.state = new_state;
468 if (old_state != new_state)
a71996fc 469 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
9fb9cbb1 470 }
440f0d58 471 spin_unlock_bh(&ct->lock);
9fb9cbb1 472
c779e849
FW
473 timeouts = nf_ct_timeout_lookup(ct);
474 if (!timeouts)
a95a7774 475 timeouts = nf_sctp_pernet(nf_ct_net(ct))->timeouts;
c779e849 476
2c8503f5 477 nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
9fb9cbb1 478
efe9f68a 479 if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
8528819a 480 dir == IP_CT_DIR_REPLY &&
efe9f68a 481 new_state == SCTP_CONNTRACK_ESTABLISHED) {
0d53778e 482 pr_debug("Setting assured bit\n");
112f35c9 483 set_bit(IPS_ASSURED_BIT, &ct->status);
858b3133 484 nf_conntrack_event_cache(IPCT_ASSURED, ct);
9fb9cbb1
YK
485 }
486
487 return NF_ACCEPT;
b37e933a
PM
488
489out_unlock:
440f0d58 490 spin_unlock_bh(&ct->lock);
b37e933a
PM
491out:
492 return -NF_ACCEPT;
9fb9cbb1
YK
493}
494
c6dd940b
FW
495static bool sctp_can_early_drop(const struct nf_conn *ct)
496{
497 switch (ct->proto.sctp.state) {
498 case SCTP_CONNTRACK_SHUTDOWN_SENT:
499 case SCTP_CONNTRACK_SHUTDOWN_RECD:
500 case SCTP_CONNTRACK_SHUTDOWN_ACK_SENT:
501 return true;
502 default:
503 break;
504 }
505
506 return false;
507}
508
c0cd1156 509#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
a258860e
PNA
510
511#include <linux/netfilter/nfnetlink.h>
512#include <linux/netfilter/nfnetlink_conntrack.h>
513
514static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
440f0d58 515 struct nf_conn *ct)
a258860e
PNA
516{
517 struct nlattr *nest_parms;
518
440f0d58 519 spin_lock_bh(&ct->lock);
ae0be8de 520 nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP);
a258860e
PNA
521 if (!nest_parms)
522 goto nla_put_failure;
523
5e8d1eb5
DM
524 if (nla_put_u8(skb, CTA_PROTOINFO_SCTP_STATE, ct->proto.sctp.state) ||
525 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
526 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL]) ||
527 nla_put_be32(skb, CTA_PROTOINFO_SCTP_VTAG_REPLY,
528 ct->proto.sctp.vtag[IP_CT_DIR_REPLY]))
529 goto nla_put_failure;
a258860e 530
440f0d58 531 spin_unlock_bh(&ct->lock);
a258860e
PNA
532
533 nla_nest_end(skb, nest_parms);
534
535 return 0;
536
537nla_put_failure:
440f0d58 538 spin_unlock_bh(&ct->lock);
a258860e
PNA
539 return -1;
540}
541
542static const struct nla_policy sctp_nla_policy[CTA_PROTOINFO_SCTP_MAX+1] = {
543 [CTA_PROTOINFO_SCTP_STATE] = { .type = NLA_U8 },
544 [CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] = { .type = NLA_U32 },
545 [CTA_PROTOINFO_SCTP_VTAG_REPLY] = { .type = NLA_U32 },
546};
547
39215846
FW
548#define SCTP_NLATTR_SIZE ( \
549 NLA_ALIGN(NLA_HDRLEN + 1) + \
550 NLA_ALIGN(NLA_HDRLEN + 4) + \
551 NLA_ALIGN(NLA_HDRLEN + 4))
552
a258860e
PNA
553static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
554{
555 struct nlattr *attr = cda[CTA_PROTOINFO_SCTP];
556 struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1];
557 int err;
558
559 /* updates may not contain the internal protocol info, skip parsing */
560 if (!attr)
561 return 0;
562
8cb08174
JB
563 err = nla_parse_nested_deprecated(tb, CTA_PROTOINFO_SCTP_MAX, attr,
564 sctp_nla_policy, NULL);
a258860e
PNA
565 if (err < 0)
566 return err;
567
568 if (!tb[CTA_PROTOINFO_SCTP_STATE] ||
569 !tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL] ||
570 !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])
571 return -EINVAL;
572
440f0d58 573 spin_lock_bh(&ct->lock);
a258860e
PNA
574 ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
575 ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
5547cd0a 576 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
a258860e 577 ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
5547cd0a 578 nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
440f0d58 579 spin_unlock_bh(&ct->lock);
a258860e
PNA
580
581 return 0;
582}
583#endif
584
a874752a 585#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
50978462
PNA
586
587#include <linux/netfilter/nfnetlink.h>
588#include <linux/netfilter/nfnetlink_cttimeout.h>
589
8264deb8
G
590static int sctp_timeout_nlattr_to_obj(struct nlattr *tb[],
591 struct net *net, void *data)
50978462
PNA
592{
593 unsigned int *timeouts = data;
a95a7774 594 struct nf_sctp_net *sn = nf_sctp_pernet(net);
50978462
PNA
595 int i;
596
597 /* set default SCTP timeouts. */
598 for (i=0; i<SCTP_CONNTRACK_MAX; i++)
8264deb8 599 timeouts[i] = sn->timeouts[i];
50978462
PNA
600
601 /* there's a 1:1 mapping between attributes and protocol states. */
602 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
603 if (tb[i]) {
604 timeouts[i] = ntohl(nla_get_be32(tb[i])) * HZ;
605 }
606 }
ef39078d
FW
607
608 timeouts[CTA_TIMEOUT_SCTP_UNSPEC] = timeouts[CTA_TIMEOUT_SCTP_CLOSED];
50978462
PNA
609 return 0;
610}
611
612static int
613sctp_timeout_obj_to_nlattr(struct sk_buff *skb, const void *data)
614{
615 const unsigned int *timeouts = data;
616 int i;
617
5e8d1eb5
DM
618 for (i=CTA_TIMEOUT_SCTP_UNSPEC+1; i<CTA_TIMEOUT_SCTP_MAX+1; i++) {
619 if (nla_put_be32(skb, i, htonl(timeouts[i] / HZ)))
620 goto nla_put_failure;
621 }
50978462
PNA
622 return 0;
623
624nla_put_failure:
625 return -ENOSPC;
626}
627
628static const struct nla_policy
629sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
630 [CTA_TIMEOUT_SCTP_CLOSED] = { .type = NLA_U32 },
631 [CTA_TIMEOUT_SCTP_COOKIE_WAIT] = { .type = NLA_U32 },
632 [CTA_TIMEOUT_SCTP_COOKIE_ECHOED] = { .type = NLA_U32 },
633 [CTA_TIMEOUT_SCTP_ESTABLISHED] = { .type = NLA_U32 },
634 [CTA_TIMEOUT_SCTP_SHUTDOWN_SENT] = { .type = NLA_U32 },
635 [CTA_TIMEOUT_SCTP_SHUTDOWN_RECD] = { .type = NLA_U32 },
636 [CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT] = { .type = NLA_U32 },
d7ee3519
MK
637 [CTA_TIMEOUT_SCTP_HEARTBEAT_SENT] = { .type = NLA_U32 },
638 [CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED] = { .type = NLA_U32 },
50978462 639};
a874752a 640#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
50978462 641
2a389de8 642void nf_conntrack_sctp_init_net(struct net *net)
49d485a3 643{
a95a7774 644 struct nf_sctp_net *sn = nf_sctp_pernet(net);
2a389de8 645 int i;
49d485a3 646
2a389de8
FW
647 for (i = 0; i < SCTP_CONNTRACK_MAX; i++)
648 sn->timeouts[i] = sctp_timeouts[i];
49d485a3 649
2a389de8
FW
650 /* timeouts[0] is unused, init it so ->timeouts[0] contains
651 * 'new' timeout, like udp or icmp.
652 */
653 sn->timeouts[0] = sctp_timeouts[SCTP_CONNTRACK_CLOSED];
deaa0a97
LZ
654}
655
dd2934a9 656const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp = {
933a41e7 657 .l4proto = IPPROTO_SCTP,
ea48cc83 658#ifdef CONFIG_NF_CONNTRACK_PROCFS
933a41e7 659 .print_conntrack = sctp_print_conntrack,
ea48cc83 660#endif
c6dd940b 661 .can_early_drop = sctp_can_early_drop,
c0cd1156 662#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
39215846 663 .nlattr_size = SCTP_NLATTR_SIZE,
a258860e
PNA
664 .to_nlattr = sctp_to_nlattr,
665 .from_nlattr = nlattr_to_sctp,
c7212e9d 666 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
a400c30e 667 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
c7212e9d
PNA
668 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
669 .nla_policy = nf_ct_port_nla_policy,
670#endif
a874752a 671#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
50978462
PNA
672 .ctnl_timeout = {
673 .nlattr_to_obj = sctp_timeout_nlattr_to_obj,
674 .obj_to_nlattr = sctp_timeout_obj_to_nlattr,
675 .nlattr_max = CTA_TIMEOUT_SCTP_MAX,
676 .obj_size = sizeof(unsigned int) * SCTP_CONNTRACK_MAX,
677 .nla_policy = sctp_timeout_nla_policy,
678 },
a874752a 679#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
9fb9cbb1 680};