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