Merge tag 'wireless-drivers-for-davem-2019-08-06' of git://git.kernel.org/pub/scm...
[linux-2.6-block.git] / net / netfilter / nf_conntrack_netlink.c
CommitLineData
c1d10adb
PNA
1/* Connection tracking via netlink socket. Allows for user space
2 * protocol helpers and general trouble making from userspace.
3 *
4 * (C) 2001 by Jay Schulist <jschlst@samba.org>
dc808fe2 5 * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
c1d10adb 6 * (C) 2003 by Patrick Mchardy <kaber@trash.net>
392025f8 7 * (C) 2005-2012 by Pablo Neira Ayuso <pablo@netfilter.org>
c1d10adb 8 *
601e68e1 9 * Initial connection tracking via netlink development funded and
c1d10adb
PNA
10 * generally made possible by Network Robots, Inc. (www.networkrobots.com)
11 *
12 * Further development of this code funded by Astaro AG (http://www.astaro.com)
13 *
14 * This software may be used and distributed according to the terms
15 * of the GNU General Public License, incorporated herein by reference.
c1d10adb
PNA
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/kernel.h>
711bbdd6 21#include <linux/rculist.h>
ea781f19 22#include <linux/rculist_nulls.h>
c1d10adb
PNA
23#include <linux/types.h>
24#include <linux/timer.h>
1cc63249 25#include <linux/security.h>
c1d10adb
PNA
26#include <linux/skbuff.h>
27#include <linux/errno.h>
28#include <linux/netlink.h>
29#include <linux/spinlock.h>
40a839fd 30#include <linux/interrupt.h>
5a0e3ad6 31#include <linux/slab.h>
3c791076 32#include <linux/siphash.h>
c1d10adb
PNA
33
34#include <linux/netfilter.h>
dc5fc579 35#include <net/netlink.h>
9592a5c0 36#include <net/sock.h>
c1d10adb
PNA
37#include <net/netfilter/nf_conntrack.h>
38#include <net/netfilter/nf_conntrack_core.h>
77ab9cff 39#include <net/netfilter/nf_conntrack_expect.h>
c1d10adb 40#include <net/netfilter/nf_conntrack_helper.h>
41d73ec0 41#include <net/netfilter/nf_conntrack_seqadj.h>
605dcad6 42#include <net/netfilter/nf_conntrack_l4proto.h>
5b1158e9 43#include <net/netfilter/nf_conntrack_tuple.h>
58401572 44#include <net/netfilter/nf_conntrack_acct.h>
ef00f89f 45#include <net/netfilter/nf_conntrack_zones.h>
a992ca2a 46#include <net/netfilter/nf_conntrack_timestamp.h>
c539f017 47#include <net/netfilter/nf_conntrack_labels.h>
87e94dbc 48#include <net/netfilter/nf_conntrack_synproxy.h>
4806e975 49#if IS_ENABLED(CONFIG_NF_NAT)
d2c5c103 50#include <net/netfilter/nf_nat.h>
8c88f87c 51#include <net/netfilter/nf_nat_helper.h>
5b1158e9 52#endif
c1d10adb
PNA
53
54#include <linux/netfilter/nfnetlink.h>
55#include <linux/netfilter/nfnetlink_conntrack.h>
56
57MODULE_LICENSE("GPL");
58
4054ff45 59static int ctnetlink_dump_tuples_proto(struct sk_buff *skb,
2a04aabf
JL
60 const struct nf_conntrack_tuple *tuple,
61 const struct nf_conntrack_l4proto *l4proto)
c1d10adb 62{
c1d10adb 63 int ret = 0;
df6fb868 64 struct nlattr *nest_parms;
c1d10adb 65
ae0be8de 66 nest_parms = nla_nest_start(skb, CTA_TUPLE_PROTO);
df6fb868
PM
67 if (!nest_parms)
68 goto nla_put_failure;
cc1eb431
DM
69 if (nla_put_u8(skb, CTA_PROTO_NUM, tuple->dst.protonum))
70 goto nla_put_failure;
c1d10adb 71
fdf70832
PM
72 if (likely(l4proto->tuple_to_nlattr))
73 ret = l4proto->tuple_to_nlattr(skb, tuple);
601e68e1 74
df6fb868 75 nla_nest_end(skb, nest_parms);
c1d10adb
PNA
76
77 return ret;
78
df6fb868 79nla_put_failure:
c1d10adb
PNA
80 return -1;
81}
82
f957be9d
FW
83static int ipv4_tuple_to_nlattr(struct sk_buff *skb,
84 const struct nf_conntrack_tuple *tuple)
85{
86 if (nla_put_in_addr(skb, CTA_IP_V4_SRC, tuple->src.u3.ip) ||
87 nla_put_in_addr(skb, CTA_IP_V4_DST, tuple->dst.u3.ip))
88 return -EMSGSIZE;
89 return 0;
90}
91
92static int ipv6_tuple_to_nlattr(struct sk_buff *skb,
93 const struct nf_conntrack_tuple *tuple)
94{
95 if (nla_put_in6_addr(skb, CTA_IP_V6_SRC, &tuple->src.u3.in6) ||
96 nla_put_in6_addr(skb, CTA_IP_V6_DST, &tuple->dst.u3.in6))
97 return -EMSGSIZE;
98 return 0;
99}
100
4054ff45 101static int ctnetlink_dump_tuples_ip(struct sk_buff *skb,
f957be9d 102 const struct nf_conntrack_tuple *tuple)
c1d10adb 103{
c1d10adb 104 int ret = 0;
df6fb868
PM
105 struct nlattr *nest_parms;
106
ae0be8de 107 nest_parms = nla_nest_start(skb, CTA_TUPLE_IP);
df6fb868
PM
108 if (!nest_parms)
109 goto nla_put_failure;
1cde6436 110
f957be9d
FW
111 switch (tuple->src.l3num) {
112 case NFPROTO_IPV4:
113 ret = ipv4_tuple_to_nlattr(skb, tuple);
114 break;
115 case NFPROTO_IPV6:
116 ret = ipv6_tuple_to_nlattr(skb, tuple);
117 break;
118 }
1cde6436 119
df6fb868 120 nla_nest_end(skb, nest_parms);
c1d10adb 121
1cde6436
PNA
122 return ret;
123
df6fb868 124nla_put_failure:
1cde6436
PNA
125 return -1;
126}
127
4054ff45
PNA
128static int ctnetlink_dump_tuples(struct sk_buff *skb,
129 const struct nf_conntrack_tuple *tuple)
1cde6436 130{
b3480fe0 131 const struct nf_conntrack_l4proto *l4proto;
1cde6436 132 int ret;
1cde6436 133
3b988ece 134 rcu_read_lock();
f957be9d 135 ret = ctnetlink_dump_tuples_ip(skb, tuple);
c1d10adb 136
3b988ece 137 if (ret >= 0) {
4a60dc74 138 l4proto = nf_ct_l4proto_find(tuple->dst.protonum);
3b988ece
HS
139 ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto);
140 }
141 rcu_read_unlock();
c1d10adb 142 return ret;
c1d10adb
PNA
143}
144
4054ff45
PNA
145static int ctnetlink_dump_zone_id(struct sk_buff *skb, int attrtype,
146 const struct nf_conntrack_zone *zone, int dir)
deedb590
DB
147{
148 if (zone->id == NF_CT_DEFAULT_ZONE_ID || zone->dir != dir)
149 return 0;
150 if (nla_put_be16(skb, attrtype, htons(zone->id)))
151 goto nla_put_failure;
152 return 0;
153
154nla_put_failure:
155 return -1;
156}
157
4054ff45 158static int ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
c1d10adb 159{
cc1eb431
DM
160 if (nla_put_be32(skb, CTA_STATUS, htonl(ct->status)))
161 goto nla_put_failure;
c1d10adb
PNA
162 return 0;
163
df6fb868 164nla_put_failure:
c1d10adb
PNA
165 return -1;
166}
167
4054ff45 168static int ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct)
c1d10adb 169{
d0b35b93 170 long timeout = nf_ct_expires(ct) / HZ;
601e68e1 171
cc1eb431
DM
172 if (nla_put_be32(skb, CTA_TIMEOUT, htonl(timeout)))
173 goto nla_put_failure;
c1d10adb
PNA
174 return 0;
175
df6fb868 176nla_put_failure:
c1d10adb
PNA
177 return -1;
178}
179
4054ff45 180static int ctnetlink_dump_protoinfo(struct sk_buff *skb, struct nf_conn *ct)
c1d10adb 181{
b3480fe0 182 const struct nf_conntrack_l4proto *l4proto;
df6fb868 183 struct nlattr *nest_proto;
c1d10adb
PNA
184 int ret;
185
4a60dc74 186 l4proto = nf_ct_l4proto_find(nf_ct_protonum(ct));
528a3a6f 187 if (!l4proto->to_nlattr)
c1d10adb 188 return 0;
601e68e1 189
ae0be8de 190 nest_proto = nla_nest_start(skb, CTA_PROTOINFO);
df6fb868
PM
191 if (!nest_proto)
192 goto nla_put_failure;
c1d10adb 193
fdf70832 194 ret = l4proto->to_nlattr(skb, nest_proto, ct);
c1d10adb 195
df6fb868 196 nla_nest_end(skb, nest_proto);
c1d10adb
PNA
197
198 return ret;
199
df6fb868 200nla_put_failure:
c1d10adb
PNA
201 return -1;
202}
203
4054ff45
PNA
204static int ctnetlink_dump_helpinfo(struct sk_buff *skb,
205 const struct nf_conn *ct)
c1d10adb 206{
df6fb868 207 struct nlattr *nest_helper;
dc808fe2 208 const struct nf_conn_help *help = nfct_help(ct);
3c158f7f 209 struct nf_conntrack_helper *helper;
c1d10adb 210
3c158f7f 211 if (!help)
c1d10adb 212 return 0;
601e68e1 213
3c158f7f
PM
214 helper = rcu_dereference(help->helper);
215 if (!helper)
216 goto out;
217
ae0be8de 218 nest_helper = nla_nest_start(skb, CTA_HELP);
df6fb868
PM
219 if (!nest_helper)
220 goto nla_put_failure;
cc1eb431
DM
221 if (nla_put_string(skb, CTA_HELP_NAME, helper->name))
222 goto nla_put_failure;
c1d10adb 223
fdf70832
PM
224 if (helper->to_nlattr)
225 helper->to_nlattr(skb, ct);
c1d10adb 226
df6fb868 227 nla_nest_end(skb, nest_helper);
3c158f7f 228out:
c1d10adb
PNA
229 return 0;
230
df6fb868 231nla_put_failure:
c1d10adb
PNA
232 return -1;
233}
234
bb5cf80e 235static int
4542fa47
HE
236dump_counters(struct sk_buff *skb, struct nf_conn_acct *acct,
237 enum ip_conntrack_dir dir, int type)
c1d10adb 238{
4542fa47
HE
239 enum ctattr_type attr = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
240 struct nf_conn_counter *counter = acct->counter;
df6fb868 241 struct nlattr *nest_count;
4542fa47 242 u64 pkts, bytes;
c1d10adb 243
4542fa47
HE
244 if (type == IPCTNL_MSG_CT_GET_CTRZERO) {
245 pkts = atomic64_xchg(&counter[dir].packets, 0);
246 bytes = atomic64_xchg(&counter[dir].bytes, 0);
247 } else {
248 pkts = atomic64_read(&counter[dir].packets);
249 bytes = atomic64_read(&counter[dir].bytes);
250 }
251
ae0be8de 252 nest_count = nla_nest_start(skb, attr);
df6fb868
PM
253 if (!nest_count)
254 goto nla_put_failure;
255
b46f6ded
ND
256 if (nla_put_be64(skb, CTA_COUNTERS_PACKETS, cpu_to_be64(pkts),
257 CTA_COUNTERS_PAD) ||
258 nla_put_be64(skb, CTA_COUNTERS_BYTES, cpu_to_be64(bytes),
259 CTA_COUNTERS_PAD))
cc1eb431 260 goto nla_put_failure;
c1d10adb 261
df6fb868 262 nla_nest_end(skb, nest_count);
c1d10adb
PNA
263
264 return 0;
265
df6fb868 266nla_put_failure:
c1d10adb
PNA
267 return -1;
268}
c1d10adb 269
80e60e67 270static int
4542fa47 271ctnetlink_dump_acct(struct sk_buff *skb, const struct nf_conn *ct, int type)
80e60e67 272{
4542fa47 273 struct nf_conn_acct *acct = nf_conn_acct_find(ct);
80e60e67 274
80e60e67
PNA
275 if (!acct)
276 return 0;
277
4542fa47
HE
278 if (dump_counters(skb, acct, IP_CT_DIR_ORIGINAL, type) < 0)
279 return -1;
280 if (dump_counters(skb, acct, IP_CT_DIR_REPLY, type) < 0)
281 return -1;
282
283 return 0;
80e60e67
PNA
284}
285
a992ca2a
PNA
286static int
287ctnetlink_dump_timestamp(struct sk_buff *skb, const struct nf_conn *ct)
288{
289 struct nlattr *nest_count;
290 const struct nf_conn_tstamp *tstamp;
291
292 tstamp = nf_conn_tstamp_find(ct);
293 if (!tstamp)
294 return 0;
295
ae0be8de 296 nest_count = nla_nest_start(skb, CTA_TIMESTAMP);
a992ca2a
PNA
297 if (!nest_count)
298 goto nla_put_failure;
299
b46f6ded
ND
300 if (nla_put_be64(skb, CTA_TIMESTAMP_START, cpu_to_be64(tstamp->start),
301 CTA_TIMESTAMP_PAD) ||
cc1eb431 302 (tstamp->stop != 0 && nla_put_be64(skb, CTA_TIMESTAMP_STOP,
b46f6ded
ND
303 cpu_to_be64(tstamp->stop),
304 CTA_TIMESTAMP_PAD)))
cc1eb431 305 goto nla_put_failure;
a992ca2a
PNA
306 nla_nest_end(skb, nest_count);
307
308 return 0;
309
310nla_put_failure:
311 return -1;
312}
313
c1d10adb 314#ifdef CONFIG_NF_CONNTRACK_MARK
4054ff45 315static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
c1d10adb 316{
cc1eb431
DM
317 if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark)))
318 goto nla_put_failure;
c1d10adb
PNA
319 return 0;
320
df6fb868 321nla_put_failure:
c1d10adb
PNA
322 return -1;
323}
324#else
325#define ctnetlink_dump_mark(a, b) (0)
326#endif
327
37fccd85 328#ifdef CONFIG_NF_CONNTRACK_SECMARK
4054ff45 329static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
37fccd85 330{
1cc63249
EP
331 struct nlattr *nest_secctx;
332 int len, ret;
333 char *secctx;
334
335 ret = security_secid_to_secctx(ct->secmark, &secctx, &len);
336 if (ret)
cba85b53 337 return 0;
1cc63249
EP
338
339 ret = -1;
ae0be8de 340 nest_secctx = nla_nest_start(skb, CTA_SECCTX);
1cc63249
EP
341 if (!nest_secctx)
342 goto nla_put_failure;
37fccd85 343
cc1eb431
DM
344 if (nla_put_string(skb, CTA_SECCTX_NAME, secctx))
345 goto nla_put_failure;
1cc63249
EP
346 nla_nest_end(skb, nest_secctx);
347
348 ret = 0;
37fccd85 349nla_put_failure:
1cc63249
EP
350 security_release_secctx(secctx, len);
351 return ret;
37fccd85
PNA
352}
353#else
1cc63249 354#define ctnetlink_dump_secctx(a, b) (0)
37fccd85
PNA
355#endif
356
0ceabd83 357#ifdef CONFIG_NF_CONNTRACK_LABELS
4a96300c 358static inline int ctnetlink_label_size(const struct nf_conn *ct)
0ceabd83
FW
359{
360 struct nf_conn_labels *labels = nf_ct_labels_find(ct);
361
362 if (!labels)
363 return 0;
23014011 364 return nla_total_size(sizeof(labels->bits));
0ceabd83
FW
365}
366
367static int
368ctnetlink_dump_labels(struct sk_buff *skb, const struct nf_conn *ct)
369{
370 struct nf_conn_labels *labels = nf_ct_labels_find(ct);
23014011 371 unsigned int i;
0ceabd83
FW
372
373 if (!labels)
374 return 0;
375
0ceabd83
FW
376 i = 0;
377 do {
378 if (labels->bits[i] != 0)
23014011
FW
379 return nla_put(skb, CTA_LABELS, sizeof(labels->bits),
380 labels->bits);
0ceabd83 381 i++;
23014011 382 } while (i < ARRAY_SIZE(labels->bits));
0ceabd83
FW
383
384 return 0;
385}
386#else
387#define ctnetlink_dump_labels(a, b) (0)
388#define ctnetlink_label_size(a) (0)
389#endif
390
0f417ce9
PNA
391#define master_tuple(ct) &(ct->master->tuplehash[IP_CT_DIR_ORIGINAL].tuple)
392
4054ff45 393static int ctnetlink_dump_master(struct sk_buff *skb, const struct nf_conn *ct)
0f417ce9
PNA
394{
395 struct nlattr *nest_parms;
396
397 if (!(ct->status & IPS_EXPECTED))
398 return 0;
399
ae0be8de 400 nest_parms = nla_nest_start(skb, CTA_TUPLE_MASTER);
0f417ce9
PNA
401 if (!nest_parms)
402 goto nla_put_failure;
403 if (ctnetlink_dump_tuples(skb, master_tuple(ct)) < 0)
404 goto nla_put_failure;
405 nla_nest_end(skb, nest_parms);
406
407 return 0;
408
409nla_put_failure:
410 return -1;
411}
412
bb5cf80e 413static int
41d73ec0 414dump_ct_seq_adj(struct sk_buff *skb, const struct nf_ct_seqadj *seq, int type)
13eae15a 415{
13eae15a
PNA
416 struct nlattr *nest_parms;
417
ae0be8de 418 nest_parms = nla_nest_start(skb, type);
13eae15a
PNA
419 if (!nest_parms)
420 goto nla_put_failure;
421
41d73ec0
PM
422 if (nla_put_be32(skb, CTA_SEQADJ_CORRECTION_POS,
423 htonl(seq->correction_pos)) ||
424 nla_put_be32(skb, CTA_SEQADJ_OFFSET_BEFORE,
425 htonl(seq->offset_before)) ||
426 nla_put_be32(skb, CTA_SEQADJ_OFFSET_AFTER,
427 htonl(seq->offset_after)))
cc1eb431 428 goto nla_put_failure;
13eae15a
PNA
429
430 nla_nest_end(skb, nest_parms);
431
432 return 0;
433
434nla_put_failure:
435 return -1;
436}
437
64f3967c 438static int ctnetlink_dump_ct_seq_adj(struct sk_buff *skb, struct nf_conn *ct)
13eae15a 439{
41d73ec0
PM
440 struct nf_conn_seqadj *seqadj = nfct_seqadj(ct);
441 struct nf_ct_seqadj *seq;
13eae15a 442
41d73ec0 443 if (!(ct->status & IPS_SEQ_ADJUST) || !seqadj)
13eae15a
PNA
444 return 0;
445
64f3967c 446 spin_lock_bh(&ct->lock);
41d73ec0
PM
447 seq = &seqadj->seq[IP_CT_DIR_ORIGINAL];
448 if (dump_ct_seq_adj(skb, seq, CTA_SEQ_ADJ_ORIG) == -1)
64f3967c 449 goto err;
13eae15a 450
41d73ec0
PM
451 seq = &seqadj->seq[IP_CT_DIR_REPLY];
452 if (dump_ct_seq_adj(skb, seq, CTA_SEQ_ADJ_REPLY) == -1)
64f3967c 453 goto err;
13eae15a 454
64f3967c 455 spin_unlock_bh(&ct->lock);
13eae15a 456 return 0;
64f3967c
LZ
457err:
458 spin_unlock_bh(&ct->lock);
459 return -1;
13eae15a 460}
13eae15a 461
20710b3b
PNA
462static int ctnetlink_dump_ct_synproxy(struct sk_buff *skb, struct nf_conn *ct)
463{
464 struct nf_conn_synproxy *synproxy = nfct_synproxy(ct);
465 struct nlattr *nest_parms;
466
467 if (!synproxy)
468 return 0;
469
ae0be8de 470 nest_parms = nla_nest_start(skb, CTA_SYNPROXY);
20710b3b
PNA
471 if (!nest_parms)
472 goto nla_put_failure;
473
474 if (nla_put_be32(skb, CTA_SYNPROXY_ISN, htonl(synproxy->isn)) ||
475 nla_put_be32(skb, CTA_SYNPROXY_ITS, htonl(synproxy->its)) ||
476 nla_put_be32(skb, CTA_SYNPROXY_TSOFF, htonl(synproxy->tsoff)))
477 goto nla_put_failure;
478
479 nla_nest_end(skb, nest_parms);
480
481 return 0;
482
483nla_put_failure:
484 return -1;
485}
486
4054ff45 487static int ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
c1d10adb 488{
3c791076
FW
489 __be32 id = (__force __be32)nf_ct_get_id(ct);
490
491 if (nla_put_be32(skb, CTA_ID, id))
cc1eb431 492 goto nla_put_failure;
c1d10adb
PNA
493 return 0;
494
df6fb868 495nla_put_failure:
c1d10adb
PNA
496 return -1;
497}
498
4054ff45 499static int ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
c1d10adb 500{
cc1eb431
DM
501 if (nla_put_be32(skb, CTA_USE, htonl(atomic_read(&ct->ct_general.use))))
502 goto nla_put_failure;
c1d10adb
PNA
503 return 0;
504
df6fb868 505nla_put_failure:
c1d10adb
PNA
506 return -1;
507}
508
c1d10adb 509static int
15e47304 510ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
80e60e67 511 struct nf_conn *ct)
c1d10adb 512{
308ac914 513 const struct nf_conntrack_zone *zone;
c1d10adb
PNA
514 struct nlmsghdr *nlh;
515 struct nfgenmsg *nfmsg;
df6fb868 516 struct nlattr *nest_parms;
15e47304 517 unsigned int flags = portid ? NLM_F_MULTI : 0, event;
c1d10adb 518
dedb67c4 519 event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_NEW);
15e47304 520 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
96bcf938
PNA
521 if (nlh == NULL)
522 goto nlmsg_failure;
c1d10adb 523
96bcf938 524 nfmsg = nlmsg_data(nlh);
5e8fbe2a 525 nfmsg->nfgen_family = nf_ct_l3num(ct);
c1d10adb
PNA
526 nfmsg->version = NFNETLINK_V0;
527 nfmsg->res_id = 0;
528
deedb590
DB
529 zone = nf_ct_zone(ct);
530
ae0be8de 531 nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG);
df6fb868
PM
532 if (!nest_parms)
533 goto nla_put_failure;
f2f3e38c 534 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
df6fb868 535 goto nla_put_failure;
deedb590
DB
536 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
537 NF_CT_ZONE_DIR_ORIG) < 0)
538 goto nla_put_failure;
df6fb868 539 nla_nest_end(skb, nest_parms);
601e68e1 540
ae0be8de 541 nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY);
df6fb868
PM
542 if (!nest_parms)
543 goto nla_put_failure;
f2f3e38c 544 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0)
df6fb868 545 goto nla_put_failure;
deedb590
DB
546 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
547 NF_CT_ZONE_DIR_REPL) < 0)
548 goto nla_put_failure;
df6fb868 549 nla_nest_end(skb, nest_parms);
c1d10adb 550
deedb590
DB
551 if (ctnetlink_dump_zone_id(skb, CTA_ZONE, zone,
552 NF_CT_DEFAULT_ZONE_DIR) < 0)
cc1eb431 553 goto nla_put_failure;
ef00f89f 554
c1d10adb
PNA
555 if (ctnetlink_dump_status(skb, ct) < 0 ||
556 ctnetlink_dump_timeout(skb, ct) < 0 ||
4542fa47 557 ctnetlink_dump_acct(skb, ct, type) < 0 ||
a992ca2a 558 ctnetlink_dump_timestamp(skb, ct) < 0 ||
c1d10adb
PNA
559 ctnetlink_dump_protoinfo(skb, ct) < 0 ||
560 ctnetlink_dump_helpinfo(skb, ct) < 0 ||
561 ctnetlink_dump_mark(skb, ct) < 0 ||
1cc63249 562 ctnetlink_dump_secctx(skb, ct) < 0 ||
0ceabd83 563 ctnetlink_dump_labels(skb, ct) < 0 ||
c1d10adb 564 ctnetlink_dump_id(skb, ct) < 0 ||
13eae15a 565 ctnetlink_dump_use(skb, ct) < 0 ||
0f417ce9 566 ctnetlink_dump_master(skb, ct) < 0 ||
20710b3b
PNA
567 ctnetlink_dump_ct_seq_adj(skb, ct) < 0 ||
568 ctnetlink_dump_ct_synproxy(skb, ct) < 0)
df6fb868 569 goto nla_put_failure;
c1d10adb 570
96bcf938 571 nlmsg_end(skb, nlh);
c1d10adb
PNA
572 return skb->len;
573
574nlmsg_failure:
df6fb868 575nla_put_failure:
96bcf938 576 nlmsg_cancel(skb, nlh);
c1d10adb
PNA
577 return -1;
578}
579
f957be9d
FW
580static const struct nla_policy cta_ip_nla_policy[CTA_IP_MAX + 1] = {
581 [CTA_IP_V4_SRC] = { .type = NLA_U32 },
582 [CTA_IP_V4_DST] = { .type = NLA_U32 },
583 [CTA_IP_V6_SRC] = { .len = sizeof(__be32) * 4 },
584 [CTA_IP_V6_DST] = { .len = sizeof(__be32) * 4 },
585};
586
8252fcea 587#if defined(CONFIG_NETFILTER_NETLINK_GLUE_CT) || defined(CONFIG_NF_CONNTRACK_EVENTS)
5caaed15 588static size_t ctnetlink_proto_size(const struct nf_conn *ct)
2732c4e4 589{
b3480fe0 590 const struct nf_conntrack_l4proto *l4proto;
5caaed15 591 size_t len, len4 = 0;
03b64f51 592
f957be9d 593 len = nla_policy_len(cta_ip_nla_policy, CTA_IP_MAX + 1);
0d035100 594 len *= 3u; /* ORIG, REPLY, MASTER */
03b64f51 595
4a60dc74 596 l4proto = nf_ct_l4proto_find(nf_ct_protonum(ct));
39215846 597 len += l4proto->nlattr_size;
5caaed15
FW
598 if (l4proto->nlattr_tuple_size) {
599 len4 = l4proto->nlattr_tuple_size();
600 len4 *= 3u; /* ORIG, REPLY, MASTER */
601 }
03b64f51 602
5caaed15 603 return len + len4;
03b64f51 604}
8252fcea 605#endif
03b64f51 606
4a96300c 607static inline size_t ctnetlink_acct_size(const struct nf_conn *ct)
d26e6a02
JP
608{
609 if (!nf_ct_ext_exist(ct, NF_CT_EXT_ACCT))
610 return 0;
611 return 2 * nla_total_size(0) /* CTA_COUNTERS_ORIG|REPL */
b46f6ded
ND
612 + 2 * nla_total_size_64bit(sizeof(uint64_t)) /* CTA_COUNTERS_PACKETS */
613 + 2 * nla_total_size_64bit(sizeof(uint64_t)) /* CTA_COUNTERS_BYTES */
d26e6a02
JP
614 ;
615}
616
4a96300c 617static inline int ctnetlink_secctx_size(const struct nf_conn *ct)
1cc63249 618{
cba85b53
PNA
619#ifdef CONFIG_NF_CONNTRACK_SECMARK
620 int len, ret;
1cc63249 621
cba85b53
PNA
622 ret = security_secid_to_secctx(ct->secmark, NULL, &len);
623 if (ret)
624 return 0;
1cc63249 625
cba85b53
PNA
626 return nla_total_size(0) /* CTA_SECCTX */
627 + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */
628#else
629 return 0;
1cc63249 630#endif
cba85b53 631}
1cc63249 632
4a96300c 633static inline size_t ctnetlink_timestamp_size(const struct nf_conn *ct)
a992ca2a
PNA
634{
635#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
636 if (!nf_ct_ext_exist(ct, NF_CT_EXT_TSTAMP))
637 return 0;
b46f6ded 638 return nla_total_size(0) + 2 * nla_total_size_64bit(sizeof(uint64_t));
a992ca2a
PNA
639#else
640 return 0;
641#endif
642}
643
4054ff45
PNA
644#ifdef CONFIG_NF_CONNTRACK_EVENTS
645static size_t ctnetlink_nlmsg_size(const struct nf_conn *ct)
03b64f51
PNA
646{
647 return NLMSG_ALIGN(sizeof(struct nfgenmsg))
648 + 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */
649 + 3 * nla_total_size(0) /* CTA_TUPLE_IP */
650 + 3 * nla_total_size(0) /* CTA_TUPLE_PROTO */
651 + 3 * nla_total_size(sizeof(u_int8_t)) /* CTA_PROTO_NUM */
652 + nla_total_size(sizeof(u_int32_t)) /* CTA_ID */
653 + nla_total_size(sizeof(u_int32_t)) /* CTA_STATUS */
f7b13e43 654 + ctnetlink_acct_size(ct)
a992ca2a 655 + ctnetlink_timestamp_size(ct)
03b64f51
PNA
656 + nla_total_size(sizeof(u_int32_t)) /* CTA_TIMEOUT */
657 + nla_total_size(0) /* CTA_PROTOINFO */
658 + nla_total_size(0) /* CTA_HELP */
659 + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */
cba85b53 660 + ctnetlink_secctx_size(ct)
4806e975 661#if IS_ENABLED(CONFIG_NF_NAT)
03b64f51
PNA
662 + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */
663 + 6 * nla_total_size(sizeof(u_int32_t)) /* CTA_NAT_SEQ_OFFSET */
d271e8bd
HE
664#endif
665#ifdef CONFIG_NF_CONNTRACK_MARK
03b64f51 666 + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
4a001068
KM
667#endif
668#ifdef CONFIG_NF_CONNTRACK_ZONES
deedb590 669 + nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE|CTA_TUPLE_ZONE */
d271e8bd 670#endif
03b64f51 671 + ctnetlink_proto_size(ct)
0ceabd83 672 + ctnetlink_label_size(ct)
03b64f51 673 ;
2732c4e4
HE
674}
675
e34d5c1a
PNA
676static int
677ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
c1d10adb 678{
308ac914 679 const struct nf_conntrack_zone *zone;
9592a5c0 680 struct net *net;
c1d10adb
PNA
681 struct nlmsghdr *nlh;
682 struct nfgenmsg *nfmsg;
df6fb868 683 struct nlattr *nest_parms;
19abb7b0 684 struct nf_conn *ct = item->ct;
c1d10adb
PNA
685 struct sk_buff *skb;
686 unsigned int type;
c1d10adb 687 unsigned int flags = 0, group;
dd7669a9 688 int err;
c1d10adb 689
a0891aa6 690 if (events & (1 << IPCT_DESTROY)) {
c1d10adb
PNA
691 type = IPCTNL_MSG_CT_DELETE;
692 group = NFNLGRP_CONNTRACK_DESTROY;
04b80cea 693 } else if (events & ((1 << IPCT_NEW) | (1 << IPCT_RELATED))) {
c1d10adb
PNA
694 type = IPCTNL_MSG_CT_NEW;
695 flags = NLM_F_CREATE|NLM_F_EXCL;
c1d10adb 696 group = NFNLGRP_CONNTRACK_NEW;
04b80cea 697 } else if (events) {
c1d10adb
PNA
698 type = IPCTNL_MSG_CT_NEW;
699 group = NFNLGRP_CONNTRACK_UPDATE;
700 } else
e34d5c1a 701 return 0;
a2427692 702
9592a5c0
AD
703 net = nf_ct_net(ct);
704 if (!item->report && !nfnetlink_has_listeners(net, group))
e34d5c1a 705 return 0;
a2427692 706
03b64f51
PNA
707 skb = nlmsg_new(ctnetlink_nlmsg_size(ct), GFP_ATOMIC);
708 if (skb == NULL)
150ace0d 709 goto errout;
c1d10adb 710
dedb67c4 711 type = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, type);
15e47304 712 nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags);
96bcf938
PNA
713 if (nlh == NULL)
714 goto nlmsg_failure;
c1d10adb 715
96bcf938 716 nfmsg = nlmsg_data(nlh);
5e8fbe2a 717 nfmsg->nfgen_family = nf_ct_l3num(ct);
c1d10adb
PNA
718 nfmsg->version = NFNETLINK_V0;
719 nfmsg->res_id = 0;
720
deedb590
DB
721 zone = nf_ct_zone(ct);
722
ae0be8de 723 nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG);
df6fb868
PM
724 if (!nest_parms)
725 goto nla_put_failure;
f2f3e38c 726 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
df6fb868 727 goto nla_put_failure;
deedb590
DB
728 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
729 NF_CT_ZONE_DIR_ORIG) < 0)
730 goto nla_put_failure;
df6fb868 731 nla_nest_end(skb, nest_parms);
601e68e1 732
ae0be8de 733 nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY);
df6fb868
PM
734 if (!nest_parms)
735 goto nla_put_failure;
f2f3e38c 736 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0)
df6fb868 737 goto nla_put_failure;
deedb590
DB
738 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
739 NF_CT_ZONE_DIR_REPL) < 0)
740 goto nla_put_failure;
df6fb868 741 nla_nest_end(skb, nest_parms);
c1d10adb 742
deedb590
DB
743 if (ctnetlink_dump_zone_id(skb, CTA_ZONE, zone,
744 NF_CT_DEFAULT_ZONE_DIR) < 0)
cc1eb431 745 goto nla_put_failure;
ef00f89f 746
1eedf699
EL
747 if (ctnetlink_dump_id(skb, ct) < 0)
748 goto nla_put_failure;
749
e57dce60
FH
750 if (ctnetlink_dump_status(skb, ct) < 0)
751 goto nla_put_failure;
752
a0891aa6 753 if (events & (1 << IPCT_DESTROY)) {
4542fa47 754 if (ctnetlink_dump_acct(skb, ct, type) < 0 ||
a992ca2a 755 ctnetlink_dump_timestamp(skb, ct) < 0)
df6fb868 756 goto nla_put_failure;
7b621c1e 757 } else {
7b621c1e 758 if (ctnetlink_dump_timeout(skb, ct) < 0)
df6fb868 759 goto nla_put_failure;
7b621c1e 760
a0891aa6 761 if (events & (1 << IPCT_PROTOINFO)
7b621c1e 762 && ctnetlink_dump_protoinfo(skb, ct) < 0)
df6fb868 763 goto nla_put_failure;
7b621c1e 764
a0891aa6 765 if ((events & (1 << IPCT_HELPER) || nfct_help(ct))
7b621c1e 766 && ctnetlink_dump_helpinfo(skb, ct) < 0)
df6fb868 767 goto nla_put_failure;
7b621c1e 768
ff660c80 769#ifdef CONFIG_NF_CONNTRACK_SECMARK
a0891aa6 770 if ((events & (1 << IPCT_SECMARK) || ct->secmark)
1cc63249 771 && ctnetlink_dump_secctx(skb, ct) < 0)
37fccd85 772 goto nla_put_failure;
ff660c80 773#endif
0ceabd83
FW
774 if (events & (1 << IPCT_LABEL) &&
775 ctnetlink_dump_labels(skb, ct) < 0)
776 goto nla_put_failure;
7b621c1e 777
a0891aa6 778 if (events & (1 << IPCT_RELATED) &&
0f417ce9
PNA
779 ctnetlink_dump_master(skb, ct) < 0)
780 goto nla_put_failure;
781
41d73ec0
PM
782 if (events & (1 << IPCT_SEQADJ) &&
783 ctnetlink_dump_ct_seq_adj(skb, ct) < 0)
13eae15a 784 goto nla_put_failure;
20710b3b
PNA
785
786 if (events & (1 << IPCT_SYNPROXY) &&
787 ctnetlink_dump_ct_synproxy(skb, ct) < 0)
788 goto nla_put_failure;
7b621c1e 789 }
b9a37e0c 790
a83099a6 791#ifdef CONFIG_NF_CONNTRACK_MARK
a0891aa6 792 if ((events & (1 << IPCT_MARK) || ct->mark)
a83099a6
EL
793 && ctnetlink_dump_mark(skb, ct) < 0)
794 goto nla_put_failure;
795#endif
96bcf938 796 nlmsg_end(skb, nlh);
15e47304 797 err = nfnetlink_send(skb, net, item->portid, group, item->report,
cd8c20b6 798 GFP_ATOMIC);
dd7669a9
PNA
799 if (err == -ENOBUFS || err == -EAGAIN)
800 return -ENOBUFS;
801
e34d5c1a 802 return 0;
c1d10adb 803
df6fb868 804nla_put_failure:
96bcf938 805 nlmsg_cancel(skb, nlh);
528a3a6f 806nlmsg_failure:
c1d10adb 807 kfree_skb(skb);
150ace0d 808errout:
37b7ef72
PNA
809 if (nfnetlink_set_err(net, 0, group, -ENOBUFS) > 0)
810 return -ENOBUFS;
811
e34d5c1a 812 return 0;
c1d10adb
PNA
813}
814#endif /* CONFIG_NF_CONNTRACK_EVENTS */
815
816static int ctnetlink_done(struct netlink_callback *cb)
817{
89f2e218
PM
818 if (cb->args[1])
819 nf_ct_put((struct nf_conn *)cb->args[1]);
397304b5 820 kfree(cb->data);
c1d10adb
PNA
821 return 0;
822}
823
866476f3 824struct ctnetlink_filter {
59c08c69 825 u8 family;
0f298a28
PNA
826 struct {
827 u_int32_t val;
828 u_int32_t mask;
829 } mark;
830};
831
866476f3 832static struct ctnetlink_filter *
59c08c69 833ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
866476f3 834{
866476f3
KE
835 struct ctnetlink_filter *filter;
836
9306425b
FW
837#ifndef CONFIG_NF_CONNTRACK_MARK
838 if (cda[CTA_MARK] && cda[CTA_MARK_MASK])
839 return ERR_PTR(-EOPNOTSUPP);
840#endif
841
866476f3
KE
842 filter = kzalloc(sizeof(*filter), GFP_KERNEL);
843 if (filter == NULL)
844 return ERR_PTR(-ENOMEM);
845
59c08c69
KE
846 filter->family = family;
847
848#ifdef CONFIG_NF_CONNTRACK_MARK
9306425b
FW
849 if (cda[CTA_MARK] && cda[CTA_MARK_MASK]) {
850 filter->mark.val = ntohl(nla_get_be32(cda[CTA_MARK]));
851 filter->mark.mask = ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
852 }
866476f3 853#endif
59c08c69 854 return filter;
866476f3
KE
855}
856
3e673b23
FW
857static int ctnetlink_start(struct netlink_callback *cb)
858{
859 const struct nlattr * const *cda = cb->data;
860 struct ctnetlink_filter *filter = NULL;
59c08c69
KE
861 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
862 u8 family = nfmsg->nfgen_family;
3e673b23 863
59c08c69
KE
864 if (family || (cda[CTA_MARK] && cda[CTA_MARK_MASK])) {
865 filter = ctnetlink_alloc_filter(cda, family);
3e673b23
FW
866 if (IS_ERR(filter))
867 return PTR_ERR(filter);
868 }
869
870 cb->data = filter;
871 return 0;
872}
873
866476f3
KE
874static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
875{
876 struct ctnetlink_filter *filter = data;
877
878 if (filter == NULL)
59c08c69
KE
879 goto out;
880
881 /* Match entries of a given L3 protocol number.
882 * If it is not specified, ie. l3proto == 0,
883 * then match everything.
884 */
885 if (filter->family && nf_ct_l3num(ct) != filter->family)
886 goto ignore_entry;
866476f3
KE
887
888#ifdef CONFIG_NF_CONNTRACK_MARK
59c08c69
KE
889 if ((ct->mark & filter->mark.mask) != filter->mark.val)
890 goto ignore_entry;
866476f3
KE
891#endif
892
59c08c69
KE
893out:
894 return 1;
895
896ignore_entry:
866476f3
KE
897 return 0;
898}
899
c1d10adb
PNA
900static int
901ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
902{
9592a5c0 903 struct net *net = sock_net(skb->sk);
89f2e218 904 struct nf_conn *ct, *last;
c1d10adb 905 struct nf_conntrack_tuple_hash *h;
ea781f19 906 struct hlist_nulls_node *n;
2344d64e
FW
907 struct nf_conn *nf_ct_evict[8];
908 int res, i;
93bb0ceb
JDB
909 spinlock_t *lockp;
910
d205dc40 911 last = (struct nf_conn *)cb->args[1];
2344d64e 912 i = 0;
93bb0ceb
JDB
913
914 local_bh_disable();
56d52d48 915 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
89f2e218 916restart:
2344d64e
FW
917 while (i) {
918 i--;
919 if (nf_ct_should_gc(nf_ct_evict[i]))
920 nf_ct_kill(nf_ct_evict[i]);
921 nf_ct_put(nf_ct_evict[i]);
922 }
923
93bb0ceb 924 lockp = &nf_conntrack_locks[cb->args[0] % CONNTRACK_LOCKS];
b16c2919 925 nf_conntrack_lock(lockp);
56d52d48 926 if (cb->args[0] >= nf_conntrack_htable_size) {
93bb0ceb
JDB
927 spin_unlock(lockp);
928 goto out;
929 }
56d52d48
FW
930 hlist_nulls_for_each_entry(h, n, &nf_conntrack_hash[cb->args[0]],
931 hnnode) {
5b1158e9 932 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
c1d10adb
PNA
933 continue;
934 ct = nf_ct_tuplehash_to_ctrack(h);
2344d64e
FW
935 if (nf_ct_is_expired(ct)) {
936 if (i < ARRAY_SIZE(nf_ct_evict) &&
937 atomic_inc_not_zero(&ct->ct_general.use))
938 nf_ct_evict[i++] = ct;
939 continue;
940 }
941
e0c7d472
FW
942 if (!net_eq(net, nf_ct_net(ct)))
943 continue;
944
d205dc40
PM
945 if (cb->args[1]) {
946 if (ct != last)
13ee6ac5 947 continue;
d205dc40 948 cb->args[1] = 0;
89f2e218 949 }
866476f3 950 if (!ctnetlink_filter_match(ct, cb->data))
0f298a28 951 continue;
866476f3 952
3b988ece
HS
953 rcu_read_lock();
954 res =
15e47304 955 ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
3b988ece
HS
956 cb->nlh->nlmsg_seq,
957 NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
958 ct);
959 rcu_read_unlock();
960 if (res < 0) {
c71caf41 961 nf_conntrack_get(&ct->ct_general);
89f2e218 962 cb->args[1] = (unsigned long)ct;
93bb0ceb 963 spin_unlock(lockp);
c1d10adb 964 goto out;
89f2e218
PM
965 }
966 }
93bb0ceb 967 spin_unlock(lockp);
d205dc40 968 if (cb->args[1]) {
89f2e218
PM
969 cb->args[1] = 0;
970 goto restart;
c1d10adb
PNA
971 }
972 }
89f2e218 973out:
93bb0ceb 974 local_bh_enable();
fefa9267
LZ
975 if (last) {
976 /* nf ct hash resize happened, now clear the leftover. */
977 if ((struct nf_conn *)cb->args[1] == last)
978 cb->args[1] = 0;
979
d205dc40 980 nf_ct_put(last);
fefa9267 981 }
c1d10adb 982
2344d64e
FW
983 while (i) {
984 i--;
985 if (nf_ct_should_gc(nf_ct_evict[i]))
986 nf_ct_kill(nf_ct_evict[i]);
987 nf_ct_put(nf_ct_evict[i]);
988 }
989
c1d10adb
PNA
990 return skb->len;
991}
992
f957be9d
FW
993static int ipv4_nlattr_to_tuple(struct nlattr *tb[],
994 struct nf_conntrack_tuple *t)
995{
996 if (!tb[CTA_IP_V4_SRC] || !tb[CTA_IP_V4_DST])
997 return -EINVAL;
998
999 t->src.u3.ip = nla_get_in_addr(tb[CTA_IP_V4_SRC]);
1000 t->dst.u3.ip = nla_get_in_addr(tb[CTA_IP_V4_DST]);
1001
1002 return 0;
1003}
1004
1005static int ipv6_nlattr_to_tuple(struct nlattr *tb[],
1006 struct nf_conntrack_tuple *t)
1007{
1008 if (!tb[CTA_IP_V6_SRC] || !tb[CTA_IP_V6_DST])
1009 return -EINVAL;
1010
1011 t->src.u3.in6 = nla_get_in6_addr(tb[CTA_IP_V6_SRC]);
1012 t->dst.u3.in6 = nla_get_in6_addr(tb[CTA_IP_V6_DST]);
1013
1014 return 0;
1015}
1016
4054ff45
PNA
1017static int ctnetlink_parse_tuple_ip(struct nlattr *attr,
1018 struct nf_conntrack_tuple *tuple)
c1d10adb 1019{
df6fb868 1020 struct nlattr *tb[CTA_IP_MAX+1];
c1d10adb
PNA
1021 int ret = 0;
1022
8cb08174 1023 ret = nla_parse_nested_deprecated(tb, CTA_IP_MAX, attr, NULL, NULL);
130ffbc2
DB
1024 if (ret < 0)
1025 return ret;
c1d10adb 1026
8cb08174
JB
1027 ret = nla_validate_nested_deprecated(attr, CTA_IP_MAX,
1028 cta_ip_nla_policy, NULL);
f957be9d
FW
1029 if (ret)
1030 return ret;
c1d10adb 1031
f957be9d
FW
1032 switch (tuple->src.l3num) {
1033 case NFPROTO_IPV4:
1034 ret = ipv4_nlattr_to_tuple(tb, tuple);
1035 break;
1036 case NFPROTO_IPV6:
1037 ret = ipv6_nlattr_to_tuple(tb, tuple);
1038 break;
f73e924c 1039 }
c1d10adb 1040
c1d10adb
PNA
1041 return ret;
1042}
1043
f73e924c
PM
1044static const struct nla_policy proto_nla_policy[CTA_PROTO_MAX+1] = {
1045 [CTA_PROTO_NUM] = { .type = NLA_U8 },
c1d10adb
PNA
1046};
1047
4054ff45
PNA
1048static int ctnetlink_parse_tuple_proto(struct nlattr *attr,
1049 struct nf_conntrack_tuple *tuple)
c1d10adb 1050{
b3480fe0 1051 const struct nf_conntrack_l4proto *l4proto;
df6fb868 1052 struct nlattr *tb[CTA_PROTO_MAX+1];
c1d10adb
PNA
1053 int ret = 0;
1054
8cb08174
JB
1055 ret = nla_parse_nested_deprecated(tb, CTA_PROTO_MAX, attr,
1056 proto_nla_policy, NULL);
f73e924c
PM
1057 if (ret < 0)
1058 return ret;
c1d10adb 1059
df6fb868 1060 if (!tb[CTA_PROTO_NUM])
c1d10adb 1061 return -EINVAL;
77236b6e 1062 tuple->dst.protonum = nla_get_u8(tb[CTA_PROTO_NUM]);
c1d10adb 1063
cd91566e 1064 rcu_read_lock();
4a60dc74 1065 l4proto = nf_ct_l4proto_find(tuple->dst.protonum);
c1d10adb 1066
f73e924c 1067 if (likely(l4proto->nlattr_to_tuple)) {
8cb08174
JB
1068 ret = nla_validate_nested_deprecated(attr, CTA_PROTO_MAX,
1069 l4proto->nla_policy,
1070 NULL);
f73e924c
PM
1071 if (ret == 0)
1072 ret = l4proto->nlattr_to_tuple(tb, tuple);
1073 }
c1d10adb 1074
cd91566e 1075 rcu_read_unlock();
601e68e1 1076
c1d10adb
PNA
1077 return ret;
1078}
1079
deedb590
DB
1080static int
1081ctnetlink_parse_zone(const struct nlattr *attr,
1082 struct nf_conntrack_zone *zone)
1083{
5e8018fc
DB
1084 nf_ct_zone_init(zone, NF_CT_DEFAULT_ZONE_ID,
1085 NF_CT_DEFAULT_ZONE_DIR, 0);
deedb590
DB
1086#ifdef CONFIG_NF_CONNTRACK_ZONES
1087 if (attr)
1088 zone->id = ntohs(nla_get_be16(attr));
1089#else
1090 if (attr)
1091 return -EOPNOTSUPP;
1092#endif
1093 return 0;
1094}
1095
1096static int
1097ctnetlink_parse_tuple_zone(struct nlattr *attr, enum ctattr_type type,
1098 struct nf_conntrack_zone *zone)
1099{
1100 int ret;
1101
1102 if (zone->id != NF_CT_DEFAULT_ZONE_ID)
1103 return -EINVAL;
1104
1105 ret = ctnetlink_parse_zone(attr, zone);
1106 if (ret < 0)
1107 return ret;
1108
1109 if (type == CTA_TUPLE_REPLY)
1110 zone->dir = NF_CT_ZONE_DIR_REPL;
1111 else
1112 zone->dir = NF_CT_ZONE_DIR_ORIG;
1113
1114 return 0;
1115}
1116
d0b0268f
PM
1117static const struct nla_policy tuple_nla_policy[CTA_TUPLE_MAX+1] = {
1118 [CTA_TUPLE_IP] = { .type = NLA_NESTED },
1119 [CTA_TUPLE_PROTO] = { .type = NLA_NESTED },
deedb590 1120 [CTA_TUPLE_ZONE] = { .type = NLA_U16 },
d0b0268f
PM
1121};
1122
bb5cf80e 1123static int
39938324 1124ctnetlink_parse_tuple(const struct nlattr * const cda[],
a2b7cbdd
MK
1125 struct nf_conntrack_tuple *tuple, u32 type,
1126 u_int8_t l3num, struct nf_conntrack_zone *zone)
c1d10adb 1127{
df6fb868 1128 struct nlattr *tb[CTA_TUPLE_MAX+1];
c1d10adb
PNA
1129 int err;
1130
c1d10adb
PNA
1131 memset(tuple, 0, sizeof(*tuple));
1132
8cb08174
JB
1133 err = nla_parse_nested_deprecated(tb, CTA_TUPLE_MAX, cda[type],
1134 tuple_nla_policy, NULL);
130ffbc2
DB
1135 if (err < 0)
1136 return err;
c1d10adb 1137
df6fb868 1138 if (!tb[CTA_TUPLE_IP])
c1d10adb
PNA
1139 return -EINVAL;
1140
1141 tuple->src.l3num = l3num;
1142
df6fb868 1143 err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP], tuple);
c1d10adb
PNA
1144 if (err < 0)
1145 return err;
1146
df6fb868 1147 if (!tb[CTA_TUPLE_PROTO])
c1d10adb
PNA
1148 return -EINVAL;
1149
df6fb868 1150 err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO], tuple);
c1d10adb
PNA
1151 if (err < 0)
1152 return err;
1153
deedb590
DB
1154 if (tb[CTA_TUPLE_ZONE]) {
1155 if (!zone)
1156 return -EINVAL;
1157
1158 err = ctnetlink_parse_tuple_zone(tb[CTA_TUPLE_ZONE],
1159 type, zone);
1160 if (err < 0)
1161 return err;
1162 }
1163
c1d10adb
PNA
1164 /* orig and expect tuples get DIR_ORIGINAL */
1165 if (type == CTA_TUPLE_REPLY)
1166 tuple->dst.dir = IP_CT_DIR_REPLY;
1167 else
1168 tuple->dst.dir = IP_CT_DIR_ORIGINAL;
1169
c1d10adb
PNA
1170 return 0;
1171}
1172
d0b0268f 1173static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = {
6d1fafca
FW
1174 [CTA_HELP_NAME] = { .type = NLA_NUL_STRING,
1175 .len = NF_CT_HELPER_NAME_LEN - 1 },
d0b0268f
PM
1176};
1177
4054ff45
PNA
1178static int ctnetlink_parse_help(const struct nlattr *attr, char **helper_name,
1179 struct nlattr **helpinfo)
c1d10adb 1180{
130ffbc2 1181 int err;
df6fb868 1182 struct nlattr *tb[CTA_HELP_MAX+1];
c1d10adb 1183
8cb08174
JB
1184 err = nla_parse_nested_deprecated(tb, CTA_HELP_MAX, attr,
1185 help_nla_policy, NULL);
130ffbc2
DB
1186 if (err < 0)
1187 return err;
c1d10adb 1188
df6fb868 1189 if (!tb[CTA_HELP_NAME])
c1d10adb
PNA
1190 return -EINVAL;
1191
df6fb868 1192 *helper_name = nla_data(tb[CTA_HELP_NAME]);
c1d10adb 1193
ae243bee
PNA
1194 if (tb[CTA_HELP_INFO])
1195 *helpinfo = tb[CTA_HELP_INFO];
1196
c1d10adb
PNA
1197 return 0;
1198}
1199
f73e924c 1200static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
d0b0268f
PM
1201 [CTA_TUPLE_ORIG] = { .type = NLA_NESTED },
1202 [CTA_TUPLE_REPLY] = { .type = NLA_NESTED },
f73e924c 1203 [CTA_STATUS] = { .type = NLA_U32 },
d0b0268f
PM
1204 [CTA_PROTOINFO] = { .type = NLA_NESTED },
1205 [CTA_HELP] = { .type = NLA_NESTED },
1206 [CTA_NAT_SRC] = { .type = NLA_NESTED },
f73e924c
PM
1207 [CTA_TIMEOUT] = { .type = NLA_U32 },
1208 [CTA_MARK] = { .type = NLA_U32 },
f73e924c 1209 [CTA_ID] = { .type = NLA_U32 },
d0b0268f
PM
1210 [CTA_NAT_DST] = { .type = NLA_NESTED },
1211 [CTA_TUPLE_MASTER] = { .type = NLA_NESTED },
6d1fafca
FW
1212 [CTA_NAT_SEQ_ADJ_ORIG] = { .type = NLA_NESTED },
1213 [CTA_NAT_SEQ_ADJ_REPLY] = { .type = NLA_NESTED },
ef00f89f 1214 [CTA_ZONE] = { .type = NLA_U16 },
0f298a28 1215 [CTA_MARK_MASK] = { .type = NLA_U32 },
9b21f6a9 1216 [CTA_LABELS] = { .type = NLA_BINARY,
d2bf2f34 1217 .len = NF_CT_LABELS_MAX_SIZE },
9b21f6a9 1218 [CTA_LABELS_MASK] = { .type = NLA_BINARY,
d2bf2f34 1219 .len = NF_CT_LABELS_MAX_SIZE },
c1d10adb
PNA
1220};
1221
90964016
PNA
1222static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data)
1223{
1224 if (test_bit(IPS_OFFLOAD_BIT, &ct->status))
1225 return 0;
1226
1227 return ctnetlink_filter_match(ct, data);
1228}
1229
866476f3
KE
1230static int ctnetlink_flush_conntrack(struct net *net,
1231 const struct nlattr * const cda[],
59c08c69 1232 u32 portid, int report, u8 family)
866476f3
KE
1233{
1234 struct ctnetlink_filter *filter = NULL;
1235
59c08c69
KE
1236 if (family || (cda[CTA_MARK] && cda[CTA_MARK_MASK])) {
1237 filter = ctnetlink_alloc_filter(cda, family);
866476f3
KE
1238 if (IS_ERR(filter))
1239 return PTR_ERR(filter);
1240 }
1241
90964016 1242 nf_ct_iterate_cleanup_net(net, ctnetlink_flush_iterate, filter,
9fd6452d 1243 portid, report);
866476f3
KE
1244 kfree(filter);
1245
1246 return 0;
1247}
1248
7b8002a1
PNA
1249static int ctnetlink_del_conntrack(struct net *net, struct sock *ctnl,
1250 struct sk_buff *skb,
1251 const struct nlmsghdr *nlh,
04ba724b
PNA
1252 const struct nlattr * const cda[],
1253 struct netlink_ext_ack *extack)
c1d10adb
PNA
1254{
1255 struct nf_conntrack_tuple_hash *h;
1256 struct nf_conntrack_tuple tuple;
1257 struct nf_conn *ct;
96bcf938 1258 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
308ac914 1259 struct nf_conntrack_zone zone;
ef00f89f
PM
1260 int err;
1261
1262 err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone);
1263 if (err < 0)
1264 return err;
c1d10adb 1265
df6fb868 1266 if (cda[CTA_TUPLE_ORIG])
deedb590 1267 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG,
e7600865 1268 nfmsg->nfgen_family, &zone);
df6fb868 1269 else if (cda[CTA_TUPLE_REPLY])
deedb590 1270 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY,
e7600865 1271 nfmsg->nfgen_family, &zone);
c1d10adb 1272 else {
e7600865
FK
1273 u_int8_t u3 = nfmsg->version ? nfmsg->nfgen_family : AF_UNSPEC;
1274
866476f3
KE
1275 return ctnetlink_flush_conntrack(net, cda,
1276 NETLINK_CB(skb).portid,
59c08c69 1277 nlmsg_report(nlh), u3);
c1d10adb
PNA
1278 }
1279
1280 if (err < 0)
1281 return err;
1282
308ac914 1283 h = nf_conntrack_find_get(net, &zone, &tuple);
9ea8cfd6 1284 if (!h)
c1d10adb 1285 return -ENOENT;
c1d10adb
PNA
1286
1287 ct = nf_ct_tuplehash_to_ctrack(h);
601e68e1 1288
90964016
PNA
1289 if (test_bit(IPS_OFFLOAD_BIT, &ct->status)) {
1290 nf_ct_put(ct);
1291 return -EBUSY;
1292 }
1293
df6fb868 1294 if (cda[CTA_ID]) {
3c791076
FW
1295 __be32 id = nla_get_be32(cda[CTA_ID]);
1296
1297 if (id != (__force __be32)nf_ct_get_id(ct)) {
c1d10adb
PNA
1298 nf_ct_put(ct);
1299 return -ENOENT;
1300 }
601e68e1 1301 }
c1d10adb 1302
f330a7fd 1303 nf_ct_delete(ct, NETLINK_CB(skb).portid, nlmsg_report(nlh));
c1d10adb 1304 nf_ct_put(ct);
c1d10adb
PNA
1305
1306 return 0;
1307}
1308
7b8002a1
PNA
1309static int ctnetlink_get_conntrack(struct net *net, struct sock *ctnl,
1310 struct sk_buff *skb,
1311 const struct nlmsghdr *nlh,
04ba724b
PNA
1312 const struct nlattr * const cda[],
1313 struct netlink_ext_ack *extack)
c1d10adb
PNA
1314{
1315 struct nf_conntrack_tuple_hash *h;
1316 struct nf_conntrack_tuple tuple;
1317 struct nf_conn *ct;
1318 struct sk_buff *skb2 = NULL;
96bcf938 1319 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 1320 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 1321 struct nf_conntrack_zone zone;
ef00f89f 1322 int err;
c1d10adb 1323
80d326fa
PNA
1324 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1325 struct netlink_dump_control c = {
3e673b23 1326 .start = ctnetlink_start,
80d326fa
PNA
1327 .dump = ctnetlink_dump_table,
1328 .done = ctnetlink_done,
3e673b23 1329 .data = (void *)cda,
80d326fa 1330 };
866476f3 1331
80d326fa
PNA
1332 return netlink_dump_start(ctnl, skb, nlh, &c);
1333 }
c1d10adb 1334
ef00f89f
PM
1335 err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone);
1336 if (err < 0)
1337 return err;
1338
df6fb868 1339 if (cda[CTA_TUPLE_ORIG])
deedb590
DB
1340 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG,
1341 u3, &zone);
df6fb868 1342 else if (cda[CTA_TUPLE_REPLY])
deedb590
DB
1343 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY,
1344 u3, &zone);
c1d10adb
PNA
1345 else
1346 return -EINVAL;
1347
1348 if (err < 0)
1349 return err;
1350
308ac914 1351 h = nf_conntrack_find_get(net, &zone, &tuple);
9ea8cfd6 1352 if (!h)
c1d10adb 1353 return -ENOENT;
9ea8cfd6 1354
c1d10adb
PNA
1355 ct = nf_ct_tuplehash_to_ctrack(h);
1356
1357 err = -ENOMEM;
96bcf938
PNA
1358 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1359 if (skb2 == NULL) {
c1d10adb
PNA
1360 nf_ct_put(ct);
1361 return -ENOMEM;
1362 }
c1d10adb 1363
528a3a6f 1364 rcu_read_lock();
15e47304 1365 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
80e60e67 1366 NFNL_MSG_TYPE(nlh->nlmsg_type), ct);
528a3a6f 1367 rcu_read_unlock();
c1d10adb
PNA
1368 nf_ct_put(ct);
1369 if (err <= 0)
1370 goto free;
1371
15e47304 1372 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
c1d10adb
PNA
1373 if (err < 0)
1374 goto out;
1375
c1d10adb
PNA
1376 return 0;
1377
1378free:
1379 kfree_skb(skb2);
1380out:
f31e8d49
PNA
1381 /* this avoids a loop in nfnetlink. */
1382 return err == -EAGAIN ? -ENOBUFS : err;
c1d10adb
PNA
1383}
1384
d871befe
PNA
1385static int ctnetlink_done_list(struct netlink_callback *cb)
1386{
1387 if (cb->args[1])
1388 nf_ct_put((struct nf_conn *)cb->args[1]);
1389 return 0;
1390}
1391
1392static int
b7779d06 1393ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
d871befe 1394{
cd5f336f 1395 struct nf_conn *ct, *last;
d871befe
PNA
1396 struct nf_conntrack_tuple_hash *h;
1397 struct hlist_nulls_node *n;
1398 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1399 u_int8_t l3proto = nfmsg->nfgen_family;
1400 int res;
b7779d06
JDB
1401 int cpu;
1402 struct hlist_nulls_head *list;
1403 struct net *net = sock_net(skb->sk);
d871befe
PNA
1404
1405 if (cb->args[2])
1406 return 0;
1407
cd5f336f
FW
1408 last = (struct nf_conn *)cb->args[1];
1409
b7779d06
JDB
1410 for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
1411 struct ct_pcpu *pcpu;
1412
1413 if (!cpu_possible(cpu))
d871befe 1414 continue;
b7779d06
JDB
1415
1416 pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
1417 spin_lock_bh(&pcpu->lock);
b7779d06
JDB
1418 list = dying ? &pcpu->dying : &pcpu->unconfirmed;
1419restart:
1420 hlist_nulls_for_each_entry(h, n, list, hnnode) {
1421 ct = nf_ct_tuplehash_to_ctrack(h);
1422 if (l3proto && nf_ct_l3num(ct) != l3proto)
d871befe 1423 continue;
b7779d06
JDB
1424 if (cb->args[1]) {
1425 if (ct != last)
1426 continue;
1427 cb->args[1] = 0;
1428 }
1429 rcu_read_lock();
1430 res = ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
1431 cb->nlh->nlmsg_seq,
1432 NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
1433 ct);
1434 rcu_read_unlock();
1435 if (res < 0) {
cd5f336f
FW
1436 if (!atomic_inc_not_zero(&ct->ct_general.use))
1437 continue;
266155b2 1438 cb->args[0] = cpu;
b7779d06
JDB
1439 cb->args[1] = (unsigned long)ct;
1440 spin_unlock_bh(&pcpu->lock);
1441 goto out;
1442 }
d871befe 1443 }
b7779d06
JDB
1444 if (cb->args[1]) {
1445 cb->args[1] = 0;
1446 goto restart;
266155b2 1447 }
b7779d06 1448 spin_unlock_bh(&pcpu->lock);
d871befe 1449 }
266155b2 1450 cb->args[2] = 1;
d871befe 1451out:
d871befe
PNA
1452 if (last)
1453 nf_ct_put(last);
1454
1455 return skb->len;
1456}
1457
1458static int
1459ctnetlink_dump_dying(struct sk_buff *skb, struct netlink_callback *cb)
1460{
b7779d06 1461 return ctnetlink_dump_list(skb, cb, true);
d871befe
PNA
1462}
1463
7b8002a1
PNA
1464static int ctnetlink_get_ct_dying(struct net *net, struct sock *ctnl,
1465 struct sk_buff *skb,
1466 const struct nlmsghdr *nlh,
04ba724b
PNA
1467 const struct nlattr * const cda[],
1468 struct netlink_ext_ack *extack)
d871befe
PNA
1469{
1470 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1471 struct netlink_dump_control c = {
1472 .dump = ctnetlink_dump_dying,
1473 .done = ctnetlink_done_list,
1474 };
1475 return netlink_dump_start(ctnl, skb, nlh, &c);
1476 }
1477
1478 return -EOPNOTSUPP;
1479}
1480
1481static int
1482ctnetlink_dump_unconfirmed(struct sk_buff *skb, struct netlink_callback *cb)
1483{
b7779d06 1484 return ctnetlink_dump_list(skb, cb, false);
d871befe
PNA
1485}
1486
7b8002a1
PNA
1487static int ctnetlink_get_ct_unconfirmed(struct net *net, struct sock *ctnl,
1488 struct sk_buff *skb,
1489 const struct nlmsghdr *nlh,
04ba724b
PNA
1490 const struct nlattr * const cda[],
1491 struct netlink_ext_ack *extack)
d871befe
PNA
1492{
1493 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1494 struct netlink_dump_control c = {
1495 .dump = ctnetlink_dump_unconfirmed,
1496 .done = ctnetlink_done_list,
1497 };
1498 return netlink_dump_start(ctnl, skb, nlh, &c);
1499 }
1500
1501 return -EOPNOTSUPP;
1502}
1503
4806e975 1504#if IS_ENABLED(CONFIG_NF_NAT)
e6a7d3c0
PNA
1505static int
1506ctnetlink_parse_nat_setup(struct nf_conn *ct,
1507 enum nf_nat_manip_type manip,
39938324 1508 const struct nlattr *attr)
e6a7d3c0 1509{
2c205dd3 1510 struct nf_nat_hook *nat_hook;
c7232c99 1511 int err;
e6a7d3c0 1512
2c205dd3
PNA
1513 nat_hook = rcu_dereference(nf_nat_hook);
1514 if (!nat_hook) {
95a5afca 1515#ifdef CONFIG_MODULES
e6a7d3c0 1516 rcu_read_unlock();
c14b78e7 1517 nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
c7232c99 1518 if (request_module("nf-nat") < 0) {
c14b78e7 1519 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
e6a7d3c0
PNA
1520 rcu_read_lock();
1521 return -EOPNOTSUPP;
1522 }
c14b78e7 1523 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
e6a7d3c0 1524 rcu_read_lock();
c05a45c0
FW
1525 nat_hook = rcu_dereference(nf_nat_hook);
1526 if (nat_hook)
e6a7d3c0
PNA
1527 return -EAGAIN;
1528#endif
1529 return -EOPNOTSUPP;
1530 }
1531
2c205dd3 1532 err = nat_hook->parse_nat_setup(ct, manip, attr);
c7232c99
PM
1533 if (err == -EAGAIN) {
1534#ifdef CONFIG_MODULES
1535 rcu_read_unlock();
c14b78e7 1536 nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
c7232c99 1537 if (request_module("nf-nat-%u", nf_ct_l3num(ct)) < 0) {
c14b78e7 1538 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
c7232c99
PM
1539 rcu_read_lock();
1540 return -EOPNOTSUPP;
1541 }
c14b78e7 1542 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
c7232c99
PM
1543 rcu_read_lock();
1544#else
1545 err = -EOPNOTSUPP;
1546#endif
1547 }
1548 return err;
e6a7d3c0 1549}
67671841 1550#endif
e6a7d3c0 1551
53b56da8
LZ
1552static void
1553__ctnetlink_change_status(struct nf_conn *ct, unsigned long on,
1554 unsigned long off)
1555{
1556 unsigned int bit;
1557
1558 /* Ignore these unchangable bits */
1559 on &= ~IPS_UNCHANGEABLE_MASK;
1560 off &= ~IPS_UNCHANGEABLE_MASK;
1561
1562 for (bit = 0; bit < __IPS_MAX_BIT; bit++) {
1563 if (on & (1 << bit))
1564 set_bit(bit, &ct->status);
1565 else if (off & (1 << bit))
1566 clear_bit(bit, &ct->status);
1567 }
1568}
1569
bb5cf80e 1570static int
39938324 1571ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
c1d10adb
PNA
1572{
1573 unsigned long d;
77236b6e 1574 unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS]));
c1d10adb
PNA
1575 d = ct->status ^ status;
1576
1577 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
1578 /* unchangeable */
0adf9d67 1579 return -EBUSY;
601e68e1 1580
c1d10adb
PNA
1581 if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
1582 /* SEEN_REPLY bit can only be set */
0adf9d67 1583 return -EBUSY;
601e68e1 1584
c1d10adb
PNA
1585 if (d & IPS_ASSURED && !(status & IPS_ASSURED))
1586 /* ASSURED bit can only be set */
0adf9d67 1587 return -EBUSY;
c1d10adb 1588
53b56da8 1589 __ctnetlink_change_status(ct, status, 0);
c1d10adb
PNA
1590 return 0;
1591}
1592
e6a7d3c0 1593static int
0eba801b 1594ctnetlink_setup_nat(struct nf_conn *ct, const struct nlattr * const cda[])
e6a7d3c0 1595{
4806e975 1596#if IS_ENABLED(CONFIG_NF_NAT)
e6a7d3c0
PNA
1597 int ret;
1598
fe337ac2
FW
1599 if (!cda[CTA_NAT_DST] && !cda[CTA_NAT_SRC])
1600 return 0;
1601
0eba801b
PNA
1602 ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_DST,
1603 cda[CTA_NAT_DST]);
1604 if (ret < 0)
1605 return ret;
1606
c47d36b3
AS
1607 return ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_SRC,
1608 cda[CTA_NAT_SRC]);
e6a7d3c0 1609#else
0eba801b
PNA
1610 if (!cda[CTA_NAT_DST] && !cda[CTA_NAT_SRC])
1611 return 0;
e6a7d3c0
PNA
1612 return -EOPNOTSUPP;
1613#endif
1614}
c1d10adb 1615
4054ff45
PNA
1616static int ctnetlink_change_helper(struct nf_conn *ct,
1617 const struct nlattr * const cda[])
c1d10adb
PNA
1618{
1619 struct nf_conntrack_helper *helper;
dc808fe2 1620 struct nf_conn_help *help = nfct_help(ct);
29fe1b48 1621 char *helpname = NULL;
ae243bee 1622 struct nlattr *helpinfo = NULL;
c1d10adb
PNA
1623 int err;
1624
ae243bee 1625 err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo);
c1d10adb
PNA
1626 if (err < 0)
1627 return err;
1628
f95d7a46
KC
1629 /* don't change helper of sibling connections */
1630 if (ct->master) {
1631 /* If we try to change the helper to the same thing twice,
1632 * treat the second attempt as a no-op instead of returning
1633 * an error.
1634 */
3173d5b8
LZ
1635 err = -EBUSY;
1636 if (help) {
1637 rcu_read_lock();
1638 helper = rcu_dereference(help->helper);
1639 if (helper && !strcmp(helper->name, helpname))
1640 err = 0;
1641 rcu_read_unlock();
1642 }
1643
1644 return err;
f95d7a46
KC
1645 }
1646
df293bbb
YK
1647 if (!strcmp(helpname, "")) {
1648 if (help && help->helper) {
c1d10adb
PNA
1649 /* we had a helper before ... */
1650 nf_ct_remove_expectations(ct);
a9b3cd7f 1651 RCU_INIT_POINTER(help->helper, NULL);
c1d10adb 1652 }
df293bbb
YK
1653
1654 return 0;
c1d10adb 1655 }
601e68e1 1656
88be4c09 1657 rcu_read_lock();
794e6871
PM
1658 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
1659 nf_ct_protonum(ct));
226c0c0e 1660 if (helper == NULL) {
88be4c09 1661 rcu_read_unlock();
0adf9d67 1662 return -EOPNOTSUPP;
226c0c0e 1663 }
df293bbb 1664
ceceae1b 1665 if (help) {
ae243bee
PNA
1666 if (help->helper == helper) {
1667 /* update private helper data if allowed. */
7be54ca4 1668 if (helper->from_nlattr)
ae243bee 1669 helper->from_nlattr(helpinfo, ct);
88be4c09 1670 err = 0;
fd7462de 1671 } else
88be4c09
LZ
1672 err = -EBUSY;
1673 } else {
1674 /* we cannot set a helper for an existing conntrack */
1675 err = -EOPNOTSUPP;
ceceae1b 1676 }
df293bbb 1677
88be4c09
LZ
1678 rcu_read_unlock();
1679 return err;
c1d10adb
PNA
1680}
1681
4054ff45
PNA
1682static int ctnetlink_change_timeout(struct nf_conn *ct,
1683 const struct nlattr * const cda[])
c1d10adb 1684{
8b1836c4 1685 u64 timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
601e68e1 1686
8b1836c4
JE
1687 if (timeout > INT_MAX)
1688 timeout = INT_MAX;
1689 ct->timeout = nfct_time_stamp + (u32)timeout;
c1d10adb 1690
f330a7fd
FW
1691 if (test_bit(IPS_DYING_BIT, &ct->status))
1692 return -ETIME;
c1d10adb
PNA
1693
1694 return 0;
1695}
1696
58fc419b
AJ
1697#if defined(CONFIG_NF_CONNTRACK_MARK)
1698static void ctnetlink_change_mark(struct nf_conn *ct,
1699 const struct nlattr * const cda[])
1700{
1701 u32 mark, newmark, mask = 0;
1702
1703 if (cda[CTA_MARK_MASK])
1704 mask = ~ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
1705
1706 mark = ntohl(nla_get_be32(cda[CTA_MARK]));
1707 newmark = (ct->mark & mask) ^ mark;
1708 if (newmark != ct->mark)
1709 ct->mark = newmark;
1710}
1711#endif
1712
d0b0268f
PM
1713static const struct nla_policy protoinfo_policy[CTA_PROTOINFO_MAX+1] = {
1714 [CTA_PROTOINFO_TCP] = { .type = NLA_NESTED },
1715 [CTA_PROTOINFO_DCCP] = { .type = NLA_NESTED },
1716 [CTA_PROTOINFO_SCTP] = { .type = NLA_NESTED },
1717};
1718
4054ff45
PNA
1719static int ctnetlink_change_protoinfo(struct nf_conn *ct,
1720 const struct nlattr * const cda[])
c1d10adb 1721{
39938324 1722 const struct nlattr *attr = cda[CTA_PROTOINFO];
b3480fe0 1723 const struct nf_conntrack_l4proto *l4proto;
39938324 1724 struct nlattr *tb[CTA_PROTOINFO_MAX+1];
c1d10adb
PNA
1725 int err = 0;
1726
8cb08174
JB
1727 err = nla_parse_nested_deprecated(tb, CTA_PROTOINFO_MAX, attr,
1728 protoinfo_policy, NULL);
130ffbc2
DB
1729 if (err < 0)
1730 return err;
c1d10adb 1731
4a60dc74 1732 l4proto = nf_ct_l4proto_find(nf_ct_protonum(ct));
fdf70832
PM
1733 if (l4proto->from_nlattr)
1734 err = l4proto->from_nlattr(tb, ct);
c1d10adb
PNA
1735
1736 return err;
1737}
1738
41d73ec0
PM
1739static const struct nla_policy seqadj_policy[CTA_SEQADJ_MAX+1] = {
1740 [CTA_SEQADJ_CORRECTION_POS] = { .type = NLA_U32 },
1741 [CTA_SEQADJ_OFFSET_BEFORE] = { .type = NLA_U32 },
1742 [CTA_SEQADJ_OFFSET_AFTER] = { .type = NLA_U32 },
d0b0268f
PM
1743};
1744
4054ff45
PNA
1745static int change_seq_adj(struct nf_ct_seqadj *seq,
1746 const struct nlattr * const attr)
13eae15a 1747{
130ffbc2 1748 int err;
41d73ec0 1749 struct nlattr *cda[CTA_SEQADJ_MAX+1];
13eae15a 1750
8cb08174
JB
1751 err = nla_parse_nested_deprecated(cda, CTA_SEQADJ_MAX, attr,
1752 seqadj_policy, NULL);
130ffbc2
DB
1753 if (err < 0)
1754 return err;
13eae15a 1755
41d73ec0 1756 if (!cda[CTA_SEQADJ_CORRECTION_POS])
13eae15a
PNA
1757 return -EINVAL;
1758
41d73ec0
PM
1759 seq->correction_pos =
1760 ntohl(nla_get_be32(cda[CTA_SEQADJ_CORRECTION_POS]));
13eae15a 1761
41d73ec0 1762 if (!cda[CTA_SEQADJ_OFFSET_BEFORE])
13eae15a
PNA
1763 return -EINVAL;
1764
41d73ec0
PM
1765 seq->offset_before =
1766 ntohl(nla_get_be32(cda[CTA_SEQADJ_OFFSET_BEFORE]));
13eae15a 1767
41d73ec0 1768 if (!cda[CTA_SEQADJ_OFFSET_AFTER])
13eae15a
PNA
1769 return -EINVAL;
1770
41d73ec0
PM
1771 seq->offset_after =
1772 ntohl(nla_get_be32(cda[CTA_SEQADJ_OFFSET_AFTER]));
13eae15a
PNA
1773
1774 return 0;
1775}
1776
1777static int
41d73ec0
PM
1778ctnetlink_change_seq_adj(struct nf_conn *ct,
1779 const struct nlattr * const cda[])
13eae15a 1780{
41d73ec0 1781 struct nf_conn_seqadj *seqadj = nfct_seqadj(ct);
13eae15a 1782 int ret = 0;
13eae15a 1783
41d73ec0 1784 if (!seqadj)
13eae15a
PNA
1785 return 0;
1786
64f3967c 1787 spin_lock_bh(&ct->lock);
41d73ec0
PM
1788 if (cda[CTA_SEQ_ADJ_ORIG]) {
1789 ret = change_seq_adj(&seqadj->seq[IP_CT_DIR_ORIGINAL],
1790 cda[CTA_SEQ_ADJ_ORIG]);
13eae15a 1791 if (ret < 0)
64f3967c 1792 goto err;
13eae15a 1793
53b56da8 1794 set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
13eae15a
PNA
1795 }
1796
41d73ec0
PM
1797 if (cda[CTA_SEQ_ADJ_REPLY]) {
1798 ret = change_seq_adj(&seqadj->seq[IP_CT_DIR_REPLY],
1799 cda[CTA_SEQ_ADJ_REPLY]);
13eae15a 1800 if (ret < 0)
64f3967c 1801 goto err;
13eae15a 1802
53b56da8 1803 set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
13eae15a
PNA
1804 }
1805
64f3967c 1806 spin_unlock_bh(&ct->lock);
13eae15a 1807 return 0;
64f3967c
LZ
1808err:
1809 spin_unlock_bh(&ct->lock);
1810 return ret;
13eae15a 1811}
13eae15a 1812
20710b3b
PNA
1813static const struct nla_policy synproxy_policy[CTA_SYNPROXY_MAX + 1] = {
1814 [CTA_SYNPROXY_ISN] = { .type = NLA_U32 },
1815 [CTA_SYNPROXY_ITS] = { .type = NLA_U32 },
1816 [CTA_SYNPROXY_TSOFF] = { .type = NLA_U32 },
1817};
1818
1819static int ctnetlink_change_synproxy(struct nf_conn *ct,
1820 const struct nlattr * const cda[])
1821{
1822 struct nf_conn_synproxy *synproxy = nfct_synproxy(ct);
1823 struct nlattr *tb[CTA_SYNPROXY_MAX + 1];
1824 int err;
1825
1826 if (!synproxy)
1827 return 0;
1828
8cb08174
JB
1829 err = nla_parse_nested_deprecated(tb, CTA_SYNPROXY_MAX,
1830 cda[CTA_SYNPROXY], synproxy_policy,
1831 NULL);
20710b3b
PNA
1832 if (err < 0)
1833 return err;
1834
1835 if (!tb[CTA_SYNPROXY_ISN] ||
1836 !tb[CTA_SYNPROXY_ITS] ||
1837 !tb[CTA_SYNPROXY_TSOFF])
1838 return -EINVAL;
1839
1840 synproxy->isn = ntohl(nla_get_be32(tb[CTA_SYNPROXY_ISN]));
1841 synproxy->its = ntohl(nla_get_be32(tb[CTA_SYNPROXY_ITS]));
1842 synproxy->tsoff = ntohl(nla_get_be32(tb[CTA_SYNPROXY_TSOFF]));
1843
1844 return 0;
1845}
1846
9b21f6a9
FW
1847static int
1848ctnetlink_attach_labels(struct nf_conn *ct, const struct nlattr * const cda[])
1849{
1850#ifdef CONFIG_NF_CONNTRACK_LABELS
1851 size_t len = nla_len(cda[CTA_LABELS]);
1852 const void *mask = cda[CTA_LABELS_MASK];
1853
1854 if (len & (sizeof(u32)-1)) /* must be multiple of u32 */
1855 return -EINVAL;
1856
1857 if (mask) {
1858 if (nla_len(cda[CTA_LABELS_MASK]) == 0 ||
1859 nla_len(cda[CTA_LABELS_MASK]) != len)
1860 return -EINVAL;
1861 mask = nla_data(cda[CTA_LABELS_MASK]);
1862 }
1863
1864 len /= sizeof(u32);
1865
1866 return nf_connlabels_replace(ct, nla_data(cda[CTA_LABELS]), mask, len);
1867#else
1868 return -EOPNOTSUPP;
1869#endif
1870}
1871
c1d10adb 1872static int
39938324
PM
1873ctnetlink_change_conntrack(struct nf_conn *ct,
1874 const struct nlattr * const cda[])
c1d10adb
PNA
1875{
1876 int err;
1877
e098360f
PNA
1878 /* only allow NAT changes and master assignation for new conntracks */
1879 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST] || cda[CTA_TUPLE_MASTER])
1880 return -EOPNOTSUPP;
1881
df6fb868 1882 if (cda[CTA_HELP]) {
c1d10adb
PNA
1883 err = ctnetlink_change_helper(ct, cda);
1884 if (err < 0)
1885 return err;
1886 }
1887
df6fb868 1888 if (cda[CTA_TIMEOUT]) {
c1d10adb
PNA
1889 err = ctnetlink_change_timeout(ct, cda);
1890 if (err < 0)
1891 return err;
1892 }
1893
df6fb868 1894 if (cda[CTA_STATUS]) {
c1d10adb
PNA
1895 err = ctnetlink_change_status(ct, cda);
1896 if (err < 0)
1897 return err;
1898 }
1899
df6fb868 1900 if (cda[CTA_PROTOINFO]) {
c1d10adb
PNA
1901 err = ctnetlink_change_protoinfo(ct, cda);
1902 if (err < 0)
1903 return err;
1904 }
1905
bcd1e830 1906#if defined(CONFIG_NF_CONNTRACK_MARK)
df6fb868 1907 if (cda[CTA_MARK])
58fc419b 1908 ctnetlink_change_mark(ct, cda);
c1d10adb
PNA
1909#endif
1910
41d73ec0
PM
1911 if (cda[CTA_SEQ_ADJ_ORIG] || cda[CTA_SEQ_ADJ_REPLY]) {
1912 err = ctnetlink_change_seq_adj(ct, cda);
13eae15a
PNA
1913 if (err < 0)
1914 return err;
1915 }
41d73ec0 1916
20710b3b
PNA
1917 if (cda[CTA_SYNPROXY]) {
1918 err = ctnetlink_change_synproxy(ct, cda);
1919 if (err < 0)
1920 return err;
1921 }
1922
9b21f6a9
FW
1923 if (cda[CTA_LABELS]) {
1924 err = ctnetlink_attach_labels(ct, cda);
1925 if (err < 0)
1926 return err;
1927 }
13eae15a 1928
c1d10adb
PNA
1929 return 0;
1930}
1931
f0a3c086 1932static struct nf_conn *
308ac914
DB
1933ctnetlink_create_conntrack(struct net *net,
1934 const struct nf_conntrack_zone *zone,
9592a5c0 1935 const struct nlattr * const cda[],
c1d10adb 1936 struct nf_conntrack_tuple *otuple,
5faa1f4c 1937 struct nf_conntrack_tuple *rtuple,
7ec47496 1938 u8 u3)
c1d10adb
PNA
1939{
1940 struct nf_conn *ct;
1941 int err = -EINVAL;
ceceae1b 1942 struct nf_conntrack_helper *helper;
315c34da 1943 struct nf_conn_tstamp *tstamp;
8b1836c4 1944 u64 timeout;
c1d10adb 1945
ef00f89f 1946 ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC);
cd7fcbf1 1947 if (IS_ERR(ct))
f0a3c086 1948 return ERR_PTR(-ENOMEM);
c1d10adb 1949
df6fb868 1950 if (!cda[CTA_TIMEOUT])
0f5b3e85 1951 goto err1;
c1d10adb 1952
8b1836c4
JE
1953 timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
1954 if (timeout > INT_MAX)
1955 timeout = INT_MAX;
1956 ct->timeout = (u32)timeout + nfct_time_stamp;
c1d10adb 1957
1575e7ea 1958 rcu_read_lock();
226c0c0e 1959 if (cda[CTA_HELP]) {
29fe1b48 1960 char *helpname = NULL;
ae243bee
PNA
1961 struct nlattr *helpinfo = NULL;
1962
1963 err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo);
0f5b3e85
PM
1964 if (err < 0)
1965 goto err2;
226c0c0e 1966
794e6871
PM
1967 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
1968 nf_ct_protonum(ct));
226c0c0e
PNA
1969 if (helper == NULL) {
1970 rcu_read_unlock();
1971#ifdef CONFIG_MODULES
1972 if (request_module("nfct-helper-%s", helpname) < 0) {
1973 err = -EOPNOTSUPP;
0f5b3e85 1974 goto err1;
226c0c0e
PNA
1975 }
1976
1977 rcu_read_lock();
794e6871
PM
1978 helper = __nf_conntrack_helper_find(helpname,
1979 nf_ct_l3num(ct),
1980 nf_ct_protonum(ct));
226c0c0e 1981 if (helper) {
226c0c0e 1982 err = -EAGAIN;
0f5b3e85 1983 goto err2;
226c0c0e
PNA
1984 }
1985 rcu_read_unlock();
1986#endif
1987 err = -EOPNOTSUPP;
0f5b3e85 1988 goto err1;
226c0c0e
PNA
1989 } else {
1990 struct nf_conn_help *help;
1991
440534d3 1992 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
226c0c0e 1993 if (help == NULL) {
226c0c0e 1994 err = -ENOMEM;
0f5b3e85 1995 goto err2;
226c0c0e 1996 }
ae243bee 1997 /* set private helper data if allowed. */
7be54ca4 1998 if (helper->from_nlattr)
ae243bee 1999 helper->from_nlattr(helpinfo, ct);
226c0c0e
PNA
2000
2001 /* not in hash table yet so not strictly necessary */
a9b3cd7f 2002 RCU_INIT_POINTER(help->helper, helper);
226c0c0e
PNA
2003 }
2004 } else {
2005 /* try an implicit helper assignation */
b2a15a60 2006 err = __nf_ct_try_assign_helper(ct, NULL, GFP_ATOMIC);
0f5b3e85
PM
2007 if (err < 0)
2008 goto err2;
1575e7ea
PNA
2009 }
2010
0eba801b
PNA
2011 err = ctnetlink_setup_nat(ct, cda);
2012 if (err < 0)
2013 goto err2;
e6a7d3c0 2014
a88e22ad 2015 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
a992ca2a 2016 nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
a88e22ad 2017 nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
c539f017 2018 nf_ct_labels_ext_add(ct);
87e94dbc
EL
2019 nfct_seqadj_ext_add(ct);
2020 nfct_synproxy_ext_add(ct);
c539f017 2021
a88e22ad
PNA
2022 /* we must add conntrack extensions before confirmation. */
2023 ct->status |= IPS_CONFIRMED;
2024
2025 if (cda[CTA_STATUS]) {
2026 err = ctnetlink_change_status(ct, cda);
0f5b3e85
PM
2027 if (err < 0)
2028 goto err2;
bbb3357d 2029 }
c1d10adb 2030
41d73ec0
PM
2031 if (cda[CTA_SEQ_ADJ_ORIG] || cda[CTA_SEQ_ADJ_REPLY]) {
2032 err = ctnetlink_change_seq_adj(ct, cda);
0f5b3e85
PM
2033 if (err < 0)
2034 goto err2;
c969aa7d 2035 }
c969aa7d 2036
e5fc9e7a 2037 memset(&ct->proto, 0, sizeof(ct->proto));
df6fb868 2038 if (cda[CTA_PROTOINFO]) {
c1d10adb 2039 err = ctnetlink_change_protoinfo(ct, cda);
0f5b3e85
PM
2040 if (err < 0)
2041 goto err2;
c1d10adb
PNA
2042 }
2043
20710b3b
PNA
2044 if (cda[CTA_SYNPROXY]) {
2045 err = ctnetlink_change_synproxy(ct, cda);
2046 if (err < 0)
2047 goto err2;
2048 }
2049
bcd1e830 2050#if defined(CONFIG_NF_CONNTRACK_MARK)
df6fb868 2051 if (cda[CTA_MARK])
58fc419b 2052 ctnetlink_change_mark(ct, cda);
c1d10adb
PNA
2053#endif
2054
5faa1f4c 2055 /* setup master conntrack: this is a confirmed expectation */
7ec47496
PNA
2056 if (cda[CTA_TUPLE_MASTER]) {
2057 struct nf_conntrack_tuple master;
2058 struct nf_conntrack_tuple_hash *master_h;
2059 struct nf_conn *master_ct;
2060
deedb590
DB
2061 err = ctnetlink_parse_tuple(cda, &master, CTA_TUPLE_MASTER,
2062 u3, NULL);
7ec47496 2063 if (err < 0)
0f5b3e85 2064 goto err2;
7ec47496 2065
ef00f89f 2066 master_h = nf_conntrack_find_get(net, zone, &master);
7ec47496
PNA
2067 if (master_h == NULL) {
2068 err = -ENOENT;
0f5b3e85 2069 goto err2;
7ec47496
PNA
2070 }
2071 master_ct = nf_ct_tuplehash_to_ctrack(master_h);
f2a89004 2072 __set_bit(IPS_EXPECTED_BIT, &ct->status);
5faa1f4c 2073 ct->master = master_ct;
f2a89004 2074 }
315c34da
PNA
2075 tstamp = nf_conn_tstamp_find(ct);
2076 if (tstamp)
d2de875c 2077 tstamp->start = ktime_get_real_ns();
5faa1f4c 2078
7d367e06
JK
2079 err = nf_conntrack_hash_check_insert(ct);
2080 if (err < 0)
2081 goto err2;
2082
58a3c9bb 2083 rcu_read_unlock();
dafc741c 2084
f0a3c086 2085 return ct;
c1d10adb 2086
0f5b3e85
PM
2087err2:
2088 rcu_read_unlock();
2089err1:
c1d10adb 2090 nf_conntrack_free(ct);
f0a3c086 2091 return ERR_PTR(err);
c1d10adb
PNA
2092}
2093
7b8002a1
PNA
2094static int ctnetlink_new_conntrack(struct net *net, struct sock *ctnl,
2095 struct sk_buff *skb,
2096 const struct nlmsghdr *nlh,
04ba724b
PNA
2097 const struct nlattr * const cda[],
2098 struct netlink_ext_ack *extack)
c1d10adb
PNA
2099{
2100 struct nf_conntrack_tuple otuple, rtuple;
2101 struct nf_conntrack_tuple_hash *h = NULL;
96bcf938 2102 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
7d367e06 2103 struct nf_conn *ct;
c1d10adb 2104 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 2105 struct nf_conntrack_zone zone;
ef00f89f
PM
2106 int err;
2107
2108 err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone);
2109 if (err < 0)
2110 return err;
c1d10adb 2111
df6fb868 2112 if (cda[CTA_TUPLE_ORIG]) {
deedb590
DB
2113 err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG,
2114 u3, &zone);
c1d10adb
PNA
2115 if (err < 0)
2116 return err;
2117 }
2118
df6fb868 2119 if (cda[CTA_TUPLE_REPLY]) {
deedb590
DB
2120 err = ctnetlink_parse_tuple(cda, &rtuple, CTA_TUPLE_REPLY,
2121 u3, &zone);
c1d10adb
PNA
2122 if (err < 0)
2123 return err;
2124 }
2125
df6fb868 2126 if (cda[CTA_TUPLE_ORIG])
308ac914 2127 h = nf_conntrack_find_get(net, &zone, &otuple);
df6fb868 2128 else if (cda[CTA_TUPLE_REPLY])
308ac914 2129 h = nf_conntrack_find_get(net, &zone, &rtuple);
c1d10adb
PNA
2130
2131 if (h == NULL) {
c1d10adb 2132 err = -ENOENT;
f0a3c086 2133 if (nlh->nlmsg_flags & NLM_F_CREATE) {
fecc1133 2134 enum ip_conntrack_events events;
5faa1f4c 2135
442fad94
FW
2136 if (!cda[CTA_TUPLE_ORIG] || !cda[CTA_TUPLE_REPLY])
2137 return -EINVAL;
aa0c2c68
LZ
2138 if (otuple.dst.protonum != rtuple.dst.protonum)
2139 return -EINVAL;
442fad94 2140
308ac914 2141 ct = ctnetlink_create_conntrack(net, &zone, cda, &otuple,
f0a3c086 2142 &rtuple, u3);
7d367e06
JK
2143 if (IS_ERR(ct))
2144 return PTR_ERR(ct);
2145
f0a3c086 2146 err = 0;
fecc1133 2147 if (test_bit(IPS_EXPECTED_BIT, &ct->status))
97aae0df 2148 events = 1 << IPCT_RELATED;
fecc1133 2149 else
97aae0df 2150 events = 1 << IPCT_NEW;
fecc1133 2151
9b21f6a9
FW
2152 if (cda[CTA_LABELS] &&
2153 ctnetlink_attach_labels(ct, cda) == 0)
2154 events |= (1 << IPCT_LABEL);
2155
858b3133
PM
2156 nf_conntrack_eventmask_report((1 << IPCT_REPLY) |
2157 (1 << IPCT_ASSURED) |
a0891aa6
PNA
2158 (1 << IPCT_HELPER) |
2159 (1 << IPCT_PROTOINFO) |
41d73ec0 2160 (1 << IPCT_SEQADJ) |
20710b3b
PNA
2161 (1 << IPCT_MARK) |
2162 (1 << IPCT_SYNPROXY) |
2163 events,
15e47304 2164 ct, NETLINK_CB(skb).portid,
a0891aa6 2165 nlmsg_report(nlh));
f0a3c086 2166 nf_ct_put(ct);
7d367e06 2167 }
5faa1f4c 2168
c1d10adb
PNA
2169 return err;
2170 }
2171 /* implicit 'else' */
2172
c1d10adb 2173 err = -EEXIST;
7d367e06 2174 ct = nf_ct_tuplehash_to_ctrack(h);
ff4ca827 2175 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
19abb7b0
PNA
2176 err = ctnetlink_change_conntrack(ct, cda);
2177 if (err == 0) {
858b3133
PM
2178 nf_conntrack_eventmask_report((1 << IPCT_REPLY) |
2179 (1 << IPCT_ASSURED) |
a0891aa6 2180 (1 << IPCT_HELPER) |
797a7d66 2181 (1 << IPCT_LABEL) |
a0891aa6 2182 (1 << IPCT_PROTOINFO) |
41d73ec0 2183 (1 << IPCT_SEQADJ) |
20710b3b
PNA
2184 (1 << IPCT_MARK) |
2185 (1 << IPCT_SYNPROXY),
15e47304 2186 ct, NETLINK_CB(skb).portid,
a0891aa6 2187 nlmsg_report(nlh));
7d367e06 2188 }
ff4ca827 2189 }
c1d10adb 2190
7d367e06 2191 nf_ct_put(ct);
c1d10adb
PNA
2192 return err;
2193}
2194
392025f8 2195static int
15e47304 2196ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
392025f8
PNA
2197 __u16 cpu, const struct ip_conntrack_stat *st)
2198{
2199 struct nlmsghdr *nlh;
2200 struct nfgenmsg *nfmsg;
15e47304 2201 unsigned int flags = portid ? NLM_F_MULTI : 0, event;
392025f8 2202
dedb67c4
PNA
2203 event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK,
2204 IPCTNL_MSG_CT_GET_STATS_CPU);
15e47304 2205 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
392025f8
PNA
2206 if (nlh == NULL)
2207 goto nlmsg_failure;
2208
2209 nfmsg = nlmsg_data(nlh);
2210 nfmsg->nfgen_family = AF_UNSPEC;
2211 nfmsg->version = NFNETLINK_V0;
2212 nfmsg->res_id = htons(cpu);
2213
8e8118f8 2214 if (nla_put_be32(skb, CTA_STATS_FOUND, htonl(st->found)) ||
392025f8
PNA
2215 nla_put_be32(skb, CTA_STATS_INVALID, htonl(st->invalid)) ||
2216 nla_put_be32(skb, CTA_STATS_IGNORE, htonl(st->ignore)) ||
392025f8
PNA
2217 nla_put_be32(skb, CTA_STATS_INSERT, htonl(st->insert)) ||
2218 nla_put_be32(skb, CTA_STATS_INSERT_FAILED,
2219 htonl(st->insert_failed)) ||
2220 nla_put_be32(skb, CTA_STATS_DROP, htonl(st->drop)) ||
2221 nla_put_be32(skb, CTA_STATS_EARLY_DROP, htonl(st->early_drop)) ||
2222 nla_put_be32(skb, CTA_STATS_ERROR, htonl(st->error)) ||
2223 nla_put_be32(skb, CTA_STATS_SEARCH_RESTART,
2224 htonl(st->search_restart)))
2225 goto nla_put_failure;
2226
2227 nlmsg_end(skb, nlh);
2228 return skb->len;
2229
2230nla_put_failure:
2231nlmsg_failure:
2232 nlmsg_cancel(skb, nlh);
2233 return -1;
2234}
2235
2236static int
2237ctnetlink_ct_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
2238{
2239 int cpu;
2240 struct net *net = sock_net(skb->sk);
2241
2242 if (cb->args[0] == nr_cpu_ids)
2243 return 0;
2244
2245 for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
2246 const struct ip_conntrack_stat *st;
2247
2248 if (!cpu_possible(cpu))
2249 continue;
2250
2251 st = per_cpu_ptr(net->ct.stat, cpu);
2252 if (ctnetlink_ct_stat_cpu_fill_info(skb,
15e47304 2253 NETLINK_CB(cb->skb).portid,
392025f8
PNA
2254 cb->nlh->nlmsg_seq,
2255 cpu, st) < 0)
2256 break;
2257 }
2258 cb->args[0] = cpu;
2259
2260 return skb->len;
2261}
2262
7b8002a1
PNA
2263static int ctnetlink_stat_ct_cpu(struct net *net, struct sock *ctnl,
2264 struct sk_buff *skb,
2265 const struct nlmsghdr *nlh,
04ba724b
PNA
2266 const struct nlattr * const cda[],
2267 struct netlink_ext_ack *extack)
392025f8
PNA
2268{
2269 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2270 struct netlink_dump_control c = {
2271 .dump = ctnetlink_ct_stat_cpu_dump,
2272 };
2273 return netlink_dump_start(ctnl, skb, nlh, &c);
2274 }
2275
2276 return 0;
2277}
2278
2279static int
15e47304 2280ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
392025f8
PNA
2281 struct net *net)
2282{
2283 struct nlmsghdr *nlh;
2284 struct nfgenmsg *nfmsg;
15e47304 2285 unsigned int flags = portid ? NLM_F_MULTI : 0, event;
392025f8
PNA
2286 unsigned int nr_conntracks = atomic_read(&net->ct.count);
2287
dedb67c4 2288 event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK, IPCTNL_MSG_CT_GET_STATS);
15e47304 2289 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
392025f8
PNA
2290 if (nlh == NULL)
2291 goto nlmsg_failure;
2292
2293 nfmsg = nlmsg_data(nlh);
2294 nfmsg->nfgen_family = AF_UNSPEC;
2295 nfmsg->version = NFNETLINK_V0;
2296 nfmsg->res_id = 0;
2297
2298 if (nla_put_be32(skb, CTA_STATS_GLOBAL_ENTRIES, htonl(nr_conntracks)))
2299 goto nla_put_failure;
2300
538c5672
FF
2301 if (nla_put_be32(skb, CTA_STATS_GLOBAL_MAX_ENTRIES, htonl(nf_conntrack_max)))
2302 goto nla_put_failure;
2303
392025f8
PNA
2304 nlmsg_end(skb, nlh);
2305 return skb->len;
2306
2307nla_put_failure:
2308nlmsg_failure:
2309 nlmsg_cancel(skb, nlh);
2310 return -1;
2311}
2312
7b8002a1
PNA
2313static int ctnetlink_stat_ct(struct net *net, struct sock *ctnl,
2314 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
2315 const struct nlattr * const cda[],
2316 struct netlink_ext_ack *extack)
392025f8
PNA
2317{
2318 struct sk_buff *skb2;
2319 int err;
2320
2321 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2322 if (skb2 == NULL)
2323 return -ENOMEM;
2324
15e47304 2325 err = ctnetlink_stat_ct_fill_info(skb2, NETLINK_CB(skb).portid,
392025f8
PNA
2326 nlh->nlmsg_seq,
2327 NFNL_MSG_TYPE(nlh->nlmsg_type),
2328 sock_net(skb->sk));
2329 if (err <= 0)
2330 goto free;
2331
15e47304 2332 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
392025f8
PNA
2333 if (err < 0)
2334 goto out;
2335
2336 return 0;
2337
2338free:
2339 kfree_skb(skb2);
2340out:
2341 /* this avoids a loop in nfnetlink. */
2342 return err == -EAGAIN ? -ENOBUFS : err;
2343}
2344
bd077937
PNA
2345static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
2346 [CTA_EXPECT_MASTER] = { .type = NLA_NESTED },
2347 [CTA_EXPECT_TUPLE] = { .type = NLA_NESTED },
2348 [CTA_EXPECT_MASK] = { .type = NLA_NESTED },
2349 [CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 },
2350 [CTA_EXPECT_ID] = { .type = NLA_U32 },
2351 [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING,
2352 .len = NF_CT_HELPER_NAME_LEN - 1 },
2353 [CTA_EXPECT_ZONE] = { .type = NLA_U16 },
2354 [CTA_EXPECT_FLAGS] = { .type = NLA_U32 },
2355 [CTA_EXPECT_CLASS] = { .type = NLA_U32 },
2356 [CTA_EXPECT_NAT] = { .type = NLA_NESTED },
2357 [CTA_EXPECT_FN] = { .type = NLA_NUL_STRING },
2358};
2359
2360static struct nf_conntrack_expect *
2361ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct,
2362 struct nf_conntrack_helper *helper,
2363 struct nf_conntrack_tuple *tuple,
2364 struct nf_conntrack_tuple *mask);
2365
83f3e94d 2366#ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
9cb01766 2367static size_t
a4b4766c 2368ctnetlink_glue_build_size(const struct nf_conn *ct)
9cb01766
PNA
2369{
2370 return 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */
2371 + 3 * nla_total_size(0) /* CTA_TUPLE_IP */
2372 + 3 * nla_total_size(0) /* CTA_TUPLE_PROTO */
2373 + 3 * nla_total_size(sizeof(u_int8_t)) /* CTA_PROTO_NUM */
2374 + nla_total_size(sizeof(u_int32_t)) /* CTA_ID */
2375 + nla_total_size(sizeof(u_int32_t)) /* CTA_STATUS */
2376 + nla_total_size(sizeof(u_int32_t)) /* CTA_TIMEOUT */
2377 + nla_total_size(0) /* CTA_PROTOINFO */
2378 + nla_total_size(0) /* CTA_HELP */
2379 + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */
2380 + ctnetlink_secctx_size(ct)
4806e975 2381#if IS_ENABLED(CONFIG_NF_NAT)
9cb01766
PNA
2382 + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */
2383 + 6 * nla_total_size(sizeof(u_int32_t)) /* CTA_NAT_SEQ_OFFSET */
2384#endif
2385#ifdef CONFIG_NF_CONNTRACK_MARK
2386 + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
4a001068
KM
2387#endif
2388#ifdef CONFIG_NF_CONNTRACK_ZONES
deedb590 2389 + nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE|CTA_TUPLE_ZONE */
9cb01766
PNA
2390#endif
2391 + ctnetlink_proto_size(ct)
2392 ;
2393}
2394
224a0597 2395static struct nf_conn *ctnetlink_glue_get_ct(const struct sk_buff *skb,
a4b4766c 2396 enum ip_conntrack_info *ctinfo)
b7bd1809 2397{
ab8bc7ed 2398 return nf_ct_get(skb, ctinfo);
b7bd1809
PNA
2399}
2400
a4b4766c 2401static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
9cb01766 2402{
308ac914 2403 const struct nf_conntrack_zone *zone;
9cb01766
PNA
2404 struct nlattr *nest_parms;
2405
deedb590
DB
2406 zone = nf_ct_zone(ct);
2407
ae0be8de 2408 nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG);
9cb01766
PNA
2409 if (!nest_parms)
2410 goto nla_put_failure;
2411 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
2412 goto nla_put_failure;
deedb590
DB
2413 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
2414 NF_CT_ZONE_DIR_ORIG) < 0)
2415 goto nla_put_failure;
9cb01766
PNA
2416 nla_nest_end(skb, nest_parms);
2417
ae0be8de 2418 nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY);
9cb01766
PNA
2419 if (!nest_parms)
2420 goto nla_put_failure;
2421 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0)
2422 goto nla_put_failure;
deedb590
DB
2423 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
2424 NF_CT_ZONE_DIR_REPL) < 0)
2425 goto nla_put_failure;
9cb01766
PNA
2426 nla_nest_end(skb, nest_parms);
2427
deedb590
DB
2428 if (ctnetlink_dump_zone_id(skb, CTA_ZONE, zone,
2429 NF_CT_DEFAULT_ZONE_DIR) < 0)
308ac914 2430 goto nla_put_failure;
9cb01766
PNA
2431
2432 if (ctnetlink_dump_id(skb, ct) < 0)
2433 goto nla_put_failure;
2434
2435 if (ctnetlink_dump_status(skb, ct) < 0)
2436 goto nla_put_failure;
2437
2438 if (ctnetlink_dump_timeout(skb, ct) < 0)
2439 goto nla_put_failure;
2440
2441 if (ctnetlink_dump_protoinfo(skb, ct) < 0)
2442 goto nla_put_failure;
2443
2444 if (ctnetlink_dump_helpinfo(skb, ct) < 0)
2445 goto nla_put_failure;
2446
2447#ifdef CONFIG_NF_CONNTRACK_SECMARK
2448 if (ct->secmark && ctnetlink_dump_secctx(skb, ct) < 0)
2449 goto nla_put_failure;
2450#endif
2451 if (ct->master && ctnetlink_dump_master(skb, ct) < 0)
2452 goto nla_put_failure;
2453
2454 if ((ct->status & IPS_SEQ_ADJUST) &&
41d73ec0 2455 ctnetlink_dump_ct_seq_adj(skb, ct) < 0)
9cb01766
PNA
2456 goto nla_put_failure;
2457
20710b3b
PNA
2458 if (ctnetlink_dump_ct_synproxy(skb, ct) < 0)
2459 goto nla_put_failure;
2460
9cb01766
PNA
2461#ifdef CONFIG_NF_CONNTRACK_MARK
2462 if (ct->mark && ctnetlink_dump_mark(skb, ct) < 0)
2463 goto nla_put_failure;
2464#endif
0ceabd83
FW
2465 if (ctnetlink_dump_labels(skb, ct) < 0)
2466 goto nla_put_failure;
9cb01766
PNA
2467 return 0;
2468
2469nla_put_failure:
9cb01766
PNA
2470 return -ENOSPC;
2471}
2472
b7bd1809 2473static int
a4b4766c
KM
2474ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct,
2475 enum ip_conntrack_info ctinfo,
2476 u_int16_t ct_attr, u_int16_t ct_info_attr)
b7bd1809
PNA
2477{
2478 struct nlattr *nest_parms;
2479
ae0be8de 2480 nest_parms = nla_nest_start(skb, ct_attr);
b7bd1809
PNA
2481 if (!nest_parms)
2482 goto nla_put_failure;
2483
a4b4766c 2484 if (__ctnetlink_glue_build(skb, ct) < 0)
b7bd1809
PNA
2485 goto nla_put_failure;
2486
2487 nla_nest_end(skb, nest_parms);
2488
2489 if (nla_put_be32(skb, ct_info_attr, htonl(ctinfo)))
2490 goto nla_put_failure;
2491
2492 return 0;
2493
2494nla_put_failure:
2495 return -ENOSPC;
2496}
2497
a963d710
KC
2498static int
2499ctnetlink_update_status(struct nf_conn *ct, const struct nlattr * const cda[])
2500{
2501 unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS]));
2502 unsigned long d = ct->status ^ status;
2503
2504 if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
2505 /* SEEN_REPLY bit can only be set */
2506 return -EBUSY;
2507
2508 if (d & IPS_ASSURED && !(status & IPS_ASSURED))
2509 /* ASSURED bit can only be set */
2510 return -EBUSY;
2511
2512 /* This check is less strict than ctnetlink_change_status()
2513 * because callers often flip IPS_EXPECTED bits when sending
2514 * an NFQA_CT attribute to the kernel. So ignore the
53b56da8
LZ
2515 * unchangeable bits but do not error out. Also user programs
2516 * are allowed to clear the bits that they are allowed to change.
a963d710 2517 */
53b56da8 2518 __ctnetlink_change_status(ct, status, ~status);
a963d710
KC
2519 return 0;
2520}
2521
9cb01766 2522static int
a4b4766c 2523ctnetlink_glue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
9cb01766
PNA
2524{
2525 int err;
2526
2527 if (cda[CTA_TIMEOUT]) {
2528 err = ctnetlink_change_timeout(ct, cda);
2529 if (err < 0)
2530 return err;
2531 }
2532 if (cda[CTA_STATUS]) {
a963d710 2533 err = ctnetlink_update_status(ct, cda);
9cb01766
PNA
2534 if (err < 0)
2535 return err;
2536 }
2537 if (cda[CTA_HELP]) {
2538 err = ctnetlink_change_helper(ct, cda);
2539 if (err < 0)
2540 return err;
2541 }
9b21f6a9
FW
2542 if (cda[CTA_LABELS]) {
2543 err = ctnetlink_attach_labels(ct, cda);
2544 if (err < 0)
2545 return err;
2546 }
9cb01766 2547#if defined(CONFIG_NF_CONNTRACK_MARK)
534473c6 2548 if (cda[CTA_MARK]) {
58fc419b 2549 ctnetlink_change_mark(ct, cda);
534473c6 2550 }
9cb01766
PNA
2551#endif
2552 return 0;
2553}
2554
2555static int
a4b4766c 2556ctnetlink_glue_parse(const struct nlattr *attr, struct nf_conn *ct)
9cb01766
PNA
2557{
2558 struct nlattr *cda[CTA_MAX+1];
68e035c9 2559 int ret;
9cb01766 2560
8cb08174
JB
2561 ret = nla_parse_nested_deprecated(cda, CTA_MAX, attr, ct_nla_policy,
2562 NULL);
130ffbc2
DB
2563 if (ret < 0)
2564 return ret;
9cb01766 2565
88be4c09 2566 return ctnetlink_glue_parse_ct((const struct nlattr **)cda, ct);
9cb01766
PNA
2567}
2568
a4b4766c
KM
2569static int ctnetlink_glue_exp_parse(const struct nlattr * const *cda,
2570 const struct nf_conn *ct,
2571 struct nf_conntrack_tuple *tuple,
2572 struct nf_conntrack_tuple *mask)
bd077937
PNA
2573{
2574 int err;
2575
2576 err = ctnetlink_parse_tuple(cda, tuple, CTA_EXPECT_TUPLE,
deedb590 2577 nf_ct_l3num(ct), NULL);
bd077937
PNA
2578 if (err < 0)
2579 return err;
2580
2581 return ctnetlink_parse_tuple(cda, mask, CTA_EXPECT_MASK,
deedb590 2582 nf_ct_l3num(ct), NULL);
bd077937
PNA
2583}
2584
2585static int
a4b4766c
KM
2586ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
2587 u32 portid, u32 report)
bd077937
PNA
2588{
2589 struct nlattr *cda[CTA_EXPECT_MAX+1];
2590 struct nf_conntrack_tuple tuple, mask;
b7e092c0 2591 struct nf_conntrack_helper *helper = NULL;
bd077937
PNA
2592 struct nf_conntrack_expect *exp;
2593 int err;
2594
8cb08174
JB
2595 err = nla_parse_nested_deprecated(cda, CTA_EXPECT_MAX, attr,
2596 exp_nla_policy, NULL);
bd077937
PNA
2597 if (err < 0)
2598 return err;
2599
a4b4766c
KM
2600 err = ctnetlink_glue_exp_parse((const struct nlattr * const *)cda,
2601 ct, &tuple, &mask);
bd077937
PNA
2602 if (err < 0)
2603 return err;
2604
2605 if (cda[CTA_EXPECT_HELP_NAME]) {
2606 const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
2607
2608 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
2609 nf_ct_protonum(ct));
2610 if (helper == NULL)
2611 return -EOPNOTSUPP;
2612 }
2613
2614 exp = ctnetlink_alloc_expect((const struct nlattr * const *)cda, ct,
2615 helper, &tuple, &mask);
2616 if (IS_ERR(exp))
2617 return PTR_ERR(exp);
2618
3c00fb0b 2619 err = nf_ct_expect_related_report(exp, portid, report, 0);
b18bcb00
LZ
2620 nf_ct_expect_put(exp);
2621 return err;
bd077937
PNA
2622}
2623
a4b4766c
KM
2624static void ctnetlink_glue_seqadj(struct sk_buff *skb, struct nf_conn *ct,
2625 enum ip_conntrack_info ctinfo, int diff)
b7bd1809
PNA
2626{
2627 if (!(ct->status & IPS_NAT_MASK))
2628 return;
2629
2630 nf_ct_tcp_seqadj_set(skb, ct, ctinfo, diff);
2631}
2632
a4b4766c
KM
2633static struct nfnl_ct_hook ctnetlink_glue_hook = {
2634 .get_ct = ctnetlink_glue_get_ct,
2635 .build_size = ctnetlink_glue_build_size,
2636 .build = ctnetlink_glue_build,
2637 .parse = ctnetlink_glue_parse,
2638 .attach_expect = ctnetlink_glue_attach_expect,
2639 .seq_adjust = ctnetlink_glue_seqadj,
9cb01766 2640};
83f3e94d 2641#endif /* CONFIG_NETFILTER_NETLINK_GLUE_CT */
9cb01766 2642
601e68e1
YH
2643/***********************************************************************
2644 * EXPECT
2645 ***********************************************************************/
c1d10adb 2646
4054ff45
PNA
2647static int ctnetlink_exp_dump_tuple(struct sk_buff *skb,
2648 const struct nf_conntrack_tuple *tuple,
a2b7cbdd 2649 u32 type)
c1d10adb 2650{
df6fb868 2651 struct nlattr *nest_parms;
601e68e1 2652
ae0be8de 2653 nest_parms = nla_nest_start(skb, type);
df6fb868
PM
2654 if (!nest_parms)
2655 goto nla_put_failure;
c1d10adb 2656 if (ctnetlink_dump_tuples(skb, tuple) < 0)
df6fb868
PM
2657 goto nla_put_failure;
2658 nla_nest_end(skb, nest_parms);
c1d10adb
PNA
2659
2660 return 0;
2661
df6fb868 2662nla_put_failure:
c1d10adb 2663 return -1;
601e68e1 2664}
c1d10adb 2665
4054ff45
PNA
2666static int ctnetlink_exp_dump_mask(struct sk_buff *skb,
2667 const struct nf_conntrack_tuple *tuple,
2668 const struct nf_conntrack_tuple_mask *mask)
1cde6436 2669{
b3480fe0 2670 const struct nf_conntrack_l4proto *l4proto;
d4156e8c 2671 struct nf_conntrack_tuple m;
df6fb868 2672 struct nlattr *nest_parms;
b3480fe0 2673 int ret;
d4156e8c
PM
2674
2675 memset(&m, 0xFF, sizeof(m));
d4156e8c 2676 memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3));
e578756c
PM
2677 m.src.u.all = mask->src.u.all;
2678 m.dst.protonum = tuple->dst.protonum;
d4156e8c 2679
ae0be8de 2680 nest_parms = nla_nest_start(skb, CTA_EXPECT_MASK);
df6fb868
PM
2681 if (!nest_parms)
2682 goto nla_put_failure;
1cde6436 2683
3b988ece 2684 rcu_read_lock();
f957be9d 2685 ret = ctnetlink_dump_tuples_ip(skb, &m);
3b988ece 2686 if (ret >= 0) {
4a60dc74 2687 l4proto = nf_ct_l4proto_find(tuple->dst.protonum);
48ab807c 2688 ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
3b988ece
HS
2689 }
2690 rcu_read_unlock();
2691
1cde6436 2692 if (unlikely(ret < 0))
df6fb868 2693 goto nla_put_failure;
1cde6436 2694
df6fb868 2695 nla_nest_end(skb, nest_parms);
1cde6436
PNA
2696
2697 return 0;
2698
df6fb868 2699nla_put_failure:
1cde6436
PNA
2700 return -1;
2701}
2702
c7232c99
PM
2703static const union nf_inet_addr any_addr;
2704
3c791076
FW
2705static __be32 nf_expect_get_id(const struct nf_conntrack_expect *exp)
2706{
2707 static __read_mostly siphash_key_t exp_id_seed;
2708 unsigned long a, b, c, d;
2709
2710 net_get_random_once(&exp_id_seed, sizeof(exp_id_seed));
2711
2712 a = (unsigned long)exp;
2713 b = (unsigned long)exp->helper;
2714 c = (unsigned long)exp->master;
2715 d = (unsigned long)siphash(&exp->tuple, sizeof(exp->tuple), &exp_id_seed);
2716
2717#ifdef CONFIG_64BIT
2718 return (__force __be32)siphash_4u64((u64)a, (u64)b, (u64)c, (u64)d, &exp_id_seed);
2719#else
2720 return (__force __be32)siphash_4u32((u32)a, (u32)b, (u32)c, (u32)d, &exp_id_seed);
2721#endif
2722}
2723
bb5cf80e 2724static int
c1d10adb 2725ctnetlink_exp_dump_expect(struct sk_buff *skb,
601e68e1 2726 const struct nf_conntrack_expect *exp)
c1d10adb
PNA
2727{
2728 struct nf_conn *master = exp->master;
c1216382 2729 long timeout = ((long)exp->timeout.expires - (long)jiffies) / HZ;
bc01befd 2730 struct nf_conn_help *help;
4806e975 2731#if IS_ENABLED(CONFIG_NF_NAT)
076a0ca0
PNA
2732 struct nlattr *nest_parms;
2733 struct nf_conntrack_tuple nat_tuple = {};
2734#endif
544d5c7d
PNA
2735 struct nf_ct_helper_expectfn *expfn;
2736
d978e5da
PM
2737 if (timeout < 0)
2738 timeout = 0;
c1d10adb
PNA
2739
2740 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
df6fb868 2741 goto nla_put_failure;
1cde6436 2742 if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
df6fb868 2743 goto nla_put_failure;
c1d10adb
PNA
2744 if (ctnetlink_exp_dump_tuple(skb,
2745 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
2746 CTA_EXPECT_MASTER) < 0)
df6fb868 2747 goto nla_put_failure;
601e68e1 2748
4806e975 2749#if IS_ENABLED(CONFIG_NF_NAT)
c7232c99
PM
2750 if (!nf_inet_addr_cmp(&exp->saved_addr, &any_addr) ||
2751 exp->saved_proto.all) {
ae0be8de 2752 nest_parms = nla_nest_start(skb, CTA_EXPECT_NAT);
076a0ca0
PNA
2753 if (!nest_parms)
2754 goto nla_put_failure;
2755
cc1eb431
DM
2756 if (nla_put_be32(skb, CTA_EXPECT_NAT_DIR, htonl(exp->dir)))
2757 goto nla_put_failure;
076a0ca0
PNA
2758
2759 nat_tuple.src.l3num = nf_ct_l3num(master);
c7232c99 2760 nat_tuple.src.u3 = exp->saved_addr;
076a0ca0
PNA
2761 nat_tuple.dst.protonum = nf_ct_protonum(master);
2762 nat_tuple.src.u = exp->saved_proto;
2763
2764 if (ctnetlink_exp_dump_tuple(skb, &nat_tuple,
2765 CTA_EXPECT_NAT_TUPLE) < 0)
2766 goto nla_put_failure;
2767 nla_nest_end(skb, nest_parms);
2768 }
2769#endif
cc1eb431 2770 if (nla_put_be32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)) ||
3c791076 2771 nla_put_be32(skb, CTA_EXPECT_ID, nf_expect_get_id(exp)) ||
cc1eb431
DM
2772 nla_put_be32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)) ||
2773 nla_put_be32(skb, CTA_EXPECT_CLASS, htonl(exp->class)))
2774 goto nla_put_failure;
bc01befd
PNA
2775 help = nfct_help(master);
2776 if (help) {
2777 struct nf_conntrack_helper *helper;
2778
2779 helper = rcu_dereference(help->helper);
cc1eb431
DM
2780 if (helper &&
2781 nla_put_string(skb, CTA_EXPECT_HELP_NAME, helper->name))
2782 goto nla_put_failure;
bc01befd 2783 }
544d5c7d 2784 expfn = nf_ct_helper_expectfn_find_by_symbol(exp->expectfn);
cc1eb431
DM
2785 if (expfn != NULL &&
2786 nla_put_string(skb, CTA_EXPECT_FN, expfn->name))
2787 goto nla_put_failure;
c1d10adb
PNA
2788
2789 return 0;
601e68e1 2790
df6fb868 2791nla_put_failure:
c1d10adb
PNA
2792 return -1;
2793}
2794
2795static int
15e47304 2796ctnetlink_exp_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
8b0a231d 2797 int event, const struct nf_conntrack_expect *exp)
c1d10adb
PNA
2798{
2799 struct nlmsghdr *nlh;
2800 struct nfgenmsg *nfmsg;
15e47304 2801 unsigned int flags = portid ? NLM_F_MULTI : 0;
c1d10adb 2802
dedb67c4 2803 event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_EXP, event);
15e47304 2804 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
96bcf938
PNA
2805 if (nlh == NULL)
2806 goto nlmsg_failure;
c1d10adb 2807
96bcf938 2808 nfmsg = nlmsg_data(nlh);
c1d10adb
PNA
2809 nfmsg->nfgen_family = exp->tuple.src.l3num;
2810 nfmsg->version = NFNETLINK_V0;
2811 nfmsg->res_id = 0;
2812
2813 if (ctnetlink_exp_dump_expect(skb, exp) < 0)
df6fb868 2814 goto nla_put_failure;
c1d10adb 2815
96bcf938 2816 nlmsg_end(skb, nlh);
c1d10adb
PNA
2817 return skb->len;
2818
2819nlmsg_failure:
df6fb868 2820nla_put_failure:
96bcf938 2821 nlmsg_cancel(skb, nlh);
c1d10adb
PNA
2822 return -1;
2823}
2824
2825#ifdef CONFIG_NF_CONNTRACK_EVENTS
e34d5c1a
PNA
2826static int
2827ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
c1d10adb 2828{
9592a5c0
AD
2829 struct nf_conntrack_expect *exp = item->exp;
2830 struct net *net = nf_ct_exp_net(exp);
c1d10adb
PNA
2831 struct nlmsghdr *nlh;
2832 struct nfgenmsg *nfmsg;
c1d10adb 2833 struct sk_buff *skb;
ebbf41df 2834 unsigned int type, group;
c1d10adb
PNA
2835 int flags = 0;
2836
ebbf41df
PNA
2837 if (events & (1 << IPEXP_DESTROY)) {
2838 type = IPCTNL_MSG_EXP_DELETE;
2839 group = NFNLGRP_CONNTRACK_EXP_DESTROY;
2840 } else if (events & (1 << IPEXP_NEW)) {
c1d10adb
PNA
2841 type = IPCTNL_MSG_EXP_NEW;
2842 flags = NLM_F_CREATE|NLM_F_EXCL;
ebbf41df 2843 group = NFNLGRP_CONNTRACK_EXP_NEW;
c1d10adb 2844 } else
e34d5c1a 2845 return 0;
c1d10adb 2846
ebbf41df 2847 if (!item->report && !nfnetlink_has_listeners(net, group))
e34d5c1a 2848 return 0;
b3a27bfb 2849
96bcf938
PNA
2850 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
2851 if (skb == NULL)
150ace0d 2852 goto errout;
c1d10adb 2853
dedb67c4 2854 type = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK_EXP, type);
15e47304 2855 nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags);
96bcf938
PNA
2856 if (nlh == NULL)
2857 goto nlmsg_failure;
c1d10adb 2858
96bcf938 2859 nfmsg = nlmsg_data(nlh);
c1d10adb
PNA
2860 nfmsg->nfgen_family = exp->tuple.src.l3num;
2861 nfmsg->version = NFNETLINK_V0;
2862 nfmsg->res_id = 0;
2863
2864 if (ctnetlink_exp_dump_expect(skb, exp) < 0)
df6fb868 2865 goto nla_put_failure;
c1d10adb 2866
96bcf938 2867 nlmsg_end(skb, nlh);
15e47304 2868 nfnetlink_send(skb, net, item->portid, group, item->report, GFP_ATOMIC);
e34d5c1a 2869 return 0;
c1d10adb 2870
df6fb868 2871nla_put_failure:
96bcf938 2872 nlmsg_cancel(skb, nlh);
528a3a6f 2873nlmsg_failure:
c1d10adb 2874 kfree_skb(skb);
150ace0d 2875errout:
9592a5c0 2876 nfnetlink_set_err(net, 0, 0, -ENOBUFS);
e34d5c1a 2877 return 0;
c1d10adb
PNA
2878}
2879#endif
cf6994c2
PM
2880static int ctnetlink_exp_done(struct netlink_callback *cb)
2881{
31f15875
PM
2882 if (cb->args[1])
2883 nf_ct_expect_put((struct nf_conntrack_expect *)cb->args[1]);
cf6994c2
PM
2884 return 0;
2885}
c1d10adb
PNA
2886
2887static int
2888ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
2889{
9592a5c0 2890 struct net *net = sock_net(skb->sk);
cf6994c2 2891 struct nf_conntrack_expect *exp, *last;
96bcf938 2892 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
87711cb8 2893 u_int8_t l3proto = nfmsg->nfgen_family;
c1d10adb 2894
7d0742da 2895 rcu_read_lock();
31f15875
PM
2896 last = (struct nf_conntrack_expect *)cb->args[1];
2897 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
cf6994c2 2898restart:
7cddd967
LZ
2899 hlist_for_each_entry_rcu(exp, &nf_ct_expect_hash[cb->args[0]],
2900 hnode) {
31f15875 2901 if (l3proto && exp->tuple.src.l3num != l3proto)
cf6994c2 2902 continue;
03d7dc5c
FW
2903
2904 if (!net_eq(nf_ct_net(exp->master), net))
2905 continue;
2906
31f15875
PM
2907 if (cb->args[1]) {
2908 if (exp != last)
2909 continue;
2910 cb->args[1] = 0;
2911 }
8b0a231d 2912 if (ctnetlink_exp_fill_info(skb,
15e47304 2913 NETLINK_CB(cb->skb).portid,
31f15875
PM
2914 cb->nlh->nlmsg_seq,
2915 IPCTNL_MSG_EXP_NEW,
8b0a231d 2916 exp) < 0) {
b54ab92b 2917 if (!refcount_inc_not_zero(&exp->use))
7d0742da 2918 continue;
31f15875
PM
2919 cb->args[1] = (unsigned long)exp;
2920 goto out;
2921 }
cf6994c2 2922 }
31f15875
PM
2923 if (cb->args[1]) {
2924 cb->args[1] = 0;
2925 goto restart;
cf6994c2
PM
2926 }
2927 }
601e68e1 2928out:
7d0742da 2929 rcu_read_unlock();
cf6994c2
PM
2930 if (last)
2931 nf_ct_expect_put(last);
c1d10adb 2932
c1d10adb
PNA
2933 return skb->len;
2934}
2935
e844a928
PNA
2936static int
2937ctnetlink_exp_ct_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
2938{
2939 struct nf_conntrack_expect *exp, *last;
2940 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
2941 struct nf_conn *ct = cb->data;
2942 struct nf_conn_help *help = nfct_help(ct);
2943 u_int8_t l3proto = nfmsg->nfgen_family;
2944
2945 if (cb->args[0])
2946 return 0;
2947
2948 rcu_read_lock();
2949 last = (struct nf_conntrack_expect *)cb->args[1];
2950restart:
7cddd967 2951 hlist_for_each_entry_rcu(exp, &help->expectations, lnode) {
e844a928
PNA
2952 if (l3proto && exp->tuple.src.l3num != l3proto)
2953 continue;
2954 if (cb->args[1]) {
2955 if (exp != last)
2956 continue;
2957 cb->args[1] = 0;
2958 }
2959 if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).portid,
2960 cb->nlh->nlmsg_seq,
2961 IPCTNL_MSG_EXP_NEW,
2962 exp) < 0) {
b54ab92b 2963 if (!refcount_inc_not_zero(&exp->use))
e844a928
PNA
2964 continue;
2965 cb->args[1] = (unsigned long)exp;
2966 goto out;
2967 }
2968 }
2969 if (cb->args[1]) {
2970 cb->args[1] = 0;
2971 goto restart;
2972 }
2973 cb->args[0] = 1;
2974out:
2975 rcu_read_unlock();
2976 if (last)
2977 nf_ct_expect_put(last);
2978
2979 return skb->len;
2980}
2981
7b8002a1
PNA
2982static int ctnetlink_dump_exp_ct(struct net *net, struct sock *ctnl,
2983 struct sk_buff *skb,
e844a928 2984 const struct nlmsghdr *nlh,
04ba724b
PNA
2985 const struct nlattr * const cda[],
2986 struct netlink_ext_ack *extack)
e844a928
PNA
2987{
2988 int err;
e844a928
PNA
2989 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2990 u_int8_t u3 = nfmsg->nfgen_family;
2991 struct nf_conntrack_tuple tuple;
2992 struct nf_conntrack_tuple_hash *h;
2993 struct nf_conn *ct;
308ac914 2994 struct nf_conntrack_zone zone;
e844a928
PNA
2995 struct netlink_dump_control c = {
2996 .dump = ctnetlink_exp_ct_dump_table,
2997 .done = ctnetlink_exp_done,
2998 };
2999
deedb590
DB
3000 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER,
3001 u3, NULL);
e844a928
PNA
3002 if (err < 0)
3003 return err;
3004
308ac914
DB
3005 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
3006 if (err < 0)
3007 return err;
e844a928 3008
308ac914 3009 h = nf_conntrack_find_get(net, &zone, &tuple);
e844a928
PNA
3010 if (!h)
3011 return -ENOENT;
3012
3013 ct = nf_ct_tuplehash_to_ctrack(h);
207df815
LZ
3014 /* No expectation linked to this connection tracking. */
3015 if (!nfct_help(ct)) {
3016 nf_ct_put(ct);
3017 return 0;
3018 }
3019
e844a928
PNA
3020 c.data = ct;
3021
3022 err = netlink_dump_start(ctnl, skb, nlh, &c);
3023 nf_ct_put(ct);
3024
3025 return err;
3026}
3027
7b8002a1
PNA
3028static int ctnetlink_get_expect(struct net *net, struct sock *ctnl,
3029 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3030 const struct nlattr * const cda[],
3031 struct netlink_ext_ack *extack)
c1d10adb
PNA
3032{
3033 struct nf_conntrack_tuple tuple;
3034 struct nf_conntrack_expect *exp;
3035 struct sk_buff *skb2;
96bcf938 3036 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 3037 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 3038 struct nf_conntrack_zone zone;
ef00f89f 3039 int err;
c1d10adb 3040
b8f3ab42 3041 if (nlh->nlmsg_flags & NLM_F_DUMP) {
e844a928 3042 if (cda[CTA_EXPECT_MASTER])
04ba724b
PNA
3043 return ctnetlink_dump_exp_ct(net, ctnl, skb, nlh, cda,
3044 extack);
e844a928
PNA
3045 else {
3046 struct netlink_dump_control c = {
3047 .dump = ctnetlink_exp_dump_table,
3048 .done = ctnetlink_exp_done,
3049 };
3050 return netlink_dump_start(ctnl, skb, nlh, &c);
3051 }
c1d10adb
PNA
3052 }
3053
ef00f89f
PM
3054 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
3055 if (err < 0)
3056 return err;
3057
35dba1d7 3058 if (cda[CTA_EXPECT_TUPLE])
deedb590
DB
3059 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE,
3060 u3, NULL);
35dba1d7 3061 else if (cda[CTA_EXPECT_MASTER])
deedb590
DB
3062 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER,
3063 u3, NULL);
c1d10adb
PNA
3064 else
3065 return -EINVAL;
3066
3067 if (err < 0)
3068 return err;
3069
308ac914 3070 exp = nf_ct_expect_find_get(net, &zone, &tuple);
c1d10adb
PNA
3071 if (!exp)
3072 return -ENOENT;
3073
df6fb868 3074 if (cda[CTA_EXPECT_ID]) {
77236b6e 3075 __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
3c791076
FW
3076
3077 if (id != nf_expect_get_id(exp)) {
6823645d 3078 nf_ct_expect_put(exp);
c1d10adb
PNA
3079 return -ENOENT;
3080 }
601e68e1 3081 }
c1d10adb
PNA
3082
3083 err = -ENOMEM;
96bcf938 3084 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
81378f72
PNA
3085 if (skb2 == NULL) {
3086 nf_ct_expect_put(exp);
c1d10adb 3087 goto out;
81378f72 3088 }
4e9b8269 3089
528a3a6f 3090 rcu_read_lock();
15e47304 3091 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).portid,
8b0a231d 3092 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, exp);
528a3a6f 3093 rcu_read_unlock();
81378f72 3094 nf_ct_expect_put(exp);
c1d10adb
PNA
3095 if (err <= 0)
3096 goto free;
3097
15e47304 3098 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
81378f72
PNA
3099 if (err < 0)
3100 goto out;
c1d10adb 3101
81378f72 3102 return 0;
c1d10adb
PNA
3103
3104free:
3105 kfree_skb(skb2);
3106out:
81378f72
PNA
3107 /* this avoids a loop in nfnetlink. */
3108 return err == -EAGAIN ? -ENOBUFS : err;
c1d10adb
PNA
3109}
3110
ac7b8483
FW
3111static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data)
3112{
3113 const struct nf_conn_help *m_help;
3114 const char *name = data;
3115
3116 m_help = nfct_help(exp->master);
3117
3118 return strcmp(m_help->helper->name, name) == 0;
3119}
3120
3121static bool expect_iter_all(struct nf_conntrack_expect *exp, void *data)
3122{
3123 return true;
3124}
3125
7b8002a1
PNA
3126static int ctnetlink_del_expect(struct net *net, struct sock *ctnl,
3127 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3128 const struct nlattr * const cda[],
3129 struct netlink_ext_ack *extack)
c1d10adb 3130{
31f15875 3131 struct nf_conntrack_expect *exp;
c1d10adb 3132 struct nf_conntrack_tuple tuple;
96bcf938 3133 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 3134 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 3135 struct nf_conntrack_zone zone;
c1d10adb
PNA
3136 int err;
3137
df6fb868 3138 if (cda[CTA_EXPECT_TUPLE]) {
c1d10adb 3139 /* delete a single expect by tuple */
ef00f89f
PM
3140 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
3141 if (err < 0)
3142 return err;
3143
deedb590
DB
3144 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE,
3145 u3, NULL);
c1d10adb
PNA
3146 if (err < 0)
3147 return err;
3148
3149 /* bump usage count to 2 */
308ac914 3150 exp = nf_ct_expect_find_get(net, &zone, &tuple);
c1d10adb
PNA
3151 if (!exp)
3152 return -ENOENT;
3153
df6fb868 3154 if (cda[CTA_EXPECT_ID]) {
77236b6e 3155 __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
35832402 3156 if (ntohl(id) != (u32)(unsigned long)exp) {
6823645d 3157 nf_ct_expect_put(exp);
c1d10adb
PNA
3158 return -ENOENT;
3159 }
3160 }
3161
3162 /* after list removal, usage count == 1 */
ca7433df 3163 spin_lock_bh(&nf_conntrack_expect_lock);
ebbf41df 3164 if (del_timer(&exp->timeout)) {
15e47304 3165 nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).portid,
ebbf41df
PNA
3166 nlmsg_report(nlh));
3167 nf_ct_expect_put(exp);
3168 }
ca7433df 3169 spin_unlock_bh(&nf_conntrack_expect_lock);
601e68e1 3170 /* have to put what we 'get' above.
c1d10adb 3171 * after this line usage count == 0 */
6823645d 3172 nf_ct_expect_put(exp);
df6fb868
PM
3173 } else if (cda[CTA_EXPECT_HELP_NAME]) {
3174 char *name = nla_data(cda[CTA_EXPECT_HELP_NAME]);
c1d10adb 3175
ac7b8483
FW
3176 nf_ct_expect_iterate_net(net, expect_iter_name, name,
3177 NETLINK_CB(skb).portid,
3178 nlmsg_report(nlh));
c1d10adb
PNA
3179 } else {
3180 /* This basically means we have to flush everything*/
ac7b8483
FW
3181 nf_ct_expect_iterate_net(net, expect_iter_all, NULL,
3182 NETLINK_CB(skb).portid,
3183 nlmsg_report(nlh));
c1d10adb
PNA
3184 }
3185
3186 return 0;
3187}
3188static int
39938324
PM
3189ctnetlink_change_expect(struct nf_conntrack_expect *x,
3190 const struct nlattr * const cda[])
c1d10adb 3191{
9768e1ac
KW
3192 if (cda[CTA_EXPECT_TIMEOUT]) {
3193 if (!del_timer(&x->timeout))
3194 return -ETIME;
3195
3196 x->timeout.expires = jiffies +
3197 ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ;
3198 add_timer(&x->timeout);
3199 }
3200 return 0;
c1d10adb
PNA
3201}
3202
076a0ca0
PNA
3203static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = {
3204 [CTA_EXPECT_NAT_DIR] = { .type = NLA_U32 },
3205 [CTA_EXPECT_NAT_TUPLE] = { .type = NLA_NESTED },
3206};
3207
3208static int
3209ctnetlink_parse_expect_nat(const struct nlattr *attr,
3210 struct nf_conntrack_expect *exp,
3211 u_int8_t u3)
3212{
4806e975 3213#if IS_ENABLED(CONFIG_NF_NAT)
076a0ca0
PNA
3214 struct nlattr *tb[CTA_EXPECT_NAT_MAX+1];
3215 struct nf_conntrack_tuple nat_tuple = {};
3216 int err;
3217
8cb08174
JB
3218 err = nla_parse_nested_deprecated(tb, CTA_EXPECT_NAT_MAX, attr,
3219 exp_nat_nla_policy, NULL);
130ffbc2
DB
3220 if (err < 0)
3221 return err;
076a0ca0
PNA
3222
3223 if (!tb[CTA_EXPECT_NAT_DIR] || !tb[CTA_EXPECT_NAT_TUPLE])
3224 return -EINVAL;
3225
3226 err = ctnetlink_parse_tuple((const struct nlattr * const *)tb,
deedb590
DB
3227 &nat_tuple, CTA_EXPECT_NAT_TUPLE,
3228 u3, NULL);
076a0ca0
PNA
3229 if (err < 0)
3230 return err;
3231
c7232c99 3232 exp->saved_addr = nat_tuple.src.u3;
076a0ca0
PNA
3233 exp->saved_proto = nat_tuple.src.u;
3234 exp->dir = ntohl(nla_get_be32(tb[CTA_EXPECT_NAT_DIR]));
3235
3236 return 0;
3237#else
3238 return -EOPNOTSUPP;
3239#endif
3240}
3241
0ef71ee1
PNA
3242static struct nf_conntrack_expect *
3243ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
3244 struct nf_conntrack_helper *helper,
3245 struct nf_conntrack_tuple *tuple,
3246 struct nf_conntrack_tuple *mask)
c1d10adb 3247{
0ef71ee1 3248 u_int32_t class = 0;
c1d10adb 3249 struct nf_conntrack_expect *exp;
dc808fe2 3250 struct nf_conn_help *help;
0ef71ee1 3251 int err;
660fdb2a 3252
2c62e0bc
GF
3253 help = nfct_help(ct);
3254 if (!help)
3255 return ERR_PTR(-EOPNOTSUPP);
3256
b8c5e52c
PNA
3257 if (cda[CTA_EXPECT_CLASS] && helper) {
3258 class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS]));
0ef71ee1
PNA
3259 if (class > helper->expect_class_max)
3260 return ERR_PTR(-EINVAL);
b8c5e52c 3261 }
6823645d 3262 exp = nf_ct_expect_alloc(ct);
0ef71ee1
PNA
3263 if (!exp)
3264 return ERR_PTR(-ENOMEM);
3265
2c62e0bc
GF
3266 if (cda[CTA_EXPECT_FLAGS]) {
3267 exp->flags = ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS]));
3268 exp->flags &= ~NF_CT_EXPECT_USERSPACE;
bc01befd 3269 } else {
2c62e0bc 3270 exp->flags = 0;
bc01befd 3271 }
544d5c7d
PNA
3272 if (cda[CTA_EXPECT_FN]) {
3273 const char *name = nla_data(cda[CTA_EXPECT_FN]);
3274 struct nf_ct_helper_expectfn *expfn;
3275
3276 expfn = nf_ct_helper_expectfn_find_by_name(name);
3277 if (expfn == NULL) {
3278 err = -EINVAL;
3279 goto err_out;
3280 }
3281 exp->expectfn = expfn->expectfn;
3282 } else
3283 exp->expectfn = NULL;
601e68e1 3284
b8c5e52c 3285 exp->class = class;
c1d10adb 3286 exp->master = ct;
660fdb2a 3287 exp->helper = helper;
0ef71ee1
PNA
3288 exp->tuple = *tuple;
3289 exp->mask.src.u3 = mask->src.u3;
3290 exp->mask.src.u.all = mask->src.u.all;
c1d10adb 3291
076a0ca0
PNA
3292 if (cda[CTA_EXPECT_NAT]) {
3293 err = ctnetlink_parse_expect_nat(cda[CTA_EXPECT_NAT],
0ef71ee1 3294 exp, nf_ct_l3num(ct));
076a0ca0
PNA
3295 if (err < 0)
3296 goto err_out;
3297 }
0ef71ee1 3298 return exp;
076a0ca0 3299err_out:
6823645d 3300 nf_ct_expect_put(exp);
0ef71ee1
PNA
3301 return ERR_PTR(err);
3302}
3303
3304static int
308ac914
DB
3305ctnetlink_create_expect(struct net *net,
3306 const struct nf_conntrack_zone *zone,
0ef71ee1
PNA
3307 const struct nlattr * const cda[],
3308 u_int8_t u3, u32 portid, int report)
3309{
3310 struct nf_conntrack_tuple tuple, mask, master_tuple;
3311 struct nf_conntrack_tuple_hash *h = NULL;
3312 struct nf_conntrack_helper *helper = NULL;
3313 struct nf_conntrack_expect *exp;
3314 struct nf_conn *ct;
3315 int err;
3316
3317 /* caller guarantees that those three CTA_EXPECT_* exist */
deedb590
DB
3318 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE,
3319 u3, NULL);
0ef71ee1
PNA
3320 if (err < 0)
3321 return err;
deedb590
DB
3322 err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK,
3323 u3, NULL);
0ef71ee1
PNA
3324 if (err < 0)
3325 return err;
deedb590
DB
3326 err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER,
3327 u3, NULL);
0ef71ee1
PNA
3328 if (err < 0)
3329 return err;
3330
3331 /* Look for master conntrack of this expectation */
3332 h = nf_conntrack_find_get(net, zone, &master_tuple);
3333 if (!h)
3334 return -ENOENT;
3335 ct = nf_ct_tuplehash_to_ctrack(h);
3336
8b5995d0 3337 rcu_read_lock();
0ef71ee1
PNA
3338 if (cda[CTA_EXPECT_HELP_NAME]) {
3339 const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
3340
3341 helper = __nf_conntrack_helper_find(helpname, u3,
3342 nf_ct_protonum(ct));
3343 if (helper == NULL) {
8b5995d0 3344 rcu_read_unlock();
0ef71ee1
PNA
3345#ifdef CONFIG_MODULES
3346 if (request_module("nfct-helper-%s", helpname) < 0) {
3347 err = -EOPNOTSUPP;
3348 goto err_ct;
3349 }
8b5995d0 3350 rcu_read_lock();
0ef71ee1
PNA
3351 helper = __nf_conntrack_helper_find(helpname, u3,
3352 nf_ct_protonum(ct));
3353 if (helper) {
3354 err = -EAGAIN;
8b5995d0 3355 goto err_rcu;
0ef71ee1 3356 }
8b5995d0 3357 rcu_read_unlock();
0ef71ee1
PNA
3358#endif
3359 err = -EOPNOTSUPP;
3360 goto err_ct;
3361 }
3362 }
3363
3364 exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask);
3365 if (IS_ERR(exp)) {
3366 err = PTR_ERR(exp);
8b5995d0 3367 goto err_rcu;
0ef71ee1
PNA
3368 }
3369
3c00fb0b 3370 err = nf_ct_expect_related_report(exp, portid, report, 0);
0ef71ee1 3371 nf_ct_expect_put(exp);
8b5995d0
GF
3372err_rcu:
3373 rcu_read_unlock();
0ef71ee1
PNA
3374err_ct:
3375 nf_ct_put(ct);
c1d10adb
PNA
3376 return err;
3377}
3378
7b8002a1
PNA
3379static int ctnetlink_new_expect(struct net *net, struct sock *ctnl,
3380 struct sk_buff *skb, const struct nlmsghdr *nlh,
04ba724b
PNA
3381 const struct nlattr * const cda[],
3382 struct netlink_ext_ack *extack)
c1d10adb
PNA
3383{
3384 struct nf_conntrack_tuple tuple;
3385 struct nf_conntrack_expect *exp;
96bcf938 3386 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 3387 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 3388 struct nf_conntrack_zone zone;
ef00f89f 3389 int err;
c1d10adb 3390
df6fb868
PM
3391 if (!cda[CTA_EXPECT_TUPLE]
3392 || !cda[CTA_EXPECT_MASK]
3393 || !cda[CTA_EXPECT_MASTER])
c1d10adb
PNA
3394 return -EINVAL;
3395
ef00f89f
PM
3396 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
3397 if (err < 0)
3398 return err;
3399
deedb590
DB
3400 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE,
3401 u3, NULL);
c1d10adb
PNA
3402 if (err < 0)
3403 return err;
3404
ca7433df 3405 spin_lock_bh(&nf_conntrack_expect_lock);
308ac914 3406 exp = __nf_ct_expect_find(net, &zone, &tuple);
c1d10adb 3407 if (!exp) {
ca7433df 3408 spin_unlock_bh(&nf_conntrack_expect_lock);
c1d10adb 3409 err = -ENOENT;
19abb7b0 3410 if (nlh->nlmsg_flags & NLM_F_CREATE) {
308ac914 3411 err = ctnetlink_create_expect(net, &zone, cda, u3,
15e47304 3412 NETLINK_CB(skb).portid,
19abb7b0
PNA
3413 nlmsg_report(nlh));
3414 }
c1d10adb
PNA
3415 return err;
3416 }
3417
3418 err = -EEXIST;
3419 if (!(nlh->nlmsg_flags & NLM_F_EXCL))
3420 err = ctnetlink_change_expect(exp, cda);
ca7433df 3421 spin_unlock_bh(&nf_conntrack_expect_lock);
c1d10adb 3422
c1d10adb
PNA
3423 return err;
3424}
3425
392025f8 3426static int
15e47304 3427ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, int cpu,
392025f8
PNA
3428 const struct ip_conntrack_stat *st)
3429{
3430 struct nlmsghdr *nlh;
3431 struct nfgenmsg *nfmsg;
15e47304 3432 unsigned int flags = portid ? NLM_F_MULTI : 0, event;
392025f8 3433
dedb67c4
PNA
3434 event = nfnl_msg_type(NFNL_SUBSYS_CTNETLINK,
3435 IPCTNL_MSG_EXP_GET_STATS_CPU);
15e47304 3436 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
392025f8
PNA
3437 if (nlh == NULL)
3438 goto nlmsg_failure;
3439
3440 nfmsg = nlmsg_data(nlh);
3441 nfmsg->nfgen_family = AF_UNSPEC;
3442 nfmsg->version = NFNETLINK_V0;
3443 nfmsg->res_id = htons(cpu);
3444
3445 if (nla_put_be32(skb, CTA_STATS_EXP_NEW, htonl(st->expect_new)) ||
3446 nla_put_be32(skb, CTA_STATS_EXP_CREATE, htonl(st->expect_create)) ||
3447 nla_put_be32(skb, CTA_STATS_EXP_DELETE, htonl(st->expect_delete)))
3448 goto nla_put_failure;
3449
3450 nlmsg_end(skb, nlh);
3451 return skb->len;
3452
3453nla_put_failure:
3454nlmsg_failure:
3455 nlmsg_cancel(skb, nlh);
3456 return -1;
3457}
3458
3459static int
3460ctnetlink_exp_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
3461{
3462 int cpu;
3463 struct net *net = sock_net(skb->sk);
3464
3465 if (cb->args[0] == nr_cpu_ids)
3466 return 0;
3467
3468 for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
3469 const struct ip_conntrack_stat *st;
3470
3471 if (!cpu_possible(cpu))
3472 continue;
3473
3474 st = per_cpu_ptr(net->ct.stat, cpu);
15e47304 3475 if (ctnetlink_exp_stat_fill_info(skb, NETLINK_CB(cb->skb).portid,
392025f8
PNA
3476 cb->nlh->nlmsg_seq,
3477 cpu, st) < 0)
3478 break;
3479 }
3480 cb->args[0] = cpu;
3481
3482 return skb->len;
3483}
3484
7b8002a1
PNA
3485static int ctnetlink_stat_exp_cpu(struct net *net, struct sock *ctnl,
3486 struct sk_buff *skb,
3487 const struct nlmsghdr *nlh,
04ba724b
PNA
3488 const struct nlattr * const cda[],
3489 struct netlink_ext_ack *extack)
392025f8
PNA
3490{
3491 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3492 struct netlink_dump_control c = {
3493 .dump = ctnetlink_exp_stat_cpu_dump,
3494 };
3495 return netlink_dump_start(ctnl, skb, nlh, &c);
3496 }
3497
3498 return 0;
3499}
3500
c1d10adb 3501#ifdef CONFIG_NF_CONNTRACK_EVENTS
e34d5c1a
PNA
3502static struct nf_ct_event_notifier ctnl_notifier = {
3503 .fcn = ctnetlink_conntrack_event,
c1d10adb
PNA
3504};
3505
e34d5c1a
PNA
3506static struct nf_exp_event_notifier ctnl_notifier_exp = {
3507 .fcn = ctnetlink_expect_event,
c1d10adb
PNA
3508};
3509#endif
3510
7c8d4cb4 3511static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
c1d10adb 3512 [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack,
f73e924c
PM
3513 .attr_count = CTA_MAX,
3514 .policy = ct_nla_policy },
c1d10adb 3515 [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack,
f73e924c
PM
3516 .attr_count = CTA_MAX,
3517 .policy = ct_nla_policy },
c1d10adb 3518 [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack,
f73e924c
PM
3519 .attr_count = CTA_MAX,
3520 .policy = ct_nla_policy },
c1d10adb 3521 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack,
f73e924c
PM
3522 .attr_count = CTA_MAX,
3523 .policy = ct_nla_policy },
392025f8
PNA
3524 [IPCTNL_MSG_CT_GET_STATS_CPU] = { .call = ctnetlink_stat_ct_cpu },
3525 [IPCTNL_MSG_CT_GET_STATS] = { .call = ctnetlink_stat_ct },
d871befe
PNA
3526 [IPCTNL_MSG_CT_GET_DYING] = { .call = ctnetlink_get_ct_dying },
3527 [IPCTNL_MSG_CT_GET_UNCONFIRMED] = { .call = ctnetlink_get_ct_unconfirmed },
c1d10adb
PNA
3528};
3529
7c8d4cb4 3530static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
c1d10adb 3531 [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
f73e924c
PM
3532 .attr_count = CTA_EXPECT_MAX,
3533 .policy = exp_nla_policy },
c1d10adb 3534 [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect,
f73e924c
PM
3535 .attr_count = CTA_EXPECT_MAX,
3536 .policy = exp_nla_policy },
c1d10adb 3537 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect,
f73e924c
PM
3538 .attr_count = CTA_EXPECT_MAX,
3539 .policy = exp_nla_policy },
392025f8 3540 [IPCTNL_MSG_EXP_GET_STATS_CPU] = { .call = ctnetlink_stat_exp_cpu },
c1d10adb
PNA
3541};
3542
7c8d4cb4 3543static const struct nfnetlink_subsystem ctnl_subsys = {
c1d10adb
PNA
3544 .name = "conntrack",
3545 .subsys_id = NFNL_SUBSYS_CTNETLINK,
3546 .cb_count = IPCTNL_MSG_MAX,
3547 .cb = ctnl_cb,
3548};
3549
7c8d4cb4 3550static const struct nfnetlink_subsystem ctnl_exp_subsys = {
c1d10adb
PNA
3551 .name = "conntrack_expect",
3552 .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP,
3553 .cb_count = IPCTNL_MSG_EXP_MAX,
3554 .cb = ctnl_exp_cb,
3555};
3556
d2483dde 3557MODULE_ALIAS("ip_conntrack_netlink");
c1d10adb 3558MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
34f9a2e4 3559MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
c1d10adb 3560
70e9942f
PNA
3561static int __net_init ctnetlink_net_init(struct net *net)
3562{
3563#ifdef CONFIG_NF_CONNTRACK_EVENTS
3564 int ret;
3565
3566 ret = nf_conntrack_register_notifier(net, &ctnl_notifier);
3567 if (ret < 0) {
3568 pr_err("ctnetlink_init: cannot register notifier.\n");
3569 goto err_out;
3570 }
3571
3572 ret = nf_ct_expect_register_notifier(net, &ctnl_notifier_exp);
3573 if (ret < 0) {
3574 pr_err("ctnetlink_init: cannot expect register notifier.\n");
3575 goto err_unreg_notifier;
3576 }
3577#endif
3578 return 0;
3579
3580#ifdef CONFIG_NF_CONNTRACK_EVENTS
3581err_unreg_notifier:
3582 nf_conntrack_unregister_notifier(net, &ctnl_notifier);
3583err_out:
3584 return ret;
3585#endif
3586}
3587
3588static void ctnetlink_net_exit(struct net *net)
3589{
3590#ifdef CONFIG_NF_CONNTRACK_EVENTS
3591 nf_ct_expect_unregister_notifier(net, &ctnl_notifier_exp);
3592 nf_conntrack_unregister_notifier(net, &ctnl_notifier);
3593#endif
3594}
3595
3596static void __net_exit ctnetlink_net_exit_batch(struct list_head *net_exit_list)
3597{
3598 struct net *net;
3599
3600 list_for_each_entry(net, net_exit_list, exit_list)
3601 ctnetlink_net_exit(net);
3602}
3603
3604static struct pernet_operations ctnetlink_net_ops = {
3605 .init = ctnetlink_net_init,
3606 .exit_batch = ctnetlink_net_exit_batch,
3607};
3608
c1d10adb
PNA
3609static int __init ctnetlink_init(void)
3610{
3611 int ret;
3612
c1d10adb
PNA
3613 ret = nfnetlink_subsys_register(&ctnl_subsys);
3614 if (ret < 0) {
654d0fbd 3615 pr_err("ctnetlink_init: cannot register with nfnetlink.\n");
c1d10adb
PNA
3616 goto err_out;
3617 }
3618
3619 ret = nfnetlink_subsys_register(&ctnl_exp_subsys);
3620 if (ret < 0) {
654d0fbd 3621 pr_err("ctnetlink_init: cannot register exp with nfnetlink.\n");
c1d10adb
PNA
3622 goto err_unreg_subsys;
3623 }
3624
ef6acf68
JL
3625 ret = register_pernet_subsys(&ctnetlink_net_ops);
3626 if (ret < 0) {
70e9942f 3627 pr_err("ctnetlink_init: cannot register pernet operations\n");
c1d10adb
PNA
3628 goto err_unreg_exp_subsys;
3629 }
83f3e94d 3630#ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
9cb01766 3631 /* setup interaction between nf_queue and nf_conntrack_netlink. */
a4b4766c 3632 RCU_INIT_POINTER(nfnl_ct_hook, &ctnetlink_glue_hook);
9cb01766 3633#endif
c1d10adb
PNA
3634 return 0;
3635
c1d10adb
PNA
3636err_unreg_exp_subsys:
3637 nfnetlink_subsys_unregister(&ctnl_exp_subsys);
c1d10adb
PNA
3638err_unreg_subsys:
3639 nfnetlink_subsys_unregister(&ctnl_subsys);
3640err_out:
3641 return ret;
3642}
3643
3644static void __exit ctnetlink_exit(void)
3645{
70e9942f 3646 unregister_pernet_subsys(&ctnetlink_net_ops);
c1d10adb
PNA
3647 nfnetlink_subsys_unregister(&ctnl_exp_subsys);
3648 nfnetlink_subsys_unregister(&ctnl_subsys);
83f3e94d 3649#ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
a4b4766c 3650 RCU_INIT_POINTER(nfnl_ct_hook, NULL);
9cb01766 3651#endif
3b7dabf0 3652 synchronize_rcu();
c1d10adb
PNA
3653}
3654
3655module_init(ctnetlink_init);
3656module_exit(ctnetlink_exit);