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