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