netfilter: connlabels: change nf_connlabels_get bit arg to 'highest used'
[deliverable/linux.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{
c1216382 152 long timeout = ((long)ct->timeout.expires - (long)jiffies) / HZ;
c1d10adb 153
77236b6e 154 if (timeout < 0)
c1d10adb 155 timeout = 0;
601e68e1 156
cc1eb431
DM
157 if (nla_put_be32(skb, CTA_TIMEOUT, htonl(timeout)))
158 goto nla_put_failure;
c1d10adb
PNA
159 return 0;
160
df6fb868 161nla_put_failure:
c1d10adb
PNA
162 return -1;
163}
164
4054ff45 165static int ctnetlink_dump_protoinfo(struct sk_buff *skb, struct nf_conn *ct)
c1d10adb 166{
5e8fbe2a 167 struct nf_conntrack_l4proto *l4proto;
df6fb868 168 struct nlattr *nest_proto;
c1d10adb
PNA
169 int ret;
170
528a3a6f
PNA
171 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
172 if (!l4proto->to_nlattr)
c1d10adb 173 return 0;
601e68e1 174
df6fb868
PM
175 nest_proto = nla_nest_start(skb, CTA_PROTOINFO | NLA_F_NESTED);
176 if (!nest_proto)
177 goto nla_put_failure;
c1d10adb 178
fdf70832 179 ret = l4proto->to_nlattr(skb, nest_proto, ct);
c1d10adb 180
df6fb868 181 nla_nest_end(skb, nest_proto);
c1d10adb
PNA
182
183 return ret;
184
df6fb868 185nla_put_failure:
c1d10adb
PNA
186 return -1;
187}
188
4054ff45
PNA
189static int ctnetlink_dump_helpinfo(struct sk_buff *skb,
190 const struct nf_conn *ct)
c1d10adb 191{
df6fb868 192 struct nlattr *nest_helper;
dc808fe2 193 const struct nf_conn_help *help = nfct_help(ct);
3c158f7f 194 struct nf_conntrack_helper *helper;
c1d10adb 195
3c158f7f 196 if (!help)
c1d10adb 197 return 0;
601e68e1 198
3c158f7f
PM
199 helper = rcu_dereference(help->helper);
200 if (!helper)
201 goto out;
202
df6fb868
PM
203 nest_helper = nla_nest_start(skb, CTA_HELP | NLA_F_NESTED);
204 if (!nest_helper)
205 goto nla_put_failure;
cc1eb431
DM
206 if (nla_put_string(skb, CTA_HELP_NAME, helper->name))
207 goto nla_put_failure;
c1d10adb 208
fdf70832
PM
209 if (helper->to_nlattr)
210 helper->to_nlattr(skb, ct);
c1d10adb 211
df6fb868 212 nla_nest_end(skb, nest_helper);
3c158f7f 213out:
c1d10adb
PNA
214 return 0;
215
df6fb868 216nla_put_failure:
c1d10adb
PNA
217 return -1;
218}
219
bb5cf80e 220static int
4542fa47
HE
221dump_counters(struct sk_buff *skb, struct nf_conn_acct *acct,
222 enum ip_conntrack_dir dir, int type)
c1d10adb 223{
4542fa47
HE
224 enum ctattr_type attr = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
225 struct nf_conn_counter *counter = acct->counter;
df6fb868 226 struct nlattr *nest_count;
4542fa47 227 u64 pkts, bytes;
c1d10adb 228
4542fa47
HE
229 if (type == IPCTNL_MSG_CT_GET_CTRZERO) {
230 pkts = atomic64_xchg(&counter[dir].packets, 0);
231 bytes = atomic64_xchg(&counter[dir].bytes, 0);
232 } else {
233 pkts = atomic64_read(&counter[dir].packets);
234 bytes = atomic64_read(&counter[dir].bytes);
235 }
236
237 nest_count = nla_nest_start(skb, attr | NLA_F_NESTED);
df6fb868
PM
238 if (!nest_count)
239 goto nla_put_failure;
240
cc1eb431
DM
241 if (nla_put_be64(skb, CTA_COUNTERS_PACKETS, cpu_to_be64(pkts)) ||
242 nla_put_be64(skb, CTA_COUNTERS_BYTES, cpu_to_be64(bytes)))
243 goto nla_put_failure;
c1d10adb 244
df6fb868 245 nla_nest_end(skb, nest_count);
c1d10adb
PNA
246
247 return 0;
248
df6fb868 249nla_put_failure:
c1d10adb
PNA
250 return -1;
251}
c1d10adb 252
80e60e67 253static int
4542fa47 254ctnetlink_dump_acct(struct sk_buff *skb, const struct nf_conn *ct, int type)
80e60e67 255{
4542fa47 256 struct nf_conn_acct *acct = nf_conn_acct_find(ct);
80e60e67 257
80e60e67
PNA
258 if (!acct)
259 return 0;
260
4542fa47
HE
261 if (dump_counters(skb, acct, IP_CT_DIR_ORIGINAL, type) < 0)
262 return -1;
263 if (dump_counters(skb, acct, IP_CT_DIR_REPLY, type) < 0)
264 return -1;
265
266 return 0;
80e60e67
PNA
267}
268
a992ca2a
PNA
269static int
270ctnetlink_dump_timestamp(struct sk_buff *skb, const struct nf_conn *ct)
271{
272 struct nlattr *nest_count;
273 const struct nf_conn_tstamp *tstamp;
274
275 tstamp = nf_conn_tstamp_find(ct);
276 if (!tstamp)
277 return 0;
278
279 nest_count = nla_nest_start(skb, CTA_TIMESTAMP | NLA_F_NESTED);
280 if (!nest_count)
281 goto nla_put_failure;
282
cc1eb431
DM
283 if (nla_put_be64(skb, CTA_TIMESTAMP_START, cpu_to_be64(tstamp->start)) ||
284 (tstamp->stop != 0 && nla_put_be64(skb, CTA_TIMESTAMP_STOP,
285 cpu_to_be64(tstamp->stop))))
286 goto nla_put_failure;
a992ca2a
PNA
287 nla_nest_end(skb, nest_count);
288
289 return 0;
290
291nla_put_failure:
292 return -1;
293}
294
c1d10adb 295#ifdef CONFIG_NF_CONNTRACK_MARK
4054ff45 296static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
c1d10adb 297{
cc1eb431
DM
298 if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark)))
299 goto nla_put_failure;
c1d10adb
PNA
300 return 0;
301
df6fb868 302nla_put_failure:
c1d10adb
PNA
303 return -1;
304}
305#else
306#define ctnetlink_dump_mark(a, b) (0)
307#endif
308
37fccd85 309#ifdef CONFIG_NF_CONNTRACK_SECMARK
4054ff45 310static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
37fccd85 311{
1cc63249
EP
312 struct nlattr *nest_secctx;
313 int len, ret;
314 char *secctx;
315
316 ret = security_secid_to_secctx(ct->secmark, &secctx, &len);
317 if (ret)
cba85b53 318 return 0;
1cc63249
EP
319
320 ret = -1;
321 nest_secctx = nla_nest_start(skb, CTA_SECCTX | NLA_F_NESTED);
322 if (!nest_secctx)
323 goto nla_put_failure;
37fccd85 324
cc1eb431
DM
325 if (nla_put_string(skb, CTA_SECCTX_NAME, secctx))
326 goto nla_put_failure;
1cc63249
EP
327 nla_nest_end(skb, nest_secctx);
328
329 ret = 0;
37fccd85 330nla_put_failure:
1cc63249
EP
331 security_release_secctx(secctx, len);
332 return ret;
37fccd85
PNA
333}
334#else
1cc63249 335#define ctnetlink_dump_secctx(a, b) (0)
37fccd85
PNA
336#endif
337
0ceabd83
FW
338#ifdef CONFIG_NF_CONNTRACK_LABELS
339static int ctnetlink_label_size(const struct nf_conn *ct)
340{
341 struct nf_conn_labels *labels = nf_ct_labels_find(ct);
342
343 if (!labels)
344 return 0;
345 return nla_total_size(labels->words * sizeof(long));
346}
347
348static int
349ctnetlink_dump_labels(struct sk_buff *skb, const struct nf_conn *ct)
350{
351 struct nf_conn_labels *labels = nf_ct_labels_find(ct);
352 unsigned int len, i;
353
354 if (!labels)
355 return 0;
356
357 len = labels->words * sizeof(long);
358 i = 0;
359 do {
360 if (labels->bits[i] != 0)
361 return nla_put(skb, CTA_LABELS, len, labels->bits);
362 i++;
363 } while (i < labels->words);
364
365 return 0;
366}
367#else
368#define ctnetlink_dump_labels(a, b) (0)
369#define ctnetlink_label_size(a) (0)
370#endif
371
0f417ce9
PNA
372#define master_tuple(ct) &(ct->master->tuplehash[IP_CT_DIR_ORIGINAL].tuple)
373
4054ff45 374static int ctnetlink_dump_master(struct sk_buff *skb, const struct nf_conn *ct)
0f417ce9
PNA
375{
376 struct nlattr *nest_parms;
377
378 if (!(ct->status & IPS_EXPECTED))
379 return 0;
380
381 nest_parms = nla_nest_start(skb, CTA_TUPLE_MASTER | NLA_F_NESTED);
382 if (!nest_parms)
383 goto nla_put_failure;
384 if (ctnetlink_dump_tuples(skb, master_tuple(ct)) < 0)
385 goto nla_put_failure;
386 nla_nest_end(skb, nest_parms);
387
388 return 0;
389
390nla_put_failure:
391 return -1;
392}
393
bb5cf80e 394static int
41d73ec0 395dump_ct_seq_adj(struct sk_buff *skb, const struct nf_ct_seqadj *seq, int type)
13eae15a 396{
13eae15a
PNA
397 struct nlattr *nest_parms;
398
399 nest_parms = nla_nest_start(skb, type | NLA_F_NESTED);
400 if (!nest_parms)
401 goto nla_put_failure;
402
41d73ec0
PM
403 if (nla_put_be32(skb, CTA_SEQADJ_CORRECTION_POS,
404 htonl(seq->correction_pos)) ||
405 nla_put_be32(skb, CTA_SEQADJ_OFFSET_BEFORE,
406 htonl(seq->offset_before)) ||
407 nla_put_be32(skb, CTA_SEQADJ_OFFSET_AFTER,
408 htonl(seq->offset_after)))
cc1eb431 409 goto nla_put_failure;
13eae15a
PNA
410
411 nla_nest_end(skb, nest_parms);
412
413 return 0;
414
415nla_put_failure:
416 return -1;
417}
418
4054ff45
PNA
419static int ctnetlink_dump_ct_seq_adj(struct sk_buff *skb,
420 const struct nf_conn *ct)
13eae15a 421{
41d73ec0
PM
422 struct nf_conn_seqadj *seqadj = nfct_seqadj(ct);
423 struct nf_ct_seqadj *seq;
13eae15a 424
41d73ec0 425 if (!(ct->status & IPS_SEQ_ADJUST) || !seqadj)
13eae15a
PNA
426 return 0;
427
41d73ec0
PM
428 seq = &seqadj->seq[IP_CT_DIR_ORIGINAL];
429 if (dump_ct_seq_adj(skb, seq, CTA_SEQ_ADJ_ORIG) == -1)
13eae15a
PNA
430 return -1;
431
41d73ec0
PM
432 seq = &seqadj->seq[IP_CT_DIR_REPLY];
433 if (dump_ct_seq_adj(skb, seq, CTA_SEQ_ADJ_REPLY) == -1)
13eae15a
PNA
434 return -1;
435
436 return 0;
437}
13eae15a 438
4054ff45 439static int ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
c1d10adb 440{
cc1eb431
DM
441 if (nla_put_be32(skb, CTA_ID, htonl((unsigned long)ct)))
442 goto nla_put_failure;
c1d10adb
PNA
443 return 0;
444
df6fb868 445nla_put_failure:
c1d10adb
PNA
446 return -1;
447}
448
4054ff45 449static int ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
c1d10adb 450{
cc1eb431
DM
451 if (nla_put_be32(skb, CTA_USE, htonl(atomic_read(&ct->ct_general.use))))
452 goto nla_put_failure;
c1d10adb
PNA
453 return 0;
454
df6fb868 455nla_put_failure:
c1d10adb
PNA
456 return -1;
457}
458
c1d10adb 459static int
15e47304 460ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
80e60e67 461 struct nf_conn *ct)
c1d10adb 462{
308ac914 463 const struct nf_conntrack_zone *zone;
c1d10adb
PNA
464 struct nlmsghdr *nlh;
465 struct nfgenmsg *nfmsg;
df6fb868 466 struct nlattr *nest_parms;
15e47304 467 unsigned int flags = portid ? NLM_F_MULTI : 0, event;
c1d10adb 468
80e60e67 469 event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_NEW);
15e47304 470 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
96bcf938
PNA
471 if (nlh == NULL)
472 goto nlmsg_failure;
c1d10adb 473
96bcf938 474 nfmsg = nlmsg_data(nlh);
5e8fbe2a 475 nfmsg->nfgen_family = nf_ct_l3num(ct);
c1d10adb
PNA
476 nfmsg->version = NFNETLINK_V0;
477 nfmsg->res_id = 0;
478
deedb590
DB
479 zone = nf_ct_zone(ct);
480
df6fb868
PM
481 nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED);
482 if (!nest_parms)
483 goto nla_put_failure;
f2f3e38c 484 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
df6fb868 485 goto nla_put_failure;
deedb590
DB
486 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
487 NF_CT_ZONE_DIR_ORIG) < 0)
488 goto nla_put_failure;
df6fb868 489 nla_nest_end(skb, nest_parms);
601e68e1 490
df6fb868
PM
491 nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY | NLA_F_NESTED);
492 if (!nest_parms)
493 goto nla_put_failure;
f2f3e38c 494 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0)
df6fb868 495 goto nla_put_failure;
deedb590
DB
496 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
497 NF_CT_ZONE_DIR_REPL) < 0)
498 goto nla_put_failure;
df6fb868 499 nla_nest_end(skb, nest_parms);
c1d10adb 500
deedb590
DB
501 if (ctnetlink_dump_zone_id(skb, CTA_ZONE, zone,
502 NF_CT_DEFAULT_ZONE_DIR) < 0)
cc1eb431 503 goto nla_put_failure;
ef00f89f 504
c1d10adb
PNA
505 if (ctnetlink_dump_status(skb, ct) < 0 ||
506 ctnetlink_dump_timeout(skb, ct) < 0 ||
4542fa47 507 ctnetlink_dump_acct(skb, ct, type) < 0 ||
a992ca2a 508 ctnetlink_dump_timestamp(skb, ct) < 0 ||
c1d10adb
PNA
509 ctnetlink_dump_protoinfo(skb, ct) < 0 ||
510 ctnetlink_dump_helpinfo(skb, ct) < 0 ||
511 ctnetlink_dump_mark(skb, ct) < 0 ||
1cc63249 512 ctnetlink_dump_secctx(skb, ct) < 0 ||
0ceabd83 513 ctnetlink_dump_labels(skb, ct) < 0 ||
c1d10adb 514 ctnetlink_dump_id(skb, ct) < 0 ||
13eae15a 515 ctnetlink_dump_use(skb, ct) < 0 ||
0f417ce9 516 ctnetlink_dump_master(skb, ct) < 0 ||
41d73ec0 517 ctnetlink_dump_ct_seq_adj(skb, ct) < 0)
df6fb868 518 goto nla_put_failure;
c1d10adb 519
96bcf938 520 nlmsg_end(skb, nlh);
c1d10adb
PNA
521 return skb->len;
522
523nlmsg_failure:
df6fb868 524nla_put_failure:
96bcf938 525 nlmsg_cancel(skb, nlh);
c1d10adb
PNA
526 return -1;
527}
528
4054ff45 529static size_t ctnetlink_proto_size(const struct nf_conn *ct)
2732c4e4
HE
530{
531 struct nf_conntrack_l3proto *l3proto;
532 struct nf_conntrack_l4proto *l4proto;
03b64f51
PNA
533 size_t len = 0;
534
535 rcu_read_lock();
536 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
537 len += l3proto->nla_size;
538
539 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
540 len += l4proto->nla_size;
541 rcu_read_unlock();
542
543 return len;
544}
545
4054ff45 546static size_t ctnetlink_acct_size(const struct nf_conn *ct)
d26e6a02
JP
547{
548 if (!nf_ct_ext_exist(ct, NF_CT_EXT_ACCT))
549 return 0;
550 return 2 * nla_total_size(0) /* CTA_COUNTERS_ORIG|REPL */
551 + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_PACKETS */
552 + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_BYTES */
553 ;
554}
555
4054ff45 556static int ctnetlink_secctx_size(const struct nf_conn *ct)
1cc63249 557{
cba85b53
PNA
558#ifdef CONFIG_NF_CONNTRACK_SECMARK
559 int len, ret;
1cc63249 560
cba85b53
PNA
561 ret = security_secid_to_secctx(ct->secmark, NULL, &len);
562 if (ret)
563 return 0;
1cc63249 564
cba85b53
PNA
565 return nla_total_size(0) /* CTA_SECCTX */
566 + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */
567#else
568 return 0;
1cc63249 569#endif
cba85b53 570}
1cc63249 571
4054ff45 572static size_t ctnetlink_timestamp_size(const struct nf_conn *ct)
a992ca2a
PNA
573{
574#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
575 if (!nf_ct_ext_exist(ct, NF_CT_EXT_TSTAMP))
576 return 0;
577 return nla_total_size(0) + 2 * nla_total_size(sizeof(uint64_t));
578#else
579 return 0;
580#endif
581}
582
4054ff45
PNA
583#ifdef CONFIG_NF_CONNTRACK_EVENTS
584static size_t ctnetlink_nlmsg_size(const struct nf_conn *ct)
03b64f51
PNA
585{
586 return NLMSG_ALIGN(sizeof(struct nfgenmsg))
587 + 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */
588 + 3 * nla_total_size(0) /* CTA_TUPLE_IP */
589 + 3 * nla_total_size(0) /* CTA_TUPLE_PROTO */
590 + 3 * nla_total_size(sizeof(u_int8_t)) /* CTA_PROTO_NUM */
591 + nla_total_size(sizeof(u_int32_t)) /* CTA_ID */
592 + nla_total_size(sizeof(u_int32_t)) /* CTA_STATUS */
f7b13e43 593 + ctnetlink_acct_size(ct)
a992ca2a 594 + ctnetlink_timestamp_size(ct)
03b64f51
PNA
595 + nla_total_size(sizeof(u_int32_t)) /* CTA_TIMEOUT */
596 + nla_total_size(0) /* CTA_PROTOINFO */
597 + nla_total_size(0) /* CTA_HELP */
598 + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */
cba85b53 599 + ctnetlink_secctx_size(ct)
d271e8bd 600#ifdef CONFIG_NF_NAT_NEEDED
03b64f51
PNA
601 + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */
602 + 6 * nla_total_size(sizeof(u_int32_t)) /* CTA_NAT_SEQ_OFFSET */
d271e8bd
HE
603#endif
604#ifdef CONFIG_NF_CONNTRACK_MARK
03b64f51 605 + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
4a001068
KM
606#endif
607#ifdef CONFIG_NF_CONNTRACK_ZONES
deedb590 608 + nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE|CTA_TUPLE_ZONE */
d271e8bd 609#endif
03b64f51 610 + ctnetlink_proto_size(ct)
0ceabd83 611 + ctnetlink_label_size(ct)
03b64f51 612 ;
2732c4e4
HE
613}
614
e34d5c1a
PNA
615static int
616ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
c1d10adb 617{
308ac914 618 const struct nf_conntrack_zone *zone;
9592a5c0 619 struct net *net;
c1d10adb
PNA
620 struct nlmsghdr *nlh;
621 struct nfgenmsg *nfmsg;
df6fb868 622 struct nlattr *nest_parms;
19abb7b0 623 struct nf_conn *ct = item->ct;
c1d10adb
PNA
624 struct sk_buff *skb;
625 unsigned int type;
c1d10adb 626 unsigned int flags = 0, group;
dd7669a9 627 int err;
c1d10adb
PNA
628
629 /* ignore our fake conntrack entry */
5bfddbd4 630 if (nf_ct_is_untracked(ct))
e34d5c1a 631 return 0;
c1d10adb 632
a0891aa6 633 if (events & (1 << IPCT_DESTROY)) {
c1d10adb
PNA
634 type = IPCTNL_MSG_CT_DELETE;
635 group = NFNLGRP_CONNTRACK_DESTROY;
a0891aa6 636 } else if (events & ((1 << IPCT_NEW) | (1 << IPCT_RELATED))) {
c1d10adb
PNA
637 type = IPCTNL_MSG_CT_NEW;
638 flags = NLM_F_CREATE|NLM_F_EXCL;
c1d10adb 639 group = NFNLGRP_CONNTRACK_NEW;
17e6e4ea 640 } else if (events) {
c1d10adb
PNA
641 type = IPCTNL_MSG_CT_NEW;
642 group = NFNLGRP_CONNTRACK_UPDATE;
643 } else
e34d5c1a 644 return 0;
a2427692 645
9592a5c0
AD
646 net = nf_ct_net(ct);
647 if (!item->report && !nfnetlink_has_listeners(net, group))
e34d5c1a 648 return 0;
a2427692 649
03b64f51
PNA
650 skb = nlmsg_new(ctnetlink_nlmsg_size(ct), GFP_ATOMIC);
651 if (skb == NULL)
150ace0d 652 goto errout;
c1d10adb 653
c1d10adb 654 type |= NFNL_SUBSYS_CTNETLINK << 8;
15e47304 655 nlh = nlmsg_put(skb, item->portid, 0, type, sizeof(*nfmsg), flags);
96bcf938
PNA
656 if (nlh == NULL)
657 goto nlmsg_failure;
c1d10adb 658
96bcf938 659 nfmsg = nlmsg_data(nlh);
5e8fbe2a 660 nfmsg->nfgen_family = nf_ct_l3num(ct);
c1d10adb
PNA
661 nfmsg->version = NFNETLINK_V0;
662 nfmsg->res_id = 0;
663
528a3a6f 664 rcu_read_lock();
deedb590
DB
665 zone = nf_ct_zone(ct);
666
df6fb868
PM
667 nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED);
668 if (!nest_parms)
669 goto nla_put_failure;
f2f3e38c 670 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
df6fb868 671 goto nla_put_failure;
deedb590
DB
672 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
673 NF_CT_ZONE_DIR_ORIG) < 0)
674 goto nla_put_failure;
df6fb868 675 nla_nest_end(skb, nest_parms);
601e68e1 676
df6fb868
PM
677 nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY | NLA_F_NESTED);
678 if (!nest_parms)
679 goto nla_put_failure;
f2f3e38c 680 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0)
df6fb868 681 goto nla_put_failure;
deedb590
DB
682 if (ctnetlink_dump_zone_id(skb, CTA_TUPLE_ZONE, zone,
683 NF_CT_ZONE_DIR_REPL) < 0)
684 goto nla_put_failure;
df6fb868 685 nla_nest_end(skb, nest_parms);
c1d10adb 686
deedb590
DB
687 if (ctnetlink_dump_zone_id(skb, CTA_ZONE, zone,
688 NF_CT_DEFAULT_ZONE_DIR) < 0)
cc1eb431 689 goto nla_put_failure;
ef00f89f 690
1eedf699
EL
691 if (ctnetlink_dump_id(skb, ct) < 0)
692 goto nla_put_failure;
693
e57dce60
FH
694 if (ctnetlink_dump_status(skb, ct) < 0)
695 goto nla_put_failure;
696
a0891aa6 697 if (events & (1 << IPCT_DESTROY)) {
4542fa47 698 if (ctnetlink_dump_acct(skb, ct, type) < 0 ||
a992ca2a 699 ctnetlink_dump_timestamp(skb, ct) < 0)
df6fb868 700 goto nla_put_failure;
7b621c1e 701 } else {
7b621c1e 702 if (ctnetlink_dump_timeout(skb, ct) < 0)
df6fb868 703 goto nla_put_failure;
7b621c1e 704
a0891aa6 705 if (events & (1 << IPCT_PROTOINFO)
7b621c1e 706 && ctnetlink_dump_protoinfo(skb, ct) < 0)
df6fb868 707 goto nla_put_failure;
7b621c1e 708
a0891aa6 709 if ((events & (1 << IPCT_HELPER) || nfct_help(ct))
7b621c1e 710 && ctnetlink_dump_helpinfo(skb, ct) < 0)
df6fb868 711 goto nla_put_failure;
7b621c1e 712
ff660c80 713#ifdef CONFIG_NF_CONNTRACK_SECMARK
a0891aa6 714 if ((events & (1 << IPCT_SECMARK) || ct->secmark)
1cc63249 715 && ctnetlink_dump_secctx(skb, ct) < 0)
37fccd85 716 goto nla_put_failure;
ff660c80 717#endif
0ceabd83
FW
718 if (events & (1 << IPCT_LABEL) &&
719 ctnetlink_dump_labels(skb, ct) < 0)
720 goto nla_put_failure;
7b621c1e 721
a0891aa6 722 if (events & (1 << IPCT_RELATED) &&
0f417ce9
PNA
723 ctnetlink_dump_master(skb, ct) < 0)
724 goto nla_put_failure;
725
41d73ec0
PM
726 if (events & (1 << IPCT_SEQADJ) &&
727 ctnetlink_dump_ct_seq_adj(skb, ct) < 0)
13eae15a 728 goto nla_put_failure;
7b621c1e 729 }
b9a37e0c 730
a83099a6 731#ifdef CONFIG_NF_CONNTRACK_MARK
a0891aa6 732 if ((events & (1 << IPCT_MARK) || ct->mark)
a83099a6
EL
733 && ctnetlink_dump_mark(skb, ct) < 0)
734 goto nla_put_failure;
735#endif
528a3a6f 736 rcu_read_unlock();
a83099a6 737
96bcf938 738 nlmsg_end(skb, nlh);
15e47304 739 err = nfnetlink_send(skb, net, item->portid, group, item->report,
cd8c20b6 740 GFP_ATOMIC);
dd7669a9
PNA
741 if (err == -ENOBUFS || err == -EAGAIN)
742 return -ENOBUFS;
743
e34d5c1a 744 return 0;
c1d10adb 745
df6fb868 746nla_put_failure:
528a3a6f 747 rcu_read_unlock();
96bcf938 748 nlmsg_cancel(skb, nlh);
528a3a6f 749nlmsg_failure:
c1d10adb 750 kfree_skb(skb);
150ace0d 751errout:
37b7ef72
PNA
752 if (nfnetlink_set_err(net, 0, group, -ENOBUFS) > 0)
753 return -ENOBUFS;
754
e34d5c1a 755 return 0;
c1d10adb
PNA
756}
757#endif /* CONFIG_NF_CONNTRACK_EVENTS */
758
759static int ctnetlink_done(struct netlink_callback *cb)
760{
89f2e218
PM
761 if (cb->args[1])
762 nf_ct_put((struct nf_conn *)cb->args[1]);
397304b5 763 kfree(cb->data);
c1d10adb
PNA
764 return 0;
765}
766
866476f3 767struct ctnetlink_filter {
0f298a28
PNA
768 struct {
769 u_int32_t val;
770 u_int32_t mask;
771 } mark;
772};
773
866476f3
KE
774static struct ctnetlink_filter *
775ctnetlink_alloc_filter(const struct nlattr * const cda[])
776{
777#ifdef CONFIG_NF_CONNTRACK_MARK
778 struct ctnetlink_filter *filter;
779
780 filter = kzalloc(sizeof(*filter), GFP_KERNEL);
781 if (filter == NULL)
782 return ERR_PTR(-ENOMEM);
783
784 filter->mark.val = ntohl(nla_get_be32(cda[CTA_MARK]));
785 filter->mark.mask = ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
786
787 return filter;
788#else
789 return ERR_PTR(-EOPNOTSUPP);
790#endif
791}
792
793static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
794{
795 struct ctnetlink_filter *filter = data;
796
797 if (filter == NULL)
798 return 1;
799
800#ifdef CONFIG_NF_CONNTRACK_MARK
801 if ((ct->mark & filter->mark.mask) == filter->mark.val)
802 return 1;
803#endif
804
805 return 0;
806}
807
c1d10adb
PNA
808static int
809ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
810{
9592a5c0 811 struct net *net = sock_net(skb->sk);
89f2e218 812 struct nf_conn *ct, *last;
c1d10adb 813 struct nf_conntrack_tuple_hash *h;
ea781f19 814 struct hlist_nulls_node *n;
96bcf938 815 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
87711cb8 816 u_int8_t l3proto = nfmsg->nfgen_family;
3b988ece 817 int res;
93bb0ceb
JDB
818 spinlock_t *lockp;
819
d205dc40 820 last = (struct nf_conn *)cb->args[1];
93bb0ceb
JDB
821
822 local_bh_disable();
9ab99d5a 823 for (; cb->args[0] < net->ct.htable_size; cb->args[0]++) {
89f2e218 824restart:
93bb0ceb 825 lockp = &nf_conntrack_locks[cb->args[0] % CONNTRACK_LOCKS];
b16c2919 826 nf_conntrack_lock(lockp);
93bb0ceb
JDB
827 if (cb->args[0] >= net->ct.htable_size) {
828 spin_unlock(lockp);
829 goto out;
830 }
13ee6ac5 831 hlist_nulls_for_each_entry(h, n, &net->ct.hash[cb->args[0]],
ea781f19 832 hnnode) {
5b1158e9 833 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
c1d10adb
PNA
834 continue;
835 ct = nf_ct_tuplehash_to_ctrack(h);
87711cb8
PNA
836 /* Dump entries of a given L3 protocol number.
837 * If it is not specified, ie. l3proto == 0,
838 * then dump everything. */
5e8fbe2a 839 if (l3proto && nf_ct_l3num(ct) != l3proto)
13ee6ac5 840 continue;
d205dc40
PM
841 if (cb->args[1]) {
842 if (ct != last)
13ee6ac5 843 continue;
d205dc40 844 cb->args[1] = 0;
89f2e218 845 }
866476f3 846 if (!ctnetlink_filter_match(ct, cb->data))
0f298a28 847 continue;
866476f3 848
3b988ece
HS
849 rcu_read_lock();
850 res =
15e47304 851 ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
3b988ece
HS
852 cb->nlh->nlmsg_seq,
853 NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
854 ct);
855 rcu_read_unlock();
856 if (res < 0) {
c71caf41 857 nf_conntrack_get(&ct->ct_general);
89f2e218 858 cb->args[1] = (unsigned long)ct;
93bb0ceb 859 spin_unlock(lockp);
c1d10adb 860 goto out;
89f2e218
PM
861 }
862 }
93bb0ceb 863 spin_unlock(lockp);
d205dc40 864 if (cb->args[1]) {
89f2e218
PM
865 cb->args[1] = 0;
866 goto restart;
c1d10adb
PNA
867 }
868 }
89f2e218 869out:
93bb0ceb 870 local_bh_enable();
d205dc40
PM
871 if (last)
872 nf_ct_put(last);
c1d10adb 873
c1d10adb
PNA
874 return skb->len;
875}
876
4054ff45
PNA
877static int ctnetlink_parse_tuple_ip(struct nlattr *attr,
878 struct nf_conntrack_tuple *tuple)
c1d10adb 879{
df6fb868 880 struct nlattr *tb[CTA_IP_MAX+1];
c1d10adb
PNA
881 struct nf_conntrack_l3proto *l3proto;
882 int ret = 0;
883
130ffbc2
DB
884 ret = nla_parse_nested(tb, CTA_IP_MAX, attr, NULL);
885 if (ret < 0)
886 return ret;
c1d10adb 887
cd91566e
FW
888 rcu_read_lock();
889 l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
c1d10adb 890
f73e924c
PM
891 if (likely(l3proto->nlattr_to_tuple)) {
892 ret = nla_validate_nested(attr, CTA_IP_MAX,
893 l3proto->nla_policy);
894 if (ret == 0)
895 ret = l3proto->nlattr_to_tuple(tb, tuple);
896 }
c1d10adb 897
cd91566e 898 rcu_read_unlock();
c1d10adb 899
c1d10adb
PNA
900 return ret;
901}
902
f73e924c
PM
903static const struct nla_policy proto_nla_policy[CTA_PROTO_MAX+1] = {
904 [CTA_PROTO_NUM] = { .type = NLA_U8 },
c1d10adb
PNA
905};
906
4054ff45
PNA
907static int ctnetlink_parse_tuple_proto(struct nlattr *attr,
908 struct nf_conntrack_tuple *tuple)
c1d10adb 909{
df6fb868 910 struct nlattr *tb[CTA_PROTO_MAX+1];
605dcad6 911 struct nf_conntrack_l4proto *l4proto;
c1d10adb
PNA
912 int ret = 0;
913
f73e924c
PM
914 ret = nla_parse_nested(tb, CTA_PROTO_MAX, attr, proto_nla_policy);
915 if (ret < 0)
916 return ret;
c1d10adb 917
df6fb868 918 if (!tb[CTA_PROTO_NUM])
c1d10adb 919 return -EINVAL;
77236b6e 920 tuple->dst.protonum = nla_get_u8(tb[CTA_PROTO_NUM]);
c1d10adb 921
cd91566e
FW
922 rcu_read_lock();
923 l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum);
c1d10adb 924
f73e924c
PM
925 if (likely(l4proto->nlattr_to_tuple)) {
926 ret = nla_validate_nested(attr, CTA_PROTO_MAX,
927 l4proto->nla_policy);
928 if (ret == 0)
929 ret = l4proto->nlattr_to_tuple(tb, tuple);
930 }
c1d10adb 931
cd91566e 932 rcu_read_unlock();
601e68e1 933
c1d10adb
PNA
934 return ret;
935}
936
deedb590
DB
937static int
938ctnetlink_parse_zone(const struct nlattr *attr,
939 struct nf_conntrack_zone *zone)
940{
5e8018fc
DB
941 nf_ct_zone_init(zone, NF_CT_DEFAULT_ZONE_ID,
942 NF_CT_DEFAULT_ZONE_DIR, 0);
deedb590
DB
943#ifdef CONFIG_NF_CONNTRACK_ZONES
944 if (attr)
945 zone->id = ntohs(nla_get_be16(attr));
946#else
947 if (attr)
948 return -EOPNOTSUPP;
949#endif
950 return 0;
951}
952
953static int
954ctnetlink_parse_tuple_zone(struct nlattr *attr, enum ctattr_type type,
955 struct nf_conntrack_zone *zone)
956{
957 int ret;
958
959 if (zone->id != NF_CT_DEFAULT_ZONE_ID)
960 return -EINVAL;
961
962 ret = ctnetlink_parse_zone(attr, zone);
963 if (ret < 0)
964 return ret;
965
966 if (type == CTA_TUPLE_REPLY)
967 zone->dir = NF_CT_ZONE_DIR_REPL;
968 else
969 zone->dir = NF_CT_ZONE_DIR_ORIG;
970
971 return 0;
972}
973
d0b0268f
PM
974static const struct nla_policy tuple_nla_policy[CTA_TUPLE_MAX+1] = {
975 [CTA_TUPLE_IP] = { .type = NLA_NESTED },
976 [CTA_TUPLE_PROTO] = { .type = NLA_NESTED },
deedb590 977 [CTA_TUPLE_ZONE] = { .type = NLA_U16 },
d0b0268f
PM
978};
979
bb5cf80e 980static int
39938324
PM
981ctnetlink_parse_tuple(const struct nlattr * const cda[],
982 struct nf_conntrack_tuple *tuple,
deedb590
DB
983 enum ctattr_type type, u_int8_t l3num,
984 struct nf_conntrack_zone *zone)
c1d10adb 985{
df6fb868 986 struct nlattr *tb[CTA_TUPLE_MAX+1];
c1d10adb
PNA
987 int err;
988
c1d10adb
PNA
989 memset(tuple, 0, sizeof(*tuple));
990
130ffbc2
DB
991 err = nla_parse_nested(tb, CTA_TUPLE_MAX, cda[type], tuple_nla_policy);
992 if (err < 0)
993 return err;
c1d10adb 994
df6fb868 995 if (!tb[CTA_TUPLE_IP])
c1d10adb
PNA
996 return -EINVAL;
997
998 tuple->src.l3num = l3num;
999
df6fb868 1000 err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP], tuple);
c1d10adb
PNA
1001 if (err < 0)
1002 return err;
1003
df6fb868 1004 if (!tb[CTA_TUPLE_PROTO])
c1d10adb
PNA
1005 return -EINVAL;
1006
df6fb868 1007 err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO], tuple);
c1d10adb
PNA
1008 if (err < 0)
1009 return err;
1010
deedb590
DB
1011 if (tb[CTA_TUPLE_ZONE]) {
1012 if (!zone)
1013 return -EINVAL;
1014
1015 err = ctnetlink_parse_tuple_zone(tb[CTA_TUPLE_ZONE],
1016 type, zone);
1017 if (err < 0)
1018 return err;
1019 }
1020
c1d10adb
PNA
1021 /* orig and expect tuples get DIR_ORIGINAL */
1022 if (type == CTA_TUPLE_REPLY)
1023 tuple->dst.dir = IP_CT_DIR_REPLY;
1024 else
1025 tuple->dst.dir = IP_CT_DIR_ORIGINAL;
1026
c1d10adb
PNA
1027 return 0;
1028}
1029
d0b0268f 1030static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = {
6d1fafca
FW
1031 [CTA_HELP_NAME] = { .type = NLA_NUL_STRING,
1032 .len = NF_CT_HELPER_NAME_LEN - 1 },
d0b0268f
PM
1033};
1034
4054ff45
PNA
1035static int ctnetlink_parse_help(const struct nlattr *attr, char **helper_name,
1036 struct nlattr **helpinfo)
c1d10adb 1037{
130ffbc2 1038 int err;
df6fb868 1039 struct nlattr *tb[CTA_HELP_MAX+1];
c1d10adb 1040
130ffbc2
DB
1041 err = nla_parse_nested(tb, CTA_HELP_MAX, attr, help_nla_policy);
1042 if (err < 0)
1043 return err;
c1d10adb 1044
df6fb868 1045 if (!tb[CTA_HELP_NAME])
c1d10adb
PNA
1046 return -EINVAL;
1047
df6fb868 1048 *helper_name = nla_data(tb[CTA_HELP_NAME]);
c1d10adb 1049
ae243bee
PNA
1050 if (tb[CTA_HELP_INFO])
1051 *helpinfo = tb[CTA_HELP_INFO];
1052
c1d10adb
PNA
1053 return 0;
1054}
1055
f73e924c 1056static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
d0b0268f
PM
1057 [CTA_TUPLE_ORIG] = { .type = NLA_NESTED },
1058 [CTA_TUPLE_REPLY] = { .type = NLA_NESTED },
f73e924c 1059 [CTA_STATUS] = { .type = NLA_U32 },
d0b0268f
PM
1060 [CTA_PROTOINFO] = { .type = NLA_NESTED },
1061 [CTA_HELP] = { .type = NLA_NESTED },
1062 [CTA_NAT_SRC] = { .type = NLA_NESTED },
f73e924c
PM
1063 [CTA_TIMEOUT] = { .type = NLA_U32 },
1064 [CTA_MARK] = { .type = NLA_U32 },
f73e924c 1065 [CTA_ID] = { .type = NLA_U32 },
d0b0268f
PM
1066 [CTA_NAT_DST] = { .type = NLA_NESTED },
1067 [CTA_TUPLE_MASTER] = { .type = NLA_NESTED },
6d1fafca
FW
1068 [CTA_NAT_SEQ_ADJ_ORIG] = { .type = NLA_NESTED },
1069 [CTA_NAT_SEQ_ADJ_REPLY] = { .type = NLA_NESTED },
ef00f89f 1070 [CTA_ZONE] = { .type = NLA_U16 },
0f298a28 1071 [CTA_MARK_MASK] = { .type = NLA_U32 },
9b21f6a9 1072 [CTA_LABELS] = { .type = NLA_BINARY,
d2bf2f34 1073 .len = NF_CT_LABELS_MAX_SIZE },
9b21f6a9 1074 [CTA_LABELS_MASK] = { .type = NLA_BINARY,
d2bf2f34 1075 .len = NF_CT_LABELS_MAX_SIZE },
c1d10adb
PNA
1076};
1077
866476f3
KE
1078static int ctnetlink_flush_conntrack(struct net *net,
1079 const struct nlattr * const cda[],
1080 u32 portid, int report)
1081{
1082 struct ctnetlink_filter *filter = NULL;
1083
1084 if (cda[CTA_MARK] && cda[CTA_MARK_MASK]) {
1085 filter = ctnetlink_alloc_filter(cda);
1086 if (IS_ERR(filter))
1087 return PTR_ERR(filter);
1088 }
1089
1090 nf_ct_iterate_cleanup(net, ctnetlink_filter_match, filter,
1091 portid, report);
1092 kfree(filter);
1093
1094 return 0;
1095}
1096
7b8002a1
PNA
1097static int ctnetlink_del_conntrack(struct net *net, struct sock *ctnl,
1098 struct sk_buff *skb,
1099 const struct nlmsghdr *nlh,
1100 const struct nlattr * const cda[])
c1d10adb
PNA
1101{
1102 struct nf_conntrack_tuple_hash *h;
1103 struct nf_conntrack_tuple tuple;
1104 struct nf_conn *ct;
96bcf938 1105 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 1106 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 1107 struct nf_conntrack_zone zone;
ef00f89f
PM
1108 int err;
1109
1110 err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone);
1111 if (err < 0)
1112 return err;
c1d10adb 1113
df6fb868 1114 if (cda[CTA_TUPLE_ORIG])
deedb590
DB
1115 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG,
1116 u3, &zone);
df6fb868 1117 else if (cda[CTA_TUPLE_REPLY])
deedb590
DB
1118 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY,
1119 u3, &zone);
c1d10adb 1120 else {
866476f3
KE
1121 return ctnetlink_flush_conntrack(net, cda,
1122 NETLINK_CB(skb).portid,
1123 nlmsg_report(nlh));
c1d10adb
PNA
1124 }
1125
1126 if (err < 0)
1127 return err;
1128
308ac914 1129 h = nf_conntrack_find_get(net, &zone, &tuple);
9ea8cfd6 1130 if (!h)
c1d10adb 1131 return -ENOENT;
c1d10adb
PNA
1132
1133 ct = nf_ct_tuplehash_to_ctrack(h);
601e68e1 1134
df6fb868 1135 if (cda[CTA_ID]) {
77236b6e 1136 u_int32_t id = ntohl(nla_get_be32(cda[CTA_ID]));
7f85f914 1137 if (id != (u32)(unsigned long)ct) {
c1d10adb
PNA
1138 nf_ct_put(ct);
1139 return -ENOENT;
1140 }
601e68e1 1141 }
c1d10adb 1142
02982c27
FW
1143 if (del_timer(&ct->timeout))
1144 nf_ct_delete(ct, NETLINK_CB(skb).portid, nlmsg_report(nlh));
1145
c1d10adb 1146 nf_ct_put(ct);
c1d10adb
PNA
1147
1148 return 0;
1149}
1150
7b8002a1
PNA
1151static int ctnetlink_get_conntrack(struct net *net, struct sock *ctnl,
1152 struct sk_buff *skb,
1153 const struct nlmsghdr *nlh,
1154 const struct nlattr * const cda[])
c1d10adb
PNA
1155{
1156 struct nf_conntrack_tuple_hash *h;
1157 struct nf_conntrack_tuple tuple;
1158 struct nf_conn *ct;
1159 struct sk_buff *skb2 = NULL;
96bcf938 1160 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 1161 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 1162 struct nf_conntrack_zone zone;
ef00f89f 1163 int err;
c1d10adb 1164
80d326fa
PNA
1165 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1166 struct netlink_dump_control c = {
1167 .dump = ctnetlink_dump_table,
1168 .done = ctnetlink_done,
1169 };
866476f3 1170
0f298a28 1171 if (cda[CTA_MARK] && cda[CTA_MARK_MASK]) {
866476f3 1172 struct ctnetlink_filter *filter;
0f298a28 1173
866476f3
KE
1174 filter = ctnetlink_alloc_filter(cda);
1175 if (IS_ERR(filter))
1176 return PTR_ERR(filter);
0f298a28 1177
0f298a28
PNA
1178 c.data = filter;
1179 }
80d326fa
PNA
1180 return netlink_dump_start(ctnl, skb, nlh, &c);
1181 }
c1d10adb 1182
ef00f89f
PM
1183 err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone);
1184 if (err < 0)
1185 return err;
1186
df6fb868 1187 if (cda[CTA_TUPLE_ORIG])
deedb590
DB
1188 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG,
1189 u3, &zone);
df6fb868 1190 else if (cda[CTA_TUPLE_REPLY])
deedb590
DB
1191 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY,
1192 u3, &zone);
c1d10adb
PNA
1193 else
1194 return -EINVAL;
1195
1196 if (err < 0)
1197 return err;
1198
308ac914 1199 h = nf_conntrack_find_get(net, &zone, &tuple);
9ea8cfd6 1200 if (!h)
c1d10adb 1201 return -ENOENT;
9ea8cfd6 1202
c1d10adb
PNA
1203 ct = nf_ct_tuplehash_to_ctrack(h);
1204
1205 err = -ENOMEM;
96bcf938
PNA
1206 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1207 if (skb2 == NULL) {
c1d10adb
PNA
1208 nf_ct_put(ct);
1209 return -ENOMEM;
1210 }
c1d10adb 1211
528a3a6f 1212 rcu_read_lock();
15e47304 1213 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
80e60e67 1214 NFNL_MSG_TYPE(nlh->nlmsg_type), ct);
528a3a6f 1215 rcu_read_unlock();
c1d10adb
PNA
1216 nf_ct_put(ct);
1217 if (err <= 0)
1218 goto free;
1219
15e47304 1220 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
c1d10adb
PNA
1221 if (err < 0)
1222 goto out;
1223
c1d10adb
PNA
1224 return 0;
1225
1226free:
1227 kfree_skb(skb2);
1228out:
f31e8d49
PNA
1229 /* this avoids a loop in nfnetlink. */
1230 return err == -EAGAIN ? -ENOBUFS : err;
c1d10adb
PNA
1231}
1232
d871befe
PNA
1233static int ctnetlink_done_list(struct netlink_callback *cb)
1234{
1235 if (cb->args[1])
1236 nf_ct_put((struct nf_conn *)cb->args[1]);
1237 return 0;
1238}
1239
1240static int
b7779d06 1241ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
d871befe 1242{
cd5f336f 1243 struct nf_conn *ct, *last;
d871befe
PNA
1244 struct nf_conntrack_tuple_hash *h;
1245 struct hlist_nulls_node *n;
1246 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1247 u_int8_t l3proto = nfmsg->nfgen_family;
1248 int res;
b7779d06
JDB
1249 int cpu;
1250 struct hlist_nulls_head *list;
1251 struct net *net = sock_net(skb->sk);
d871befe
PNA
1252
1253 if (cb->args[2])
1254 return 0;
1255
cd5f336f
FW
1256 last = (struct nf_conn *)cb->args[1];
1257
b7779d06
JDB
1258 for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
1259 struct ct_pcpu *pcpu;
1260
1261 if (!cpu_possible(cpu))
d871befe 1262 continue;
b7779d06
JDB
1263
1264 pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
1265 spin_lock_bh(&pcpu->lock);
b7779d06
JDB
1266 list = dying ? &pcpu->dying : &pcpu->unconfirmed;
1267restart:
1268 hlist_nulls_for_each_entry(h, n, list, hnnode) {
1269 ct = nf_ct_tuplehash_to_ctrack(h);
1270 if (l3proto && nf_ct_l3num(ct) != l3proto)
d871befe 1271 continue;
b7779d06
JDB
1272 if (cb->args[1]) {
1273 if (ct != last)
1274 continue;
1275 cb->args[1] = 0;
1276 }
1277 rcu_read_lock();
1278 res = ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
1279 cb->nlh->nlmsg_seq,
1280 NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
1281 ct);
1282 rcu_read_unlock();
1283 if (res < 0) {
cd5f336f
FW
1284 if (!atomic_inc_not_zero(&ct->ct_general.use))
1285 continue;
266155b2 1286 cb->args[0] = cpu;
b7779d06
JDB
1287 cb->args[1] = (unsigned long)ct;
1288 spin_unlock_bh(&pcpu->lock);
1289 goto out;
1290 }
d871befe 1291 }
b7779d06
JDB
1292 if (cb->args[1]) {
1293 cb->args[1] = 0;
1294 goto restart;
266155b2 1295 }
b7779d06 1296 spin_unlock_bh(&pcpu->lock);
d871befe 1297 }
266155b2 1298 cb->args[2] = 1;
d871befe 1299out:
d871befe
PNA
1300 if (last)
1301 nf_ct_put(last);
1302
1303 return skb->len;
1304}
1305
1306static int
1307ctnetlink_dump_dying(struct sk_buff *skb, struct netlink_callback *cb)
1308{
b7779d06 1309 return ctnetlink_dump_list(skb, cb, true);
d871befe
PNA
1310}
1311
7b8002a1
PNA
1312static int ctnetlink_get_ct_dying(struct net *net, struct sock *ctnl,
1313 struct sk_buff *skb,
1314 const struct nlmsghdr *nlh,
1315 const struct nlattr * const cda[])
d871befe
PNA
1316{
1317 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1318 struct netlink_dump_control c = {
1319 .dump = ctnetlink_dump_dying,
1320 .done = ctnetlink_done_list,
1321 };
1322 return netlink_dump_start(ctnl, skb, nlh, &c);
1323 }
1324
1325 return -EOPNOTSUPP;
1326}
1327
1328static int
1329ctnetlink_dump_unconfirmed(struct sk_buff *skb, struct netlink_callback *cb)
1330{
b7779d06 1331 return ctnetlink_dump_list(skb, cb, false);
d871befe
PNA
1332}
1333
7b8002a1
PNA
1334static int ctnetlink_get_ct_unconfirmed(struct net *net, struct sock *ctnl,
1335 struct sk_buff *skb,
1336 const struct nlmsghdr *nlh,
1337 const struct nlattr * const cda[])
d871befe
PNA
1338{
1339 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1340 struct netlink_dump_control c = {
1341 .dump = ctnetlink_dump_unconfirmed,
1342 .done = ctnetlink_done_list,
1343 };
1344 return netlink_dump_start(ctnl, skb, nlh, &c);
1345 }
1346
1347 return -EOPNOTSUPP;
1348}
1349
67671841 1350#ifdef CONFIG_NF_NAT_NEEDED
e6a7d3c0
PNA
1351static int
1352ctnetlink_parse_nat_setup(struct nf_conn *ct,
1353 enum nf_nat_manip_type manip,
39938324 1354 const struct nlattr *attr)
e6a7d3c0
PNA
1355{
1356 typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
c7232c99 1357 int err;
e6a7d3c0
PNA
1358
1359 parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
1360 if (!parse_nat_setup) {
95a5afca 1361#ifdef CONFIG_MODULES
e6a7d3c0 1362 rcu_read_unlock();
c14b78e7 1363 nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
c7232c99 1364 if (request_module("nf-nat") < 0) {
c14b78e7 1365 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
e6a7d3c0
PNA
1366 rcu_read_lock();
1367 return -EOPNOTSUPP;
1368 }
c14b78e7 1369 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
e6a7d3c0
PNA
1370 rcu_read_lock();
1371 if (nfnetlink_parse_nat_setup_hook)
1372 return -EAGAIN;
1373#endif
1374 return -EOPNOTSUPP;
1375 }
1376
c7232c99
PM
1377 err = parse_nat_setup(ct, manip, attr);
1378 if (err == -EAGAIN) {
1379#ifdef CONFIG_MODULES
1380 rcu_read_unlock();
c14b78e7 1381 nfnl_unlock(NFNL_SUBSYS_CTNETLINK);
c7232c99 1382 if (request_module("nf-nat-%u", nf_ct_l3num(ct)) < 0) {
c14b78e7 1383 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
c7232c99
PM
1384 rcu_read_lock();
1385 return -EOPNOTSUPP;
1386 }
c14b78e7 1387 nfnl_lock(NFNL_SUBSYS_CTNETLINK);
c7232c99
PM
1388 rcu_read_lock();
1389#else
1390 err = -EOPNOTSUPP;
1391#endif
1392 }
1393 return err;
e6a7d3c0 1394}
67671841 1395#endif
e6a7d3c0 1396
bb5cf80e 1397static int
39938324 1398ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
c1d10adb
PNA
1399{
1400 unsigned long d;
77236b6e 1401 unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS]));
c1d10adb
PNA
1402 d = ct->status ^ status;
1403
1404 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
1405 /* unchangeable */
0adf9d67 1406 return -EBUSY;
601e68e1 1407
c1d10adb
PNA
1408 if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
1409 /* SEEN_REPLY bit can only be set */
0adf9d67 1410 return -EBUSY;
601e68e1 1411
c1d10adb
PNA
1412 if (d & IPS_ASSURED && !(status & IPS_ASSURED))
1413 /* ASSURED bit can only be set */
0adf9d67 1414 return -EBUSY;
c1d10adb 1415
c1d10adb
PNA
1416 /* Be careful here, modifying NAT bits can screw up things,
1417 * so don't let users modify them directly if they don't pass
5b1158e9 1418 * nf_nat_range. */
c1d10adb
PNA
1419 ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK);
1420 return 0;
1421}
1422
e6a7d3c0 1423static int
0eba801b 1424ctnetlink_setup_nat(struct nf_conn *ct, const struct nlattr * const cda[])
e6a7d3c0
PNA
1425{
1426#ifdef CONFIG_NF_NAT_NEEDED
1427 int ret;
1428
fe337ac2
FW
1429 if (!cda[CTA_NAT_DST] && !cda[CTA_NAT_SRC])
1430 return 0;
1431
0eba801b
PNA
1432 ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_DST,
1433 cda[CTA_NAT_DST]);
1434 if (ret < 0)
1435 return ret;
1436
1437 ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_SRC,
1438 cda[CTA_NAT_SRC]);
1439 return ret;
e6a7d3c0 1440#else
0eba801b
PNA
1441 if (!cda[CTA_NAT_DST] && !cda[CTA_NAT_SRC])
1442 return 0;
e6a7d3c0
PNA
1443 return -EOPNOTSUPP;
1444#endif
1445}
c1d10adb 1446
4054ff45
PNA
1447static int ctnetlink_change_helper(struct nf_conn *ct,
1448 const struct nlattr * const cda[])
c1d10adb
PNA
1449{
1450 struct nf_conntrack_helper *helper;
dc808fe2 1451 struct nf_conn_help *help = nfct_help(ct);
29fe1b48 1452 char *helpname = NULL;
ae243bee 1453 struct nlattr *helpinfo = NULL;
c1d10adb
PNA
1454 int err;
1455
c1d10adb
PNA
1456 /* don't change helper of sibling connections */
1457 if (ct->master)
0adf9d67 1458 return -EBUSY;
c1d10adb 1459
ae243bee 1460 err = ctnetlink_parse_help(cda[CTA_HELP], &helpname, &helpinfo);
c1d10adb
PNA
1461 if (err < 0)
1462 return err;
1463
df293bbb
YK
1464 if (!strcmp(helpname, "")) {
1465 if (help && help->helper) {
c1d10adb
PNA
1466 /* we had a helper before ... */
1467 nf_ct_remove_expectations(ct);
a9b3cd7f 1468 RCU_INIT_POINTER(help->helper, NULL);
c1d10adb 1469 }
df293bbb
YK
1470
1471 return 0;
c1d10adb 1472 }
601e68e1 1473
794e6871
PM
1474 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
1475 nf_ct_protonum(ct));
226c0c0e
PNA
1476 if (helper == NULL) {
1477#ifdef CONFIG_MODULES
ca7433df 1478 spin_unlock_bh(&nf_conntrack_expect_lock);
226c0c0e
PNA
1479
1480 if (request_module("nfct-helper-%s", helpname) < 0) {
ca7433df 1481 spin_lock_bh(&nf_conntrack_expect_lock);
226c0c0e
PNA
1482 return -EOPNOTSUPP;
1483 }
1484
ca7433df 1485 spin_lock_bh(&nf_conntrack_expect_lock);
794e6871
PM
1486 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
1487 nf_ct_protonum(ct));
226c0c0e
PNA
1488 if (helper)
1489 return -EAGAIN;
1490#endif
0adf9d67 1491 return -EOPNOTSUPP;
226c0c0e 1492 }
df293bbb 1493
ceceae1b 1494 if (help) {
ae243bee
PNA
1495 if (help->helper == helper) {
1496 /* update private helper data if allowed. */
7be54ca4 1497 if (helper->from_nlattr)
ae243bee 1498 helper->from_nlattr(helpinfo, ct);
ceceae1b 1499 return 0;
fd7462de 1500 } else
ceceae1b 1501 return -EBUSY;
ceceae1b 1502 }
df293bbb 1503
fd7462de
PNA
1504 /* we cannot set a helper for an existing conntrack */
1505 return -EOPNOTSUPP;
c1d10adb
PNA
1506}
1507
4054ff45
PNA
1508static int ctnetlink_change_timeout(struct nf_conn *ct,
1509 const struct nlattr * const cda[])
c1d10adb 1510{
77236b6e 1511 u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
601e68e1 1512
c1d10adb
PNA
1513 if (!del_timer(&ct->timeout))
1514 return -ETIME;
1515
1516 ct->timeout.expires = jiffies + timeout * HZ;
1517 add_timer(&ct->timeout);
1518
1519 return 0;
1520}
1521
d0b0268f
PM
1522static const struct nla_policy protoinfo_policy[CTA_PROTOINFO_MAX+1] = {
1523 [CTA_PROTOINFO_TCP] = { .type = NLA_NESTED },
1524 [CTA_PROTOINFO_DCCP] = { .type = NLA_NESTED },
1525 [CTA_PROTOINFO_SCTP] = { .type = NLA_NESTED },
1526};
1527
4054ff45
PNA
1528static int ctnetlink_change_protoinfo(struct nf_conn *ct,
1529 const struct nlattr * const cda[])
c1d10adb 1530{
39938324
PM
1531 const struct nlattr *attr = cda[CTA_PROTOINFO];
1532 struct nlattr *tb[CTA_PROTOINFO_MAX+1];
605dcad6 1533 struct nf_conntrack_l4proto *l4proto;
c1d10adb
PNA
1534 int err = 0;
1535
130ffbc2
DB
1536 err = nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, protoinfo_policy);
1537 if (err < 0)
1538 return err;
c1d10adb 1539
cd91566e
FW
1540 rcu_read_lock();
1541 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
fdf70832
PM
1542 if (l4proto->from_nlattr)
1543 err = l4proto->from_nlattr(tb, ct);
cd91566e 1544 rcu_read_unlock();
c1d10adb
PNA
1545
1546 return err;
1547}
1548
41d73ec0
PM
1549static const struct nla_policy seqadj_policy[CTA_SEQADJ_MAX+1] = {
1550 [CTA_SEQADJ_CORRECTION_POS] = { .type = NLA_U32 },
1551 [CTA_SEQADJ_OFFSET_BEFORE] = { .type = NLA_U32 },
1552 [CTA_SEQADJ_OFFSET_AFTER] = { .type = NLA_U32 },
d0b0268f
PM
1553};
1554
4054ff45
PNA
1555static int change_seq_adj(struct nf_ct_seqadj *seq,
1556 const struct nlattr * const attr)
13eae15a 1557{
130ffbc2 1558 int err;
41d73ec0 1559 struct nlattr *cda[CTA_SEQADJ_MAX+1];
13eae15a 1560
41d73ec0 1561 err = nla_parse_nested(cda, CTA_SEQADJ_MAX, attr, seqadj_policy);
130ffbc2
DB
1562 if (err < 0)
1563 return err;
13eae15a 1564
41d73ec0 1565 if (!cda[CTA_SEQADJ_CORRECTION_POS])
13eae15a
PNA
1566 return -EINVAL;
1567
41d73ec0
PM
1568 seq->correction_pos =
1569 ntohl(nla_get_be32(cda[CTA_SEQADJ_CORRECTION_POS]));
13eae15a 1570
41d73ec0 1571 if (!cda[CTA_SEQADJ_OFFSET_BEFORE])
13eae15a
PNA
1572 return -EINVAL;
1573
41d73ec0
PM
1574 seq->offset_before =
1575 ntohl(nla_get_be32(cda[CTA_SEQADJ_OFFSET_BEFORE]));
13eae15a 1576
41d73ec0 1577 if (!cda[CTA_SEQADJ_OFFSET_AFTER])
13eae15a
PNA
1578 return -EINVAL;
1579
41d73ec0
PM
1580 seq->offset_after =
1581 ntohl(nla_get_be32(cda[CTA_SEQADJ_OFFSET_AFTER]));
13eae15a
PNA
1582
1583 return 0;
1584}
1585
1586static int
41d73ec0
PM
1587ctnetlink_change_seq_adj(struct nf_conn *ct,
1588 const struct nlattr * const cda[])
13eae15a 1589{
41d73ec0 1590 struct nf_conn_seqadj *seqadj = nfct_seqadj(ct);
13eae15a 1591 int ret = 0;
13eae15a 1592
41d73ec0 1593 if (!seqadj)
13eae15a
PNA
1594 return 0;
1595
41d73ec0
PM
1596 if (cda[CTA_SEQ_ADJ_ORIG]) {
1597 ret = change_seq_adj(&seqadj->seq[IP_CT_DIR_ORIGINAL],
1598 cda[CTA_SEQ_ADJ_ORIG]);
13eae15a
PNA
1599 if (ret < 0)
1600 return ret;
1601
1602 ct->status |= IPS_SEQ_ADJUST;
1603 }
1604
41d73ec0
PM
1605 if (cda[CTA_SEQ_ADJ_REPLY]) {
1606 ret = change_seq_adj(&seqadj->seq[IP_CT_DIR_REPLY],
1607 cda[CTA_SEQ_ADJ_REPLY]);
13eae15a
PNA
1608 if (ret < 0)
1609 return ret;
1610
1611 ct->status |= IPS_SEQ_ADJUST;
1612 }
1613
1614 return 0;
1615}
13eae15a 1616
9b21f6a9
FW
1617static int
1618ctnetlink_attach_labels(struct nf_conn *ct, const struct nlattr * const cda[])
1619{
1620#ifdef CONFIG_NF_CONNTRACK_LABELS
1621 size_t len = nla_len(cda[CTA_LABELS]);
1622 const void *mask = cda[CTA_LABELS_MASK];
1623
1624 if (len & (sizeof(u32)-1)) /* must be multiple of u32 */
1625 return -EINVAL;
1626
1627 if (mask) {
1628 if (nla_len(cda[CTA_LABELS_MASK]) == 0 ||
1629 nla_len(cda[CTA_LABELS_MASK]) != len)
1630 return -EINVAL;
1631 mask = nla_data(cda[CTA_LABELS_MASK]);
1632 }
1633
1634 len /= sizeof(u32);
1635
1636 return nf_connlabels_replace(ct, nla_data(cda[CTA_LABELS]), mask, len);
1637#else
1638 return -EOPNOTSUPP;
1639#endif
1640}
1641
c1d10adb 1642static int
39938324
PM
1643ctnetlink_change_conntrack(struct nf_conn *ct,
1644 const struct nlattr * const cda[])
c1d10adb
PNA
1645{
1646 int err;
1647
e098360f
PNA
1648 /* only allow NAT changes and master assignation for new conntracks */
1649 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST] || cda[CTA_TUPLE_MASTER])
1650 return -EOPNOTSUPP;
1651
df6fb868 1652 if (cda[CTA_HELP]) {
c1d10adb
PNA
1653 err = ctnetlink_change_helper(ct, cda);
1654 if (err < 0)
1655 return err;
1656 }
1657
df6fb868 1658 if (cda[CTA_TIMEOUT]) {
c1d10adb
PNA
1659 err = ctnetlink_change_timeout(ct, cda);
1660 if (err < 0)
1661 return err;
1662 }
1663
df6fb868 1664 if (cda[CTA_STATUS]) {
c1d10adb
PNA
1665 err = ctnetlink_change_status(ct, cda);
1666 if (err < 0)
1667 return err;
1668 }
1669
df6fb868 1670 if (cda[CTA_PROTOINFO]) {
c1d10adb
PNA
1671 err = ctnetlink_change_protoinfo(ct, cda);
1672 if (err < 0)
1673 return err;
1674 }
1675
bcd1e830 1676#if defined(CONFIG_NF_CONNTRACK_MARK)
df6fb868 1677 if (cda[CTA_MARK])
77236b6e 1678 ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
c1d10adb
PNA
1679#endif
1680
41d73ec0
PM
1681 if (cda[CTA_SEQ_ADJ_ORIG] || cda[CTA_SEQ_ADJ_REPLY]) {
1682 err = ctnetlink_change_seq_adj(ct, cda);
13eae15a
PNA
1683 if (err < 0)
1684 return err;
1685 }
41d73ec0 1686
9b21f6a9
FW
1687 if (cda[CTA_LABELS]) {
1688 err = ctnetlink_attach_labels(ct, cda);
1689 if (err < 0)
1690 return err;
1691 }
13eae15a 1692
c1d10adb
PNA
1693 return 0;
1694}
1695
f0a3c086 1696static struct nf_conn *
308ac914
DB
1697ctnetlink_create_conntrack(struct net *net,
1698 const struct nf_conntrack_zone *zone,
9592a5c0 1699 const struct nlattr * const cda[],
c1d10adb 1700 struct nf_conntrack_tuple *otuple,
5faa1f4c 1701 struct nf_conntrack_tuple *rtuple,
7ec47496 1702 u8 u3)
c1d10adb
PNA
1703{
1704 struct nf_conn *ct;
1705 int err = -EINVAL;
ceceae1b 1706 struct nf_conntrack_helper *helper;
315c34da 1707 struct nf_conn_tstamp *tstamp;
c1d10adb 1708
ef00f89f 1709 ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC);
cd7fcbf1 1710 if (IS_ERR(ct))
f0a3c086 1711 return ERR_PTR(-ENOMEM);
c1d10adb 1712
df6fb868 1713 if (!cda[CTA_TIMEOUT])
0f5b3e85 1714 goto err1;
77236b6e 1715 ct->timeout.expires = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
c1d10adb
PNA
1716
1717 ct->timeout.expires = jiffies + ct->timeout.expires * 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:
b67bfe0d 2628 hlist_for_each_entry(exp, &net->ct.expect_hash[cb->args[0]],
31f15875
PM
2629 hnode) {
2630 if (l3proto && exp->tuple.src.l3num != l3proto)
cf6994c2 2631 continue;
31f15875
PM
2632 if (cb->args[1]) {
2633 if (exp != last)
2634 continue;
2635 cb->args[1] = 0;
2636 }
8b0a231d 2637 if (ctnetlink_exp_fill_info(skb,
15e47304 2638 NETLINK_CB(cb->skb).portid,
31f15875
PM
2639 cb->nlh->nlmsg_seq,
2640 IPCTNL_MSG_EXP_NEW,
8b0a231d 2641 exp) < 0) {
7d0742da
PM
2642 if (!atomic_inc_not_zero(&exp->use))
2643 continue;
31f15875
PM
2644 cb->args[1] = (unsigned long)exp;
2645 goto out;
2646 }
cf6994c2 2647 }
31f15875
PM
2648 if (cb->args[1]) {
2649 cb->args[1] = 0;
2650 goto restart;
cf6994c2
PM
2651 }
2652 }
601e68e1 2653out:
7d0742da 2654 rcu_read_unlock();
cf6994c2
PM
2655 if (last)
2656 nf_ct_expect_put(last);
c1d10adb 2657
c1d10adb
PNA
2658 return skb->len;
2659}
2660
e844a928
PNA
2661static int
2662ctnetlink_exp_ct_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
2663{
2664 struct nf_conntrack_expect *exp, *last;
2665 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
2666 struct nf_conn *ct = cb->data;
2667 struct nf_conn_help *help = nfct_help(ct);
2668 u_int8_t l3proto = nfmsg->nfgen_family;
2669
2670 if (cb->args[0])
2671 return 0;
2672
2673 rcu_read_lock();
2674 last = (struct nf_conntrack_expect *)cb->args[1];
2675restart:
2676 hlist_for_each_entry(exp, &help->expectations, lnode) {
2677 if (l3proto && exp->tuple.src.l3num != l3proto)
2678 continue;
2679 if (cb->args[1]) {
2680 if (exp != last)
2681 continue;
2682 cb->args[1] = 0;
2683 }
2684 if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).portid,
2685 cb->nlh->nlmsg_seq,
2686 IPCTNL_MSG_EXP_NEW,
2687 exp) < 0) {
2688 if (!atomic_inc_not_zero(&exp->use))
2689 continue;
2690 cb->args[1] = (unsigned long)exp;
2691 goto out;
2692 }
2693 }
2694 if (cb->args[1]) {
2695 cb->args[1] = 0;
2696 goto restart;
2697 }
2698 cb->args[0] = 1;
2699out:
2700 rcu_read_unlock();
2701 if (last)
2702 nf_ct_expect_put(last);
2703
2704 return skb->len;
2705}
2706
7b8002a1
PNA
2707static int ctnetlink_dump_exp_ct(struct net *net, struct sock *ctnl,
2708 struct sk_buff *skb,
e844a928
PNA
2709 const struct nlmsghdr *nlh,
2710 const struct nlattr * const cda[])
2711{
2712 int err;
e844a928
PNA
2713 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2714 u_int8_t u3 = nfmsg->nfgen_family;
2715 struct nf_conntrack_tuple tuple;
2716 struct nf_conntrack_tuple_hash *h;
2717 struct nf_conn *ct;
308ac914 2718 struct nf_conntrack_zone zone;
e844a928
PNA
2719 struct netlink_dump_control c = {
2720 .dump = ctnetlink_exp_ct_dump_table,
2721 .done = ctnetlink_exp_done,
2722 };
2723
deedb590
DB
2724 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER,
2725 u3, NULL);
e844a928
PNA
2726 if (err < 0)
2727 return err;
2728
308ac914
DB
2729 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
2730 if (err < 0)
2731 return err;
e844a928 2732
308ac914 2733 h = nf_conntrack_find_get(net, &zone, &tuple);
e844a928
PNA
2734 if (!h)
2735 return -ENOENT;
2736
2737 ct = nf_ct_tuplehash_to_ctrack(h);
2738 c.data = ct;
2739
2740 err = netlink_dump_start(ctnl, skb, nlh, &c);
2741 nf_ct_put(ct);
2742
2743 return err;
2744}
2745
7b8002a1
PNA
2746static int ctnetlink_get_expect(struct net *net, struct sock *ctnl,
2747 struct sk_buff *skb, const struct nlmsghdr *nlh,
2748 const struct nlattr * const cda[])
c1d10adb
PNA
2749{
2750 struct nf_conntrack_tuple tuple;
2751 struct nf_conntrack_expect *exp;
2752 struct sk_buff *skb2;
96bcf938 2753 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 2754 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 2755 struct nf_conntrack_zone zone;
ef00f89f 2756 int err;
c1d10adb 2757
b8f3ab42 2758 if (nlh->nlmsg_flags & NLM_F_DUMP) {
e844a928 2759 if (cda[CTA_EXPECT_MASTER])
7b8002a1 2760 return ctnetlink_dump_exp_ct(net, ctnl, skb, nlh, cda);
e844a928
PNA
2761 else {
2762 struct netlink_dump_control c = {
2763 .dump = ctnetlink_exp_dump_table,
2764 .done = ctnetlink_exp_done,
2765 };
2766 return netlink_dump_start(ctnl, skb, nlh, &c);
2767 }
c1d10adb
PNA
2768 }
2769
ef00f89f
PM
2770 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
2771 if (err < 0)
2772 return err;
2773
35dba1d7 2774 if (cda[CTA_EXPECT_TUPLE])
deedb590
DB
2775 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE,
2776 u3, NULL);
35dba1d7 2777 else if (cda[CTA_EXPECT_MASTER])
deedb590
DB
2778 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER,
2779 u3, NULL);
c1d10adb
PNA
2780 else
2781 return -EINVAL;
2782
2783 if (err < 0)
2784 return err;
2785
308ac914 2786 exp = nf_ct_expect_find_get(net, &zone, &tuple);
c1d10adb
PNA
2787 if (!exp)
2788 return -ENOENT;
2789
df6fb868 2790 if (cda[CTA_EXPECT_ID]) {
77236b6e 2791 __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
35832402 2792 if (ntohl(id) != (u32)(unsigned long)exp) {
6823645d 2793 nf_ct_expect_put(exp);
c1d10adb
PNA
2794 return -ENOENT;
2795 }
601e68e1 2796 }
c1d10adb
PNA
2797
2798 err = -ENOMEM;
96bcf938 2799 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
81378f72
PNA
2800 if (skb2 == NULL) {
2801 nf_ct_expect_put(exp);
c1d10adb 2802 goto out;
81378f72 2803 }
4e9b8269 2804
528a3a6f 2805 rcu_read_lock();
15e47304 2806 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).portid,
8b0a231d 2807 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, exp);
528a3a6f 2808 rcu_read_unlock();
81378f72 2809 nf_ct_expect_put(exp);
c1d10adb
PNA
2810 if (err <= 0)
2811 goto free;
2812
15e47304 2813 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).portid, MSG_DONTWAIT);
81378f72
PNA
2814 if (err < 0)
2815 goto out;
c1d10adb 2816
81378f72 2817 return 0;
c1d10adb
PNA
2818
2819free:
2820 kfree_skb(skb2);
2821out:
81378f72
PNA
2822 /* this avoids a loop in nfnetlink. */
2823 return err == -EAGAIN ? -ENOBUFS : err;
c1d10adb
PNA
2824}
2825
7b8002a1
PNA
2826static int ctnetlink_del_expect(struct net *net, struct sock *ctnl,
2827 struct sk_buff *skb, const struct nlmsghdr *nlh,
2828 const struct nlattr * const cda[])
c1d10adb 2829{
31f15875 2830 struct nf_conntrack_expect *exp;
c1d10adb 2831 struct nf_conntrack_tuple tuple;
96bcf938 2832 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
b67bfe0d 2833 struct hlist_node *next;
c1d10adb 2834 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 2835 struct nf_conntrack_zone zone;
31f15875 2836 unsigned int i;
c1d10adb
PNA
2837 int err;
2838
df6fb868 2839 if (cda[CTA_EXPECT_TUPLE]) {
c1d10adb 2840 /* delete a single expect by tuple */
ef00f89f
PM
2841 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
2842 if (err < 0)
2843 return err;
2844
deedb590
DB
2845 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE,
2846 u3, NULL);
c1d10adb
PNA
2847 if (err < 0)
2848 return err;
2849
2850 /* bump usage count to 2 */
308ac914 2851 exp = nf_ct_expect_find_get(net, &zone, &tuple);
c1d10adb
PNA
2852 if (!exp)
2853 return -ENOENT;
2854
df6fb868 2855 if (cda[CTA_EXPECT_ID]) {
77236b6e 2856 __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
35832402 2857 if (ntohl(id) != (u32)(unsigned long)exp) {
6823645d 2858 nf_ct_expect_put(exp);
c1d10adb
PNA
2859 return -ENOENT;
2860 }
2861 }
2862
2863 /* after list removal, usage count == 1 */
ca7433df 2864 spin_lock_bh(&nf_conntrack_expect_lock);
ebbf41df 2865 if (del_timer(&exp->timeout)) {
15e47304 2866 nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).portid,
ebbf41df
PNA
2867 nlmsg_report(nlh));
2868 nf_ct_expect_put(exp);
2869 }
ca7433df 2870 spin_unlock_bh(&nf_conntrack_expect_lock);
601e68e1 2871 /* have to put what we 'get' above.
c1d10adb 2872 * after this line usage count == 0 */
6823645d 2873 nf_ct_expect_put(exp);
df6fb868
PM
2874 } else if (cda[CTA_EXPECT_HELP_NAME]) {
2875 char *name = nla_data(cda[CTA_EXPECT_HELP_NAME]);
31f15875 2876 struct nf_conn_help *m_help;
c1d10adb
PNA
2877
2878 /* delete all expectations for this helper */
ca7433df 2879 spin_lock_bh(&nf_conntrack_expect_lock);
31f15875 2880 for (i = 0; i < nf_ct_expect_hsize; i++) {
b67bfe0d 2881 hlist_for_each_entry_safe(exp, next,
9592a5c0 2882 &net->ct.expect_hash[i],
31f15875
PM
2883 hnode) {
2884 m_help = nfct_help(exp->master);
794e6871
PM
2885 if (!strcmp(m_help->helper->name, name) &&
2886 del_timer(&exp->timeout)) {
ebbf41df 2887 nf_ct_unlink_expect_report(exp,
15e47304 2888 NETLINK_CB(skb).portid,
ebbf41df 2889 nlmsg_report(nlh));
31f15875
PM
2890 nf_ct_expect_put(exp);
2891 }
c1d10adb
PNA
2892 }
2893 }
ca7433df 2894 spin_unlock_bh(&nf_conntrack_expect_lock);
c1d10adb
PNA
2895 } else {
2896 /* This basically means we have to flush everything*/
ca7433df 2897 spin_lock_bh(&nf_conntrack_expect_lock);
31f15875 2898 for (i = 0; i < nf_ct_expect_hsize; i++) {
b67bfe0d 2899 hlist_for_each_entry_safe(exp, next,
9592a5c0 2900 &net->ct.expect_hash[i],
31f15875
PM
2901 hnode) {
2902 if (del_timer(&exp->timeout)) {
ebbf41df 2903 nf_ct_unlink_expect_report(exp,
15e47304 2904 NETLINK_CB(skb).portid,
ebbf41df 2905 nlmsg_report(nlh));
31f15875
PM
2906 nf_ct_expect_put(exp);
2907 }
c1d10adb
PNA
2908 }
2909 }
ca7433df 2910 spin_unlock_bh(&nf_conntrack_expect_lock);
c1d10adb
PNA
2911 }
2912
2913 return 0;
2914}
2915static int
39938324
PM
2916ctnetlink_change_expect(struct nf_conntrack_expect *x,
2917 const struct nlattr * const cda[])
c1d10adb 2918{
9768e1ac
KW
2919 if (cda[CTA_EXPECT_TIMEOUT]) {
2920 if (!del_timer(&x->timeout))
2921 return -ETIME;
2922
2923 x->timeout.expires = jiffies +
2924 ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ;
2925 add_timer(&x->timeout);
2926 }
2927 return 0;
c1d10adb
PNA
2928}
2929
076a0ca0
PNA
2930static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = {
2931 [CTA_EXPECT_NAT_DIR] = { .type = NLA_U32 },
2932 [CTA_EXPECT_NAT_TUPLE] = { .type = NLA_NESTED },
2933};
2934
2935static int
2936ctnetlink_parse_expect_nat(const struct nlattr *attr,
2937 struct nf_conntrack_expect *exp,
2938 u_int8_t u3)
2939{
2940#ifdef CONFIG_NF_NAT_NEEDED
2941 struct nlattr *tb[CTA_EXPECT_NAT_MAX+1];
2942 struct nf_conntrack_tuple nat_tuple = {};
2943 int err;
2944
130ffbc2
DB
2945 err = nla_parse_nested(tb, CTA_EXPECT_NAT_MAX, attr, exp_nat_nla_policy);
2946 if (err < 0)
2947 return err;
076a0ca0
PNA
2948
2949 if (!tb[CTA_EXPECT_NAT_DIR] || !tb[CTA_EXPECT_NAT_TUPLE])
2950 return -EINVAL;
2951
2952 err = ctnetlink_parse_tuple((const struct nlattr * const *)tb,
deedb590
DB
2953 &nat_tuple, CTA_EXPECT_NAT_TUPLE,
2954 u3, NULL);
076a0ca0
PNA
2955 if (err < 0)
2956 return err;
2957
c7232c99 2958 exp->saved_addr = nat_tuple.src.u3;
076a0ca0
PNA
2959 exp->saved_proto = nat_tuple.src.u;
2960 exp->dir = ntohl(nla_get_be32(tb[CTA_EXPECT_NAT_DIR]));
2961
2962 return 0;
2963#else
2964 return -EOPNOTSUPP;
2965#endif
2966}
2967
0ef71ee1
PNA
2968static struct nf_conntrack_expect *
2969ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
2970 struct nf_conntrack_helper *helper,
2971 struct nf_conntrack_tuple *tuple,
2972 struct nf_conntrack_tuple *mask)
c1d10adb 2973{
0ef71ee1 2974 u_int32_t class = 0;
c1d10adb 2975 struct nf_conntrack_expect *exp;
dc808fe2 2976 struct nf_conn_help *help;
0ef71ee1 2977 int err;
660fdb2a 2978
b8c5e52c
PNA
2979 if (cda[CTA_EXPECT_CLASS] && helper) {
2980 class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS]));
0ef71ee1
PNA
2981 if (class > helper->expect_class_max)
2982 return ERR_PTR(-EINVAL);
b8c5e52c 2983 }
6823645d 2984 exp = nf_ct_expect_alloc(ct);
0ef71ee1
PNA
2985 if (!exp)
2986 return ERR_PTR(-ENOMEM);
2987
bc01befd
PNA
2988 help = nfct_help(ct);
2989 if (!help) {
2990 if (!cda[CTA_EXPECT_TIMEOUT]) {
2991 err = -EINVAL;
1310b955 2992 goto err_out;
bc01befd
PNA
2993 }
2994 exp->timeout.expires =
2995 jiffies + ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ;
601e68e1 2996
bc01befd
PNA
2997 exp->flags = NF_CT_EXPECT_USERSPACE;
2998 if (cda[CTA_EXPECT_FLAGS]) {
2999 exp->flags |=
3000 ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS]));
3001 }
3002 } else {
3003 if (cda[CTA_EXPECT_FLAGS]) {
3004 exp->flags = ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS]));
3005 exp->flags &= ~NF_CT_EXPECT_USERSPACE;
3006 } else
3007 exp->flags = 0;
3008 }
544d5c7d
PNA
3009 if (cda[CTA_EXPECT_FN]) {
3010 const char *name = nla_data(cda[CTA_EXPECT_FN]);
3011 struct nf_ct_helper_expectfn *expfn;
3012
3013 expfn = nf_ct_helper_expectfn_find_by_name(name);
3014 if (expfn == NULL) {
3015 err = -EINVAL;
3016 goto err_out;
3017 }
3018 exp->expectfn = expfn->expectfn;
3019 } else
3020 exp->expectfn = NULL;
601e68e1 3021
b8c5e52c 3022 exp->class = class;
c1d10adb 3023 exp->master = ct;
660fdb2a 3024 exp->helper = helper;
0ef71ee1
PNA
3025 exp->tuple = *tuple;
3026 exp->mask.src.u3 = mask->src.u3;
3027 exp->mask.src.u.all = mask->src.u.all;
c1d10adb 3028
076a0ca0
PNA
3029 if (cda[CTA_EXPECT_NAT]) {
3030 err = ctnetlink_parse_expect_nat(cda[CTA_EXPECT_NAT],
0ef71ee1 3031 exp, nf_ct_l3num(ct));
076a0ca0
PNA
3032 if (err < 0)
3033 goto err_out;
3034 }
0ef71ee1 3035 return exp;
076a0ca0 3036err_out:
6823645d 3037 nf_ct_expect_put(exp);
0ef71ee1
PNA
3038 return ERR_PTR(err);
3039}
3040
3041static int
308ac914
DB
3042ctnetlink_create_expect(struct net *net,
3043 const struct nf_conntrack_zone *zone,
0ef71ee1
PNA
3044 const struct nlattr * const cda[],
3045 u_int8_t u3, u32 portid, int report)
3046{
3047 struct nf_conntrack_tuple tuple, mask, master_tuple;
3048 struct nf_conntrack_tuple_hash *h = NULL;
3049 struct nf_conntrack_helper *helper = NULL;
3050 struct nf_conntrack_expect *exp;
3051 struct nf_conn *ct;
3052 int err;
3053
3054 /* caller guarantees that those three CTA_EXPECT_* exist */
deedb590
DB
3055 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE,
3056 u3, NULL);
0ef71ee1
PNA
3057 if (err < 0)
3058 return err;
deedb590
DB
3059 err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK,
3060 u3, NULL);
0ef71ee1
PNA
3061 if (err < 0)
3062 return err;
deedb590
DB
3063 err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER,
3064 u3, NULL);
0ef71ee1
PNA
3065 if (err < 0)
3066 return err;
3067
3068 /* Look for master conntrack of this expectation */
3069 h = nf_conntrack_find_get(net, zone, &master_tuple);
3070 if (!h)
3071 return -ENOENT;
3072 ct = nf_ct_tuplehash_to_ctrack(h);
3073
3074 if (cda[CTA_EXPECT_HELP_NAME]) {
3075 const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
3076
3077 helper = __nf_conntrack_helper_find(helpname, u3,
3078 nf_ct_protonum(ct));
3079 if (helper == NULL) {
3080#ifdef CONFIG_MODULES
3081 if (request_module("nfct-helper-%s", helpname) < 0) {
3082 err = -EOPNOTSUPP;
3083 goto err_ct;
3084 }
3085 helper = __nf_conntrack_helper_find(helpname, u3,
3086 nf_ct_protonum(ct));
3087 if (helper) {
3088 err = -EAGAIN;
3089 goto err_ct;
3090 }
3091#endif
3092 err = -EOPNOTSUPP;
3093 goto err_ct;
3094 }
3095 }
3096
3097 exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask);
3098 if (IS_ERR(exp)) {
3099 err = PTR_ERR(exp);
3100 goto err_ct;
3101 }
3102
3103 err = nf_ct_expect_related_report(exp, portid, report);
0ef71ee1
PNA
3104 nf_ct_expect_put(exp);
3105err_ct:
3106 nf_ct_put(ct);
c1d10adb
PNA
3107 return err;
3108}
3109
7b8002a1
PNA
3110static int ctnetlink_new_expect(struct net *net, struct sock *ctnl,
3111 struct sk_buff *skb, const struct nlmsghdr *nlh,
3112 const struct nlattr * const cda[])
c1d10adb
PNA
3113{
3114 struct nf_conntrack_tuple tuple;
3115 struct nf_conntrack_expect *exp;
96bcf938 3116 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 3117 u_int8_t u3 = nfmsg->nfgen_family;
308ac914 3118 struct nf_conntrack_zone zone;
ef00f89f 3119 int err;
c1d10adb 3120
df6fb868
PM
3121 if (!cda[CTA_EXPECT_TUPLE]
3122 || !cda[CTA_EXPECT_MASK]
3123 || !cda[CTA_EXPECT_MASTER])
c1d10adb
PNA
3124 return -EINVAL;
3125
ef00f89f
PM
3126 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
3127 if (err < 0)
3128 return err;
3129
deedb590
DB
3130 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE,
3131 u3, NULL);
c1d10adb
PNA
3132 if (err < 0)
3133 return err;
3134
ca7433df 3135 spin_lock_bh(&nf_conntrack_expect_lock);
308ac914 3136 exp = __nf_ct_expect_find(net, &zone, &tuple);
c1d10adb 3137 if (!exp) {
ca7433df 3138 spin_unlock_bh(&nf_conntrack_expect_lock);
c1d10adb 3139 err = -ENOENT;
19abb7b0 3140 if (nlh->nlmsg_flags & NLM_F_CREATE) {
308ac914 3141 err = ctnetlink_create_expect(net, &zone, cda, u3,
15e47304 3142 NETLINK_CB(skb).portid,
19abb7b0
PNA
3143 nlmsg_report(nlh));
3144 }
c1d10adb
PNA
3145 return err;
3146 }
3147
3148 err = -EEXIST;
3149 if (!(nlh->nlmsg_flags & NLM_F_EXCL))
3150 err = ctnetlink_change_expect(exp, cda);
ca7433df 3151 spin_unlock_bh(&nf_conntrack_expect_lock);
c1d10adb 3152
c1d10adb
PNA
3153 return err;
3154}
3155
392025f8 3156static int
15e47304 3157ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, int cpu,
392025f8
PNA
3158 const struct ip_conntrack_stat *st)
3159{
3160 struct nlmsghdr *nlh;
3161 struct nfgenmsg *nfmsg;
15e47304 3162 unsigned int flags = portid ? NLM_F_MULTI : 0, event;
392025f8
PNA
3163
3164 event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_EXP_GET_STATS_CPU);
15e47304 3165 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*nfmsg), flags);
392025f8
PNA
3166 if (nlh == NULL)
3167 goto nlmsg_failure;
3168
3169 nfmsg = nlmsg_data(nlh);
3170 nfmsg->nfgen_family = AF_UNSPEC;
3171 nfmsg->version = NFNETLINK_V0;
3172 nfmsg->res_id = htons(cpu);
3173
3174 if (nla_put_be32(skb, CTA_STATS_EXP_NEW, htonl(st->expect_new)) ||
3175 nla_put_be32(skb, CTA_STATS_EXP_CREATE, htonl(st->expect_create)) ||
3176 nla_put_be32(skb, CTA_STATS_EXP_DELETE, htonl(st->expect_delete)))
3177 goto nla_put_failure;
3178
3179 nlmsg_end(skb, nlh);
3180 return skb->len;
3181
3182nla_put_failure:
3183nlmsg_failure:
3184 nlmsg_cancel(skb, nlh);
3185 return -1;
3186}
3187
3188static int
3189ctnetlink_exp_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
3190{
3191 int cpu;
3192 struct net *net = sock_net(skb->sk);
3193
3194 if (cb->args[0] == nr_cpu_ids)
3195 return 0;
3196
3197 for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
3198 const struct ip_conntrack_stat *st;
3199
3200 if (!cpu_possible(cpu))
3201 continue;
3202
3203 st = per_cpu_ptr(net->ct.stat, cpu);
15e47304 3204 if (ctnetlink_exp_stat_fill_info(skb, NETLINK_CB(cb->skb).portid,
392025f8
PNA
3205 cb->nlh->nlmsg_seq,
3206 cpu, st) < 0)
3207 break;
3208 }
3209 cb->args[0] = cpu;
3210
3211 return skb->len;
3212}
3213
7b8002a1
PNA
3214static int ctnetlink_stat_exp_cpu(struct net *net, struct sock *ctnl,
3215 struct sk_buff *skb,
3216 const struct nlmsghdr *nlh,
3217 const struct nlattr * const cda[])
392025f8
PNA
3218{
3219 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3220 struct netlink_dump_control c = {
3221 .dump = ctnetlink_exp_stat_cpu_dump,
3222 };
3223 return netlink_dump_start(ctnl, skb, nlh, &c);
3224 }
3225
3226 return 0;
3227}
3228
c1d10adb 3229#ifdef CONFIG_NF_CONNTRACK_EVENTS
e34d5c1a
PNA
3230static struct nf_ct_event_notifier ctnl_notifier = {
3231 .fcn = ctnetlink_conntrack_event,
c1d10adb
PNA
3232};
3233
e34d5c1a
PNA
3234static struct nf_exp_event_notifier ctnl_notifier_exp = {
3235 .fcn = ctnetlink_expect_event,
c1d10adb
PNA
3236};
3237#endif
3238
7c8d4cb4 3239static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
c1d10adb 3240 [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack,
f73e924c
PM
3241 .attr_count = CTA_MAX,
3242 .policy = ct_nla_policy },
c1d10adb 3243 [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack,
f73e924c
PM
3244 .attr_count = CTA_MAX,
3245 .policy = ct_nla_policy },
c1d10adb 3246 [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack,
f73e924c
PM
3247 .attr_count = CTA_MAX,
3248 .policy = ct_nla_policy },
c1d10adb 3249 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack,
f73e924c
PM
3250 .attr_count = CTA_MAX,
3251 .policy = ct_nla_policy },
392025f8
PNA
3252 [IPCTNL_MSG_CT_GET_STATS_CPU] = { .call = ctnetlink_stat_ct_cpu },
3253 [IPCTNL_MSG_CT_GET_STATS] = { .call = ctnetlink_stat_ct },
d871befe
PNA
3254 [IPCTNL_MSG_CT_GET_DYING] = { .call = ctnetlink_get_ct_dying },
3255 [IPCTNL_MSG_CT_GET_UNCONFIRMED] = { .call = ctnetlink_get_ct_unconfirmed },
c1d10adb
PNA
3256};
3257
7c8d4cb4 3258static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
c1d10adb 3259 [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
f73e924c
PM
3260 .attr_count = CTA_EXPECT_MAX,
3261 .policy = exp_nla_policy },
c1d10adb 3262 [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect,
f73e924c
PM
3263 .attr_count = CTA_EXPECT_MAX,
3264 .policy = exp_nla_policy },
c1d10adb 3265 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect,
f73e924c
PM
3266 .attr_count = CTA_EXPECT_MAX,
3267 .policy = exp_nla_policy },
392025f8 3268 [IPCTNL_MSG_EXP_GET_STATS_CPU] = { .call = ctnetlink_stat_exp_cpu },
c1d10adb
PNA
3269};
3270
7c8d4cb4 3271static const struct nfnetlink_subsystem ctnl_subsys = {
c1d10adb
PNA
3272 .name = "conntrack",
3273 .subsys_id = NFNL_SUBSYS_CTNETLINK,
3274 .cb_count = IPCTNL_MSG_MAX,
3275 .cb = ctnl_cb,
3276};
3277
7c8d4cb4 3278static const struct nfnetlink_subsystem ctnl_exp_subsys = {
c1d10adb
PNA
3279 .name = "conntrack_expect",
3280 .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP,
3281 .cb_count = IPCTNL_MSG_EXP_MAX,
3282 .cb = ctnl_exp_cb,
3283};
3284
d2483dde 3285MODULE_ALIAS("ip_conntrack_netlink");
c1d10adb 3286MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
34f9a2e4 3287MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
c1d10adb 3288
70e9942f
PNA
3289static int __net_init ctnetlink_net_init(struct net *net)
3290{
3291#ifdef CONFIG_NF_CONNTRACK_EVENTS
3292 int ret;
3293
3294 ret = nf_conntrack_register_notifier(net, &ctnl_notifier);
3295 if (ret < 0) {
3296 pr_err("ctnetlink_init: cannot register notifier.\n");
3297 goto err_out;
3298 }
3299
3300 ret = nf_ct_expect_register_notifier(net, &ctnl_notifier_exp);
3301 if (ret < 0) {
3302 pr_err("ctnetlink_init: cannot expect register notifier.\n");
3303 goto err_unreg_notifier;
3304 }
3305#endif
3306 return 0;
3307
3308#ifdef CONFIG_NF_CONNTRACK_EVENTS
3309err_unreg_notifier:
3310 nf_conntrack_unregister_notifier(net, &ctnl_notifier);
3311err_out:
3312 return ret;
3313#endif
3314}
3315
3316static void ctnetlink_net_exit(struct net *net)
3317{
3318#ifdef CONFIG_NF_CONNTRACK_EVENTS
3319 nf_ct_expect_unregister_notifier(net, &ctnl_notifier_exp);
3320 nf_conntrack_unregister_notifier(net, &ctnl_notifier);
3321#endif
3322}
3323
3324static void __net_exit ctnetlink_net_exit_batch(struct list_head *net_exit_list)
3325{
3326 struct net *net;
3327
3328 list_for_each_entry(net, net_exit_list, exit_list)
3329 ctnetlink_net_exit(net);
3330}
3331
3332static struct pernet_operations ctnetlink_net_ops = {
3333 .init = ctnetlink_net_init,
3334 .exit_batch = ctnetlink_net_exit_batch,
3335};
3336
c1d10adb
PNA
3337static int __init ctnetlink_init(void)
3338{
3339 int ret;
3340
654d0fbd 3341 pr_info("ctnetlink v%s: registering with nfnetlink.\n", version);
c1d10adb
PNA
3342 ret = nfnetlink_subsys_register(&ctnl_subsys);
3343 if (ret < 0) {
654d0fbd 3344 pr_err("ctnetlink_init: cannot register with nfnetlink.\n");
c1d10adb
PNA
3345 goto err_out;
3346 }
3347
3348 ret = nfnetlink_subsys_register(&ctnl_exp_subsys);
3349 if (ret < 0) {
654d0fbd 3350 pr_err("ctnetlink_init: cannot register exp with nfnetlink.\n");
c1d10adb
PNA
3351 goto err_unreg_subsys;
3352 }
3353
ef6acf68
JL
3354 ret = register_pernet_subsys(&ctnetlink_net_ops);
3355 if (ret < 0) {
70e9942f 3356 pr_err("ctnetlink_init: cannot register pernet operations\n");
c1d10adb
PNA
3357 goto err_unreg_exp_subsys;
3358 }
83f3e94d 3359#ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
9cb01766 3360 /* setup interaction between nf_queue and nf_conntrack_netlink. */
a4b4766c 3361 RCU_INIT_POINTER(nfnl_ct_hook, &ctnetlink_glue_hook);
9cb01766 3362#endif
c1d10adb
PNA
3363 return 0;
3364
c1d10adb
PNA
3365err_unreg_exp_subsys:
3366 nfnetlink_subsys_unregister(&ctnl_exp_subsys);
c1d10adb
PNA
3367err_unreg_subsys:
3368 nfnetlink_subsys_unregister(&ctnl_subsys);
3369err_out:
3370 return ret;
3371}
3372
3373static void __exit ctnetlink_exit(void)
3374{
654d0fbd 3375 pr_info("ctnetlink: unregistering from nfnetlink.\n");
c1d10adb 3376
70e9942f 3377 unregister_pernet_subsys(&ctnetlink_net_ops);
c1d10adb
PNA
3378 nfnetlink_subsys_unregister(&ctnl_exp_subsys);
3379 nfnetlink_subsys_unregister(&ctnl_subsys);
83f3e94d 3380#ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
a4b4766c 3381 RCU_INIT_POINTER(nfnl_ct_hook, NULL);
9cb01766 3382#endif
c1d10adb
PNA
3383}
3384
3385module_init(ctnetlink_init);
3386module_exit(ctnetlink_exit);
This page took 1.056238 seconds and 5 git commands to generate.