Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[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>
70e9942f 7 * (C) 2005-2011 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
PNA
39#include <net/netfilter/nf_conntrack_helper.h>
40#include <net/netfilter/nf_conntrack_l3proto.h>
605dcad6 41#include <net/netfilter/nf_conntrack_l4proto.h>
5b1158e9 42#include <net/netfilter/nf_conntrack_tuple.h>
58401572 43#include <net/netfilter/nf_conntrack_acct.h>
ef00f89f 44#include <net/netfilter/nf_conntrack_zones.h>
a992ca2a 45#include <net/netfilter/nf_conntrack_timestamp.h>
5b1158e9
JK
46#ifdef CONFIG_NF_NAT_NEEDED
47#include <net/netfilter/nf_nat_core.h>
48#include <net/netfilter/nf_nat_protocol.h>
49#endif
c1d10adb
PNA
50
51#include <linux/netfilter/nfnetlink.h>
52#include <linux/netfilter/nfnetlink_conntrack.h>
53
54MODULE_LICENSE("GPL");
55
dc808fe2 56static char __initdata version[] = "0.93";
c1d10adb 57
c1d10adb 58static inline int
601e68e1 59ctnetlink_dump_tuples_proto(struct sk_buff *skb,
1cde6436 60 const struct nf_conntrack_tuple *tuple,
605dcad6 61 struct nf_conntrack_l4proto *l4proto)
c1d10adb 62{
c1d10adb 63 int ret = 0;
df6fb868 64 struct nlattr *nest_parms;
c1d10adb 65
df6fb868
PM
66 nest_parms = nla_nest_start(skb, CTA_TUPLE_PROTO | NLA_F_NESTED);
67 if (!nest_parms)
68 goto nla_put_failure;
cc1eb431
DM
69 if (nla_put_u8(skb, CTA_PROTO_NUM, tuple->dst.protonum))
70 goto nla_put_failure;
c1d10adb 71
fdf70832
PM
72 if (likely(l4proto->tuple_to_nlattr))
73 ret = l4proto->tuple_to_nlattr(skb, tuple);
601e68e1 74
df6fb868 75 nla_nest_end(skb, nest_parms);
c1d10adb
PNA
76
77 return ret;
78
df6fb868 79nla_put_failure:
c1d10adb
PNA
80 return -1;
81}
82
83static inline int
1cde6436
PNA
84ctnetlink_dump_tuples_ip(struct sk_buff *skb,
85 const struct nf_conntrack_tuple *tuple,
86 struct nf_conntrack_l3proto *l3proto)
c1d10adb 87{
c1d10adb 88 int ret = 0;
df6fb868
PM
89 struct nlattr *nest_parms;
90
91 nest_parms = nla_nest_start(skb, CTA_TUPLE_IP | NLA_F_NESTED);
92 if (!nest_parms)
93 goto nla_put_failure;
1cde6436 94
fdf70832
PM
95 if (likely(l3proto->tuple_to_nlattr))
96 ret = l3proto->tuple_to_nlattr(skb, tuple);
1cde6436 97
df6fb868 98 nla_nest_end(skb, nest_parms);
c1d10adb 99
1cde6436
PNA
100 return ret;
101
df6fb868 102nla_put_failure:
1cde6436
PNA
103 return -1;
104}
105
bb5cf80e 106static int
1cde6436
PNA
107ctnetlink_dump_tuples(struct sk_buff *skb,
108 const struct nf_conntrack_tuple *tuple)
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
127static inline int
128ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
129{
cc1eb431
DM
130 if (nla_put_be32(skb, CTA_STATUS, htonl(ct->status)))
131 goto nla_put_failure;
c1d10adb
PNA
132 return 0;
133
df6fb868 134nla_put_failure:
c1d10adb
PNA
135 return -1;
136}
137
138static inline int
139ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct)
140{
c1216382 141 long timeout = ((long)ct->timeout.expires - (long)jiffies) / HZ;
c1d10adb 142
77236b6e 143 if (timeout < 0)
c1d10adb 144 timeout = 0;
601e68e1 145
cc1eb431
DM
146 if (nla_put_be32(skb, CTA_TIMEOUT, htonl(timeout)))
147 goto nla_put_failure;
c1d10adb
PNA
148 return 0;
149
df6fb868 150nla_put_failure:
c1d10adb
PNA
151 return -1;
152}
153
154static inline int
440f0d58 155ctnetlink_dump_protoinfo(struct sk_buff *skb, struct nf_conn *ct)
c1d10adb 156{
5e8fbe2a 157 struct nf_conntrack_l4proto *l4proto;
df6fb868 158 struct nlattr *nest_proto;
c1d10adb
PNA
159 int ret;
160
528a3a6f
PNA
161 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
162 if (!l4proto->to_nlattr)
c1d10adb 163 return 0;
601e68e1 164
df6fb868
PM
165 nest_proto = nla_nest_start(skb, CTA_PROTOINFO | NLA_F_NESTED);
166 if (!nest_proto)
167 goto nla_put_failure;
c1d10adb 168
fdf70832 169 ret = l4proto->to_nlattr(skb, nest_proto, ct);
c1d10adb 170
df6fb868 171 nla_nest_end(skb, nest_proto);
c1d10adb
PNA
172
173 return ret;
174
df6fb868 175nla_put_failure:
c1d10adb
PNA
176 return -1;
177}
178
179static inline int
180ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
181{
df6fb868 182 struct nlattr *nest_helper;
dc808fe2 183 const struct nf_conn_help *help = nfct_help(ct);
3c158f7f 184 struct nf_conntrack_helper *helper;
c1d10adb 185
3c158f7f 186 if (!help)
c1d10adb 187 return 0;
601e68e1 188
3c158f7f
PM
189 helper = rcu_dereference(help->helper);
190 if (!helper)
191 goto out;
192
df6fb868
PM
193 nest_helper = nla_nest_start(skb, CTA_HELP | NLA_F_NESTED);
194 if (!nest_helper)
195 goto nla_put_failure;
cc1eb431
DM
196 if (nla_put_string(skb, CTA_HELP_NAME, helper->name))
197 goto nla_put_failure;
c1d10adb 198
fdf70832
PM
199 if (helper->to_nlattr)
200 helper->to_nlattr(skb, ct);
c1d10adb 201
df6fb868 202 nla_nest_end(skb, nest_helper);
3c158f7f 203out:
c1d10adb
PNA
204 return 0;
205
df6fb868 206nla_put_failure:
c1d10adb
PNA
207 return -1;
208}
209
bb5cf80e 210static int
80e60e67
PNA
211dump_counters(struct sk_buff *skb, u64 pkts, u64 bytes,
212 enum ip_conntrack_dir dir)
c1d10adb
PNA
213{
214 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
df6fb868 215 struct nlattr *nest_count;
c1d10adb 216
df6fb868
PM
217 nest_count = nla_nest_start(skb, type | NLA_F_NESTED);
218 if (!nest_count)
219 goto nla_put_failure;
220
cc1eb431
DM
221 if (nla_put_be64(skb, CTA_COUNTERS_PACKETS, cpu_to_be64(pkts)) ||
222 nla_put_be64(skb, CTA_COUNTERS_BYTES, cpu_to_be64(bytes)))
223 goto nla_put_failure;
c1d10adb 224
df6fb868 225 nla_nest_end(skb, nest_count);
c1d10adb
PNA
226
227 return 0;
228
df6fb868 229nla_put_failure:
c1d10adb
PNA
230 return -1;
231}
c1d10adb 232
80e60e67
PNA
233static int
234ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
235 enum ip_conntrack_dir dir, int type)
236{
237 struct nf_conn_counter *acct;
238 u64 pkts, bytes;
239
240 acct = nf_conn_acct_find(ct);
241 if (!acct)
242 return 0;
243
244 if (type == IPCTNL_MSG_CT_GET_CTRZERO) {
245 pkts = atomic64_xchg(&acct[dir].packets, 0);
246 bytes = atomic64_xchg(&acct[dir].bytes, 0);
247 } else {
248 pkts = atomic64_read(&acct[dir].packets);
249 bytes = atomic64_read(&acct[dir].bytes);
250 }
251 return dump_counters(skb, pkts, bytes, dir);
252}
253
a992ca2a
PNA
254static int
255ctnetlink_dump_timestamp(struct sk_buff *skb, const struct nf_conn *ct)
256{
257 struct nlattr *nest_count;
258 const struct nf_conn_tstamp *tstamp;
259
260 tstamp = nf_conn_tstamp_find(ct);
261 if (!tstamp)
262 return 0;
263
264 nest_count = nla_nest_start(skb, CTA_TIMESTAMP | NLA_F_NESTED);
265 if (!nest_count)
266 goto nla_put_failure;
267
cc1eb431
DM
268 if (nla_put_be64(skb, CTA_TIMESTAMP_START, cpu_to_be64(tstamp->start)) ||
269 (tstamp->stop != 0 && nla_put_be64(skb, CTA_TIMESTAMP_STOP,
270 cpu_to_be64(tstamp->stop))))
271 goto nla_put_failure;
a992ca2a
PNA
272 nla_nest_end(skb, nest_count);
273
274 return 0;
275
276nla_put_failure:
277 return -1;
278}
279
c1d10adb
PNA
280#ifdef CONFIG_NF_CONNTRACK_MARK
281static inline int
282ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
283{
cc1eb431
DM
284 if (nla_put_be32(skb, CTA_MARK, htonl(ct->mark)))
285 goto nla_put_failure;
c1d10adb
PNA
286 return 0;
287
df6fb868 288nla_put_failure:
c1d10adb
PNA
289 return -1;
290}
291#else
292#define ctnetlink_dump_mark(a, b) (0)
293#endif
294
37fccd85
PNA
295#ifdef CONFIG_NF_CONNTRACK_SECMARK
296static inline int
1cc63249 297ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
37fccd85 298{
1cc63249
EP
299 struct nlattr *nest_secctx;
300 int len, ret;
301 char *secctx;
302
303 ret = security_secid_to_secctx(ct->secmark, &secctx, &len);
304 if (ret)
cba85b53 305 return 0;
1cc63249
EP
306
307 ret = -1;
308 nest_secctx = nla_nest_start(skb, CTA_SECCTX | NLA_F_NESTED);
309 if (!nest_secctx)
310 goto nla_put_failure;
37fccd85 311
cc1eb431
DM
312 if (nla_put_string(skb, CTA_SECCTX_NAME, secctx))
313 goto nla_put_failure;
1cc63249
EP
314 nla_nest_end(skb, nest_secctx);
315
316 ret = 0;
37fccd85 317nla_put_failure:
1cc63249
EP
318 security_release_secctx(secctx, len);
319 return ret;
37fccd85
PNA
320}
321#else
1cc63249 322#define ctnetlink_dump_secctx(a, b) (0)
37fccd85
PNA
323#endif
324
0f417ce9
PNA
325#define master_tuple(ct) &(ct->master->tuplehash[IP_CT_DIR_ORIGINAL].tuple)
326
327static inline int
328ctnetlink_dump_master(struct sk_buff *skb, const struct nf_conn *ct)
329{
330 struct nlattr *nest_parms;
331
332 if (!(ct->status & IPS_EXPECTED))
333 return 0;
334
335 nest_parms = nla_nest_start(skb, CTA_TUPLE_MASTER | NLA_F_NESTED);
336 if (!nest_parms)
337 goto nla_put_failure;
338 if (ctnetlink_dump_tuples(skb, master_tuple(ct)) < 0)
339 goto nla_put_failure;
340 nla_nest_end(skb, nest_parms);
341
342 return 0;
343
344nla_put_failure:
345 return -1;
346}
347
13eae15a 348#ifdef CONFIG_NF_NAT_NEEDED
bb5cf80e 349static int
13eae15a
PNA
350dump_nat_seq_adj(struct sk_buff *skb, const struct nf_nat_seq *natseq, int type)
351{
13eae15a
PNA
352 struct nlattr *nest_parms;
353
354 nest_parms = nla_nest_start(skb, type | NLA_F_NESTED);
355 if (!nest_parms)
356 goto nla_put_failure;
357
cc1eb431
DM
358 if (nla_put_be32(skb, CTA_NAT_SEQ_CORRECTION_POS,
359 htonl(natseq->correction_pos)) ||
360 nla_put_be32(skb, CTA_NAT_SEQ_OFFSET_BEFORE,
361 htonl(natseq->offset_before)) ||
362 nla_put_be32(skb, CTA_NAT_SEQ_OFFSET_AFTER,
363 htonl(natseq->offset_after)))
364 goto nla_put_failure;
13eae15a
PNA
365
366 nla_nest_end(skb, nest_parms);
367
368 return 0;
369
370nla_put_failure:
371 return -1;
372}
373
374static inline int
375ctnetlink_dump_nat_seq_adj(struct sk_buff *skb, const struct nf_conn *ct)
376{
377 struct nf_nat_seq *natseq;
378 struct nf_conn_nat *nat = nfct_nat(ct);
379
380 if (!(ct->status & IPS_SEQ_ADJUST) || !nat)
381 return 0;
382
383 natseq = &nat->seq[IP_CT_DIR_ORIGINAL];
384 if (dump_nat_seq_adj(skb, natseq, CTA_NAT_SEQ_ADJ_ORIG) == -1)
385 return -1;
386
387 natseq = &nat->seq[IP_CT_DIR_REPLY];
388 if (dump_nat_seq_adj(skb, natseq, CTA_NAT_SEQ_ADJ_REPLY) == -1)
389 return -1;
390
391 return 0;
392}
393#else
394#define ctnetlink_dump_nat_seq_adj(a, b) (0)
395#endif
396
c1d10adb
PNA
397static inline int
398ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
399{
cc1eb431
DM
400 if (nla_put_be32(skb, CTA_ID, htonl((unsigned long)ct)))
401 goto nla_put_failure;
c1d10adb
PNA
402 return 0;
403
df6fb868 404nla_put_failure:
c1d10adb
PNA
405 return -1;
406}
407
408static inline int
409ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
410{
cc1eb431
DM
411 if (nla_put_be32(skb, CTA_USE, htonl(atomic_read(&ct->ct_general.use))))
412 goto nla_put_failure;
c1d10adb
PNA
413 return 0;
414
df6fb868 415nla_put_failure:
c1d10adb
PNA
416 return -1;
417}
418
c1d10adb 419static int
80e60e67
PNA
420ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq, u32 type,
421 struct nf_conn *ct)
c1d10adb
PNA
422{
423 struct nlmsghdr *nlh;
424 struct nfgenmsg *nfmsg;
df6fb868 425 struct nlattr *nest_parms;
80e60e67 426 unsigned int flags = pid ? NLM_F_MULTI : 0, event;
c1d10adb 427
80e60e67 428 event = (NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_NEW);
96bcf938
PNA
429 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
430 if (nlh == NULL)
431 goto nlmsg_failure;
c1d10adb 432
96bcf938 433 nfmsg = nlmsg_data(nlh);
5e8fbe2a 434 nfmsg->nfgen_family = nf_ct_l3num(ct);
c1d10adb
PNA
435 nfmsg->version = NFNETLINK_V0;
436 nfmsg->res_id = 0;
437
df6fb868
PM
438 nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED);
439 if (!nest_parms)
440 goto nla_put_failure;
f2f3e38c 441 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
df6fb868
PM
442 goto nla_put_failure;
443 nla_nest_end(skb, nest_parms);
601e68e1 444
df6fb868
PM
445 nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY | NLA_F_NESTED);
446 if (!nest_parms)
447 goto nla_put_failure;
f2f3e38c 448 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0)
df6fb868
PM
449 goto nla_put_failure;
450 nla_nest_end(skb, nest_parms);
c1d10adb 451
cc1eb431
DM
452 if (nf_ct_zone(ct) &&
453 nla_put_be16(skb, CTA_ZONE, htons(nf_ct_zone(ct))))
454 goto nla_put_failure;
ef00f89f 455
c1d10adb
PNA
456 if (ctnetlink_dump_status(skb, ct) < 0 ||
457 ctnetlink_dump_timeout(skb, ct) < 0 ||
80e60e67
PNA
458 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL, type) < 0 ||
459 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY, type) < 0 ||
a992ca2a 460 ctnetlink_dump_timestamp(skb, ct) < 0 ||
c1d10adb
PNA
461 ctnetlink_dump_protoinfo(skb, ct) < 0 ||
462 ctnetlink_dump_helpinfo(skb, ct) < 0 ||
463 ctnetlink_dump_mark(skb, ct) < 0 ||
1cc63249 464 ctnetlink_dump_secctx(skb, ct) < 0 ||
c1d10adb 465 ctnetlink_dump_id(skb, ct) < 0 ||
13eae15a 466 ctnetlink_dump_use(skb, ct) < 0 ||
0f417ce9 467 ctnetlink_dump_master(skb, ct) < 0 ||
13eae15a 468 ctnetlink_dump_nat_seq_adj(skb, ct) < 0)
df6fb868 469 goto nla_put_failure;
c1d10adb 470
96bcf938 471 nlmsg_end(skb, nlh);
c1d10adb
PNA
472 return skb->len;
473
474nlmsg_failure:
df6fb868 475nla_put_failure:
96bcf938 476 nlmsg_cancel(skb, nlh);
c1d10adb
PNA
477 return -1;
478}
479
480#ifdef CONFIG_NF_CONNTRACK_EVENTS
03b64f51
PNA
481static inline size_t
482ctnetlink_proto_size(const struct nf_conn *ct)
2732c4e4
HE
483{
484 struct nf_conntrack_l3proto *l3proto;
485 struct nf_conntrack_l4proto *l4proto;
03b64f51
PNA
486 size_t len = 0;
487
488 rcu_read_lock();
489 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
490 len += l3proto->nla_size;
491
492 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
493 len += l4proto->nla_size;
494 rcu_read_unlock();
495
496 return len;
497}
498
d26e6a02
JP
499static inline size_t
500ctnetlink_counters_size(const struct nf_conn *ct)
501{
502 if (!nf_ct_ext_exist(ct, NF_CT_EXT_ACCT))
503 return 0;
504 return 2 * nla_total_size(0) /* CTA_COUNTERS_ORIG|REPL */
505 + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_PACKETS */
506 + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_BYTES */
507 ;
508}
509
cba85b53
PNA
510static inline int
511ctnetlink_secctx_size(const struct nf_conn *ct)
1cc63249 512{
cba85b53
PNA
513#ifdef CONFIG_NF_CONNTRACK_SECMARK
514 int len, ret;
1cc63249 515
cba85b53
PNA
516 ret = security_secid_to_secctx(ct->secmark, NULL, &len);
517 if (ret)
518 return 0;
1cc63249 519
cba85b53
PNA
520 return nla_total_size(0) /* CTA_SECCTX */
521 + nla_total_size(sizeof(char) * len); /* CTA_SECCTX_NAME */
522#else
523 return 0;
1cc63249 524#endif
cba85b53 525}
1cc63249 526
a992ca2a
PNA
527static inline size_t
528ctnetlink_timestamp_size(const struct nf_conn *ct)
529{
530#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
531 if (!nf_ct_ext_exist(ct, NF_CT_EXT_TSTAMP))
532 return 0;
533 return nla_total_size(0) + 2 * nla_total_size(sizeof(uint64_t));
534#else
535 return 0;
536#endif
537}
538
03b64f51
PNA
539static inline size_t
540ctnetlink_nlmsg_size(const struct nf_conn *ct)
541{
542 return NLMSG_ALIGN(sizeof(struct nfgenmsg))
543 + 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */
544 + 3 * nla_total_size(0) /* CTA_TUPLE_IP */
545 + 3 * nla_total_size(0) /* CTA_TUPLE_PROTO */
546 + 3 * nla_total_size(sizeof(u_int8_t)) /* CTA_PROTO_NUM */
547 + nla_total_size(sizeof(u_int32_t)) /* CTA_ID */
548 + nla_total_size(sizeof(u_int32_t)) /* CTA_STATUS */
d26e6a02 549 + ctnetlink_counters_size(ct)
a992ca2a 550 + ctnetlink_timestamp_size(ct)
03b64f51
PNA
551 + nla_total_size(sizeof(u_int32_t)) /* CTA_TIMEOUT */
552 + nla_total_size(0) /* CTA_PROTOINFO */
553 + nla_total_size(0) /* CTA_HELP */
554 + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */
cba85b53 555 + ctnetlink_secctx_size(ct)
d271e8bd 556#ifdef CONFIG_NF_NAT_NEEDED
03b64f51
PNA
557 + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */
558 + 6 * nla_total_size(sizeof(u_int32_t)) /* CTA_NAT_SEQ_OFFSET */
d271e8bd
HE
559#endif
560#ifdef CONFIG_NF_CONNTRACK_MARK
03b64f51 561 + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
d271e8bd 562#endif
03b64f51
PNA
563 + ctnetlink_proto_size(ct)
564 ;
2732c4e4
HE
565}
566
e34d5c1a
PNA
567static int
568ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
c1d10adb 569{
9592a5c0 570 struct net *net;
c1d10adb
PNA
571 struct nlmsghdr *nlh;
572 struct nfgenmsg *nfmsg;
df6fb868 573 struct nlattr *nest_parms;
19abb7b0 574 struct nf_conn *ct = item->ct;
c1d10adb
PNA
575 struct sk_buff *skb;
576 unsigned int type;
c1d10adb 577 unsigned int flags = 0, group;
dd7669a9 578 int err;
c1d10adb
PNA
579
580 /* ignore our fake conntrack entry */
5bfddbd4 581 if (nf_ct_is_untracked(ct))
e34d5c1a 582 return 0;
c1d10adb 583
a0891aa6 584 if (events & (1 << IPCT_DESTROY)) {
c1d10adb
PNA
585 type = IPCTNL_MSG_CT_DELETE;
586 group = NFNLGRP_CONNTRACK_DESTROY;
a0891aa6 587 } else if (events & ((1 << IPCT_NEW) | (1 << IPCT_RELATED))) {
c1d10adb
PNA
588 type = IPCTNL_MSG_CT_NEW;
589 flags = NLM_F_CREATE|NLM_F_EXCL;
c1d10adb 590 group = NFNLGRP_CONNTRACK_NEW;
17e6e4ea 591 } else if (events) {
c1d10adb
PNA
592 type = IPCTNL_MSG_CT_NEW;
593 group = NFNLGRP_CONNTRACK_UPDATE;
594 } else
e34d5c1a 595 return 0;
a2427692 596
9592a5c0
AD
597 net = nf_ct_net(ct);
598 if (!item->report && !nfnetlink_has_listeners(net, group))
e34d5c1a 599 return 0;
a2427692 600
03b64f51
PNA
601 skb = nlmsg_new(ctnetlink_nlmsg_size(ct), GFP_ATOMIC);
602 if (skb == NULL)
150ace0d 603 goto errout;
c1d10adb 604
c1d10adb 605 type |= NFNL_SUBSYS_CTNETLINK << 8;
96bcf938
PNA
606 nlh = nlmsg_put(skb, item->pid, 0, type, sizeof(*nfmsg), flags);
607 if (nlh == NULL)
608 goto nlmsg_failure;
c1d10adb 609
96bcf938 610 nfmsg = nlmsg_data(nlh);
5e8fbe2a 611 nfmsg->nfgen_family = nf_ct_l3num(ct);
c1d10adb
PNA
612 nfmsg->version = NFNETLINK_V0;
613 nfmsg->res_id = 0;
614
528a3a6f 615 rcu_read_lock();
df6fb868
PM
616 nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED);
617 if (!nest_parms)
618 goto nla_put_failure;
f2f3e38c 619 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
df6fb868
PM
620 goto nla_put_failure;
621 nla_nest_end(skb, nest_parms);
601e68e1 622
df6fb868
PM
623 nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY | NLA_F_NESTED);
624 if (!nest_parms)
625 goto nla_put_failure;
f2f3e38c 626 if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0)
df6fb868
PM
627 goto nla_put_failure;
628 nla_nest_end(skb, nest_parms);
c1d10adb 629
cc1eb431
DM
630 if (nf_ct_zone(ct) &&
631 nla_put_be16(skb, CTA_ZONE, htons(nf_ct_zone(ct))))
632 goto nla_put_failure;
ef00f89f 633
1eedf699
EL
634 if (ctnetlink_dump_id(skb, ct) < 0)
635 goto nla_put_failure;
636
e57dce60
FH
637 if (ctnetlink_dump_status(skb, ct) < 0)
638 goto nla_put_failure;
639
a0891aa6 640 if (events & (1 << IPCT_DESTROY)) {
80e60e67
PNA
641 if (ctnetlink_dump_counters(skb, ct,
642 IP_CT_DIR_ORIGINAL, type) < 0 ||
643 ctnetlink_dump_counters(skb, ct,
644 IP_CT_DIR_REPLY, type) < 0 ||
a992ca2a 645 ctnetlink_dump_timestamp(skb, ct) < 0)
df6fb868 646 goto nla_put_failure;
7b621c1e 647 } else {
7b621c1e 648 if (ctnetlink_dump_timeout(skb, ct) < 0)
df6fb868 649 goto nla_put_failure;
7b621c1e 650
a0891aa6 651 if (events & (1 << IPCT_PROTOINFO)
7b621c1e 652 && ctnetlink_dump_protoinfo(skb, ct) < 0)
df6fb868 653 goto nla_put_failure;
7b621c1e 654
a0891aa6 655 if ((events & (1 << IPCT_HELPER) || nfct_help(ct))
7b621c1e 656 && ctnetlink_dump_helpinfo(skb, ct) < 0)
df6fb868 657 goto nla_put_failure;
7b621c1e 658
ff660c80 659#ifdef CONFIG_NF_CONNTRACK_SECMARK
a0891aa6 660 if ((events & (1 << IPCT_SECMARK) || ct->secmark)
1cc63249 661 && ctnetlink_dump_secctx(skb, ct) < 0)
37fccd85 662 goto nla_put_failure;
ff660c80 663#endif
7b621c1e 664
a0891aa6 665 if (events & (1 << IPCT_RELATED) &&
0f417ce9
PNA
666 ctnetlink_dump_master(skb, ct) < 0)
667 goto nla_put_failure;
668
a0891aa6 669 if (events & (1 << IPCT_NATSEQADJ) &&
13eae15a
PNA
670 ctnetlink_dump_nat_seq_adj(skb, ct) < 0)
671 goto nla_put_failure;
7b621c1e 672 }
b9a37e0c 673
a83099a6 674#ifdef CONFIG_NF_CONNTRACK_MARK
a0891aa6 675 if ((events & (1 << IPCT_MARK) || ct->mark)
a83099a6
EL
676 && ctnetlink_dump_mark(skb, ct) < 0)
677 goto nla_put_failure;
678#endif
528a3a6f 679 rcu_read_unlock();
a83099a6 680
96bcf938 681 nlmsg_end(skb, nlh);
9592a5c0 682 err = nfnetlink_send(skb, net, item->pid, group, item->report,
cd8c20b6 683 GFP_ATOMIC);
dd7669a9
PNA
684 if (err == -ENOBUFS || err == -EAGAIN)
685 return -ENOBUFS;
686
e34d5c1a 687 return 0;
c1d10adb 688
df6fb868 689nla_put_failure:
528a3a6f 690 rcu_read_unlock();
96bcf938 691 nlmsg_cancel(skb, nlh);
528a3a6f 692nlmsg_failure:
c1d10adb 693 kfree_skb(skb);
150ace0d 694errout:
37b7ef72
PNA
695 if (nfnetlink_set_err(net, 0, group, -ENOBUFS) > 0)
696 return -ENOBUFS;
697
e34d5c1a 698 return 0;
c1d10adb
PNA
699}
700#endif /* CONFIG_NF_CONNTRACK_EVENTS */
701
702static int ctnetlink_done(struct netlink_callback *cb)
703{
89f2e218
PM
704 if (cb->args[1])
705 nf_ct_put((struct nf_conn *)cb->args[1]);
0f298a28
PNA
706 if (cb->data)
707 kfree(cb->data);
c1d10adb
PNA
708 return 0;
709}
710
0f298a28
PNA
711struct ctnetlink_dump_filter {
712 struct {
713 u_int32_t val;
714 u_int32_t mask;
715 } mark;
716};
717
c1d10adb
PNA
718static int
719ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
720{
9592a5c0 721 struct net *net = sock_net(skb->sk);
89f2e218 722 struct nf_conn *ct, *last;
c1d10adb 723 struct nf_conntrack_tuple_hash *h;
ea781f19 724 struct hlist_nulls_node *n;
96bcf938 725 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
87711cb8 726 u_int8_t l3proto = nfmsg->nfgen_family;
3b988ece 727 int res;
0f298a28
PNA
728#ifdef CONFIG_NF_CONNTRACK_MARK
729 const struct ctnetlink_dump_filter *filter = cb->data;
730#endif
3b988ece 731
13ee6ac5 732 spin_lock_bh(&nf_conntrack_lock);
d205dc40 733 last = (struct nf_conn *)cb->args[1];
9ab99d5a 734 for (; cb->args[0] < net->ct.htable_size; cb->args[0]++) {
89f2e218 735restart:
13ee6ac5 736 hlist_nulls_for_each_entry(h, n, &net->ct.hash[cb->args[0]],
ea781f19 737 hnnode) {
5b1158e9 738 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
c1d10adb
PNA
739 continue;
740 ct = nf_ct_tuplehash_to_ctrack(h);
87711cb8
PNA
741 /* Dump entries of a given L3 protocol number.
742 * If it is not specified, ie. l3proto == 0,
743 * then dump everything. */
5e8fbe2a 744 if (l3proto && nf_ct_l3num(ct) != l3proto)
13ee6ac5 745 continue;
d205dc40
PM
746 if (cb->args[1]) {
747 if (ct != last)
13ee6ac5 748 continue;
d205dc40 749 cb->args[1] = 0;
89f2e218 750 }
0f298a28
PNA
751#ifdef CONFIG_NF_CONNTRACK_MARK
752 if (filter && !((ct->mark & filter->mark.mask) ==
753 filter->mark.val)) {
754 continue;
755 }
756#endif
3b988ece
HS
757 rcu_read_lock();
758 res =
759 ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
760 cb->nlh->nlmsg_seq,
761 NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
762 ct);
763 rcu_read_unlock();
764 if (res < 0) {
c71caf41 765 nf_conntrack_get(&ct->ct_general);
89f2e218 766 cb->args[1] = (unsigned long)ct;
c1d10adb 767 goto out;
89f2e218
PM
768 }
769 }
d205dc40 770 if (cb->args[1]) {
89f2e218
PM
771 cb->args[1] = 0;
772 goto restart;
c1d10adb
PNA
773 }
774 }
89f2e218 775out:
13ee6ac5 776 spin_unlock_bh(&nf_conntrack_lock);
d205dc40
PM
777 if (last)
778 nf_ct_put(last);
c1d10adb 779
c1d10adb
PNA
780 return skb->len;
781}
782
c1d10adb 783static inline int
df6fb868 784ctnetlink_parse_tuple_ip(struct nlattr *attr, struct nf_conntrack_tuple *tuple)
c1d10adb 785{
df6fb868 786 struct nlattr *tb[CTA_IP_MAX+1];
c1d10adb
PNA
787 struct nf_conntrack_l3proto *l3proto;
788 int ret = 0;
789
df6fb868 790 nla_parse_nested(tb, CTA_IP_MAX, attr, NULL);
c1d10adb 791
cd91566e
FW
792 rcu_read_lock();
793 l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
c1d10adb 794
f73e924c
PM
795 if (likely(l3proto->nlattr_to_tuple)) {
796 ret = nla_validate_nested(attr, CTA_IP_MAX,
797 l3proto->nla_policy);
798 if (ret == 0)
799 ret = l3proto->nlattr_to_tuple(tb, tuple);
800 }
c1d10adb 801
cd91566e 802 rcu_read_unlock();
c1d10adb 803
c1d10adb
PNA
804 return ret;
805}
806
f73e924c
PM
807static const struct nla_policy proto_nla_policy[CTA_PROTO_MAX+1] = {
808 [CTA_PROTO_NUM] = { .type = NLA_U8 },
c1d10adb
PNA
809};
810
811static inline int
df6fb868 812ctnetlink_parse_tuple_proto(struct nlattr *attr,
c1d10adb
PNA
813 struct nf_conntrack_tuple *tuple)
814{
df6fb868 815 struct nlattr *tb[CTA_PROTO_MAX+1];
605dcad6 816 struct nf_conntrack_l4proto *l4proto;
c1d10adb
PNA
817 int ret = 0;
818
f73e924c
PM
819 ret = nla_parse_nested(tb, CTA_PROTO_MAX, attr, proto_nla_policy);
820 if (ret < 0)
821 return ret;
c1d10adb 822
df6fb868 823 if (!tb[CTA_PROTO_NUM])
c1d10adb 824 return -EINVAL;
77236b6e 825 tuple->dst.protonum = nla_get_u8(tb[CTA_PROTO_NUM]);
c1d10adb 826
cd91566e
FW
827 rcu_read_lock();
828 l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum);
c1d10adb 829
f73e924c
PM
830 if (likely(l4proto->nlattr_to_tuple)) {
831 ret = nla_validate_nested(attr, CTA_PROTO_MAX,
832 l4proto->nla_policy);
833 if (ret == 0)
834 ret = l4proto->nlattr_to_tuple(tb, tuple);
835 }
c1d10adb 836
cd91566e 837 rcu_read_unlock();
601e68e1 838
c1d10adb
PNA
839 return ret;
840}
841
d0b0268f
PM
842static const struct nla_policy tuple_nla_policy[CTA_TUPLE_MAX+1] = {
843 [CTA_TUPLE_IP] = { .type = NLA_NESTED },
844 [CTA_TUPLE_PROTO] = { .type = NLA_NESTED },
845};
846
bb5cf80e 847static int
39938324
PM
848ctnetlink_parse_tuple(const struct nlattr * const cda[],
849 struct nf_conntrack_tuple *tuple,
a00f1f36 850 enum ctattr_type type, u_int8_t l3num)
c1d10adb 851{
df6fb868 852 struct nlattr *tb[CTA_TUPLE_MAX+1];
c1d10adb
PNA
853 int err;
854
c1d10adb
PNA
855 memset(tuple, 0, sizeof(*tuple));
856
d0b0268f 857 nla_parse_nested(tb, CTA_TUPLE_MAX, cda[type], tuple_nla_policy);
c1d10adb 858
df6fb868 859 if (!tb[CTA_TUPLE_IP])
c1d10adb
PNA
860 return -EINVAL;
861
862 tuple->src.l3num = l3num;
863
df6fb868 864 err = ctnetlink_parse_tuple_ip(tb[CTA_TUPLE_IP], tuple);
c1d10adb
PNA
865 if (err < 0)
866 return err;
867
df6fb868 868 if (!tb[CTA_TUPLE_PROTO])
c1d10adb
PNA
869 return -EINVAL;
870
df6fb868 871 err = ctnetlink_parse_tuple_proto(tb[CTA_TUPLE_PROTO], tuple);
c1d10adb
PNA
872 if (err < 0)
873 return err;
874
875 /* orig and expect tuples get DIR_ORIGINAL */
876 if (type == CTA_TUPLE_REPLY)
877 tuple->dst.dir = IP_CT_DIR_REPLY;
878 else
879 tuple->dst.dir = IP_CT_DIR_ORIGINAL;
880
c1d10adb
PNA
881 return 0;
882}
883
ef00f89f
PM
884static int
885ctnetlink_parse_zone(const struct nlattr *attr, u16 *zone)
886{
887 if (attr)
888#ifdef CONFIG_NF_CONNTRACK_ZONES
889 *zone = ntohs(nla_get_be16(attr));
890#else
891 return -EOPNOTSUPP;
892#endif
893 else
894 *zone = 0;
895
896 return 0;
897}
898
d0b0268f
PM
899static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = {
900 [CTA_HELP_NAME] = { .type = NLA_NUL_STRING },
901};
902
c1d10adb 903static inline int
39938324 904ctnetlink_parse_help(const struct nlattr *attr, char **helper_name)
c1d10adb 905{
df6fb868 906 struct nlattr *tb[CTA_HELP_MAX+1];
c1d10adb 907
d0b0268f 908 nla_parse_nested(tb, CTA_HELP_MAX, attr, help_nla_policy);
c1d10adb 909
df6fb868 910 if (!tb[CTA_HELP_NAME])
c1d10adb
PNA
911 return -EINVAL;
912
df6fb868 913 *helper_name = nla_data(tb[CTA_HELP_NAME]);
c1d10adb
PNA
914
915 return 0;
916}
917
f73e924c 918static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
d0b0268f
PM
919 [CTA_TUPLE_ORIG] = { .type = NLA_NESTED },
920 [CTA_TUPLE_REPLY] = { .type = NLA_NESTED },
f73e924c 921 [CTA_STATUS] = { .type = NLA_U32 },
d0b0268f
PM
922 [CTA_PROTOINFO] = { .type = NLA_NESTED },
923 [CTA_HELP] = { .type = NLA_NESTED },
924 [CTA_NAT_SRC] = { .type = NLA_NESTED },
f73e924c
PM
925 [CTA_TIMEOUT] = { .type = NLA_U32 },
926 [CTA_MARK] = { .type = NLA_U32 },
f73e924c 927 [CTA_ID] = { .type = NLA_U32 },
d0b0268f
PM
928 [CTA_NAT_DST] = { .type = NLA_NESTED },
929 [CTA_TUPLE_MASTER] = { .type = NLA_NESTED },
ef00f89f 930 [CTA_ZONE] = { .type = NLA_U16 },
0f298a28 931 [CTA_MARK_MASK] = { .type = NLA_U32 },
c1d10adb
PNA
932};
933
934static int
601e68e1 935ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
39938324
PM
936 const struct nlmsghdr *nlh,
937 const struct nlattr * const cda[])
c1d10adb 938{
9592a5c0 939 struct net *net = sock_net(ctnl);
c1d10adb
PNA
940 struct nf_conntrack_tuple_hash *h;
941 struct nf_conntrack_tuple tuple;
942 struct nf_conn *ct;
96bcf938 943 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 944 u_int8_t u3 = nfmsg->nfgen_family;
ef00f89f
PM
945 u16 zone;
946 int err;
947
948 err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone);
949 if (err < 0)
950 return err;
c1d10adb 951
df6fb868 952 if (cda[CTA_TUPLE_ORIG])
c1d10adb 953 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
df6fb868 954 else if (cda[CTA_TUPLE_REPLY])
c1d10adb
PNA
955 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
956 else {
957 /* Flush the whole table */
9592a5c0 958 nf_conntrack_flush_report(net,
274d383b
PNA
959 NETLINK_CB(skb).pid,
960 nlmsg_report(nlh));
c1d10adb
PNA
961 return 0;
962 }
963
964 if (err < 0)
965 return err;
966
ef00f89f 967 h = nf_conntrack_find_get(net, zone, &tuple);
9ea8cfd6 968 if (!h)
c1d10adb 969 return -ENOENT;
c1d10adb
PNA
970
971 ct = nf_ct_tuplehash_to_ctrack(h);
601e68e1 972
df6fb868 973 if (cda[CTA_ID]) {
77236b6e 974 u_int32_t id = ntohl(nla_get_be32(cda[CTA_ID]));
7f85f914 975 if (id != (u32)(unsigned long)ct) {
c1d10adb
PNA
976 nf_ct_put(ct);
977 return -ENOENT;
978 }
601e68e1 979 }
c1d10adb 980
a16a1647
PNA
981 if (del_timer(&ct->timeout)) {
982 if (nf_conntrack_event_report(IPCT_DESTROY, ct,
983 NETLINK_CB(skb).pid,
984 nlmsg_report(nlh)) < 0) {
985 nf_ct_delete_from_lists(ct);
986 /* we failed to report the event, try later */
987 nf_ct_insert_dying_list(ct);
988 nf_ct_put(ct);
989 return 0;
990 }
991 /* death_by_timeout would report the event again */
992 set_bit(IPS_DYING_BIT, &ct->status);
dd7669a9 993 nf_ct_delete_from_lists(ct);
dd7669a9 994 nf_ct_put(ct);
dd7669a9 995 }
c1d10adb 996 nf_ct_put(ct);
c1d10adb
PNA
997
998 return 0;
999}
1000
1001static int
601e68e1 1002ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
39938324
PM
1003 const struct nlmsghdr *nlh,
1004 const struct nlattr * const cda[])
c1d10adb 1005{
9592a5c0 1006 struct net *net = sock_net(ctnl);
c1d10adb
PNA
1007 struct nf_conntrack_tuple_hash *h;
1008 struct nf_conntrack_tuple tuple;
1009 struct nf_conn *ct;
1010 struct sk_buff *skb2 = NULL;
96bcf938 1011 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 1012 u_int8_t u3 = nfmsg->nfgen_family;
ef00f89f
PM
1013 u16 zone;
1014 int err;
c1d10adb 1015
80d326fa
PNA
1016 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1017 struct netlink_dump_control c = {
1018 .dump = ctnetlink_dump_table,
1019 .done = ctnetlink_done,
1020 };
0f298a28
PNA
1021#ifdef CONFIG_NF_CONNTRACK_MARK
1022 if (cda[CTA_MARK] && cda[CTA_MARK_MASK]) {
1023 struct ctnetlink_dump_filter *filter;
1024
1025 filter = kzalloc(sizeof(struct ctnetlink_dump_filter),
1026 GFP_ATOMIC);
1027 if (filter == NULL)
1028 return -ENOMEM;
1029
1030 filter->mark.val = ntohl(nla_get_be32(cda[CTA_MARK]));
1031 filter->mark.mask =
1032 ntohl(nla_get_be32(cda[CTA_MARK_MASK]));
1033 c.data = filter;
1034 }
1035#endif
80d326fa
PNA
1036 return netlink_dump_start(ctnl, skb, nlh, &c);
1037 }
c1d10adb 1038
ef00f89f
PM
1039 err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone);
1040 if (err < 0)
1041 return err;
1042
df6fb868 1043 if (cda[CTA_TUPLE_ORIG])
c1d10adb 1044 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_ORIG, u3);
df6fb868 1045 else if (cda[CTA_TUPLE_REPLY])
c1d10adb
PNA
1046 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
1047 else
1048 return -EINVAL;
1049
1050 if (err < 0)
1051 return err;
1052
ef00f89f 1053 h = nf_conntrack_find_get(net, zone, &tuple);
9ea8cfd6 1054 if (!h)
c1d10adb 1055 return -ENOENT;
9ea8cfd6 1056
c1d10adb
PNA
1057 ct = nf_ct_tuplehash_to_ctrack(h);
1058
1059 err = -ENOMEM;
96bcf938
PNA
1060 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1061 if (skb2 == NULL) {
c1d10adb
PNA
1062 nf_ct_put(ct);
1063 return -ENOMEM;
1064 }
c1d10adb 1065
528a3a6f 1066 rcu_read_lock();
601e68e1 1067 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
80e60e67 1068 NFNL_MSG_TYPE(nlh->nlmsg_type), ct);
528a3a6f 1069 rcu_read_unlock();
c1d10adb
PNA
1070 nf_ct_put(ct);
1071 if (err <= 0)
1072 goto free;
1073
1074 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
1075 if (err < 0)
1076 goto out;
1077
c1d10adb
PNA
1078 return 0;
1079
1080free:
1081 kfree_skb(skb2);
1082out:
f31e8d49
PNA
1083 /* this avoids a loop in nfnetlink. */
1084 return err == -EAGAIN ? -ENOBUFS : err;
c1d10adb
PNA
1085}
1086
67671841 1087#ifdef CONFIG_NF_NAT_NEEDED
e6a7d3c0
PNA
1088static int
1089ctnetlink_parse_nat_setup(struct nf_conn *ct,
1090 enum nf_nat_manip_type manip,
39938324 1091 const struct nlattr *attr)
e6a7d3c0
PNA
1092{
1093 typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
1094
1095 parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
1096 if (!parse_nat_setup) {
95a5afca 1097#ifdef CONFIG_MODULES
e6a7d3c0
PNA
1098 rcu_read_unlock();
1099 nfnl_unlock();
1100 if (request_module("nf-nat-ipv4") < 0) {
1101 nfnl_lock();
1102 rcu_read_lock();
1103 return -EOPNOTSUPP;
1104 }
1105 nfnl_lock();
1106 rcu_read_lock();
1107 if (nfnetlink_parse_nat_setup_hook)
1108 return -EAGAIN;
1109#endif
1110 return -EOPNOTSUPP;
1111 }
1112
1113 return parse_nat_setup(ct, manip, attr);
1114}
67671841 1115#endif
e6a7d3c0 1116
bb5cf80e 1117static int
39938324 1118ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
c1d10adb
PNA
1119{
1120 unsigned long d;
77236b6e 1121 unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS]));
c1d10adb
PNA
1122 d = ct->status ^ status;
1123
1124 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
1125 /* unchangeable */
0adf9d67 1126 return -EBUSY;
601e68e1 1127
c1d10adb
PNA
1128 if (d & IPS_SEEN_REPLY && !(status & IPS_SEEN_REPLY))
1129 /* SEEN_REPLY bit can only be set */
0adf9d67 1130 return -EBUSY;
601e68e1 1131
c1d10adb
PNA
1132 if (d & IPS_ASSURED && !(status & IPS_ASSURED))
1133 /* ASSURED bit can only be set */
0adf9d67 1134 return -EBUSY;
c1d10adb 1135
c1d10adb
PNA
1136 /* Be careful here, modifying NAT bits can screw up things,
1137 * so don't let users modify them directly if they don't pass
5b1158e9 1138 * nf_nat_range. */
c1d10adb
PNA
1139 ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK);
1140 return 0;
1141}
1142
e6a7d3c0 1143static int
39938324 1144ctnetlink_change_nat(struct nf_conn *ct, const struct nlattr * const cda[])
e6a7d3c0
PNA
1145{
1146#ifdef CONFIG_NF_NAT_NEEDED
1147 int ret;
1148
1149 if (cda[CTA_NAT_DST]) {
1150 ret = ctnetlink_parse_nat_setup(ct,
cbc9f2f4 1151 NF_NAT_MANIP_DST,
e6a7d3c0
PNA
1152 cda[CTA_NAT_DST]);
1153 if (ret < 0)
1154 return ret;
1155 }
1156 if (cda[CTA_NAT_SRC]) {
1157 ret = ctnetlink_parse_nat_setup(ct,
cbc9f2f4 1158 NF_NAT_MANIP_SRC,
e6a7d3c0
PNA
1159 cda[CTA_NAT_SRC]);
1160 if (ret < 0)
1161 return ret;
1162 }
1163 return 0;
1164#else
1165 return -EOPNOTSUPP;
1166#endif
1167}
c1d10adb
PNA
1168
1169static inline int
39938324 1170ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
c1d10adb
PNA
1171{
1172 struct nf_conntrack_helper *helper;
dc808fe2 1173 struct nf_conn_help *help = nfct_help(ct);
29fe1b48 1174 char *helpname = NULL;
c1d10adb
PNA
1175 int err;
1176
c1d10adb
PNA
1177 /* don't change helper of sibling connections */
1178 if (ct->master)
0adf9d67 1179 return -EBUSY;
c1d10adb 1180
df6fb868 1181 err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
c1d10adb
PNA
1182 if (err < 0)
1183 return err;
1184
df293bbb
YK
1185 if (!strcmp(helpname, "")) {
1186 if (help && help->helper) {
c1d10adb
PNA
1187 /* we had a helper before ... */
1188 nf_ct_remove_expectations(ct);
a9b3cd7f 1189 RCU_INIT_POINTER(help->helper, NULL);
c1d10adb 1190 }
df293bbb
YK
1191
1192 return 0;
c1d10adb 1193 }
601e68e1 1194
794e6871
PM
1195 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
1196 nf_ct_protonum(ct));
226c0c0e
PNA
1197 if (helper == NULL) {
1198#ifdef CONFIG_MODULES
1199 spin_unlock_bh(&nf_conntrack_lock);
1200
1201 if (request_module("nfct-helper-%s", helpname) < 0) {
1202 spin_lock_bh(&nf_conntrack_lock);
1203 return -EOPNOTSUPP;
1204 }
1205
1206 spin_lock_bh(&nf_conntrack_lock);
794e6871
PM
1207 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
1208 nf_ct_protonum(ct));
226c0c0e
PNA
1209 if (helper)
1210 return -EAGAIN;
1211#endif
0adf9d67 1212 return -EOPNOTSUPP;
226c0c0e 1213 }
df293bbb 1214
ceceae1b
YK
1215 if (help) {
1216 if (help->helper == helper)
1217 return 0;
1218 if (help->helper)
1219 return -EBUSY;
1220 /* need to zero data of old helper */
1221 memset(&help->help, 0, sizeof(help->help));
1222 } else {
a88e22ad
PNA
1223 /* we cannot set a helper for an existing conntrack */
1224 return -EOPNOTSUPP;
ceceae1b 1225 }
df293bbb 1226
cf778b00 1227 rcu_assign_pointer(help->helper, helper);
c1d10adb
PNA
1228
1229 return 0;
1230}
1231
1232static inline int
39938324 1233ctnetlink_change_timeout(struct nf_conn *ct, const struct nlattr * const cda[])
c1d10adb 1234{
77236b6e 1235 u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
601e68e1 1236
c1d10adb
PNA
1237 if (!del_timer(&ct->timeout))
1238 return -ETIME;
1239
1240 ct->timeout.expires = jiffies + timeout * HZ;
1241 add_timer(&ct->timeout);
1242
1243 return 0;
1244}
1245
d0b0268f
PM
1246static const struct nla_policy protoinfo_policy[CTA_PROTOINFO_MAX+1] = {
1247 [CTA_PROTOINFO_TCP] = { .type = NLA_NESTED },
1248 [CTA_PROTOINFO_DCCP] = { .type = NLA_NESTED },
1249 [CTA_PROTOINFO_SCTP] = { .type = NLA_NESTED },
1250};
1251
c1d10adb 1252static inline int
39938324 1253ctnetlink_change_protoinfo(struct nf_conn *ct, const struct nlattr * const cda[])
c1d10adb 1254{
39938324
PM
1255 const struct nlattr *attr = cda[CTA_PROTOINFO];
1256 struct nlattr *tb[CTA_PROTOINFO_MAX+1];
605dcad6 1257 struct nf_conntrack_l4proto *l4proto;
c1d10adb
PNA
1258 int err = 0;
1259
d0b0268f 1260 nla_parse_nested(tb, CTA_PROTOINFO_MAX, attr, protoinfo_policy);
c1d10adb 1261
cd91566e
FW
1262 rcu_read_lock();
1263 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
fdf70832
PM
1264 if (l4proto->from_nlattr)
1265 err = l4proto->from_nlattr(tb, ct);
cd91566e 1266 rcu_read_unlock();
c1d10adb
PNA
1267
1268 return err;
1269}
1270
13eae15a 1271#ifdef CONFIG_NF_NAT_NEEDED
d0b0268f
PM
1272static const struct nla_policy nat_seq_policy[CTA_NAT_SEQ_MAX+1] = {
1273 [CTA_NAT_SEQ_CORRECTION_POS] = { .type = NLA_U32 },
1274 [CTA_NAT_SEQ_OFFSET_BEFORE] = { .type = NLA_U32 },
1275 [CTA_NAT_SEQ_OFFSET_AFTER] = { .type = NLA_U32 },
1276};
1277
13eae15a 1278static inline int
39938324 1279change_nat_seq_adj(struct nf_nat_seq *natseq, const struct nlattr * const attr)
13eae15a
PNA
1280{
1281 struct nlattr *cda[CTA_NAT_SEQ_MAX+1];
1282
d0b0268f 1283 nla_parse_nested(cda, CTA_NAT_SEQ_MAX, attr, nat_seq_policy);
13eae15a
PNA
1284
1285 if (!cda[CTA_NAT_SEQ_CORRECTION_POS])
1286 return -EINVAL;
1287
1288 natseq->correction_pos =
77236b6e 1289 ntohl(nla_get_be32(cda[CTA_NAT_SEQ_CORRECTION_POS]));
13eae15a
PNA
1290
1291 if (!cda[CTA_NAT_SEQ_OFFSET_BEFORE])
1292 return -EINVAL;
1293
1294 natseq->offset_before =
77236b6e 1295 ntohl(nla_get_be32(cda[CTA_NAT_SEQ_OFFSET_BEFORE]));
13eae15a
PNA
1296
1297 if (!cda[CTA_NAT_SEQ_OFFSET_AFTER])
1298 return -EINVAL;
1299
1300 natseq->offset_after =
77236b6e 1301 ntohl(nla_get_be32(cda[CTA_NAT_SEQ_OFFSET_AFTER]));
13eae15a
PNA
1302
1303 return 0;
1304}
1305
1306static int
39938324
PM
1307ctnetlink_change_nat_seq_adj(struct nf_conn *ct,
1308 const struct nlattr * const cda[])
13eae15a
PNA
1309{
1310 int ret = 0;
1311 struct nf_conn_nat *nat = nfct_nat(ct);
1312
1313 if (!nat)
1314 return 0;
1315
1316 if (cda[CTA_NAT_SEQ_ADJ_ORIG]) {
1317 ret = change_nat_seq_adj(&nat->seq[IP_CT_DIR_ORIGINAL],
1318 cda[CTA_NAT_SEQ_ADJ_ORIG]);
1319 if (ret < 0)
1320 return ret;
1321
1322 ct->status |= IPS_SEQ_ADJUST;
1323 }
1324
1325 if (cda[CTA_NAT_SEQ_ADJ_REPLY]) {
1326 ret = change_nat_seq_adj(&nat->seq[IP_CT_DIR_REPLY],
1327 cda[CTA_NAT_SEQ_ADJ_REPLY]);
1328 if (ret < 0)
1329 return ret;
1330
1331 ct->status |= IPS_SEQ_ADJUST;
1332 }
1333
1334 return 0;
1335}
1336#endif
1337
c1d10adb 1338static int
39938324
PM
1339ctnetlink_change_conntrack(struct nf_conn *ct,
1340 const struct nlattr * const cda[])
c1d10adb
PNA
1341{
1342 int err;
1343
e098360f
PNA
1344 /* only allow NAT changes and master assignation for new conntracks */
1345 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST] || cda[CTA_TUPLE_MASTER])
1346 return -EOPNOTSUPP;
1347
df6fb868 1348 if (cda[CTA_HELP]) {
c1d10adb
PNA
1349 err = ctnetlink_change_helper(ct, cda);
1350 if (err < 0)
1351 return err;
1352 }
1353
df6fb868 1354 if (cda[CTA_TIMEOUT]) {
c1d10adb
PNA
1355 err = ctnetlink_change_timeout(ct, cda);
1356 if (err < 0)
1357 return err;
1358 }
1359
df6fb868 1360 if (cda[CTA_STATUS]) {
c1d10adb
PNA
1361 err = ctnetlink_change_status(ct, cda);
1362 if (err < 0)
1363 return err;
1364 }
1365
df6fb868 1366 if (cda[CTA_PROTOINFO]) {
c1d10adb
PNA
1367 err = ctnetlink_change_protoinfo(ct, cda);
1368 if (err < 0)
1369 return err;
1370 }
1371
bcd1e830 1372#if defined(CONFIG_NF_CONNTRACK_MARK)
df6fb868 1373 if (cda[CTA_MARK])
77236b6e 1374 ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
c1d10adb
PNA
1375#endif
1376
13eae15a
PNA
1377#ifdef CONFIG_NF_NAT_NEEDED
1378 if (cda[CTA_NAT_SEQ_ADJ_ORIG] || cda[CTA_NAT_SEQ_ADJ_REPLY]) {
1379 err = ctnetlink_change_nat_seq_adj(ct, cda);
1380 if (err < 0)
1381 return err;
1382 }
1383#endif
1384
c1d10adb
PNA
1385 return 0;
1386}
1387
f0a3c086 1388static struct nf_conn *
ef00f89f 1389ctnetlink_create_conntrack(struct net *net, u16 zone,
9592a5c0 1390 const struct nlattr * const cda[],
c1d10adb 1391 struct nf_conntrack_tuple *otuple,
5faa1f4c 1392 struct nf_conntrack_tuple *rtuple,
7ec47496 1393 u8 u3)
c1d10adb
PNA
1394{
1395 struct nf_conn *ct;
1396 int err = -EINVAL;
ceceae1b 1397 struct nf_conntrack_helper *helper;
315c34da 1398 struct nf_conn_tstamp *tstamp;
c1d10adb 1399
ef00f89f 1400 ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC);
cd7fcbf1 1401 if (IS_ERR(ct))
f0a3c086 1402 return ERR_PTR(-ENOMEM);
c1d10adb 1403
df6fb868 1404 if (!cda[CTA_TIMEOUT])
0f5b3e85 1405 goto err1;
77236b6e 1406 ct->timeout.expires = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
c1d10adb
PNA
1407
1408 ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
c1d10adb 1409
1575e7ea 1410 rcu_read_lock();
226c0c0e 1411 if (cda[CTA_HELP]) {
29fe1b48 1412 char *helpname = NULL;
226c0c0e
PNA
1413
1414 err = ctnetlink_parse_help(cda[CTA_HELP], &helpname);
0f5b3e85
PM
1415 if (err < 0)
1416 goto err2;
226c0c0e 1417
794e6871
PM
1418 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
1419 nf_ct_protonum(ct));
226c0c0e
PNA
1420 if (helper == NULL) {
1421 rcu_read_unlock();
1422#ifdef CONFIG_MODULES
1423 if (request_module("nfct-helper-%s", helpname) < 0) {
1424 err = -EOPNOTSUPP;
0f5b3e85 1425 goto err1;
226c0c0e
PNA
1426 }
1427
1428 rcu_read_lock();
794e6871
PM
1429 helper = __nf_conntrack_helper_find(helpname,
1430 nf_ct_l3num(ct),
1431 nf_ct_protonum(ct));
226c0c0e 1432 if (helper) {
226c0c0e 1433 err = -EAGAIN;
0f5b3e85 1434 goto err2;
226c0c0e
PNA
1435 }
1436 rcu_read_unlock();
1437#endif
1438 err = -EOPNOTSUPP;
0f5b3e85 1439 goto err1;
226c0c0e
PNA
1440 } else {
1441 struct nf_conn_help *help;
1442
1443 help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
1444 if (help == NULL) {
226c0c0e 1445 err = -ENOMEM;
0f5b3e85 1446 goto err2;
226c0c0e
PNA
1447 }
1448
1449 /* not in hash table yet so not strictly necessary */
a9b3cd7f 1450 RCU_INIT_POINTER(help->helper, helper);
226c0c0e
PNA
1451 }
1452 } else {
1453 /* try an implicit helper assignation */
b2a15a60 1454 err = __nf_ct_try_assign_helper(ct, NULL, GFP_ATOMIC);
0f5b3e85
PM
1455 if (err < 0)
1456 goto err2;
1575e7ea
PNA
1457 }
1458
a88e22ad
PNA
1459 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
1460 err = ctnetlink_change_nat(ct, cda);
0f5b3e85
PM
1461 if (err < 0)
1462 goto err2;
e6a7d3c0
PNA
1463 }
1464
a88e22ad 1465 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
a992ca2a 1466 nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
a88e22ad
PNA
1467 nf_ct_ecache_ext_add(ct, 0, 0, GFP_ATOMIC);
1468 /* we must add conntrack extensions before confirmation. */
1469 ct->status |= IPS_CONFIRMED;
1470
1471 if (cda[CTA_STATUS]) {
1472 err = ctnetlink_change_status(ct, cda);
0f5b3e85
PM
1473 if (err < 0)
1474 goto err2;
bbb3357d 1475 }
c1d10adb 1476
c969aa7d
PNA
1477#ifdef CONFIG_NF_NAT_NEEDED
1478 if (cda[CTA_NAT_SEQ_ADJ_ORIG] || cda[CTA_NAT_SEQ_ADJ_REPLY]) {
1479 err = ctnetlink_change_nat_seq_adj(ct, cda);
0f5b3e85
PM
1480 if (err < 0)
1481 goto err2;
c969aa7d
PNA
1482 }
1483#endif
1484
e5fc9e7a 1485 memset(&ct->proto, 0, sizeof(ct->proto));
df6fb868 1486 if (cda[CTA_PROTOINFO]) {
c1d10adb 1487 err = ctnetlink_change_protoinfo(ct, cda);
0f5b3e85
PM
1488 if (err < 0)
1489 goto err2;
c1d10adb
PNA
1490 }
1491
bcd1e830 1492#if defined(CONFIG_NF_CONNTRACK_MARK)
df6fb868 1493 if (cda[CTA_MARK])
77236b6e 1494 ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
c1d10adb
PNA
1495#endif
1496
5faa1f4c 1497 /* setup master conntrack: this is a confirmed expectation */
7ec47496
PNA
1498 if (cda[CTA_TUPLE_MASTER]) {
1499 struct nf_conntrack_tuple master;
1500 struct nf_conntrack_tuple_hash *master_h;
1501 struct nf_conn *master_ct;
1502
1503 err = ctnetlink_parse_tuple(cda, &master, CTA_TUPLE_MASTER, u3);
1504 if (err < 0)
0f5b3e85 1505 goto err2;
7ec47496 1506
ef00f89f 1507 master_h = nf_conntrack_find_get(net, zone, &master);
7ec47496
PNA
1508 if (master_h == NULL) {
1509 err = -ENOENT;
0f5b3e85 1510 goto err2;
7ec47496
PNA
1511 }
1512 master_ct = nf_ct_tuplehash_to_ctrack(master_h);
f2a89004 1513 __set_bit(IPS_EXPECTED_BIT, &ct->status);
5faa1f4c 1514 ct->master = master_ct;
f2a89004 1515 }
315c34da
PNA
1516 tstamp = nf_conn_tstamp_find(ct);
1517 if (tstamp)
1518 tstamp->start = ktime_to_ns(ktime_get_real());
5faa1f4c 1519
7d367e06
JK
1520 err = nf_conntrack_hash_check_insert(ct);
1521 if (err < 0)
1522 goto err2;
1523
58a3c9bb 1524 rcu_read_unlock();
dafc741c 1525
f0a3c086 1526 return ct;
c1d10adb 1527
0f5b3e85
PM
1528err2:
1529 rcu_read_unlock();
1530err1:
c1d10adb 1531 nf_conntrack_free(ct);
f0a3c086 1532 return ERR_PTR(err);
c1d10adb
PNA
1533}
1534
601e68e1
YH
1535static int
1536ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
39938324
PM
1537 const struct nlmsghdr *nlh,
1538 const struct nlattr * const cda[])
c1d10adb 1539{
9592a5c0 1540 struct net *net = sock_net(ctnl);
c1d10adb
PNA
1541 struct nf_conntrack_tuple otuple, rtuple;
1542 struct nf_conntrack_tuple_hash *h = NULL;
96bcf938 1543 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
7d367e06 1544 struct nf_conn *ct;
c1d10adb 1545 u_int8_t u3 = nfmsg->nfgen_family;
ef00f89f
PM
1546 u16 zone;
1547 int err;
1548
1549 err = ctnetlink_parse_zone(cda[CTA_ZONE], &zone);
1550 if (err < 0)
1551 return err;
c1d10adb 1552
df6fb868 1553 if (cda[CTA_TUPLE_ORIG]) {
c1d10adb
PNA
1554 err = ctnetlink_parse_tuple(cda, &otuple, CTA_TUPLE_ORIG, u3);
1555 if (err < 0)
1556 return err;
1557 }
1558
df6fb868 1559 if (cda[CTA_TUPLE_REPLY]) {
c1d10adb
PNA
1560 err = ctnetlink_parse_tuple(cda, &rtuple, CTA_TUPLE_REPLY, u3);
1561 if (err < 0)
1562 return err;
1563 }
1564
df6fb868 1565 if (cda[CTA_TUPLE_ORIG])
7d367e06 1566 h = nf_conntrack_find_get(net, zone, &otuple);
df6fb868 1567 else if (cda[CTA_TUPLE_REPLY])
7d367e06 1568 h = nf_conntrack_find_get(net, zone, &rtuple);
c1d10adb
PNA
1569
1570 if (h == NULL) {
c1d10adb 1571 err = -ENOENT;
f0a3c086 1572 if (nlh->nlmsg_flags & NLM_F_CREATE) {
fecc1133 1573 enum ip_conntrack_events events;
5faa1f4c 1574
ef00f89f 1575 ct = ctnetlink_create_conntrack(net, zone, cda, &otuple,
f0a3c086 1576 &rtuple, u3);
7d367e06
JK
1577 if (IS_ERR(ct))
1578 return PTR_ERR(ct);
1579
f0a3c086 1580 err = 0;
fecc1133
PNA
1581 if (test_bit(IPS_EXPECTED_BIT, &ct->status))
1582 events = IPCT_RELATED;
1583 else
1584 events = IPCT_NEW;
1585
858b3133
PM
1586 nf_conntrack_eventmask_report((1 << IPCT_REPLY) |
1587 (1 << IPCT_ASSURED) |
a0891aa6
PNA
1588 (1 << IPCT_HELPER) |
1589 (1 << IPCT_PROTOINFO) |
1590 (1 << IPCT_NATSEQADJ) |
1591 (1 << IPCT_MARK) | events,
1592 ct, NETLINK_CB(skb).pid,
1593 nlmsg_report(nlh));
f0a3c086 1594 nf_ct_put(ct);
7d367e06 1595 }
5faa1f4c 1596
c1d10adb
PNA
1597 return err;
1598 }
1599 /* implicit 'else' */
1600
c1d10adb 1601 err = -EEXIST;
7d367e06 1602 ct = nf_ct_tuplehash_to_ctrack(h);
ff4ca827 1603 if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
7d367e06 1604 spin_lock_bh(&nf_conntrack_lock);
19abb7b0 1605 err = ctnetlink_change_conntrack(ct, cda);
7d367e06 1606 spin_unlock_bh(&nf_conntrack_lock);
19abb7b0 1607 if (err == 0) {
858b3133
PM
1608 nf_conntrack_eventmask_report((1 << IPCT_REPLY) |
1609 (1 << IPCT_ASSURED) |
a0891aa6
PNA
1610 (1 << IPCT_HELPER) |
1611 (1 << IPCT_PROTOINFO) |
1612 (1 << IPCT_NATSEQADJ) |
1613 (1 << IPCT_MARK),
1614 ct, NETLINK_CB(skb).pid,
1615 nlmsg_report(nlh));
7d367e06 1616 }
ff4ca827 1617 }
c1d10adb 1618
7d367e06 1619 nf_ct_put(ct);
c1d10adb
PNA
1620 return err;
1621}
1622
601e68e1
YH
1623/***********************************************************************
1624 * EXPECT
1625 ***********************************************************************/
c1d10adb
PNA
1626
1627static inline int
1628ctnetlink_exp_dump_tuple(struct sk_buff *skb,
1629 const struct nf_conntrack_tuple *tuple,
1630 enum ctattr_expect type)
1631{
df6fb868 1632 struct nlattr *nest_parms;
601e68e1 1633
df6fb868
PM
1634 nest_parms = nla_nest_start(skb, type | NLA_F_NESTED);
1635 if (!nest_parms)
1636 goto nla_put_failure;
c1d10adb 1637 if (ctnetlink_dump_tuples(skb, tuple) < 0)
df6fb868
PM
1638 goto nla_put_failure;
1639 nla_nest_end(skb, nest_parms);
c1d10adb
PNA
1640
1641 return 0;
1642
df6fb868 1643nla_put_failure:
c1d10adb 1644 return -1;
601e68e1 1645}
c1d10adb 1646
1cde6436
PNA
1647static inline int
1648ctnetlink_exp_dump_mask(struct sk_buff *skb,
1649 const struct nf_conntrack_tuple *tuple,
d4156e8c 1650 const struct nf_conntrack_tuple_mask *mask)
1cde6436
PNA
1651{
1652 int ret;
1653 struct nf_conntrack_l3proto *l3proto;
605dcad6 1654 struct nf_conntrack_l4proto *l4proto;
d4156e8c 1655 struct nf_conntrack_tuple m;
df6fb868 1656 struct nlattr *nest_parms;
d4156e8c
PM
1657
1658 memset(&m, 0xFF, sizeof(m));
d4156e8c 1659 memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3));
e578756c
PM
1660 m.src.u.all = mask->src.u.all;
1661 m.dst.protonum = tuple->dst.protonum;
d4156e8c 1662
df6fb868
PM
1663 nest_parms = nla_nest_start(skb, CTA_EXPECT_MASK | NLA_F_NESTED);
1664 if (!nest_parms)
1665 goto nla_put_failure;
1cde6436 1666
3b988ece 1667 rcu_read_lock();
528a3a6f 1668 l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
d4156e8c 1669 ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto);
3b988ece
HS
1670 if (ret >= 0) {
1671 l4proto = __nf_ct_l4proto_find(tuple->src.l3num,
1672 tuple->dst.protonum);
d4156e8c 1673 ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
3b988ece
HS
1674 }
1675 rcu_read_unlock();
1676
1cde6436 1677 if (unlikely(ret < 0))
df6fb868 1678 goto nla_put_failure;
1cde6436 1679
df6fb868 1680 nla_nest_end(skb, nest_parms);
1cde6436
PNA
1681
1682 return 0;
1683
df6fb868 1684nla_put_failure:
1cde6436
PNA
1685 return -1;
1686}
1687
bb5cf80e 1688static int
c1d10adb 1689ctnetlink_exp_dump_expect(struct sk_buff *skb,
601e68e1 1690 const struct nf_conntrack_expect *exp)
c1d10adb
PNA
1691{
1692 struct nf_conn *master = exp->master;
c1216382 1693 long timeout = ((long)exp->timeout.expires - (long)jiffies) / HZ;
bc01befd 1694 struct nf_conn_help *help;
076a0ca0
PNA
1695#ifdef CONFIG_NF_NAT_NEEDED
1696 struct nlattr *nest_parms;
1697 struct nf_conntrack_tuple nat_tuple = {};
1698#endif
544d5c7d
PNA
1699 struct nf_ct_helper_expectfn *expfn;
1700
d978e5da
PM
1701 if (timeout < 0)
1702 timeout = 0;
c1d10adb
PNA
1703
1704 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
df6fb868 1705 goto nla_put_failure;
1cde6436 1706 if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
df6fb868 1707 goto nla_put_failure;
c1d10adb
PNA
1708 if (ctnetlink_exp_dump_tuple(skb,
1709 &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
1710 CTA_EXPECT_MASTER) < 0)
df6fb868 1711 goto nla_put_failure;
601e68e1 1712
076a0ca0
PNA
1713#ifdef CONFIG_NF_NAT_NEEDED
1714 if (exp->saved_ip || exp->saved_proto.all) {
1715 nest_parms = nla_nest_start(skb, CTA_EXPECT_NAT | NLA_F_NESTED);
1716 if (!nest_parms)
1717 goto nla_put_failure;
1718
cc1eb431
DM
1719 if (nla_put_be32(skb, CTA_EXPECT_NAT_DIR, htonl(exp->dir)))
1720 goto nla_put_failure;
076a0ca0
PNA
1721
1722 nat_tuple.src.l3num = nf_ct_l3num(master);
1723 nat_tuple.src.u3.ip = exp->saved_ip;
1724 nat_tuple.dst.protonum = nf_ct_protonum(master);
1725 nat_tuple.src.u = exp->saved_proto;
1726
1727 if (ctnetlink_exp_dump_tuple(skb, &nat_tuple,
1728 CTA_EXPECT_NAT_TUPLE) < 0)
1729 goto nla_put_failure;
1730 nla_nest_end(skb, nest_parms);
1731 }
1732#endif
cc1eb431
DM
1733 if (nla_put_be32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)) ||
1734 nla_put_be32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp)) ||
1735 nla_put_be32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)) ||
1736 nla_put_be32(skb, CTA_EXPECT_CLASS, htonl(exp->class)))
1737 goto nla_put_failure;
bc01befd
PNA
1738 help = nfct_help(master);
1739 if (help) {
1740 struct nf_conntrack_helper *helper;
1741
1742 helper = rcu_dereference(help->helper);
cc1eb431
DM
1743 if (helper &&
1744 nla_put_string(skb, CTA_EXPECT_HELP_NAME, helper->name))
1745 goto nla_put_failure;
bc01befd 1746 }
544d5c7d 1747 expfn = nf_ct_helper_expectfn_find_by_symbol(exp->expectfn);
cc1eb431
DM
1748 if (expfn != NULL &&
1749 nla_put_string(skb, CTA_EXPECT_FN, expfn->name))
1750 goto nla_put_failure;
c1d10adb
PNA
1751
1752 return 0;
601e68e1 1753
df6fb868 1754nla_put_failure:
c1d10adb
PNA
1755 return -1;
1756}
1757
1758static int
1759ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
8b0a231d 1760 int event, const struct nf_conntrack_expect *exp)
c1d10adb
PNA
1761{
1762 struct nlmsghdr *nlh;
1763 struct nfgenmsg *nfmsg;
96bcf938 1764 unsigned int flags = pid ? NLM_F_MULTI : 0;
c1d10adb
PNA
1765
1766 event |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
96bcf938
PNA
1767 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
1768 if (nlh == NULL)
1769 goto nlmsg_failure;
c1d10adb 1770
96bcf938 1771 nfmsg = nlmsg_data(nlh);
c1d10adb
PNA
1772 nfmsg->nfgen_family = exp->tuple.src.l3num;
1773 nfmsg->version = NFNETLINK_V0;
1774 nfmsg->res_id = 0;
1775
1776 if (ctnetlink_exp_dump_expect(skb, exp) < 0)
df6fb868 1777 goto nla_put_failure;
c1d10adb 1778
96bcf938 1779 nlmsg_end(skb, nlh);
c1d10adb
PNA
1780 return skb->len;
1781
1782nlmsg_failure:
df6fb868 1783nla_put_failure:
96bcf938 1784 nlmsg_cancel(skb, nlh);
c1d10adb
PNA
1785 return -1;
1786}
1787
1788#ifdef CONFIG_NF_CONNTRACK_EVENTS
e34d5c1a
PNA
1789static int
1790ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
c1d10adb 1791{
9592a5c0
AD
1792 struct nf_conntrack_expect *exp = item->exp;
1793 struct net *net = nf_ct_exp_net(exp);
c1d10adb
PNA
1794 struct nlmsghdr *nlh;
1795 struct nfgenmsg *nfmsg;
c1d10adb 1796 struct sk_buff *skb;
ebbf41df 1797 unsigned int type, group;
c1d10adb
PNA
1798 int flags = 0;
1799
ebbf41df
PNA
1800 if (events & (1 << IPEXP_DESTROY)) {
1801 type = IPCTNL_MSG_EXP_DELETE;
1802 group = NFNLGRP_CONNTRACK_EXP_DESTROY;
1803 } else if (events & (1 << IPEXP_NEW)) {
c1d10adb
PNA
1804 type = IPCTNL_MSG_EXP_NEW;
1805 flags = NLM_F_CREATE|NLM_F_EXCL;
ebbf41df 1806 group = NFNLGRP_CONNTRACK_EXP_NEW;
c1d10adb 1807 } else
e34d5c1a 1808 return 0;
c1d10adb 1809
ebbf41df 1810 if (!item->report && !nfnetlink_has_listeners(net, group))
e34d5c1a 1811 return 0;
b3a27bfb 1812
96bcf938
PNA
1813 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
1814 if (skb == NULL)
150ace0d 1815 goto errout;
c1d10adb 1816
b633ad5f 1817 type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
96bcf938
PNA
1818 nlh = nlmsg_put(skb, item->pid, 0, type, sizeof(*nfmsg), flags);
1819 if (nlh == NULL)
1820 goto nlmsg_failure;
c1d10adb 1821
96bcf938 1822 nfmsg = nlmsg_data(nlh);
c1d10adb
PNA
1823 nfmsg->nfgen_family = exp->tuple.src.l3num;
1824 nfmsg->version = NFNETLINK_V0;
1825 nfmsg->res_id = 0;
1826
528a3a6f 1827 rcu_read_lock();
c1d10adb 1828 if (ctnetlink_exp_dump_expect(skb, exp) < 0)
df6fb868 1829 goto nla_put_failure;
528a3a6f 1830 rcu_read_unlock();
c1d10adb 1831
96bcf938 1832 nlmsg_end(skb, nlh);
ebbf41df 1833 nfnetlink_send(skb, net, item->pid, group, item->report, GFP_ATOMIC);
e34d5c1a 1834 return 0;
c1d10adb 1835
df6fb868 1836nla_put_failure:
528a3a6f 1837 rcu_read_unlock();
96bcf938 1838 nlmsg_cancel(skb, nlh);
528a3a6f 1839nlmsg_failure:
c1d10adb 1840 kfree_skb(skb);
150ace0d 1841errout:
9592a5c0 1842 nfnetlink_set_err(net, 0, 0, -ENOBUFS);
e34d5c1a 1843 return 0;
c1d10adb
PNA
1844}
1845#endif
cf6994c2
PM
1846static int ctnetlink_exp_done(struct netlink_callback *cb)
1847{
31f15875
PM
1848 if (cb->args[1])
1849 nf_ct_expect_put((struct nf_conntrack_expect *)cb->args[1]);
cf6994c2
PM
1850 return 0;
1851}
c1d10adb
PNA
1852
1853static int
1854ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1855{
9592a5c0 1856 struct net *net = sock_net(skb->sk);
cf6994c2 1857 struct nf_conntrack_expect *exp, *last;
96bcf938 1858 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
31f15875 1859 struct hlist_node *n;
87711cb8 1860 u_int8_t l3proto = nfmsg->nfgen_family;
c1d10adb 1861
7d0742da 1862 rcu_read_lock();
31f15875
PM
1863 last = (struct nf_conntrack_expect *)cb->args[1];
1864 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
cf6994c2 1865restart:
9b03f38d 1866 hlist_for_each_entry(exp, n, &net->ct.expect_hash[cb->args[0]],
31f15875
PM
1867 hnode) {
1868 if (l3proto && exp->tuple.src.l3num != l3proto)
cf6994c2 1869 continue;
31f15875
PM
1870 if (cb->args[1]) {
1871 if (exp != last)
1872 continue;
1873 cb->args[1] = 0;
1874 }
8b0a231d
PNA
1875 if (ctnetlink_exp_fill_info(skb,
1876 NETLINK_CB(cb->skb).pid,
31f15875
PM
1877 cb->nlh->nlmsg_seq,
1878 IPCTNL_MSG_EXP_NEW,
8b0a231d 1879 exp) < 0) {
7d0742da
PM
1880 if (!atomic_inc_not_zero(&exp->use))
1881 continue;
31f15875
PM
1882 cb->args[1] = (unsigned long)exp;
1883 goto out;
1884 }
cf6994c2 1885 }
31f15875
PM
1886 if (cb->args[1]) {
1887 cb->args[1] = 0;
1888 goto restart;
cf6994c2
PM
1889 }
1890 }
601e68e1 1891out:
7d0742da 1892 rcu_read_unlock();
cf6994c2
PM
1893 if (last)
1894 nf_ct_expect_put(last);
c1d10adb 1895
c1d10adb
PNA
1896 return skb->len;
1897}
1898
f73e924c 1899static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
d0b0268f
PM
1900 [CTA_EXPECT_MASTER] = { .type = NLA_NESTED },
1901 [CTA_EXPECT_TUPLE] = { .type = NLA_NESTED },
1902 [CTA_EXPECT_MASK] = { .type = NLA_NESTED },
f73e924c
PM
1903 [CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 },
1904 [CTA_EXPECT_ID] = { .type = NLA_U32 },
d0b0268f 1905 [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING },
bcac0dfa 1906 [CTA_EXPECT_ZONE] = { .type = NLA_U16 },
8b008faf 1907 [CTA_EXPECT_FLAGS] = { .type = NLA_U32 },
b8c5e52c 1908 [CTA_EXPECT_CLASS] = { .type = NLA_U32 },
076a0ca0 1909 [CTA_EXPECT_NAT] = { .type = NLA_NESTED },
544d5c7d 1910 [CTA_EXPECT_FN] = { .type = NLA_NUL_STRING },
c1d10adb
PNA
1911};
1912
1913static int
601e68e1 1914ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
39938324
PM
1915 const struct nlmsghdr *nlh,
1916 const struct nlattr * const cda[])
c1d10adb 1917{
9592a5c0 1918 struct net *net = sock_net(ctnl);
c1d10adb
PNA
1919 struct nf_conntrack_tuple tuple;
1920 struct nf_conntrack_expect *exp;
1921 struct sk_buff *skb2;
96bcf938 1922 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 1923 u_int8_t u3 = nfmsg->nfgen_family;
ef00f89f
PM
1924 u16 zone;
1925 int err;
c1d10adb 1926
b8f3ab42 1927 if (nlh->nlmsg_flags & NLM_F_DUMP) {
80d326fa
PNA
1928 struct netlink_dump_control c = {
1929 .dump = ctnetlink_exp_dump_table,
1930 .done = ctnetlink_exp_done,
1931 };
1932 return netlink_dump_start(ctnl, skb, nlh, &c);
c1d10adb
PNA
1933 }
1934
ef00f89f
PM
1935 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
1936 if (err < 0)
1937 return err;
1938
35dba1d7
PNA
1939 if (cda[CTA_EXPECT_TUPLE])
1940 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
1941 else if (cda[CTA_EXPECT_MASTER])
c1d10adb
PNA
1942 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_MASTER, u3);
1943 else
1944 return -EINVAL;
1945
1946 if (err < 0)
1947 return err;
1948
ef00f89f 1949 exp = nf_ct_expect_find_get(net, zone, &tuple);
c1d10adb
PNA
1950 if (!exp)
1951 return -ENOENT;
1952
df6fb868 1953 if (cda[CTA_EXPECT_ID]) {
77236b6e 1954 __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
35832402 1955 if (ntohl(id) != (u32)(unsigned long)exp) {
6823645d 1956 nf_ct_expect_put(exp);
c1d10adb
PNA
1957 return -ENOENT;
1958 }
601e68e1 1959 }
c1d10adb
PNA
1960
1961 err = -ENOMEM;
96bcf938 1962 skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
81378f72
PNA
1963 if (skb2 == NULL) {
1964 nf_ct_expect_put(exp);
c1d10adb 1965 goto out;
81378f72 1966 }
4e9b8269 1967
528a3a6f 1968 rcu_read_lock();
601e68e1 1969 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
8b0a231d 1970 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, exp);
528a3a6f 1971 rcu_read_unlock();
81378f72 1972 nf_ct_expect_put(exp);
c1d10adb
PNA
1973 if (err <= 0)
1974 goto free;
1975
81378f72
PNA
1976 err = netlink_unicast(ctnl, skb2, NETLINK_CB(skb).pid, MSG_DONTWAIT);
1977 if (err < 0)
1978 goto out;
c1d10adb 1979
81378f72 1980 return 0;
c1d10adb
PNA
1981
1982free:
1983 kfree_skb(skb2);
1984out:
81378f72
PNA
1985 /* this avoids a loop in nfnetlink. */
1986 return err == -EAGAIN ? -ENOBUFS : err;
c1d10adb
PNA
1987}
1988
1989static int
601e68e1 1990ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
39938324
PM
1991 const struct nlmsghdr *nlh,
1992 const struct nlattr * const cda[])
c1d10adb 1993{
9592a5c0 1994 struct net *net = sock_net(ctnl);
31f15875 1995 struct nf_conntrack_expect *exp;
c1d10adb 1996 struct nf_conntrack_tuple tuple;
96bcf938 1997 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
31f15875 1998 struct hlist_node *n, *next;
c1d10adb 1999 u_int8_t u3 = nfmsg->nfgen_family;
31f15875 2000 unsigned int i;
ef00f89f 2001 u16 zone;
c1d10adb
PNA
2002 int err;
2003
df6fb868 2004 if (cda[CTA_EXPECT_TUPLE]) {
c1d10adb 2005 /* delete a single expect by tuple */
ef00f89f
PM
2006 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
2007 if (err < 0)
2008 return err;
2009
c1d10adb
PNA
2010 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
2011 if (err < 0)
2012 return err;
2013
2014 /* bump usage count to 2 */
ef00f89f 2015 exp = nf_ct_expect_find_get(net, zone, &tuple);
c1d10adb
PNA
2016 if (!exp)
2017 return -ENOENT;
2018
df6fb868 2019 if (cda[CTA_EXPECT_ID]) {
77236b6e 2020 __be32 id = nla_get_be32(cda[CTA_EXPECT_ID]);
35832402 2021 if (ntohl(id) != (u32)(unsigned long)exp) {
6823645d 2022 nf_ct_expect_put(exp);
c1d10adb
PNA
2023 return -ENOENT;
2024 }
2025 }
2026
2027 /* after list removal, usage count == 1 */
ebbf41df
PNA
2028 spin_lock_bh(&nf_conntrack_lock);
2029 if (del_timer(&exp->timeout)) {
2030 nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).pid,
2031 nlmsg_report(nlh));
2032 nf_ct_expect_put(exp);
2033 }
2034 spin_unlock_bh(&nf_conntrack_lock);
601e68e1 2035 /* have to put what we 'get' above.
c1d10adb 2036 * after this line usage count == 0 */
6823645d 2037 nf_ct_expect_put(exp);
df6fb868
PM
2038 } else if (cda[CTA_EXPECT_HELP_NAME]) {
2039 char *name = nla_data(cda[CTA_EXPECT_HELP_NAME]);
31f15875 2040 struct nf_conn_help *m_help;
c1d10adb
PNA
2041
2042 /* delete all expectations for this helper */
f8ba1aff 2043 spin_lock_bh(&nf_conntrack_lock);
31f15875
PM
2044 for (i = 0; i < nf_ct_expect_hsize; i++) {
2045 hlist_for_each_entry_safe(exp, n, next,
9592a5c0 2046 &net->ct.expect_hash[i],
31f15875
PM
2047 hnode) {
2048 m_help = nfct_help(exp->master);
794e6871
PM
2049 if (!strcmp(m_help->helper->name, name) &&
2050 del_timer(&exp->timeout)) {
ebbf41df
PNA
2051 nf_ct_unlink_expect_report(exp,
2052 NETLINK_CB(skb).pid,
2053 nlmsg_report(nlh));
31f15875
PM
2054 nf_ct_expect_put(exp);
2055 }
c1d10adb
PNA
2056 }
2057 }
f8ba1aff 2058 spin_unlock_bh(&nf_conntrack_lock);
c1d10adb
PNA
2059 } else {
2060 /* This basically means we have to flush everything*/
f8ba1aff 2061 spin_lock_bh(&nf_conntrack_lock);
31f15875
PM
2062 for (i = 0; i < nf_ct_expect_hsize; i++) {
2063 hlist_for_each_entry_safe(exp, n, next,
9592a5c0 2064 &net->ct.expect_hash[i],
31f15875
PM
2065 hnode) {
2066 if (del_timer(&exp->timeout)) {
ebbf41df
PNA
2067 nf_ct_unlink_expect_report(exp,
2068 NETLINK_CB(skb).pid,
2069 nlmsg_report(nlh));
31f15875
PM
2070 nf_ct_expect_put(exp);
2071 }
c1d10adb
PNA
2072 }
2073 }
f8ba1aff 2074 spin_unlock_bh(&nf_conntrack_lock);
c1d10adb
PNA
2075 }
2076
2077 return 0;
2078}
2079static int
39938324
PM
2080ctnetlink_change_expect(struct nf_conntrack_expect *x,
2081 const struct nlattr * const cda[])
c1d10adb
PNA
2082{
2083 return -EOPNOTSUPP;
2084}
2085
076a0ca0
PNA
2086static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = {
2087 [CTA_EXPECT_NAT_DIR] = { .type = NLA_U32 },
2088 [CTA_EXPECT_NAT_TUPLE] = { .type = NLA_NESTED },
2089};
2090
2091static int
2092ctnetlink_parse_expect_nat(const struct nlattr *attr,
2093 struct nf_conntrack_expect *exp,
2094 u_int8_t u3)
2095{
2096#ifdef CONFIG_NF_NAT_NEEDED
2097 struct nlattr *tb[CTA_EXPECT_NAT_MAX+1];
2098 struct nf_conntrack_tuple nat_tuple = {};
2099 int err;
2100
2101 nla_parse_nested(tb, CTA_EXPECT_NAT_MAX, attr, exp_nat_nla_policy);
2102
2103 if (!tb[CTA_EXPECT_NAT_DIR] || !tb[CTA_EXPECT_NAT_TUPLE])
2104 return -EINVAL;
2105
2106 err = ctnetlink_parse_tuple((const struct nlattr * const *)tb,
2107 &nat_tuple, CTA_EXPECT_NAT_TUPLE, u3);
2108 if (err < 0)
2109 return err;
2110
2111 exp->saved_ip = nat_tuple.src.u3.ip;
2112 exp->saved_proto = nat_tuple.src.u;
2113 exp->dir = ntohl(nla_get_be32(tb[CTA_EXPECT_NAT_DIR]));
2114
2115 return 0;
2116#else
2117 return -EOPNOTSUPP;
2118#endif
2119}
2120
c1d10adb 2121static int
ef00f89f
PM
2122ctnetlink_create_expect(struct net *net, u16 zone,
2123 const struct nlattr * const cda[],
9592a5c0 2124 u_int8_t u3,
39938324 2125 u32 pid, int report)
c1d10adb
PNA
2126{
2127 struct nf_conntrack_tuple tuple, mask, master_tuple;
2128 struct nf_conntrack_tuple_hash *h = NULL;
2129 struct nf_conntrack_expect *exp;
2130 struct nf_conn *ct;
dc808fe2 2131 struct nf_conn_help *help;
660fdb2a 2132 struct nf_conntrack_helper *helper = NULL;
b8c5e52c 2133 u_int32_t class = 0;
c1d10adb
PNA
2134 int err = 0;
2135
c1d10adb
PNA
2136 /* caller guarantees that those three CTA_EXPECT_* exist */
2137 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
2138 if (err < 0)
2139 return err;
2140 err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3);
2141 if (err < 0)
2142 return err;
2143 err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3);
2144 if (err < 0)
2145 return err;
2146
2147 /* Look for master conntrack of this expectation */
ef00f89f 2148 h = nf_conntrack_find_get(net, zone, &master_tuple);
c1d10adb
PNA
2149 if (!h)
2150 return -ENOENT;
2151 ct = nf_ct_tuplehash_to_ctrack(h);
660fdb2a
PNA
2152
2153 /* Look for helper of this expectation */
2154 if (cda[CTA_EXPECT_HELP_NAME]) {
2155 const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
2156
2157 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
2158 nf_ct_protonum(ct));
2159 if (helper == NULL) {
2160#ifdef CONFIG_MODULES
2161 if (request_module("nfct-helper-%s", helpname) < 0) {
2162 err = -EOPNOTSUPP;
2163 goto out;
2164 }
2165
2166 helper = __nf_conntrack_helper_find(helpname,
2167 nf_ct_l3num(ct),
2168 nf_ct_protonum(ct));
2169 if (helper) {
2170 err = -EAGAIN;
2171 goto out;
2172 }
2173#endif
2174 err = -EOPNOTSUPP;
2175 goto out;
2176 }
2177 }
2178
b8c5e52c
PNA
2179 if (cda[CTA_EXPECT_CLASS] && helper) {
2180 class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS]));
2181 if (class > helper->expect_class_max) {
2182 err = -EINVAL;
2183 goto out;
2184 }
2185 }
6823645d 2186 exp = nf_ct_expect_alloc(ct);
c1d10adb
PNA
2187 if (!exp) {
2188 err = -ENOMEM;
2189 goto out;
2190 }
bc01befd
PNA
2191 help = nfct_help(ct);
2192 if (!help) {
2193 if (!cda[CTA_EXPECT_TIMEOUT]) {
2194 err = -EINVAL;
2195 goto out;
2196 }
2197 exp->timeout.expires =
2198 jiffies + ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ;
601e68e1 2199
bc01befd
PNA
2200 exp->flags = NF_CT_EXPECT_USERSPACE;
2201 if (cda[CTA_EXPECT_FLAGS]) {
2202 exp->flags |=
2203 ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS]));
2204 }
2205 } else {
2206 if (cda[CTA_EXPECT_FLAGS]) {
2207 exp->flags = ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS]));
2208 exp->flags &= ~NF_CT_EXPECT_USERSPACE;
2209 } else
2210 exp->flags = 0;
2211 }
544d5c7d
PNA
2212 if (cda[CTA_EXPECT_FN]) {
2213 const char *name = nla_data(cda[CTA_EXPECT_FN]);
2214 struct nf_ct_helper_expectfn *expfn;
2215
2216 expfn = nf_ct_helper_expectfn_find_by_name(name);
2217 if (expfn == NULL) {
2218 err = -EINVAL;
2219 goto err_out;
2220 }
2221 exp->expectfn = expfn->expectfn;
2222 } else
2223 exp->expectfn = NULL;
601e68e1 2224
b8c5e52c 2225 exp->class = class;
c1d10adb 2226 exp->master = ct;
660fdb2a 2227 exp->helper = helper;
c1d10adb 2228 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
d4156e8c
PM
2229 memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
2230 exp->mask.src.u.all = mask.src.u.all;
c1d10adb 2231
076a0ca0
PNA
2232 if (cda[CTA_EXPECT_NAT]) {
2233 err = ctnetlink_parse_expect_nat(cda[CTA_EXPECT_NAT],
2234 exp, u3);
2235 if (err < 0)
2236 goto err_out;
2237 }
19abb7b0 2238 err = nf_ct_expect_related_report(exp, pid, report);
076a0ca0 2239err_out:
6823645d 2240 nf_ct_expect_put(exp);
601e68e1 2241out:
c1d10adb
PNA
2242 nf_ct_put(nf_ct_tuplehash_to_ctrack(h));
2243 return err;
2244}
2245
2246static int
2247ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
39938324
PM
2248 const struct nlmsghdr *nlh,
2249 const struct nlattr * const cda[])
c1d10adb 2250{
9592a5c0 2251 struct net *net = sock_net(ctnl);
c1d10adb
PNA
2252 struct nf_conntrack_tuple tuple;
2253 struct nf_conntrack_expect *exp;
96bcf938 2254 struct nfgenmsg *nfmsg = nlmsg_data(nlh);
c1d10adb 2255 u_int8_t u3 = nfmsg->nfgen_family;
ef00f89f
PM
2256 u16 zone;
2257 int err;
c1d10adb 2258
df6fb868
PM
2259 if (!cda[CTA_EXPECT_TUPLE]
2260 || !cda[CTA_EXPECT_MASK]
2261 || !cda[CTA_EXPECT_MASTER])
c1d10adb
PNA
2262 return -EINVAL;
2263
ef00f89f
PM
2264 err = ctnetlink_parse_zone(cda[CTA_EXPECT_ZONE], &zone);
2265 if (err < 0)
2266 return err;
2267
c1d10adb
PNA
2268 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
2269 if (err < 0)
2270 return err;
2271
f8ba1aff 2272 spin_lock_bh(&nf_conntrack_lock);
ef00f89f 2273 exp = __nf_ct_expect_find(net, zone, &tuple);
c1d10adb
PNA
2274
2275 if (!exp) {
f8ba1aff 2276 spin_unlock_bh(&nf_conntrack_lock);
c1d10adb 2277 err = -ENOENT;
19abb7b0 2278 if (nlh->nlmsg_flags & NLM_F_CREATE) {
ef00f89f 2279 err = ctnetlink_create_expect(net, zone, cda,
19abb7b0
PNA
2280 u3,
2281 NETLINK_CB(skb).pid,
2282 nlmsg_report(nlh));
2283 }
c1d10adb
PNA
2284 return err;
2285 }
2286
2287 err = -EEXIST;
2288 if (!(nlh->nlmsg_flags & NLM_F_EXCL))
2289 err = ctnetlink_change_expect(exp, cda);
f8ba1aff 2290 spin_unlock_bh(&nf_conntrack_lock);
c1d10adb 2291
c1d10adb
PNA
2292 return err;
2293}
2294
2295#ifdef CONFIG_NF_CONNTRACK_EVENTS
e34d5c1a
PNA
2296static struct nf_ct_event_notifier ctnl_notifier = {
2297 .fcn = ctnetlink_conntrack_event,
c1d10adb
PNA
2298};
2299
e34d5c1a
PNA
2300static struct nf_exp_event_notifier ctnl_notifier_exp = {
2301 .fcn = ctnetlink_expect_event,
c1d10adb
PNA
2302};
2303#endif
2304
7c8d4cb4 2305static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
c1d10adb 2306 [IPCTNL_MSG_CT_NEW] = { .call = ctnetlink_new_conntrack,
f73e924c
PM
2307 .attr_count = CTA_MAX,
2308 .policy = ct_nla_policy },
c1d10adb 2309 [IPCTNL_MSG_CT_GET] = { .call = ctnetlink_get_conntrack,
f73e924c
PM
2310 .attr_count = CTA_MAX,
2311 .policy = ct_nla_policy },
c1d10adb 2312 [IPCTNL_MSG_CT_DELETE] = { .call = ctnetlink_del_conntrack,
f73e924c
PM
2313 .attr_count = CTA_MAX,
2314 .policy = ct_nla_policy },
c1d10adb 2315 [IPCTNL_MSG_CT_GET_CTRZERO] = { .call = ctnetlink_get_conntrack,
f73e924c
PM
2316 .attr_count = CTA_MAX,
2317 .policy = ct_nla_policy },
c1d10adb
PNA
2318};
2319
7c8d4cb4 2320static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = {
c1d10adb 2321 [IPCTNL_MSG_EXP_GET] = { .call = ctnetlink_get_expect,
f73e924c
PM
2322 .attr_count = CTA_EXPECT_MAX,
2323 .policy = exp_nla_policy },
c1d10adb 2324 [IPCTNL_MSG_EXP_NEW] = { .call = ctnetlink_new_expect,
f73e924c
PM
2325 .attr_count = CTA_EXPECT_MAX,
2326 .policy = exp_nla_policy },
c1d10adb 2327 [IPCTNL_MSG_EXP_DELETE] = { .call = ctnetlink_del_expect,
f73e924c
PM
2328 .attr_count = CTA_EXPECT_MAX,
2329 .policy = exp_nla_policy },
c1d10adb
PNA
2330};
2331
7c8d4cb4 2332static const struct nfnetlink_subsystem ctnl_subsys = {
c1d10adb
PNA
2333 .name = "conntrack",
2334 .subsys_id = NFNL_SUBSYS_CTNETLINK,
2335 .cb_count = IPCTNL_MSG_MAX,
2336 .cb = ctnl_cb,
2337};
2338
7c8d4cb4 2339static const struct nfnetlink_subsystem ctnl_exp_subsys = {
c1d10adb
PNA
2340 .name = "conntrack_expect",
2341 .subsys_id = NFNL_SUBSYS_CTNETLINK_EXP,
2342 .cb_count = IPCTNL_MSG_EXP_MAX,
2343 .cb = ctnl_exp_cb,
2344};
2345
d2483dde 2346MODULE_ALIAS("ip_conntrack_netlink");
c1d10adb 2347MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
34f9a2e4 2348MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
c1d10adb 2349
70e9942f
PNA
2350static int __net_init ctnetlink_net_init(struct net *net)
2351{
2352#ifdef CONFIG_NF_CONNTRACK_EVENTS
2353 int ret;
2354
2355 ret = nf_conntrack_register_notifier(net, &ctnl_notifier);
2356 if (ret < 0) {
2357 pr_err("ctnetlink_init: cannot register notifier.\n");
2358 goto err_out;
2359 }
2360
2361 ret = nf_ct_expect_register_notifier(net, &ctnl_notifier_exp);
2362 if (ret < 0) {
2363 pr_err("ctnetlink_init: cannot expect register notifier.\n");
2364 goto err_unreg_notifier;
2365 }
2366#endif
2367 return 0;
2368
2369#ifdef CONFIG_NF_CONNTRACK_EVENTS
2370err_unreg_notifier:
2371 nf_conntrack_unregister_notifier(net, &ctnl_notifier);
2372err_out:
2373 return ret;
2374#endif
2375}
2376
2377static void ctnetlink_net_exit(struct net *net)
2378{
2379#ifdef CONFIG_NF_CONNTRACK_EVENTS
2380 nf_ct_expect_unregister_notifier(net, &ctnl_notifier_exp);
2381 nf_conntrack_unregister_notifier(net, &ctnl_notifier);
2382#endif
2383}
2384
2385static void __net_exit ctnetlink_net_exit_batch(struct list_head *net_exit_list)
2386{
2387 struct net *net;
2388
2389 list_for_each_entry(net, net_exit_list, exit_list)
2390 ctnetlink_net_exit(net);
2391}
2392
2393static struct pernet_operations ctnetlink_net_ops = {
2394 .init = ctnetlink_net_init,
2395 .exit_batch = ctnetlink_net_exit_batch,
2396};
2397
c1d10adb
PNA
2398static int __init ctnetlink_init(void)
2399{
2400 int ret;
2401
654d0fbd 2402 pr_info("ctnetlink v%s: registering with nfnetlink.\n", version);
c1d10adb
PNA
2403 ret = nfnetlink_subsys_register(&ctnl_subsys);
2404 if (ret < 0) {
654d0fbd 2405 pr_err("ctnetlink_init: cannot register with nfnetlink.\n");
c1d10adb
PNA
2406 goto err_out;
2407 }
2408
2409 ret = nfnetlink_subsys_register(&ctnl_exp_subsys);
2410 if (ret < 0) {
654d0fbd 2411 pr_err("ctnetlink_init: cannot register exp with nfnetlink.\n");
c1d10adb
PNA
2412 goto err_unreg_subsys;
2413 }
2414
70e9942f
PNA
2415 if (register_pernet_subsys(&ctnetlink_net_ops)) {
2416 pr_err("ctnetlink_init: cannot register pernet operations\n");
c1d10adb
PNA
2417 goto err_unreg_exp_subsys;
2418 }
2419
c1d10adb
PNA
2420 return 0;
2421
c1d10adb
PNA
2422err_unreg_exp_subsys:
2423 nfnetlink_subsys_unregister(&ctnl_exp_subsys);
c1d10adb
PNA
2424err_unreg_subsys:
2425 nfnetlink_subsys_unregister(&ctnl_subsys);
2426err_out:
2427 return ret;
2428}
2429
2430static void __exit ctnetlink_exit(void)
2431{
654d0fbd 2432 pr_info("ctnetlink: unregistering from nfnetlink.\n");
c1d10adb 2433
70e9942f 2434 unregister_pernet_subsys(&ctnetlink_net_ops);
c1d10adb
PNA
2435 nfnetlink_subsys_unregister(&ctnl_exp_subsys);
2436 nfnetlink_subsys_unregister(&ctnl_subsys);
c1d10adb
PNA
2437}
2438
2439module_init(ctnetlink_init);
2440module_exit(ctnetlink_exit);
This page took 0.857015 seconds and 5 git commands to generate.