1 /*
2 * Copyright (c) 2007-2009 Patrick McHardy <kaber@trash.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Development of this code funded by Astaro AG (http://www.astaro.com/)
9 */
10
11 #include <linux/module.h>
12 #include <linux/init.h>
13 #include <linux/list.h>
14 #include <linux/skbuff.h>
15 #include <linux/netlink.h>
16 #include <linux/vmalloc.h>
17 #include <linux/netfilter.h>
18 #include <linux/netfilter/nfnetlink.h>
19 #include <linux/netfilter/nf_tables.h>
20 #include <net/netfilter/nf_tables_core.h>
21 #include <net/netfilter/nf_tables.h>
22 #include <net/net_namespace.h>
23 #include <net/sock.h>
24
25 static LIST_HEAD(nf_tables_expressions);
26 static LIST_HEAD(nf_tables_objects);
27
28 /**
29 * nft_register_afinfo - register nf_tables address family info
30 *
31 * @afi: address family info to register
32 *
33 * Register the address family for use with nf_tables. Returns zero on
34 * success or a negative errno code otherwise.
35 */
nft_register_afinfo(struct net * net,struct nft_af_info * afi)36 int nft_register_afinfo(struct net *net, struct nft_af_info *afi)
37 {
38 INIT_LIST_HEAD(&afi->tables);
39 nfnl_lock(NFNL_SUBSYS_NFTABLES);
40 list_add_tail_rcu(&afi->list, &net->nft.af_info);
41 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
42 return 0;
43 }
44 EXPORT_SYMBOL_GPL(nft_register_afinfo);
45
46 static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi);
47
48 /**
49 * nft_unregister_afinfo - unregister nf_tables address family info
50 *
51 * @afi: address family info to unregister
52 *
53 * Unregister the address family for use with nf_tables.
54 */
nft_unregister_afinfo(struct net * net,struct nft_af_info * afi)55 void nft_unregister_afinfo(struct net *net, struct nft_af_info *afi)
56 {
57 nfnl_lock(NFNL_SUBSYS_NFTABLES);
58 __nft_release_afinfo(net, afi);
59 list_del_rcu(&afi->list);
60 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
61 }
62 EXPORT_SYMBOL_GPL(nft_unregister_afinfo);
63
nft_afinfo_lookup(struct net * net,int family)64 static struct nft_af_info *nft_afinfo_lookup(struct net *net, int family)
65 {
66 struct nft_af_info *afi;
67
68 list_for_each_entry(afi, &net->nft.af_info, list) {
69 if (afi->family == family)
70 return afi;
71 }
72 return NULL;
73 }
74
75 static struct nft_af_info *
nf_tables_afinfo_lookup(struct net * net,int family,bool autoload)76 nf_tables_afinfo_lookup(struct net *net, int family, bool autoload)
77 {
78 struct nft_af_info *afi;
79
80 afi = nft_afinfo_lookup(net, family);
81 if (afi != NULL)
82 return afi;
83 #ifdef CONFIG_MODULES
84 if (autoload) {
85 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
86 request_module("nft-afinfo-%u", family);
87 nfnl_lock(NFNL_SUBSYS_NFTABLES);
88 afi = nft_afinfo_lookup(net, family);
89 if (afi != NULL)
90 return ERR_PTR(-EAGAIN);
91 }
92 #endif
93 return ERR_PTR(-EAFNOSUPPORT);
94 }
95
nft_ctx_init(struct nft_ctx * ctx,struct net * net,const struct sk_buff * skb,const struct nlmsghdr * nlh,struct nft_af_info * afi,struct nft_table * table,struct nft_chain * chain,const struct nlattr * const * nla)96 static void nft_ctx_init(struct nft_ctx *ctx,
97 struct net *net,
98 const struct sk_buff *skb,
99 const struct nlmsghdr *nlh,
100 struct nft_af_info *afi,
101 struct nft_table *table,
102 struct nft_chain *chain,
103 const struct nlattr * const *nla)
104 {
105 ctx->net = net;
106 ctx->afi = afi;
107 ctx->table = table;
108 ctx->chain = chain;
109 ctx->nla = nla;
110 ctx->portid = NETLINK_CB(skb).portid;
111 ctx->report = nlmsg_report(nlh);
112 ctx->seq = nlh->nlmsg_seq;
113 }
114
nft_trans_alloc_gfp(const struct nft_ctx * ctx,int msg_type,u32 size,gfp_t gfp)115 static struct nft_trans *nft_trans_alloc_gfp(const struct nft_ctx *ctx,
116 int msg_type, u32 size, gfp_t gfp)
117 {
118 struct nft_trans *trans;
119
120 trans = kzalloc(sizeof(struct nft_trans) + size, gfp);
121 if (trans == NULL)
122 return NULL;
123
124 trans->msg_type = msg_type;
125 trans->ctx = *ctx;
126
127 return trans;
128 }
129
nft_trans_alloc(const struct nft_ctx * ctx,int msg_type,u32 size)130 static struct nft_trans *nft_trans_alloc(const struct nft_ctx *ctx,
131 int msg_type, u32 size)
132 {
133 return nft_trans_alloc_gfp(ctx, msg_type, size, GFP_KERNEL);
134 }
135
nft_trans_destroy(struct nft_trans * trans)136 static void nft_trans_destroy(struct nft_trans *trans)
137 {
138 list_del(&trans->list);
139 kfree(trans);
140 }
141
nf_tables_register_hooks(struct net * net,const struct nft_table * table,struct nft_chain * chain,unsigned int hook_nops)142 static int nf_tables_register_hooks(struct net *net,
143 const struct nft_table *table,
144 struct nft_chain *chain,
145 unsigned int hook_nops)
146 {
147 if (table->flags & NFT_TABLE_F_DORMANT ||
148 !nft_is_base_chain(chain))
149 return 0;
150
151 return nf_register_net_hooks(net, nft_base_chain(chain)->ops,
152 hook_nops);
153 }
154
nf_tables_unregister_hooks(struct net * net,const struct nft_table * table,struct nft_chain * chain,unsigned int hook_nops)155 static void nf_tables_unregister_hooks(struct net *net,
156 const struct nft_table *table,
157 struct nft_chain *chain,
158 unsigned int hook_nops)
159 {
160 if (table->flags & NFT_TABLE_F_DORMANT ||
161 !nft_is_base_chain(chain))
162 return;
163
164 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops, hook_nops);
165 }
166
nft_trans_table_add(struct nft_ctx * ctx,int msg_type)167 static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
168 {
169 struct nft_trans *trans;
170
171 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_table));
172 if (trans == NULL)
173 return -ENOMEM;
174
175 if (msg_type == NFT_MSG_NEWTABLE)
176 nft_activate_next(ctx->net, ctx->table);
177
178 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
179 return 0;
180 }
181
nft_deltable(struct nft_ctx * ctx)182 static int nft_deltable(struct nft_ctx *ctx)
183 {
184 int err;
185
186 err = nft_trans_table_add(ctx, NFT_MSG_DELTABLE);
187 if (err < 0)
188 return err;
189
190 nft_deactivate_next(ctx->net, ctx->table);
191 return err;
192 }
193
nft_trans_chain_add(struct nft_ctx * ctx,int msg_type)194 static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
195 {
196 struct nft_trans *trans;
197
198 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
199 if (trans == NULL)
200 return -ENOMEM;
201
202 if (msg_type == NFT_MSG_NEWCHAIN)
203 nft_activate_next(ctx->net, ctx->chain);
204
205 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
206 return 0;
207 }
208
nft_delchain(struct nft_ctx * ctx)209 static int nft_delchain(struct nft_ctx *ctx)
210 {
211 int err;
212
213 err = nft_trans_chain_add(ctx, NFT_MSG_DELCHAIN);
214 if (err < 0)
215 return err;
216
217 ctx->table->use--;
218 nft_deactivate_next(ctx->net, ctx->chain);
219
220 return err;
221 }
222
223 /* either expr ops provide both activate/deactivate, or neither */
nft_expr_check_ops(const struct nft_expr_ops * ops)224 static bool nft_expr_check_ops(const struct nft_expr_ops *ops)
225 {
226 if (!ops)
227 return true;
228
229 if (WARN_ON_ONCE((!ops->activate ^ !ops->deactivate)))
230 return false;
231
232 return true;
233 }
234
nft_rule_expr_activate(const struct nft_ctx * ctx,struct nft_rule * rule)235 static void nft_rule_expr_activate(const struct nft_ctx *ctx,
236 struct nft_rule *rule)
237 {
238 struct nft_expr *expr;
239
240 expr = nft_expr_first(rule);
241 while (expr != nft_expr_last(rule) && expr->ops) {
242 if (expr->ops->activate)
243 expr->ops->activate(ctx, expr);
244
245 expr = nft_expr_next(expr);
246 }
247 }
248
nft_rule_expr_deactivate(const struct nft_ctx * ctx,struct nft_rule * rule)249 static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
250 struct nft_rule *rule)
251 {
252 struct nft_expr *expr;
253
254 expr = nft_expr_first(rule);
255 while (expr != nft_expr_last(rule) && expr->ops) {
256 if (expr->ops->deactivate)
257 expr->ops->deactivate(ctx, expr);
258
259 expr = nft_expr_next(expr);
260 }
261 }
262
263 static int
nf_tables_delrule_deactivate(struct nft_ctx * ctx,struct nft_rule * rule)264 nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
265 {
266 /* You cannot delete the same rule twice */
267 if (nft_is_active_next(ctx->net, rule)) {
268 nft_deactivate_next(ctx->net, rule);
269 ctx->chain->use--;
270 return 0;
271 }
272 return -ENOENT;
273 }
274
nft_trans_rule_add(struct nft_ctx * ctx,int msg_type,struct nft_rule * rule)275 static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
276 struct nft_rule *rule)
277 {
278 struct nft_trans *trans;
279
280 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
281 if (trans == NULL)
282 return NULL;
283
284 if (msg_type == NFT_MSG_NEWRULE && ctx->nla[NFTA_RULE_ID] != NULL) {
285 nft_trans_rule_id(trans) =
286 ntohl(nla_get_be32(ctx->nla[NFTA_RULE_ID]));
287 }
288 nft_trans_rule(trans) = rule;
289 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
290
291 return trans;
292 }
293
nft_delrule(struct nft_ctx * ctx,struct nft_rule * rule)294 static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
295 {
296 struct nft_trans *trans;
297 int err;
298
299 trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
300 if (trans == NULL)
301 return -ENOMEM;
302
303 err = nf_tables_delrule_deactivate(ctx, rule);
304 if (err < 0) {
305 nft_trans_destroy(trans);
306 return err;
307 }
308 nft_rule_expr_deactivate(ctx, rule);
309
310 return 0;
311 }
312
nft_delrule_by_chain(struct nft_ctx * ctx)313 static int nft_delrule_by_chain(struct nft_ctx *ctx)
314 {
315 struct nft_rule *rule;
316 int err;
317
318 list_for_each_entry(rule, &ctx->chain->rules, list) {
319 if (!nft_is_active_next(ctx->net, rule))
320 continue;
321
322 err = nft_delrule(ctx, rule);
323 if (err < 0)
324 return err;
325 }
326 return 0;
327 }
328
nft_trans_set_add(struct nft_ctx * ctx,int msg_type,struct nft_set * set)329 static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
330 struct nft_set *set)
331 {
332 struct nft_trans *trans;
333
334 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_set));
335 if (trans == NULL)
336 return -ENOMEM;
337
338 if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
339 nft_trans_set_id(trans) =
340 ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
341 nft_activate_next(ctx->net, set);
342 }
343 nft_trans_set(trans) = set;
344 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
345
346 return 0;
347 }
348
nft_delset(struct nft_ctx * ctx,struct nft_set * set)349 static int nft_delset(struct nft_ctx *ctx, struct nft_set *set)
350 {
351 int err;
352
353 err = nft_trans_set_add(ctx, NFT_MSG_DELSET, set);
354 if (err < 0)
355 return err;
356
357 nft_deactivate_next(ctx->net, set);
358 ctx->table->use--;
359
360 return err;
361 }
362
nft_trans_obj_add(struct nft_ctx * ctx,int msg_type,struct nft_object * obj)363 static int nft_trans_obj_add(struct nft_ctx *ctx, int msg_type,
364 struct nft_object *obj)
365 {
366 struct nft_trans *trans;
367
368 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_obj));
369 if (trans == NULL)
370 return -ENOMEM;
371
372 if (msg_type == NFT_MSG_NEWOBJ)
373 nft_activate_next(ctx->net, obj);
374
375 nft_trans_obj(trans) = obj;
376 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
377
378 return 0;
379 }
380
nft_delobj(struct nft_ctx * ctx,struct nft_object * obj)381 static int nft_delobj(struct nft_ctx *ctx, struct nft_object *obj)
382 {
383 int err;
384
385 err = nft_trans_obj_add(ctx, NFT_MSG_DELOBJ, obj);
386 if (err < 0)
387 return err;
388
389 nft_deactivate_next(ctx->net, obj);
390 ctx->table->use--;
391
392 return err;
393 }
394
395 /*
396 * Tables
397 */
398
nft_table_lookup(const struct nft_af_info * afi,const struct nlattr * nla,u8 genmask)399 static struct nft_table *nft_table_lookup(const struct nft_af_info *afi,
400 const struct nlattr *nla,
401 u8 genmask)
402 {
403 struct nft_table *table;
404
405 list_for_each_entry(table, &afi->tables, list) {
406 if (!nla_strcmp(nla, table->name) &&
407 nft_active_genmask(table, genmask))
408 return table;
409 }
410 return NULL;
411 }
412
nf_tables_table_lookup(const struct nft_af_info * afi,const struct nlattr * nla,u8 genmask)413 static struct nft_table *nf_tables_table_lookup(const struct nft_af_info *afi,
414 const struct nlattr *nla,
415 u8 genmask)
416 {
417 struct nft_table *table;
418
419 if (nla == NULL)
420 return ERR_PTR(-EINVAL);
421
422 table = nft_table_lookup(afi, nla, genmask);
423 if (table != NULL)
424 return table;
425
426 return ERR_PTR(-ENOENT);
427 }
428
nf_tables_alloc_handle(struct nft_table * table)429 static inline u64 nf_tables_alloc_handle(struct nft_table *table)
430 {
431 return ++table->hgenerator;
432 }
433
434 static const struct nf_chain_type *chain_type[NFPROTO_NUMPROTO][NFT_CHAIN_T_MAX];
435
436 static const struct nf_chain_type *
__nf_tables_chain_type_lookup(int family,const struct nlattr * nla)437 __nf_tables_chain_type_lookup(int family, const struct nlattr *nla)
438 {
439 int i;
440
441 for (i = 0; i < NFT_CHAIN_T_MAX; i++) {
442 if (chain_type[family][i] != NULL &&
443 !nla_strcmp(nla, chain_type[family][i]->name))
444 return chain_type[family][i];
445 }
446 return NULL;
447 }
448
449 static const struct nf_chain_type *
nf_tables_chain_type_lookup(const struct nft_af_info * afi,const struct nlattr * nla,bool autoload)450 nf_tables_chain_type_lookup(const struct nft_af_info *afi,
451 const struct nlattr *nla,
452 bool autoload)
453 {
454 const struct nf_chain_type *type;
455
456 type = __nf_tables_chain_type_lookup(afi->family, nla);
457 if (type != NULL)
458 return type;
459 #ifdef CONFIG_MODULES
460 if (autoload) {
461 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
462 request_module("nft-chain-%u-%.*s", afi->family,
463 nla_len(nla), (const char *)nla_data(nla));
464 nfnl_lock(NFNL_SUBSYS_NFTABLES);
465 type = __nf_tables_chain_type_lookup(afi->family, nla);
466 if (type != NULL)
467 return ERR_PTR(-EAGAIN);
468 }
469 #endif
470 return ERR_PTR(-ENOENT);
471 }
472
473 static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
474 [NFTA_TABLE_NAME] = { .type = NLA_STRING,
475 .len = NFT_TABLE_MAXNAMELEN - 1 },
476 [NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
477 };
478
nf_tables_fill_table_info(struct sk_buff * skb,struct net * net,u32 portid,u32 seq,int event,u32 flags,int family,const struct nft_table * table)479 static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
480 u32 portid, u32 seq, int event, u32 flags,
481 int family, const struct nft_table *table)
482 {
483 struct nlmsghdr *nlh;
484 struct nfgenmsg *nfmsg;
485
486 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
487 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
488 if (nlh == NULL)
489 goto nla_put_failure;
490
491 nfmsg = nlmsg_data(nlh);
492 nfmsg->nfgen_family = family;
493 nfmsg->version = NFNETLINK_V0;
494 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
495
496 if (nla_put_string(skb, NFTA_TABLE_NAME, table->name) ||
497 nla_put_be32(skb, NFTA_TABLE_FLAGS, htonl(table->flags)) ||
498 nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)))
499 goto nla_put_failure;
500
501 nlmsg_end(skb, nlh);
502 return 0;
503
504 nla_put_failure:
505 nlmsg_trim(skb, nlh);
506 return -1;
507 }
508
nf_tables_table_notify(const struct nft_ctx * ctx,int event)509 static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
510 {
511 struct sk_buff *skb;
512 int err;
513
514 if (!ctx->report &&
515 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
516 return;
517
518 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
519 if (skb == NULL)
520 goto err;
521
522 err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq,
523 event, 0, ctx->afi->family, ctx->table);
524 if (err < 0) {
525 kfree_skb(skb);
526 goto err;
527 }
528
529 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
530 ctx->report, GFP_KERNEL);
531 return;
532 err:
533 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
534 }
535
nf_tables_dump_tables(struct sk_buff * skb,struct netlink_callback * cb)536 static int nf_tables_dump_tables(struct sk_buff *skb,
537 struct netlink_callback *cb)
538 {
539 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
540 const struct nft_af_info *afi;
541 const struct nft_table *table;
542 unsigned int idx = 0, s_idx = cb->args[0];
543 struct net *net = sock_net(skb->sk);
544 int family = nfmsg->nfgen_family;
545
546 rcu_read_lock();
547 cb->seq = net->nft.base_seq;
548
549 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
550 if (family != NFPROTO_UNSPEC && family != afi->family)
551 continue;
552
553 list_for_each_entry_rcu(table, &afi->tables, list) {
554 if (idx < s_idx)
555 goto cont;
556 if (idx > s_idx)
557 memset(&cb->args[1], 0,
558 sizeof(cb->args) - sizeof(cb->args[0]));
559 if (!nft_is_active(net, table))
560 continue;
561 if (nf_tables_fill_table_info(skb, net,
562 NETLINK_CB(cb->skb).portid,
563 cb->nlh->nlmsg_seq,
564 NFT_MSG_NEWTABLE,
565 NLM_F_MULTI,
566 afi->family, table) < 0)
567 goto done;
568
569 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
570 cont:
571 idx++;
572 }
573 }
574 done:
575 rcu_read_unlock();
576 cb->args[0] = idx;
577 return skb->len;
578 }
579
nf_tables_gettable(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)580 static int nf_tables_gettable(struct net *net, struct sock *nlsk,
581 struct sk_buff *skb, const struct nlmsghdr *nlh,
582 const struct nlattr * const nla[],
583 struct netlink_ext_ack *extack)
584 {
585 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
586 u8 genmask = nft_genmask_cur(net);
587 const struct nft_af_info *afi;
588 const struct nft_table *table;
589 struct sk_buff *skb2;
590 int family = nfmsg->nfgen_family;
591 int err;
592
593 if (nlh->nlmsg_flags & NLM_F_DUMP) {
594 struct netlink_dump_control c = {
595 .dump = nf_tables_dump_tables,
596 };
597 return netlink_dump_start(nlsk, skb, nlh, &c);
598 }
599
600 afi = nf_tables_afinfo_lookup(net, family, false);
601 if (IS_ERR(afi))
602 return PTR_ERR(afi);
603
604 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
605 if (IS_ERR(table))
606 return PTR_ERR(table);
607
608 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
609 if (!skb2)
610 return -ENOMEM;
611
612 err = nf_tables_fill_table_info(skb2, net, NETLINK_CB(skb).portid,
613 nlh->nlmsg_seq, NFT_MSG_NEWTABLE, 0,
614 family, table);
615 if (err < 0)
616 goto err;
617
618 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
619
620 err:
621 kfree_skb(skb2);
622 return err;
623 }
624
_nf_tables_table_disable(struct net * net,const struct nft_af_info * afi,struct nft_table * table,u32 cnt)625 static void _nf_tables_table_disable(struct net *net,
626 const struct nft_af_info *afi,
627 struct nft_table *table,
628 u32 cnt)
629 {
630 struct nft_chain *chain;
631 u32 i = 0;
632
633 list_for_each_entry(chain, &table->chains, list) {
634 if (!nft_is_active_next(net, chain))
635 continue;
636 if (!nft_is_base_chain(chain))
637 continue;
638
639 if (cnt && i++ == cnt)
640 break;
641
642 nf_unregister_net_hooks(net, nft_base_chain(chain)->ops,
643 afi->nops);
644 }
645 }
646
nf_tables_table_enable(struct net * net,const struct nft_af_info * afi,struct nft_table * table)647 static int nf_tables_table_enable(struct net *net,
648 const struct nft_af_info *afi,
649 struct nft_table *table)
650 {
651 struct nft_chain *chain;
652 int err, i = 0;
653
654 list_for_each_entry(chain, &table->chains, list) {
655 if (!nft_is_active_next(net, chain))
656 continue;
657 if (!nft_is_base_chain(chain))
658 continue;
659
660 err = nf_register_net_hooks(net, nft_base_chain(chain)->ops,
661 afi->nops);
662 if (err < 0)
663 goto err;
664
665 i++;
666 }
667 return 0;
668 err:
669 if (i)
670 _nf_tables_table_disable(net, afi, table, i);
671 return err;
672 }
673
nf_tables_table_disable(struct net * net,const struct nft_af_info * afi,struct nft_table * table)674 static void nf_tables_table_disable(struct net *net,
675 const struct nft_af_info *afi,
676 struct nft_table *table)
677 {
678 _nf_tables_table_disable(net, afi, table, 0);
679 }
680
nf_tables_updtable(struct nft_ctx * ctx)681 static int nf_tables_updtable(struct nft_ctx *ctx)
682 {
683 struct nft_trans *trans;
684 u32 flags;
685 int ret = 0;
686
687 if (!ctx->nla[NFTA_TABLE_FLAGS])
688 return 0;
689
690 flags = ntohl(nla_get_be32(ctx->nla[NFTA_TABLE_FLAGS]));
691 if (flags & ~NFT_TABLE_F_DORMANT)
692 return -EINVAL;
693
694 if (flags == ctx->table->flags)
695 return 0;
696
697 trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
698 sizeof(struct nft_trans_table));
699 if (trans == NULL)
700 return -ENOMEM;
701
702 if ((flags & NFT_TABLE_F_DORMANT) &&
703 !(ctx->table->flags & NFT_TABLE_F_DORMANT)) {
704 nft_trans_table_enable(trans) = false;
705 } else if (!(flags & NFT_TABLE_F_DORMANT) &&
706 ctx->table->flags & NFT_TABLE_F_DORMANT) {
707 ret = nf_tables_table_enable(ctx->net, ctx->afi, ctx->table);
708 if (ret >= 0) {
709 ctx->table->flags &= ~NFT_TABLE_F_DORMANT;
710 nft_trans_table_enable(trans) = true;
711 }
712 }
713 if (ret < 0)
714 goto err;
715
716 nft_trans_table_update(trans) = true;
717 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
718 return 0;
719 err:
720 nft_trans_destroy(trans);
721 return ret;
722 }
723
nf_tables_newtable(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)724 static int nf_tables_newtable(struct net *net, struct sock *nlsk,
725 struct sk_buff *skb, const struct nlmsghdr *nlh,
726 const struct nlattr * const nla[],
727 struct netlink_ext_ack *extack)
728 {
729 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
730 u8 genmask = nft_genmask_next(net);
731 const struct nlattr *name;
732 struct nft_af_info *afi;
733 struct nft_table *table;
734 int family = nfmsg->nfgen_family;
735 u32 flags = 0;
736 struct nft_ctx ctx;
737 int err;
738
739 afi = nf_tables_afinfo_lookup(net, family, true);
740 if (IS_ERR(afi))
741 return PTR_ERR(afi);
742
743 name = nla[NFTA_TABLE_NAME];
744 table = nf_tables_table_lookup(afi, name, genmask);
745 if (IS_ERR(table)) {
746 if (PTR_ERR(table) != -ENOENT)
747 return PTR_ERR(table);
748 } else {
749 if (nlh->nlmsg_flags & NLM_F_EXCL)
750 return -EEXIST;
751 if (nlh->nlmsg_flags & NLM_F_REPLACE)
752 return -EOPNOTSUPP;
753
754 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
755 return nf_tables_updtable(&ctx);
756 }
757
758 if (nla[NFTA_TABLE_FLAGS]) {
759 flags = ntohl(nla_get_be32(nla[NFTA_TABLE_FLAGS]));
760 if (flags & ~NFT_TABLE_F_DORMANT)
761 return -EINVAL;
762 }
763
764 err = -EAFNOSUPPORT;
765 if (!try_module_get(afi->owner))
766 goto err1;
767
768 err = -ENOMEM;
769 table = kzalloc(sizeof(*table), GFP_KERNEL);
770 if (table == NULL)
771 goto err2;
772
773 table->name = nla_strdup(name, GFP_KERNEL);
774 if (table->name == NULL)
775 goto err3;
776
777 INIT_LIST_HEAD(&table->chains);
778 INIT_LIST_HEAD(&table->sets);
779 INIT_LIST_HEAD(&table->objects);
780 table->flags = flags;
781
782 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
783 err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
784 if (err < 0)
785 goto err4;
786
787 list_add_tail_rcu(&table->list, &afi->tables);
788 return 0;
789 err4:
790 kfree(table->name);
791 err3:
792 kfree(table);
793 err2:
794 module_put(afi->owner);
795 err1:
796 return err;
797 }
798
nft_flush_table(struct nft_ctx * ctx)799 static int nft_flush_table(struct nft_ctx *ctx)
800 {
801 int err;
802 struct nft_chain *chain, *nc;
803 struct nft_object *obj, *ne;
804 struct nft_set *set, *ns;
805
806 list_for_each_entry(chain, &ctx->table->chains, list) {
807 if (!nft_is_active_next(ctx->net, chain))
808 continue;
809
810 ctx->chain = chain;
811
812 err = nft_delrule_by_chain(ctx);
813 if (err < 0)
814 goto out;
815 }
816
817 list_for_each_entry_safe(set, ns, &ctx->table->sets, list) {
818 if (!nft_is_active_next(ctx->net, set))
819 continue;
820
821 if (set->flags & NFT_SET_ANONYMOUS &&
822 !list_empty(&set->bindings))
823 continue;
824
825 err = nft_delset(ctx, set);
826 if (err < 0)
827 goto out;
828 }
829
830 list_for_each_entry_safe(obj, ne, &ctx->table->objects, list) {
831 err = nft_delobj(ctx, obj);
832 if (err < 0)
833 goto out;
834 }
835
836 list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
837 if (!nft_is_active_next(ctx->net, chain))
838 continue;
839
840 ctx->chain = chain;
841
842 err = nft_delchain(ctx);
843 if (err < 0)
844 goto out;
845 }
846
847 err = nft_deltable(ctx);
848 out:
849 return err;
850 }
851
nft_flush(struct nft_ctx * ctx,int family)852 static int nft_flush(struct nft_ctx *ctx, int family)
853 {
854 struct nft_af_info *afi;
855 struct nft_table *table, *nt;
856 const struct nlattr * const *nla = ctx->nla;
857 int err = 0;
858
859 list_for_each_entry(afi, &ctx->net->nft.af_info, list) {
860 if (family != AF_UNSPEC && afi->family != family)
861 continue;
862
863 ctx->afi = afi;
864 list_for_each_entry_safe(table, nt, &afi->tables, list) {
865 if (!nft_is_active_next(ctx->net, table))
866 continue;
867
868 if (nla[NFTA_TABLE_NAME] &&
869 nla_strcmp(nla[NFTA_TABLE_NAME], table->name) != 0)
870 continue;
871
872 ctx->table = table;
873
874 err = nft_flush_table(ctx);
875 if (err < 0)
876 goto out;
877 }
878 }
879 out:
880 return err;
881 }
882
nf_tables_deltable(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)883 static int nf_tables_deltable(struct net *net, struct sock *nlsk,
884 struct sk_buff *skb, const struct nlmsghdr *nlh,
885 const struct nlattr * const nla[],
886 struct netlink_ext_ack *extack)
887 {
888 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
889 u8 genmask = nft_genmask_next(net);
890 struct nft_af_info *afi;
891 struct nft_table *table;
892 int family = nfmsg->nfgen_family;
893 struct nft_ctx ctx;
894
895 nft_ctx_init(&ctx, net, skb, nlh, NULL, NULL, NULL, nla);
896 if (family == AF_UNSPEC || nla[NFTA_TABLE_NAME] == NULL)
897 return nft_flush(&ctx, family);
898
899 afi = nf_tables_afinfo_lookup(net, family, false);
900 if (IS_ERR(afi))
901 return PTR_ERR(afi);
902
903 table = nf_tables_table_lookup(afi, nla[NFTA_TABLE_NAME], genmask);
904 if (IS_ERR(table))
905 return PTR_ERR(table);
906
907 if (nlh->nlmsg_flags & NLM_F_NONREC &&
908 table->use > 0)
909 return -EBUSY;
910
911 ctx.afi = afi;
912 ctx.table = table;
913
914 return nft_flush_table(&ctx);
915 }
916
nf_tables_table_destroy(struct nft_ctx * ctx)917 static void nf_tables_table_destroy(struct nft_ctx *ctx)
918 {
919 BUG_ON(ctx->table->use > 0);
920
921 kfree(ctx->table->name);
922 kfree(ctx->table);
923 module_put(ctx->afi->owner);
924 }
925
nft_register_chain_type(const struct nf_chain_type * ctype)926 int nft_register_chain_type(const struct nf_chain_type *ctype)
927 {
928 int err = 0;
929
930 if (WARN_ON(ctype->family >= NFPROTO_NUMPROTO))
931 return -EINVAL;
932
933 nfnl_lock(NFNL_SUBSYS_NFTABLES);
934 if (chain_type[ctype->family][ctype->type] != NULL) {
935 err = -EBUSY;
936 goto out;
937 }
938 chain_type[ctype->family][ctype->type] = ctype;
939 out:
940 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
941 return err;
942 }
943 EXPORT_SYMBOL_GPL(nft_register_chain_type);
944
nft_unregister_chain_type(const struct nf_chain_type * ctype)945 void nft_unregister_chain_type(const struct nf_chain_type *ctype)
946 {
947 nfnl_lock(NFNL_SUBSYS_NFTABLES);
948 chain_type[ctype->family][ctype->type] = NULL;
949 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
950 }
951 EXPORT_SYMBOL_GPL(nft_unregister_chain_type);
952
953 /*
954 * Chains
955 */
956
957 static struct nft_chain *
nf_tables_chain_lookup_byhandle(const struct nft_table * table,u64 handle,u8 genmask)958 nf_tables_chain_lookup_byhandle(const struct nft_table *table, u64 handle,
959 u8 genmask)
960 {
961 struct nft_chain *chain;
962
963 list_for_each_entry(chain, &table->chains, list) {
964 if (chain->handle == handle &&
965 nft_active_genmask(chain, genmask))
966 return chain;
967 }
968
969 return ERR_PTR(-ENOENT);
970 }
971
nf_tables_chain_lookup(const struct nft_table * table,const struct nlattr * nla,u8 genmask)972 static struct nft_chain *nf_tables_chain_lookup(const struct nft_table *table,
973 const struct nlattr *nla,
974 u8 genmask)
975 {
976 struct nft_chain *chain;
977
978 if (nla == NULL)
979 return ERR_PTR(-EINVAL);
980
981 list_for_each_entry(chain, &table->chains, list) {
982 if (!nla_strcmp(nla, chain->name) &&
983 nft_active_genmask(chain, genmask))
984 return chain;
985 }
986
987 return ERR_PTR(-ENOENT);
988 }
989
990 static const struct nla_policy nft_chain_policy[NFTA_CHAIN_MAX + 1] = {
991 [NFTA_CHAIN_TABLE] = { .type = NLA_STRING,
992 .len = NFT_TABLE_MAXNAMELEN - 1 },
993 [NFTA_CHAIN_HANDLE] = { .type = NLA_U64 },
994 [NFTA_CHAIN_NAME] = { .type = NLA_STRING,
995 .len = NFT_CHAIN_MAXNAMELEN - 1 },
996 [NFTA_CHAIN_HOOK] = { .type = NLA_NESTED },
997 [NFTA_CHAIN_POLICY] = { .type = NLA_U32 },
998 [NFTA_CHAIN_TYPE] = { .type = NLA_STRING },
999 [NFTA_CHAIN_COUNTERS] = { .type = NLA_NESTED },
1000 };
1001
1002 static const struct nla_policy nft_hook_policy[NFTA_HOOK_MAX + 1] = {
1003 [NFTA_HOOK_HOOKNUM] = { .type = NLA_U32 },
1004 [NFTA_HOOK_PRIORITY] = { .type = NLA_U32 },
1005 [NFTA_HOOK_DEV] = { .type = NLA_STRING,
1006 .len = IFNAMSIZ - 1 },
1007 };
1008
nft_dump_stats(struct sk_buff * skb,struct nft_stats __percpu * stats)1009 static int nft_dump_stats(struct sk_buff *skb, struct nft_stats __percpu *stats)
1010 {
1011 struct nft_stats *cpu_stats, total;
1012 struct nlattr *nest;
1013 unsigned int seq;
1014 u64 pkts, bytes;
1015 int cpu;
1016
1017 memset(&total, 0, sizeof(total));
1018 for_each_possible_cpu(cpu) {
1019 cpu_stats = per_cpu_ptr(stats, cpu);
1020 do {
1021 seq = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
1022 pkts = cpu_stats->pkts;
1023 bytes = cpu_stats->bytes;
1024 } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, seq));
1025 total.pkts += pkts;
1026 total.bytes += bytes;
1027 }
1028 nest = nla_nest_start(skb, NFTA_CHAIN_COUNTERS);
1029 if (nest == NULL)
1030 goto nla_put_failure;
1031
1032 if (nla_put_be64(skb, NFTA_COUNTER_PACKETS, cpu_to_be64(total.pkts),
1033 NFTA_COUNTER_PAD) ||
1034 nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes),
1035 NFTA_COUNTER_PAD))
1036 goto nla_put_failure;
1037
1038 nla_nest_end(skb, nest);
1039 return 0;
1040
1041 nla_put_failure:
1042 return -ENOSPC;
1043 }
1044
nf_tables_fill_chain_info(struct sk_buff * skb,struct net * net,u32 portid,u32 seq,int event,u32 flags,int family,const struct nft_table * table,const struct nft_chain * chain)1045 static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
1046 u32 portid, u32 seq, int event, u32 flags,
1047 int family, const struct nft_table *table,
1048 const struct nft_chain *chain)
1049 {
1050 struct nlmsghdr *nlh;
1051 struct nfgenmsg *nfmsg;
1052
1053 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
1054 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
1055 if (nlh == NULL)
1056 goto nla_put_failure;
1057
1058 nfmsg = nlmsg_data(nlh);
1059 nfmsg->nfgen_family = family;
1060 nfmsg->version = NFNETLINK_V0;
1061 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
1062
1063 if (nla_put_string(skb, NFTA_CHAIN_TABLE, table->name))
1064 goto nla_put_failure;
1065 if (nla_put_be64(skb, NFTA_CHAIN_HANDLE, cpu_to_be64(chain->handle),
1066 NFTA_CHAIN_PAD))
1067 goto nla_put_failure;
1068 if (nla_put_string(skb, NFTA_CHAIN_NAME, chain->name))
1069 goto nla_put_failure;
1070
1071 if (nft_is_base_chain(chain)) {
1072 const struct nft_base_chain *basechain = nft_base_chain(chain);
1073 const struct nf_hook_ops *ops = &basechain->ops[0];
1074 struct nlattr *nest;
1075
1076 nest = nla_nest_start(skb, NFTA_CHAIN_HOOK);
1077 if (nest == NULL)
1078 goto nla_put_failure;
1079 if (nla_put_be32(skb, NFTA_HOOK_HOOKNUM, htonl(ops->hooknum)))
1080 goto nla_put_failure;
1081 if (nla_put_be32(skb, NFTA_HOOK_PRIORITY, htonl(ops->priority)))
1082 goto nla_put_failure;
1083 if (basechain->dev_name[0] &&
1084 nla_put_string(skb, NFTA_HOOK_DEV, basechain->dev_name))
1085 goto nla_put_failure;
1086 nla_nest_end(skb, nest);
1087
1088 if (nla_put_be32(skb, NFTA_CHAIN_POLICY,
1089 htonl(basechain->policy)))
1090 goto nla_put_failure;
1091
1092 if (nla_put_string(skb, NFTA_CHAIN_TYPE, basechain->type->name))
1093 goto nla_put_failure;
1094
1095 if (basechain->stats && nft_dump_stats(skb, basechain->stats))
1096 goto nla_put_failure;
1097 }
1098
1099 if (nla_put_be32(skb, NFTA_CHAIN_USE, htonl(chain->use)))
1100 goto nla_put_failure;
1101
1102 nlmsg_end(skb, nlh);
1103 return 0;
1104
1105 nla_put_failure:
1106 nlmsg_trim(skb, nlh);
1107 return -1;
1108 }
1109
nf_tables_chain_notify(const struct nft_ctx * ctx,int event)1110 static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
1111 {
1112 struct sk_buff *skb;
1113 int err;
1114
1115 if (!ctx->report &&
1116 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
1117 return;
1118
1119 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
1120 if (skb == NULL)
1121 goto err;
1122
1123 err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq,
1124 event, 0, ctx->afi->family, ctx->table,
1125 ctx->chain);
1126 if (err < 0) {
1127 kfree_skb(skb);
1128 goto err;
1129 }
1130
1131 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1132 ctx->report, GFP_KERNEL);
1133 return;
1134 err:
1135 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
1136 }
1137
nf_tables_dump_chains(struct sk_buff * skb,struct netlink_callback * cb)1138 static int nf_tables_dump_chains(struct sk_buff *skb,
1139 struct netlink_callback *cb)
1140 {
1141 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
1142 const struct nft_af_info *afi;
1143 const struct nft_table *table;
1144 const struct nft_chain *chain;
1145 unsigned int idx = 0, s_idx = cb->args[0];
1146 struct net *net = sock_net(skb->sk);
1147 int family = nfmsg->nfgen_family;
1148
1149 rcu_read_lock();
1150 cb->seq = net->nft.base_seq;
1151
1152 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
1153 if (family != NFPROTO_UNSPEC && family != afi->family)
1154 continue;
1155
1156 list_for_each_entry_rcu(table, &afi->tables, list) {
1157 list_for_each_entry_rcu(chain, &table->chains, list) {
1158 if (idx < s_idx)
1159 goto cont;
1160 if (idx > s_idx)
1161 memset(&cb->args[1], 0,
1162 sizeof(cb->args) - sizeof(cb->args[0]));
1163 if (!nft_is_active(net, chain))
1164 continue;
1165 if (nf_tables_fill_chain_info(skb, net,
1166 NETLINK_CB(cb->skb).portid,
1167 cb->nlh->nlmsg_seq,
1168 NFT_MSG_NEWCHAIN,
1169 NLM_F_MULTI,
1170 afi->family, table, chain) < 0)
1171 goto done;
1172
1173 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
1174 cont:
1175 idx++;
1176 }
1177 }
1178 }
1179 done:
1180 rcu_read_unlock();
1181 cb->args[0] = idx;
1182 return skb->len;
1183 }
1184
nf_tables_getchain(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)1185 static int nf_tables_getchain(struct net *net, struct sock *nlsk,
1186 struct sk_buff *skb, const struct nlmsghdr *nlh,
1187 const struct nlattr * const nla[],
1188 struct netlink_ext_ack *extack)
1189 {
1190 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1191 u8 genmask = nft_genmask_cur(net);
1192 const struct nft_af_info *afi;
1193 const struct nft_table *table;
1194 const struct nft_chain *chain;
1195 struct sk_buff *skb2;
1196 int family = nfmsg->nfgen_family;
1197 int err;
1198
1199 if (nlh->nlmsg_flags & NLM_F_DUMP) {
1200 struct netlink_dump_control c = {
1201 .dump = nf_tables_dump_chains,
1202 };
1203 return netlink_dump_start(nlsk, skb, nlh, &c);
1204 }
1205
1206 afi = nf_tables_afinfo_lookup(net, family, false);
1207 if (IS_ERR(afi))
1208 return PTR_ERR(afi);
1209
1210 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
1211 if (IS_ERR(table))
1212 return PTR_ERR(table);
1213
1214 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);
1215 if (IS_ERR(chain))
1216 return PTR_ERR(chain);
1217
1218 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1219 if (!skb2)
1220 return -ENOMEM;
1221
1222 err = nf_tables_fill_chain_info(skb2, net, NETLINK_CB(skb).portid,
1223 nlh->nlmsg_seq, NFT_MSG_NEWCHAIN, 0,
1224 family, table, chain);
1225 if (err < 0)
1226 goto err;
1227
1228 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
1229
1230 err:
1231 kfree_skb(skb2);
1232 return err;
1233 }
1234
1235 static const struct nla_policy nft_counter_policy[NFTA_COUNTER_MAX + 1] = {
1236 [NFTA_COUNTER_PACKETS] = { .type = NLA_U64 },
1237 [NFTA_COUNTER_BYTES] = { .type = NLA_U64 },
1238 };
1239
nft_stats_alloc(const struct nlattr * attr)1240 static struct nft_stats __percpu *nft_stats_alloc(const struct nlattr *attr)
1241 {
1242 struct nlattr *tb[NFTA_COUNTER_MAX+1];
1243 struct nft_stats __percpu *newstats;
1244 struct nft_stats *stats;
1245 int err;
1246
1247 err = nla_parse_nested(tb, NFTA_COUNTER_MAX, attr, nft_counter_policy,
1248 NULL);
1249 if (err < 0)
1250 return ERR_PTR(err);
1251
1252 if (!tb[NFTA_COUNTER_BYTES] || !tb[NFTA_COUNTER_PACKETS])
1253 return ERR_PTR(-EINVAL);
1254
1255 newstats = netdev_alloc_pcpu_stats(struct nft_stats);
1256 if (newstats == NULL)
1257 return ERR_PTR(-ENOMEM);
1258
1259 /* Restore old counters on this cpu, no problem. Per-cpu statistics
1260 * are not exposed to userspace.
1261 */
1262 preempt_disable();
1263 stats = this_cpu_ptr(newstats);
1264 stats->bytes = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_BYTES]));
1265 stats->pkts = be64_to_cpu(nla_get_be64(tb[NFTA_COUNTER_PACKETS]));
1266 preempt_enable();
1267
1268 return newstats;
1269 }
1270
nft_chain_stats_replace(struct nft_base_chain * chain,struct nft_stats __percpu * newstats)1271 static void nft_chain_stats_replace(struct nft_base_chain *chain,
1272 struct nft_stats __percpu *newstats)
1273 {
1274 if (newstats == NULL)
1275 return;
1276
1277 if (chain->stats) {
1278 struct nft_stats __percpu *oldstats =
1279 nft_dereference(chain->stats);
1280
1281 rcu_assign_pointer(chain->stats, newstats);
1282 synchronize_rcu();
1283 free_percpu(oldstats);
1284 } else {
1285 rcu_assign_pointer(chain->stats, newstats);
1286 static_branch_inc(&nft_counters_enabled);
1287 }
1288 }
1289
nf_tables_chain_destroy(struct nft_chain * chain)1290 static void nf_tables_chain_destroy(struct nft_chain *chain)
1291 {
1292 BUG_ON(chain->use > 0);
1293
1294 if (nft_is_base_chain(chain)) {
1295 struct nft_base_chain *basechain = nft_base_chain(chain);
1296
1297 module_put(basechain->type->owner);
1298 free_percpu(basechain->stats);
1299 if (basechain->stats)
1300 static_branch_dec(&nft_counters_enabled);
1301 if (basechain->ops[0].dev != NULL)
1302 dev_put(basechain->ops[0].dev);
1303 kfree(chain->name);
1304 kfree(basechain);
1305 } else {
1306 kfree(chain->name);
1307 kfree(chain);
1308 }
1309 }
1310
1311 struct nft_chain_hook {
1312 u32 num;
1313 u32 priority;
1314 const struct nf_chain_type *type;
1315 struct net_device *dev;
1316 };
1317
nft_chain_parse_hook(struct net * net,const struct nlattr * const nla[],struct nft_af_info * afi,struct nft_chain_hook * hook,bool create)1318 static int nft_chain_parse_hook(struct net *net,
1319 const struct nlattr * const nla[],
1320 struct nft_af_info *afi,
1321 struct nft_chain_hook *hook, bool create)
1322 {
1323 struct nlattr *ha[NFTA_HOOK_MAX + 1];
1324 const struct nf_chain_type *type;
1325 struct net_device *dev;
1326 int err;
1327
1328 err = nla_parse_nested(ha, NFTA_HOOK_MAX, nla[NFTA_CHAIN_HOOK],
1329 nft_hook_policy, NULL);
1330 if (err < 0)
1331 return err;
1332
1333 if (ha[NFTA_HOOK_HOOKNUM] == NULL ||
1334 ha[NFTA_HOOK_PRIORITY] == NULL)
1335 return -EINVAL;
1336
1337 hook->num = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
1338 if (hook->num >= afi->nhooks)
1339 return -EINVAL;
1340
1341 hook->priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
1342
1343 type = chain_type[afi->family][NFT_CHAIN_T_DEFAULT];
1344 if (nla[NFTA_CHAIN_TYPE]) {
1345 type = nf_tables_chain_type_lookup(afi, nla[NFTA_CHAIN_TYPE],
1346 create);
1347 if (IS_ERR(type))
1348 return PTR_ERR(type);
1349 }
1350 if (!(type->hook_mask & (1 << hook->num)))
1351 return -EOPNOTSUPP;
1352 if (!try_module_get(type->owner))
1353 return -ENOENT;
1354
1355 hook->type = type;
1356
1357 hook->dev = NULL;
1358 if (afi->flags & NFT_AF_NEEDS_DEV) {
1359 char ifname[IFNAMSIZ];
1360
1361 if (!ha[NFTA_HOOK_DEV]) {
1362 module_put(type->owner);
1363 return -EOPNOTSUPP;
1364 }
1365
1366 nla_strlcpy(ifname, ha[NFTA_HOOK_DEV], IFNAMSIZ);
1367 dev = dev_get_by_name(net, ifname);
1368 if (!dev) {
1369 module_put(type->owner);
1370 return -ENOENT;
1371 }
1372 hook->dev = dev;
1373 } else if (ha[NFTA_HOOK_DEV]) {
1374 module_put(type->owner);
1375 return -EOPNOTSUPP;
1376 }
1377
1378 return 0;
1379 }
1380
nft_chain_release_hook(struct nft_chain_hook * hook)1381 static void nft_chain_release_hook(struct nft_chain_hook *hook)
1382 {
1383 module_put(hook->type->owner);
1384 if (hook->dev != NULL)
1385 dev_put(hook->dev);
1386 }
1387
nf_tables_addchain(struct nft_ctx * ctx,u8 family,u8 genmask,u8 policy,bool create)1388 static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
1389 u8 policy, bool create)
1390 {
1391 const struct nlattr * const *nla = ctx->nla;
1392 struct nft_table *table = ctx->table;
1393 struct nft_af_info *afi = ctx->afi;
1394 struct nft_base_chain *basechain;
1395 struct nft_stats __percpu *stats;
1396 struct net *net = ctx->net;
1397 struct nft_chain *chain;
1398 unsigned int i;
1399 int err;
1400
1401 if (table->use == UINT_MAX)
1402 return -EOVERFLOW;
1403
1404 if (nla[NFTA_CHAIN_HOOK]) {
1405 struct nft_chain_hook hook;
1406 struct nf_hook_ops *ops;
1407 nf_hookfn *hookfn;
1408
1409 err = nft_chain_parse_hook(net, nla, afi, &hook, create);
1410 if (err < 0)
1411 return err;
1412
1413 basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
1414 if (basechain == NULL) {
1415 nft_chain_release_hook(&hook);
1416 return -ENOMEM;
1417 }
1418
1419 if (hook.dev != NULL)
1420 strncpy(basechain->dev_name, hook.dev->name, IFNAMSIZ);
1421
1422 if (nla[NFTA_CHAIN_COUNTERS]) {
1423 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
1424 if (IS_ERR(stats)) {
1425 nft_chain_release_hook(&hook);
1426 kfree(basechain);
1427 return PTR_ERR(stats);
1428 }
1429 basechain->stats = stats;
1430 static_branch_inc(&nft_counters_enabled);
1431 }
1432
1433 hookfn = hook.type->hooks[hook.num];
1434 basechain->type = hook.type;
1435 chain = &basechain->chain;
1436
1437 for (i = 0; i < afi->nops; i++) {
1438 ops = &basechain->ops[i];
1439 ops->pf = family;
1440 ops->hooknum = hook.num;
1441 ops->priority = hook.priority;
1442 ops->priv = chain;
1443 ops->hook = afi->hooks[ops->hooknum];
1444 ops->dev = hook.dev;
1445 if (hookfn)
1446 ops->hook = hookfn;
1447 if (afi->hook_ops_init)
1448 afi->hook_ops_init(ops, i);
1449 }
1450
1451 chain->flags |= NFT_BASE_CHAIN;
1452 basechain->policy = policy;
1453 } else {
1454 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
1455 if (chain == NULL)
1456 return -ENOMEM;
1457 }
1458 INIT_LIST_HEAD(&chain->rules);
1459 chain->handle = nf_tables_alloc_handle(table);
1460 chain->table = table;
1461 chain->name = nla_strdup(nla[NFTA_CHAIN_NAME], GFP_KERNEL);
1462 if (!chain->name) {
1463 err = -ENOMEM;
1464 goto err1;
1465 }
1466
1467 err = nf_tables_register_hooks(net, table, chain, afi->nops);
1468 if (err < 0)
1469 goto err1;
1470
1471 ctx->chain = chain;
1472 err = nft_trans_chain_add(ctx, NFT_MSG_NEWCHAIN);
1473 if (err < 0)
1474 goto err2;
1475
1476 table->use++;
1477 list_add_tail_rcu(&chain->list, &table->chains);
1478
1479 return 0;
1480 err2:
1481 nf_tables_unregister_hooks(net, table, chain, afi->nops);
1482 err1:
1483 nf_tables_chain_destroy(chain);
1484
1485 return err;
1486 }
1487
nf_tables_updchain(struct nft_ctx * ctx,u8 genmask,u8 policy,bool create)1488 static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
1489 bool create)
1490 {
1491 const struct nlattr * const *nla = ctx->nla;
1492 struct nft_table *table = ctx->table;
1493 struct nft_chain *chain = ctx->chain;
1494 struct nft_af_info *afi = ctx->afi;
1495 struct nft_base_chain *basechain;
1496 struct nft_stats *stats = NULL;
1497 struct nft_chain_hook hook;
1498 struct nf_hook_ops *ops;
1499 struct nft_trans *trans;
1500 int err, i;
1501
1502 if (nla[NFTA_CHAIN_HOOK]) {
1503 if (!nft_is_base_chain(chain))
1504 return -EBUSY;
1505
1506 err = nft_chain_parse_hook(ctx->net, nla, ctx->afi, &hook,
1507 create);
1508 if (err < 0)
1509 return err;
1510
1511 basechain = nft_base_chain(chain);
1512 if (basechain->type != hook.type) {
1513 nft_chain_release_hook(&hook);
1514 return -EBUSY;
1515 }
1516
1517 for (i = 0; i < afi->nops; i++) {
1518 ops = &basechain->ops[i];
1519 if (ops->hooknum != hook.num ||
1520 ops->priority != hook.priority ||
1521 ops->dev != hook.dev) {
1522 nft_chain_release_hook(&hook);
1523 return -EBUSY;
1524 }
1525 }
1526 nft_chain_release_hook(&hook);
1527 }
1528
1529 if (nla[NFTA_CHAIN_HANDLE] &&
1530 nla[NFTA_CHAIN_NAME]) {
1531 struct nft_chain *chain2;
1532
1533 chain2 = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME],
1534 genmask);
1535 if (!IS_ERR(chain2))
1536 return -EEXIST;
1537 }
1538
1539 if (nla[NFTA_CHAIN_COUNTERS]) {
1540 if (!nft_is_base_chain(chain))
1541 return -EOPNOTSUPP;
1542
1543 stats = nft_stats_alloc(nla[NFTA_CHAIN_COUNTERS]);
1544 if (IS_ERR(stats))
1545 return PTR_ERR(stats);
1546 }
1547
1548 err = -ENOMEM;
1549 trans = nft_trans_alloc(ctx, NFT_MSG_NEWCHAIN,
1550 sizeof(struct nft_trans_chain));
1551 if (trans == NULL)
1552 goto err;
1553
1554 nft_trans_chain_stats(trans) = stats;
1555 nft_trans_chain_update(trans) = true;
1556
1557 if (nla[NFTA_CHAIN_POLICY])
1558 nft_trans_chain_policy(trans) = policy;
1559 else
1560 nft_trans_chain_policy(trans) = -1;
1561
1562 if (nla[NFTA_CHAIN_HANDLE] &&
1563 nla[NFTA_CHAIN_NAME]) {
1564 struct nft_trans *tmp;
1565 char *name;
1566
1567 err = -ENOMEM;
1568 name = nla_strdup(nla[NFTA_CHAIN_NAME], GFP_KERNEL);
1569 if (!name)
1570 goto err;
1571
1572 err = -EEXIST;
1573 list_for_each_entry(tmp, &ctx->net->nft.commit_list, list) {
1574 if (tmp->msg_type == NFT_MSG_NEWCHAIN &&
1575 tmp->ctx.table == table &&
1576 nft_trans_chain_update(tmp) &&
1577 nft_trans_chain_name(tmp) &&
1578 strcmp(name, nft_trans_chain_name(tmp)) == 0) {
1579 kfree(name);
1580 goto err;
1581 }
1582 }
1583
1584 nft_trans_chain_name(trans) = name;
1585 }
1586 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
1587
1588 return 0;
1589 err:
1590 free_percpu(stats);
1591 kfree(trans);
1592 return err;
1593 }
1594
nf_tables_newchain(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)1595 static int nf_tables_newchain(struct net *net, struct sock *nlsk,
1596 struct sk_buff *skb, const struct nlmsghdr *nlh,
1597 const struct nlattr * const nla[],
1598 struct netlink_ext_ack *extack)
1599 {
1600 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1601 const struct nlattr * uninitialized_var(name);
1602 u8 genmask = nft_genmask_next(net);
1603 int family = nfmsg->nfgen_family;
1604 struct nft_af_info *afi;
1605 struct nft_table *table;
1606 struct nft_chain *chain;
1607 u8 policy = NF_ACCEPT;
1608 struct nft_ctx ctx;
1609 u64 handle = 0;
1610 bool create;
1611
1612 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
1613
1614 afi = nf_tables_afinfo_lookup(net, family, true);
1615 if (IS_ERR(afi))
1616 return PTR_ERR(afi);
1617
1618 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
1619 if (IS_ERR(table))
1620 return PTR_ERR(table);
1621
1622 chain = NULL;
1623 name = nla[NFTA_CHAIN_NAME];
1624
1625 if (nla[NFTA_CHAIN_HANDLE]) {
1626 handle = be64_to_cpu(nla_get_be64(nla[NFTA_CHAIN_HANDLE]));
1627 chain = nf_tables_chain_lookup_byhandle(table, handle, genmask);
1628 if (IS_ERR(chain))
1629 return PTR_ERR(chain);
1630 } else {
1631 chain = nf_tables_chain_lookup(table, name, genmask);
1632 if (IS_ERR(chain)) {
1633 if (PTR_ERR(chain) != -ENOENT)
1634 return PTR_ERR(chain);
1635 chain = NULL;
1636 }
1637 }
1638
1639 if (nla[NFTA_CHAIN_POLICY]) {
1640 if (chain != NULL &&
1641 !nft_is_base_chain(chain))
1642 return -EOPNOTSUPP;
1643
1644 if (chain == NULL &&
1645 nla[NFTA_CHAIN_HOOK] == NULL)
1646 return -EOPNOTSUPP;
1647
1648 policy = ntohl(nla_get_be32(nla[NFTA_CHAIN_POLICY]));
1649 switch (policy) {
1650 case NF_DROP:
1651 case NF_ACCEPT:
1652 break;
1653 default:
1654 return -EINVAL;
1655 }
1656 }
1657
1658 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
1659
1660 if (chain != NULL) {
1661 if (nlh->nlmsg_flags & NLM_F_EXCL)
1662 return -EEXIST;
1663 if (nlh->nlmsg_flags & NLM_F_REPLACE)
1664 return -EOPNOTSUPP;
1665
1666 return nf_tables_updchain(&ctx, genmask, policy, create);
1667 }
1668
1669 return nf_tables_addchain(&ctx, family, genmask, policy, create);
1670 }
1671
nf_tables_delchain(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)1672 static int nf_tables_delchain(struct net *net, struct sock *nlsk,
1673 struct sk_buff *skb, const struct nlmsghdr *nlh,
1674 const struct nlattr * const nla[],
1675 struct netlink_ext_ack *extack)
1676 {
1677 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1678 u8 genmask = nft_genmask_next(net);
1679 struct nft_af_info *afi;
1680 struct nft_table *table;
1681 struct nft_chain *chain;
1682 struct nft_rule *rule;
1683 int family = nfmsg->nfgen_family;
1684 struct nft_ctx ctx;
1685 u32 use;
1686 int err;
1687
1688 afi = nf_tables_afinfo_lookup(net, family, false);
1689 if (IS_ERR(afi))
1690 return PTR_ERR(afi);
1691
1692 table = nf_tables_table_lookup(afi, nla[NFTA_CHAIN_TABLE], genmask);
1693 if (IS_ERR(table))
1694 return PTR_ERR(table);
1695
1696 chain = nf_tables_chain_lookup(table, nla[NFTA_CHAIN_NAME], genmask);
1697 if (IS_ERR(chain))
1698 return PTR_ERR(chain);
1699
1700 if (nlh->nlmsg_flags & NLM_F_NONREC &&
1701 chain->use > 0)
1702 return -EBUSY;
1703
1704 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
1705
1706 use = chain->use;
1707 list_for_each_entry(rule, &chain->rules, list) {
1708 if (!nft_is_active_next(net, rule))
1709 continue;
1710 use--;
1711
1712 err = nft_delrule(&ctx, rule);
1713 if (err < 0)
1714 return err;
1715 }
1716
1717 /* There are rules and elements that are still holding references to us,
1718 * we cannot do a recursive removal in this case.
1719 */
1720 if (use > 0)
1721 return -EBUSY;
1722
1723 return nft_delchain(&ctx);
1724 }
1725
1726 /*
1727 * Expressions
1728 */
1729
1730 /**
1731 * nft_register_expr - register nf_tables expr type
1732 * @ops: expr type
1733 *
1734 * Registers the expr type for use with nf_tables. Returns zero on
1735 * success or a negative errno code otherwise.
1736 */
nft_register_expr(struct nft_expr_type * type)1737 int nft_register_expr(struct nft_expr_type *type)
1738 {
1739 if (!nft_expr_check_ops(type->ops))
1740 return -EINVAL;
1741
1742 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1743 if (type->family == NFPROTO_UNSPEC)
1744 list_add_tail_rcu(&type->list, &nf_tables_expressions);
1745 else
1746 list_add_rcu(&type->list, &nf_tables_expressions);
1747 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1748 return 0;
1749 }
1750 EXPORT_SYMBOL_GPL(nft_register_expr);
1751
1752 /**
1753 * nft_unregister_expr - unregister nf_tables expr type
1754 * @ops: expr type
1755 *
1756 * Unregisters the expr typefor use with nf_tables.
1757 */
nft_unregister_expr(struct nft_expr_type * type)1758 void nft_unregister_expr(struct nft_expr_type *type)
1759 {
1760 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1761 list_del_rcu(&type->list);
1762 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1763 }
1764 EXPORT_SYMBOL_GPL(nft_unregister_expr);
1765
__nft_expr_type_get(u8 family,struct nlattr * nla)1766 static const struct nft_expr_type *__nft_expr_type_get(u8 family,
1767 struct nlattr *nla)
1768 {
1769 const struct nft_expr_type *type;
1770
1771 list_for_each_entry(type, &nf_tables_expressions, list) {
1772 if (!nla_strcmp(nla, type->name) &&
1773 (!type->family || type->family == family))
1774 return type;
1775 }
1776 return NULL;
1777 }
1778
nft_expr_type_get(u8 family,struct nlattr * nla)1779 static const struct nft_expr_type *nft_expr_type_get(u8 family,
1780 struct nlattr *nla)
1781 {
1782 const struct nft_expr_type *type;
1783
1784 if (nla == NULL)
1785 return ERR_PTR(-EINVAL);
1786
1787 type = __nft_expr_type_get(family, nla);
1788 if (type != NULL && try_module_get(type->owner))
1789 return type;
1790
1791 #ifdef CONFIG_MODULES
1792 if (type == NULL) {
1793 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1794 request_module("nft-expr-%u-%.*s", family,
1795 nla_len(nla), (char *)nla_data(nla));
1796 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1797 if (__nft_expr_type_get(family, nla))
1798 return ERR_PTR(-EAGAIN);
1799
1800 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
1801 request_module("nft-expr-%.*s",
1802 nla_len(nla), (char *)nla_data(nla));
1803 nfnl_lock(NFNL_SUBSYS_NFTABLES);
1804 if (__nft_expr_type_get(family, nla))
1805 return ERR_PTR(-EAGAIN);
1806 }
1807 #endif
1808 return ERR_PTR(-ENOENT);
1809 }
1810
1811 static const struct nla_policy nft_expr_policy[NFTA_EXPR_MAX + 1] = {
1812 [NFTA_EXPR_NAME] = { .type = NLA_STRING },
1813 [NFTA_EXPR_DATA] = { .type = NLA_NESTED },
1814 };
1815
nf_tables_fill_expr_info(struct sk_buff * skb,const struct nft_expr * expr)1816 static int nf_tables_fill_expr_info(struct sk_buff *skb,
1817 const struct nft_expr *expr)
1818 {
1819 if (nla_put_string(skb, NFTA_EXPR_NAME, expr->ops->type->name))
1820 goto nla_put_failure;
1821
1822 if (expr->ops->dump) {
1823 struct nlattr *data = nla_nest_start(skb, NFTA_EXPR_DATA);
1824 if (data == NULL)
1825 goto nla_put_failure;
1826 if (expr->ops->dump(skb, expr) < 0)
1827 goto nla_put_failure;
1828 nla_nest_end(skb, data);
1829 }
1830
1831 return skb->len;
1832
1833 nla_put_failure:
1834 return -1;
1835 };
1836
nft_expr_dump(struct sk_buff * skb,unsigned int attr,const struct nft_expr * expr)1837 int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
1838 const struct nft_expr *expr)
1839 {
1840 struct nlattr *nest;
1841
1842 nest = nla_nest_start(skb, attr);
1843 if (!nest)
1844 goto nla_put_failure;
1845 if (nf_tables_fill_expr_info(skb, expr) < 0)
1846 goto nla_put_failure;
1847 nla_nest_end(skb, nest);
1848 return 0;
1849
1850 nla_put_failure:
1851 return -1;
1852 }
1853
1854 struct nft_expr_info {
1855 const struct nft_expr_ops *ops;
1856 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
1857 };
1858
nf_tables_expr_parse(const struct nft_ctx * ctx,const struct nlattr * nla,struct nft_expr_info * info)1859 static int nf_tables_expr_parse(const struct nft_ctx *ctx,
1860 const struct nlattr *nla,
1861 struct nft_expr_info *info)
1862 {
1863 const struct nft_expr_type *type;
1864 const struct nft_expr_ops *ops;
1865 struct nlattr *tb[NFTA_EXPR_MAX + 1];
1866 int err;
1867
1868 err = nla_parse_nested(tb, NFTA_EXPR_MAX, nla, nft_expr_policy, NULL);
1869 if (err < 0)
1870 return err;
1871
1872 type = nft_expr_type_get(ctx->afi->family, tb[NFTA_EXPR_NAME]);
1873 if (IS_ERR(type))
1874 return PTR_ERR(type);
1875
1876 if (tb[NFTA_EXPR_DATA]) {
1877 err = nla_parse_nested(info->tb, type->maxattr,
1878 tb[NFTA_EXPR_DATA], type->policy, NULL);
1879 if (err < 0)
1880 goto err1;
1881 } else
1882 memset(info->tb, 0, sizeof(info->tb[0]) * (type->maxattr + 1));
1883
1884 if (type->select_ops != NULL) {
1885 ops = type->select_ops(ctx,
1886 (const struct nlattr * const *)info->tb);
1887 if (IS_ERR(ops)) {
1888 err = PTR_ERR(ops);
1889 goto err1;
1890 }
1891 if (!nft_expr_check_ops(ops)) {
1892 err = -EINVAL;
1893 goto err1;
1894 }
1895 } else
1896 ops = type->ops;
1897
1898 info->ops = ops;
1899 return 0;
1900
1901 err1:
1902 module_put(type->owner);
1903 return err;
1904 }
1905
nf_tables_newexpr(const struct nft_ctx * ctx,const struct nft_expr_info * info,struct nft_expr * expr)1906 static int nf_tables_newexpr(const struct nft_ctx *ctx,
1907 const struct nft_expr_info *info,
1908 struct nft_expr *expr)
1909 {
1910 const struct nft_expr_ops *ops = info->ops;
1911 int err;
1912
1913 expr->ops = ops;
1914 if (ops->init) {
1915 err = ops->init(ctx, expr, (const struct nlattr **)info->tb);
1916 if (err < 0)
1917 goto err1;
1918 }
1919
1920 if (ops->validate) {
1921 const struct nft_data *data = NULL;
1922
1923 err = ops->validate(ctx, expr, &data);
1924 if (err < 0)
1925 goto err2;
1926 }
1927
1928 return 0;
1929
1930 err2:
1931 if (ops->destroy)
1932 ops->destroy(ctx, expr);
1933 err1:
1934 expr->ops = NULL;
1935 return err;
1936 }
1937
nf_tables_expr_destroy(const struct nft_ctx * ctx,struct nft_expr * expr)1938 static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
1939 struct nft_expr *expr)
1940 {
1941 if (expr->ops->destroy)
1942 expr->ops->destroy(ctx, expr);
1943 module_put(expr->ops->type->owner);
1944 }
1945
nft_expr_init(const struct nft_ctx * ctx,const struct nlattr * nla)1946 struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
1947 const struct nlattr *nla)
1948 {
1949 struct nft_expr_info info;
1950 struct nft_expr *expr;
1951 int err;
1952
1953 err = nf_tables_expr_parse(ctx, nla, &info);
1954 if (err < 0)
1955 goto err1;
1956
1957 err = -ENOMEM;
1958 expr = kzalloc(info.ops->size, GFP_KERNEL);
1959 if (expr == NULL)
1960 goto err2;
1961
1962 err = nf_tables_newexpr(ctx, &info, expr);
1963 if (err < 0)
1964 goto err3;
1965
1966 return expr;
1967 err3:
1968 kfree(expr);
1969 err2:
1970 module_put(info.ops->type->owner);
1971 err1:
1972 return ERR_PTR(err);
1973 }
1974
nft_expr_destroy(const struct nft_ctx * ctx,struct nft_expr * expr)1975 void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr)
1976 {
1977 nf_tables_expr_destroy(ctx, expr);
1978 kfree(expr);
1979 }
1980
1981 /*
1982 * Rules
1983 */
1984
__nf_tables_rule_lookup(const struct nft_chain * chain,u64 handle)1985 static struct nft_rule *__nf_tables_rule_lookup(const struct nft_chain *chain,
1986 u64 handle)
1987 {
1988 struct nft_rule *rule;
1989
1990 // FIXME: this sucks
1991 list_for_each_entry(rule, &chain->rules, list) {
1992 if (handle == rule->handle)
1993 return rule;
1994 }
1995
1996 return ERR_PTR(-ENOENT);
1997 }
1998
nf_tables_rule_lookup(const struct nft_chain * chain,const struct nlattr * nla)1999 static struct nft_rule *nf_tables_rule_lookup(const struct nft_chain *chain,
2000 const struct nlattr *nla)
2001 {
2002 if (nla == NULL)
2003 return ERR_PTR(-EINVAL);
2004
2005 return __nf_tables_rule_lookup(chain, be64_to_cpu(nla_get_be64(nla)));
2006 }
2007
2008 static const struct nla_policy nft_rule_policy[NFTA_RULE_MAX + 1] = {
2009 [NFTA_RULE_TABLE] = { .type = NLA_STRING,
2010 .len = NFT_TABLE_MAXNAMELEN - 1 },
2011 [NFTA_RULE_CHAIN] = { .type = NLA_STRING,
2012 .len = NFT_CHAIN_MAXNAMELEN - 1 },
2013 [NFTA_RULE_HANDLE] = { .type = NLA_U64 },
2014 [NFTA_RULE_EXPRESSIONS] = { .type = NLA_NESTED },
2015 [NFTA_RULE_COMPAT] = { .type = NLA_NESTED },
2016 [NFTA_RULE_POSITION] = { .type = NLA_U64 },
2017 [NFTA_RULE_USERDATA] = { .type = NLA_BINARY,
2018 .len = NFT_USERDATA_MAXLEN },
2019 [NFTA_RULE_ID] = { .type = NLA_U32 },
2020 };
2021
nf_tables_fill_rule_info(struct sk_buff * skb,struct net * net,u32 portid,u32 seq,int event,u32 flags,int family,const struct nft_table * table,const struct nft_chain * chain,const struct nft_rule * rule)2022 static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
2023 u32 portid, u32 seq, int event,
2024 u32 flags, int family,
2025 const struct nft_table *table,
2026 const struct nft_chain *chain,
2027 const struct nft_rule *rule)
2028 {
2029 struct nlmsghdr *nlh;
2030 struct nfgenmsg *nfmsg;
2031 const struct nft_expr *expr, *next;
2032 struct nlattr *list;
2033 const struct nft_rule *prule;
2034 u16 type = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
2035
2036 nlh = nlmsg_put(skb, portid, seq, type, sizeof(struct nfgenmsg), flags);
2037 if (nlh == NULL)
2038 goto nla_put_failure;
2039
2040 nfmsg = nlmsg_data(nlh);
2041 nfmsg->nfgen_family = family;
2042 nfmsg->version = NFNETLINK_V0;
2043 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
2044
2045 if (nla_put_string(skb, NFTA_RULE_TABLE, table->name))
2046 goto nla_put_failure;
2047 if (nla_put_string(skb, NFTA_RULE_CHAIN, chain->name))
2048 goto nla_put_failure;
2049 if (nla_put_be64(skb, NFTA_RULE_HANDLE, cpu_to_be64(rule->handle),
2050 NFTA_RULE_PAD))
2051 goto nla_put_failure;
2052
2053 if ((event != NFT_MSG_DELRULE) && (rule->list.prev != &chain->rules)) {
2054 prule = list_prev_entry(rule, list);
2055 if (nla_put_be64(skb, NFTA_RULE_POSITION,
2056 cpu_to_be64(prule->handle),
2057 NFTA_RULE_PAD))
2058 goto nla_put_failure;
2059 }
2060
2061 list = nla_nest_start(skb, NFTA_RULE_EXPRESSIONS);
2062 if (list == NULL)
2063 goto nla_put_failure;
2064 nft_rule_for_each_expr(expr, next, rule) {
2065 if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
2066 goto nla_put_failure;
2067 }
2068 nla_nest_end(skb, list);
2069
2070 if (rule->udata) {
2071 struct nft_userdata *udata = nft_userdata(rule);
2072 if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1,
2073 udata->data) < 0)
2074 goto nla_put_failure;
2075 }
2076
2077 nlmsg_end(skb, nlh);
2078 return 0;
2079
2080 nla_put_failure:
2081 nlmsg_trim(skb, nlh);
2082 return -1;
2083 }
2084
nf_tables_rule_notify(const struct nft_ctx * ctx,const struct nft_rule * rule,int event)2085 static void nf_tables_rule_notify(const struct nft_ctx *ctx,
2086 const struct nft_rule *rule, int event)
2087 {
2088 struct sk_buff *skb;
2089 int err;
2090
2091 if (!ctx->report &&
2092 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
2093 return;
2094
2095 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
2096 if (skb == NULL)
2097 goto err;
2098
2099 err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq,
2100 event, 0, ctx->afi->family, ctx->table,
2101 ctx->chain, rule);
2102 if (err < 0) {
2103 kfree_skb(skb);
2104 goto err;
2105 }
2106
2107 nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
2108 ctx->report, GFP_KERNEL);
2109 return;
2110 err:
2111 nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
2112 }
2113
2114 struct nft_rule_dump_ctx {
2115 char *table;
2116 char *chain;
2117 };
2118
nf_tables_dump_rules(struct sk_buff * skb,struct netlink_callback * cb)2119 static int nf_tables_dump_rules(struct sk_buff *skb,
2120 struct netlink_callback *cb)
2121 {
2122 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
2123 const struct nft_rule_dump_ctx *ctx = cb->data;
2124 const struct nft_af_info *afi;
2125 const struct nft_table *table;
2126 const struct nft_chain *chain;
2127 const struct nft_rule *rule;
2128 unsigned int idx = 0, s_idx = cb->args[0];
2129 struct net *net = sock_net(skb->sk);
2130 int family = nfmsg->nfgen_family;
2131
2132 rcu_read_lock();
2133 cb->seq = net->nft.base_seq;
2134
2135 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
2136 if (family != NFPROTO_UNSPEC && family != afi->family)
2137 continue;
2138
2139 list_for_each_entry_rcu(table, &afi->tables, list) {
2140 if (ctx && ctx->table &&
2141 strcmp(ctx->table, table->name) != 0)
2142 continue;
2143
2144 list_for_each_entry_rcu(chain, &table->chains, list) {
2145 if (ctx && ctx->chain &&
2146 strcmp(ctx->chain, chain->name) != 0)
2147 continue;
2148
2149 list_for_each_entry_rcu(rule, &chain->rules, list) {
2150 if (!nft_is_active(net, rule))
2151 goto cont;
2152 if (idx < s_idx)
2153 goto cont;
2154 if (idx > s_idx)
2155 memset(&cb->args[1], 0,
2156 sizeof(cb->args) - sizeof(cb->args[0]));
2157 if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid,
2158 cb->nlh->nlmsg_seq,
2159 NFT_MSG_NEWRULE,
2160 NLM_F_MULTI | NLM_F_APPEND,
2161 afi->family, table, chain, rule) < 0)
2162 goto done;
2163
2164 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
2165 cont:
2166 idx++;
2167 }
2168 }
2169 }
2170 }
2171 done:
2172 rcu_read_unlock();
2173
2174 cb->args[0] = idx;
2175 return skb->len;
2176 }
2177
nf_tables_dump_rules_done(struct netlink_callback * cb)2178 static int nf_tables_dump_rules_done(struct netlink_callback *cb)
2179 {
2180 struct nft_rule_dump_ctx *ctx = cb->data;
2181
2182 if (ctx) {
2183 kfree(ctx->table);
2184 kfree(ctx->chain);
2185 kfree(ctx);
2186 }
2187 return 0;
2188 }
2189
nf_tables_getrule(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)2190 static int nf_tables_getrule(struct net *net, struct sock *nlsk,
2191 struct sk_buff *skb, const struct nlmsghdr *nlh,
2192 const struct nlattr * const nla[],
2193 struct netlink_ext_ack *extack)
2194 {
2195 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2196 u8 genmask = nft_genmask_cur(net);
2197 const struct nft_af_info *afi;
2198 const struct nft_table *table;
2199 const struct nft_chain *chain;
2200 const struct nft_rule *rule;
2201 struct sk_buff *skb2;
2202 int family = nfmsg->nfgen_family;
2203 int err;
2204
2205 if (nlh->nlmsg_flags & NLM_F_DUMP) {
2206 struct netlink_dump_control c = {
2207 .dump = nf_tables_dump_rules,
2208 .done = nf_tables_dump_rules_done,
2209 };
2210
2211 if (nla[NFTA_RULE_TABLE] || nla[NFTA_RULE_CHAIN]) {
2212 struct nft_rule_dump_ctx *ctx;
2213
2214 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2215 if (!ctx)
2216 return -ENOMEM;
2217
2218 if (nla[NFTA_RULE_TABLE]) {
2219 ctx->table = nla_strdup(nla[NFTA_RULE_TABLE],
2220 GFP_KERNEL);
2221 if (!ctx->table) {
2222 kfree(ctx);
2223 return -ENOMEM;
2224 }
2225 }
2226 if (nla[NFTA_RULE_CHAIN]) {
2227 ctx->chain = nla_strdup(nla[NFTA_RULE_CHAIN],
2228 GFP_KERNEL);
2229 if (!ctx->chain) {
2230 kfree(ctx->table);
2231 kfree(ctx);
2232 return -ENOMEM;
2233 }
2234 }
2235 c.data = ctx;
2236 }
2237
2238 return netlink_dump_start(nlsk, skb, nlh, &c);
2239 }
2240
2241 afi = nf_tables_afinfo_lookup(net, family, false);
2242 if (IS_ERR(afi))
2243 return PTR_ERR(afi);
2244
2245 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
2246 if (IS_ERR(table))
2247 return PTR_ERR(table);
2248
2249 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN], genmask);
2250 if (IS_ERR(chain))
2251 return PTR_ERR(chain);
2252
2253 rule = nf_tables_rule_lookup(chain, nla[NFTA_RULE_HANDLE]);
2254 if (IS_ERR(rule))
2255 return PTR_ERR(rule);
2256
2257 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
2258 if (!skb2)
2259 return -ENOMEM;
2260
2261 err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid,
2262 nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0,
2263 family, table, chain, rule);
2264 if (err < 0)
2265 goto err;
2266
2267 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
2268
2269 err:
2270 kfree_skb(skb2);
2271 return err;
2272 }
2273
nf_tables_rule_destroy(const struct nft_ctx * ctx,struct nft_rule * rule)2274 static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
2275 struct nft_rule *rule)
2276 {
2277 struct nft_expr *expr, *next;
2278
2279 /*
2280 * Careful: some expressions might not be initialized in case this
2281 * is called on error from nf_tables_newrule().
2282 */
2283 expr = nft_expr_first(rule);
2284 while (expr != nft_expr_last(rule) && expr->ops) {
2285 next = nft_expr_next(expr);
2286 nf_tables_expr_destroy(ctx, expr);
2287 expr = next;
2288 }
2289 kfree(rule);
2290 }
2291
nf_tables_rule_release(const struct nft_ctx * ctx,struct nft_rule * rule)2292 static void nf_tables_rule_release(const struct nft_ctx *ctx,
2293 struct nft_rule *rule)
2294 {
2295 nft_rule_expr_deactivate(ctx, rule);
2296 nf_tables_rule_destroy(ctx, rule);
2297 }
2298
2299 #define NFT_RULE_MAXEXPRS 128
2300
2301 static struct nft_expr_info *info;
2302
nf_tables_newrule(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)2303 static int nf_tables_newrule(struct net *net, struct sock *nlsk,
2304 struct sk_buff *skb, const struct nlmsghdr *nlh,
2305 const struct nlattr * const nla[],
2306 struct netlink_ext_ack *extack)
2307 {
2308 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2309 u8 genmask = nft_genmask_next(net);
2310 struct nft_af_info *afi;
2311 struct nft_table *table;
2312 struct nft_chain *chain;
2313 struct nft_rule *rule, *old_rule = NULL;
2314 struct nft_userdata *udata;
2315 struct nft_trans *trans = NULL;
2316 struct nft_expr *expr;
2317 struct nft_ctx ctx;
2318 struct nlattr *tmp;
2319 unsigned int size, i, n, ulen = 0, usize = 0;
2320 int err, rem;
2321 bool create;
2322 u64 handle, pos_handle;
2323
2324 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
2325
2326 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
2327 if (IS_ERR(afi))
2328 return PTR_ERR(afi);
2329
2330 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
2331 if (IS_ERR(table))
2332 return PTR_ERR(table);
2333
2334 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN], genmask);
2335 if (IS_ERR(chain))
2336 return PTR_ERR(chain);
2337
2338 if (nla[NFTA_RULE_HANDLE]) {
2339 handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_HANDLE]));
2340 rule = __nf_tables_rule_lookup(chain, handle);
2341 if (IS_ERR(rule))
2342 return PTR_ERR(rule);
2343
2344 if (nlh->nlmsg_flags & NLM_F_EXCL)
2345 return -EEXIST;
2346 if (nlh->nlmsg_flags & NLM_F_REPLACE)
2347 old_rule = rule;
2348 else
2349 return -EOPNOTSUPP;
2350 } else {
2351 if (!create || nlh->nlmsg_flags & NLM_F_REPLACE)
2352 return -EINVAL;
2353 handle = nf_tables_alloc_handle(table);
2354
2355 if (chain->use == UINT_MAX)
2356 return -EOVERFLOW;
2357 }
2358
2359 if (nla[NFTA_RULE_POSITION]) {
2360 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
2361 return -EOPNOTSUPP;
2362
2363 pos_handle = be64_to_cpu(nla_get_be64(nla[NFTA_RULE_POSITION]));
2364 old_rule = __nf_tables_rule_lookup(chain, pos_handle);
2365 if (IS_ERR(old_rule))
2366 return PTR_ERR(old_rule);
2367 }
2368
2369 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
2370
2371 n = 0;
2372 size = 0;
2373 if (nla[NFTA_RULE_EXPRESSIONS]) {
2374 nla_for_each_nested(tmp, nla[NFTA_RULE_EXPRESSIONS], rem) {
2375 err = -EINVAL;
2376 if (nla_type(tmp) != NFTA_LIST_ELEM)
2377 goto err1;
2378 if (n == NFT_RULE_MAXEXPRS)
2379 goto err1;
2380 err = nf_tables_expr_parse(&ctx, tmp, &info[n]);
2381 if (err < 0)
2382 goto err1;
2383 size += info[n].ops->size;
2384 n++;
2385 }
2386 }
2387 /* Check for overflow of dlen field */
2388 err = -EFBIG;
2389 if (size >= 1 << 12)
2390 goto err1;
2391
2392 if (nla[NFTA_RULE_USERDATA]) {
2393 ulen = nla_len(nla[NFTA_RULE_USERDATA]);
2394 if (ulen > 0)
2395 usize = sizeof(struct nft_userdata) + ulen;
2396 }
2397
2398 err = -ENOMEM;
2399 rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL);
2400 if (rule == NULL)
2401 goto err1;
2402
2403 nft_activate_next(net, rule);
2404
2405 rule->handle = handle;
2406 rule->dlen = size;
2407 rule->udata = ulen ? 1 : 0;
2408
2409 if (ulen) {
2410 udata = nft_userdata(rule);
2411 udata->len = ulen - 1;
2412 nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen);
2413 }
2414
2415 expr = nft_expr_first(rule);
2416 for (i = 0; i < n; i++) {
2417 err = nf_tables_newexpr(&ctx, &info[i], expr);
2418 if (err < 0)
2419 goto err2;
2420 info[i].ops = NULL;
2421 expr = nft_expr_next(expr);
2422 }
2423
2424 if (nlh->nlmsg_flags & NLM_F_REPLACE) {
2425 trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule);
2426 if (trans == NULL) {
2427 err = -ENOMEM;
2428 goto err2;
2429 }
2430 err = nft_delrule(&ctx, old_rule);
2431 if (err < 0) {
2432 nft_trans_destroy(trans);
2433 goto err2;
2434 }
2435
2436 list_add_tail_rcu(&rule->list, &old_rule->list);
2437 } else {
2438 if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
2439 err = -ENOMEM;
2440 goto err2;
2441 }
2442
2443 if (nlh->nlmsg_flags & NLM_F_APPEND) {
2444 if (old_rule)
2445 list_add_rcu(&rule->list, &old_rule->list);
2446 else
2447 list_add_tail_rcu(&rule->list, &chain->rules);
2448 } else {
2449 if (old_rule)
2450 list_add_tail_rcu(&rule->list, &old_rule->list);
2451 else
2452 list_add_rcu(&rule->list, &chain->rules);
2453 }
2454 }
2455 chain->use++;
2456 return 0;
2457
2458 err2:
2459 nf_tables_rule_release(&ctx, rule);
2460 err1:
2461 for (i = 0; i < n; i++) {
2462 if (info[i].ops != NULL)
2463 module_put(info[i].ops->type->owner);
2464 }
2465 return err;
2466 }
2467
nft_rule_lookup_byid(const struct net * net,const struct nlattr * nla)2468 static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
2469 const struct nlattr *nla)
2470 {
2471 u32 id = ntohl(nla_get_be32(nla));
2472 struct nft_trans *trans;
2473
2474 list_for_each_entry(trans, &net->nft.commit_list, list) {
2475 struct nft_rule *rule = nft_trans_rule(trans);
2476
2477 if (trans->msg_type == NFT_MSG_NEWRULE &&
2478 id == nft_trans_rule_id(trans))
2479 return rule;
2480 }
2481 return ERR_PTR(-ENOENT);
2482 }
2483
nf_tables_delrule(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)2484 static int nf_tables_delrule(struct net *net, struct sock *nlsk,
2485 struct sk_buff *skb, const struct nlmsghdr *nlh,
2486 const struct nlattr * const nla[],
2487 struct netlink_ext_ack *extack)
2488 {
2489 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2490 u8 genmask = nft_genmask_next(net);
2491 struct nft_af_info *afi;
2492 struct nft_table *table;
2493 struct nft_chain *chain = NULL;
2494 struct nft_rule *rule;
2495 int family = nfmsg->nfgen_family, err = 0;
2496 struct nft_ctx ctx;
2497
2498 afi = nf_tables_afinfo_lookup(net, family, false);
2499 if (IS_ERR(afi))
2500 return PTR_ERR(afi);
2501
2502 table = nf_tables_table_lookup(afi, nla[NFTA_RULE_TABLE], genmask);
2503 if (IS_ERR(table))
2504 return PTR_ERR(table);
2505
2506 if (nla[NFTA_RULE_CHAIN]) {
2507 chain = nf_tables_chain_lookup(table, nla[NFTA_RULE_CHAIN],
2508 genmask);
2509 if (IS_ERR(chain))
2510 return PTR_ERR(chain);
2511 }
2512
2513 nft_ctx_init(&ctx, net, skb, nlh, afi, table, chain, nla);
2514
2515 if (chain) {
2516 if (nla[NFTA_RULE_HANDLE]) {
2517 rule = nf_tables_rule_lookup(chain,
2518 nla[NFTA_RULE_HANDLE]);
2519 if (IS_ERR(rule))
2520 return PTR_ERR(rule);
2521
2522 err = nft_delrule(&ctx, rule);
2523 } else if (nla[NFTA_RULE_ID]) {
2524 rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]);
2525 if (IS_ERR(rule))
2526 return PTR_ERR(rule);
2527
2528 err = nft_delrule(&ctx, rule);
2529 } else {
2530 err = nft_delrule_by_chain(&ctx);
2531 }
2532 } else {
2533 list_for_each_entry(chain, &table->chains, list) {
2534 if (!nft_is_active_next(net, chain))
2535 continue;
2536
2537 ctx.chain = chain;
2538 err = nft_delrule_by_chain(&ctx);
2539 if (err < 0)
2540 break;
2541 }
2542 }
2543
2544 return err;
2545 }
2546
2547 /*
2548 * Sets
2549 */
2550
2551 static LIST_HEAD(nf_tables_set_types);
2552
nft_register_set(struct nft_set_type * type)2553 int nft_register_set(struct nft_set_type *type)
2554 {
2555 nfnl_lock(NFNL_SUBSYS_NFTABLES);
2556 list_add_tail_rcu(&type->list, &nf_tables_set_types);
2557 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2558 return 0;
2559 }
2560 EXPORT_SYMBOL_GPL(nft_register_set);
2561
nft_unregister_set(struct nft_set_type * type)2562 void nft_unregister_set(struct nft_set_type *type)
2563 {
2564 nfnl_lock(NFNL_SUBSYS_NFTABLES);
2565 list_del_rcu(&type->list);
2566 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2567 }
2568 EXPORT_SYMBOL_GPL(nft_unregister_set);
2569
2570 #define NFT_SET_FEATURES (NFT_SET_INTERVAL | NFT_SET_MAP | \
2571 NFT_SET_TIMEOUT | NFT_SET_OBJECT)
2572
nft_set_ops_candidate(const struct nft_set_ops * ops,u32 flags)2573 static bool nft_set_ops_candidate(const struct nft_set_ops *ops, u32 flags)
2574 {
2575 return (flags & ops->features) == (flags & NFT_SET_FEATURES);
2576 }
2577
2578 /*
2579 * Select a set implementation based on the data characteristics and the
2580 * given policy. The total memory use might not be known if no size is
2581 * given, in that case the amount of memory per element is used.
2582 */
2583 static const struct nft_set_ops *
nft_select_set_ops(const struct nft_ctx * ctx,const struct nlattr * const nla[],const struct nft_set_desc * desc,enum nft_set_policies policy)2584 nft_select_set_ops(const struct nft_ctx *ctx,
2585 const struct nlattr * const nla[],
2586 const struct nft_set_desc *desc,
2587 enum nft_set_policies policy)
2588 {
2589 const struct nft_set_ops *ops, *bops;
2590 struct nft_set_estimate est, best;
2591 const struct nft_set_type *type;
2592 u32 flags = 0;
2593
2594 #ifdef CONFIG_MODULES
2595 if (list_empty(&nf_tables_set_types)) {
2596 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
2597 request_module("nft-set");
2598 nfnl_lock(NFNL_SUBSYS_NFTABLES);
2599 if (!list_empty(&nf_tables_set_types))
2600 return ERR_PTR(-EAGAIN);
2601 }
2602 #endif
2603 if (nla[NFTA_SET_FLAGS] != NULL)
2604 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
2605
2606 bops = NULL;
2607 best.size = ~0;
2608 best.lookup = ~0;
2609 best.space = ~0;
2610
2611 list_for_each_entry(type, &nf_tables_set_types, list) {
2612 if (!type->select_ops)
2613 ops = type->ops;
2614 else
2615 ops = type->select_ops(ctx, desc, flags);
2616 if (!ops)
2617 continue;
2618
2619 if (!nft_set_ops_candidate(ops, flags))
2620 continue;
2621 if (!ops->estimate(desc, flags, &est))
2622 continue;
2623
2624 switch (policy) {
2625 case NFT_SET_POL_PERFORMANCE:
2626 if (est.lookup < best.lookup)
2627 break;
2628 if (est.lookup == best.lookup) {
2629 if (!desc->size) {
2630 if (est.space < best.space)
2631 break;
2632 } else if (est.size < best.size) {
2633 break;
2634 }
2635 }
2636 continue;
2637 case NFT_SET_POL_MEMORY:
2638 if (!desc->size) {
2639 if (est.space < best.space)
2640 break;
2641 if (est.space == best.space &&
2642 est.lookup < best.lookup)
2643 break;
2644 } else if (est.size < best.size) {
2645 break;
2646 }
2647 continue;
2648 default:
2649 break;
2650 }
2651
2652 if (!try_module_get(type->owner))
2653 continue;
2654 if (bops != NULL)
2655 module_put(bops->type->owner);
2656
2657 bops = ops;
2658 best = est;
2659 }
2660
2661 if (bops != NULL)
2662 return bops;
2663
2664 return ERR_PTR(-EOPNOTSUPP);
2665 }
2666
2667 static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
2668 [NFTA_SET_TABLE] = { .type = NLA_STRING,
2669 .len = NFT_TABLE_MAXNAMELEN - 1 },
2670 [NFTA_SET_NAME] = { .type = NLA_STRING,
2671 .len = NFT_SET_MAXNAMELEN - 1 },
2672 [NFTA_SET_FLAGS] = { .type = NLA_U32 },
2673 [NFTA_SET_KEY_TYPE] = { .type = NLA_U32 },
2674 [NFTA_SET_KEY_LEN] = { .type = NLA_U32 },
2675 [NFTA_SET_DATA_TYPE] = { .type = NLA_U32 },
2676 [NFTA_SET_DATA_LEN] = { .type = NLA_U32 },
2677 [NFTA_SET_POLICY] = { .type = NLA_U32 },
2678 [NFTA_SET_DESC] = { .type = NLA_NESTED },
2679 [NFTA_SET_ID] = { .type = NLA_U32 },
2680 [NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
2681 [NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
2682 [NFTA_SET_USERDATA] = { .type = NLA_BINARY,
2683 .len = NFT_USERDATA_MAXLEN },
2684 [NFTA_SET_OBJ_TYPE] = { .type = NLA_U32 },
2685 };
2686
2687 static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
2688 [NFTA_SET_DESC_SIZE] = { .type = NLA_U32 },
2689 };
2690
nft_ctx_init_from_setattr(struct nft_ctx * ctx,struct net * net,const struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],u8 genmask)2691 static int nft_ctx_init_from_setattr(struct nft_ctx *ctx, struct net *net,
2692 const struct sk_buff *skb,
2693 const struct nlmsghdr *nlh,
2694 const struct nlattr * const nla[],
2695 u8 genmask)
2696 {
2697 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2698 struct nft_af_info *afi = NULL;
2699 struct nft_table *table = NULL;
2700
2701 if (nfmsg->nfgen_family != NFPROTO_UNSPEC) {
2702 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
2703 if (IS_ERR(afi))
2704 return PTR_ERR(afi);
2705 }
2706
2707 if (nla[NFTA_SET_TABLE] != NULL) {
2708 if (afi == NULL)
2709 return -EAFNOSUPPORT;
2710
2711 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE],
2712 genmask);
2713 if (IS_ERR(table))
2714 return PTR_ERR(table);
2715 }
2716
2717 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
2718 return 0;
2719 }
2720
nf_tables_set_lookup(const struct nft_table * table,const struct nlattr * nla,u8 genmask)2721 static struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
2722 const struct nlattr *nla, u8 genmask)
2723 {
2724 struct nft_set *set;
2725
2726 if (nla == NULL)
2727 return ERR_PTR(-EINVAL);
2728
2729 list_for_each_entry(set, &table->sets, list) {
2730 if (!nla_strcmp(nla, set->name) &&
2731 nft_active_genmask(set, genmask))
2732 return set;
2733 }
2734 return ERR_PTR(-ENOENT);
2735 }
2736
nf_tables_set_lookup_byid(const struct net * net,const struct nlattr * nla,u8 genmask)2737 static struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
2738 const struct nlattr *nla,
2739 u8 genmask)
2740 {
2741 struct nft_trans *trans;
2742 u32 id = ntohl(nla_get_be32(nla));
2743
2744 list_for_each_entry(trans, &net->nft.commit_list, list) {
2745 if (trans->msg_type == NFT_MSG_NEWSET) {
2746 struct nft_set *set = nft_trans_set(trans);
2747
2748 if (id == nft_trans_set_id(trans) &&
2749 nft_active_genmask(set, genmask))
2750 return set;
2751 }
2752 }
2753 return ERR_PTR(-ENOENT);
2754 }
2755
nft_set_lookup(const struct net * net,const struct nft_table * table,const struct nlattr * nla_set_name,const struct nlattr * nla_set_id,u8 genmask)2756 struct nft_set *nft_set_lookup(const struct net *net,
2757 const struct nft_table *table,
2758 const struct nlattr *nla_set_name,
2759 const struct nlattr *nla_set_id,
2760 u8 genmask)
2761 {
2762 struct nft_set *set;
2763
2764 set = nf_tables_set_lookup(table, nla_set_name, genmask);
2765 if (IS_ERR(set)) {
2766 if (!nla_set_id)
2767 return set;
2768
2769 set = nf_tables_set_lookup_byid(net, nla_set_id, genmask);
2770 }
2771 return set;
2772 }
2773 EXPORT_SYMBOL_GPL(nft_set_lookup);
2774
nf_tables_set_alloc_name(struct nft_ctx * ctx,struct nft_set * set,const char * name)2775 static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
2776 const char *name)
2777 {
2778 const struct nft_set *i;
2779 const char *p;
2780 unsigned long *inuse;
2781 unsigned int n = 0, min = 0;
2782
2783 p = strchr(name, '%');
2784 if (p != NULL) {
2785 if (p[1] != 'd' || strchr(p + 2, '%'))
2786 return -EINVAL;
2787
2788 inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
2789 if (inuse == NULL)
2790 return -ENOMEM;
2791 cont:
2792 list_for_each_entry(i, &ctx->table->sets, list) {
2793 int tmp;
2794
2795 if (!nft_is_active_next(ctx->net, set))
2796 continue;
2797 if (!sscanf(i->name, name, &tmp))
2798 continue;
2799 if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE)
2800 continue;
2801
2802 set_bit(tmp - min, inuse);
2803 }
2804
2805 n = find_first_zero_bit(inuse, BITS_PER_BYTE * PAGE_SIZE);
2806 if (n >= BITS_PER_BYTE * PAGE_SIZE) {
2807 min += BITS_PER_BYTE * PAGE_SIZE;
2808 memset(inuse, 0, PAGE_SIZE);
2809 goto cont;
2810 }
2811 free_page((unsigned long)inuse);
2812 }
2813
2814 set->name = kasprintf(GFP_KERNEL, name, min + n);
2815 if (!set->name)
2816 return -ENOMEM;
2817
2818 list_for_each_entry(i, &ctx->table->sets, list) {
2819 if (!nft_is_active_next(ctx->net, i))
2820 continue;
2821 if (!strcmp(set->name, i->name)) {
2822 kfree(set->name);
2823 return -ENFILE;
2824 }
2825 }
2826 return 0;
2827 }
2828
nf_tables_fill_set(struct sk_buff * skb,const struct nft_ctx * ctx,const struct nft_set * set,u16 event,u16 flags)2829 static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
2830 const struct nft_set *set, u16 event, u16 flags)
2831 {
2832 struct nfgenmsg *nfmsg;
2833 struct nlmsghdr *nlh;
2834 struct nlattr *desc;
2835 u32 portid = ctx->portid;
2836 u32 seq = ctx->seq;
2837
2838 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
2839 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
2840 flags);
2841 if (nlh == NULL)
2842 goto nla_put_failure;
2843
2844 nfmsg = nlmsg_data(nlh);
2845 nfmsg->nfgen_family = ctx->afi->family;
2846 nfmsg->version = NFNETLINK_V0;
2847 nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff);
2848
2849 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
2850 goto nla_put_failure;
2851 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
2852 goto nla_put_failure;
2853 if (set->flags != 0)
2854 if (nla_put_be32(skb, NFTA_SET_FLAGS, htonl(set->flags)))
2855 goto nla_put_failure;
2856
2857 if (nla_put_be32(skb, NFTA_SET_KEY_TYPE, htonl(set->ktype)))
2858 goto nla_put_failure;
2859 if (nla_put_be32(skb, NFTA_SET_KEY_LEN, htonl(set->klen)))
2860 goto nla_put_failure;
2861 if (set->flags & NFT_SET_MAP) {
2862 if (nla_put_be32(skb, NFTA_SET_DATA_TYPE, htonl(set->dtype)))
2863 goto nla_put_failure;
2864 if (nla_put_be32(skb, NFTA_SET_DATA_LEN, htonl(set->dlen)))
2865 goto nla_put_failure;
2866 }
2867 if (set->flags & NFT_SET_OBJECT &&
2868 nla_put_be32(skb, NFTA_SET_OBJ_TYPE, htonl(set->objtype)))
2869 goto nla_put_failure;
2870
2871 if (set->timeout &&
2872 nla_put_be64(skb, NFTA_SET_TIMEOUT,
2873 cpu_to_be64(jiffies_to_msecs(set->timeout)),
2874 NFTA_SET_PAD))
2875 goto nla_put_failure;
2876 if (set->gc_int &&
2877 nla_put_be32(skb, NFTA_SET_GC_INTERVAL, htonl(set->gc_int)))
2878 goto nla_put_failure;
2879
2880 if (set->policy != NFT_SET_POL_PERFORMANCE) {
2881 if (nla_put_be32(skb, NFTA_SET_POLICY, htonl(set->policy)))
2882 goto nla_put_failure;
2883 }
2884
2885 if (nla_put(skb, NFTA_SET_USERDATA, set->udlen, set->udata))
2886 goto nla_put_failure;
2887
2888 desc = nla_nest_start(skb, NFTA_SET_DESC);
2889 if (desc == NULL)
2890 goto nla_put_failure;
2891 if (set->size &&
2892 nla_put_be32(skb, NFTA_SET_DESC_SIZE, htonl(set->size)))
2893 goto nla_put_failure;
2894 nla_nest_end(skb, desc);
2895
2896 nlmsg_end(skb, nlh);
2897 return 0;
2898
2899 nla_put_failure:
2900 nlmsg_trim(skb, nlh);
2901 return -1;
2902 }
2903
nf_tables_set_notify(const struct nft_ctx * ctx,const struct nft_set * set,int event,gfp_t gfp_flags)2904 static void nf_tables_set_notify(const struct nft_ctx *ctx,
2905 const struct nft_set *set, int event,
2906 gfp_t gfp_flags)
2907 {
2908 struct sk_buff *skb;
2909 u32 portid = ctx->portid;
2910 int err;
2911
2912 if (!ctx->report &&
2913 !nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
2914 return;
2915
2916 skb = nlmsg_new(NLMSG_GOODSIZE, gfp_flags);
2917 if (skb == NULL)
2918 goto err;
2919
2920 err = nf_tables_fill_set(skb, ctx, set, event, 0);
2921 if (err < 0) {
2922 kfree_skb(skb);
2923 goto err;
2924 }
2925
2926 nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES, ctx->report,
2927 gfp_flags);
2928 return;
2929 err:
2930 nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
2931 }
2932
nf_tables_dump_sets(struct sk_buff * skb,struct netlink_callback * cb)2933 static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
2934 {
2935 const struct nft_set *set;
2936 unsigned int idx, s_idx = cb->args[0];
2937 struct nft_af_info *afi;
2938 struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
2939 struct net *net = sock_net(skb->sk);
2940 int cur_family = cb->args[3];
2941 struct nft_ctx *ctx = cb->data, ctx_set;
2942
2943 if (cb->args[1])
2944 return skb->len;
2945
2946 rcu_read_lock();
2947 cb->seq = net->nft.base_seq;
2948
2949 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
2950 if (ctx->afi && ctx->afi != afi)
2951 continue;
2952
2953 if (cur_family) {
2954 if (afi->family != cur_family)
2955 continue;
2956
2957 cur_family = 0;
2958 }
2959 list_for_each_entry_rcu(table, &afi->tables, list) {
2960 if (ctx->table && ctx->table != table)
2961 continue;
2962
2963 if (cur_table) {
2964 if (cur_table != table)
2965 continue;
2966
2967 cur_table = NULL;
2968 }
2969 idx = 0;
2970 list_for_each_entry_rcu(set, &table->sets, list) {
2971 if (idx < s_idx)
2972 goto cont;
2973 if (!nft_is_active(net, set))
2974 goto cont;
2975
2976 ctx_set = *ctx;
2977 ctx_set.table = table;
2978 ctx_set.afi = afi;
2979 if (nf_tables_fill_set(skb, &ctx_set, set,
2980 NFT_MSG_NEWSET,
2981 NLM_F_MULTI) < 0) {
2982 cb->args[0] = idx;
2983 cb->args[2] = (unsigned long) table;
2984 cb->args[3] = afi->family;
2985 goto done;
2986 }
2987 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
2988 cont:
2989 idx++;
2990 }
2991 if (s_idx)
2992 s_idx = 0;
2993 }
2994 }
2995 cb->args[1] = 1;
2996 done:
2997 rcu_read_unlock();
2998 return skb->len;
2999 }
3000
nf_tables_dump_sets_done(struct netlink_callback * cb)3001 static int nf_tables_dump_sets_done(struct netlink_callback *cb)
3002 {
3003 kfree(cb->data);
3004 return 0;
3005 }
3006
nf_tables_getset(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)3007 static int nf_tables_getset(struct net *net, struct sock *nlsk,
3008 struct sk_buff *skb, const struct nlmsghdr *nlh,
3009 const struct nlattr * const nla[],
3010 struct netlink_ext_ack *extack)
3011 {
3012 u8 genmask = nft_genmask_cur(net);
3013 const struct nft_set *set;
3014 struct nft_ctx ctx;
3015 struct sk_buff *skb2;
3016 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
3017 int err;
3018
3019 /* Verify existence before starting dump */
3020 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
3021 if (err < 0)
3022 return err;
3023
3024 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3025 struct netlink_dump_control c = {
3026 .dump = nf_tables_dump_sets,
3027 .done = nf_tables_dump_sets_done,
3028 };
3029 struct nft_ctx *ctx_dump;
3030
3031 ctx_dump = kmalloc(sizeof(*ctx_dump), GFP_KERNEL);
3032 if (ctx_dump == NULL)
3033 return -ENOMEM;
3034
3035 *ctx_dump = ctx;
3036 c.data = ctx_dump;
3037
3038 return netlink_dump_start(nlsk, skb, nlh, &c);
3039 }
3040
3041 /* Only accept unspec with dump */
3042 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
3043 return -EAFNOSUPPORT;
3044 if (!nla[NFTA_SET_TABLE])
3045 return -EINVAL;
3046
3047 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
3048 if (IS_ERR(set))
3049 return PTR_ERR(set);
3050
3051 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
3052 if (skb2 == NULL)
3053 return -ENOMEM;
3054
3055 err = nf_tables_fill_set(skb2, &ctx, set, NFT_MSG_NEWSET, 0);
3056 if (err < 0)
3057 goto err;
3058
3059 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
3060
3061 err:
3062 kfree_skb(skb2);
3063 return err;
3064 }
3065
nf_tables_set_desc_parse(const struct nft_ctx * ctx,struct nft_set_desc * desc,const struct nlattr * nla)3066 static int nf_tables_set_desc_parse(const struct nft_ctx *ctx,
3067 struct nft_set_desc *desc,
3068 const struct nlattr *nla)
3069 {
3070 struct nlattr *da[NFTA_SET_DESC_MAX + 1];
3071 int err;
3072
3073 err = nla_parse_nested(da, NFTA_SET_DESC_MAX, nla,
3074 nft_set_desc_policy, NULL);
3075 if (err < 0)
3076 return err;
3077
3078 if (da[NFTA_SET_DESC_SIZE] != NULL)
3079 desc->size = ntohl(nla_get_be32(da[NFTA_SET_DESC_SIZE]));
3080
3081 return 0;
3082 }
3083
nf_tables_newset(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)3084 static int nf_tables_newset(struct net *net, struct sock *nlsk,
3085 struct sk_buff *skb, const struct nlmsghdr *nlh,
3086 const struct nlattr * const nla[],
3087 struct netlink_ext_ack *extack)
3088 {
3089 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
3090 u8 genmask = nft_genmask_next(net);
3091 const struct nft_set_ops *ops;
3092 struct nft_af_info *afi;
3093 struct nft_table *table;
3094 struct nft_set *set;
3095 struct nft_ctx ctx;
3096 char *name;
3097 unsigned int size;
3098 bool create;
3099 u64 timeout;
3100 u32 ktype, dtype, flags, policy, gc_int, objtype;
3101 struct nft_set_desc desc;
3102 unsigned char *udata;
3103 u16 udlen;
3104 int err;
3105
3106 if (nla[NFTA_SET_TABLE] == NULL ||
3107 nla[NFTA_SET_NAME] == NULL ||
3108 nla[NFTA_SET_KEY_LEN] == NULL ||
3109 nla[NFTA_SET_ID] == NULL)
3110 return -EINVAL;
3111
3112 memset(&desc, 0, sizeof(desc));
3113
3114 ktype = NFT_DATA_VALUE;
3115 if (nla[NFTA_SET_KEY_TYPE] != NULL) {
3116 ktype = ntohl(nla_get_be32(nla[NFTA_SET_KEY_TYPE]));
3117 if ((ktype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK)
3118 return -EINVAL;
3119 }
3120
3121 desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
3122 if (desc.klen == 0 || desc.klen > NFT_DATA_VALUE_MAXLEN)
3123 return -EINVAL;
3124
3125 flags = 0;
3126 if (nla[NFTA_SET_FLAGS] != NULL) {
3127 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
3128 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
3129 NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
3130 NFT_SET_MAP | NFT_SET_EVAL |
3131 NFT_SET_OBJECT))
3132 return -EINVAL;
3133 /* Only one of these operations is supported */
3134 if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) ==
3135 (NFT_SET_MAP | NFT_SET_OBJECT))
3136 return -EOPNOTSUPP;
3137 if ((flags & (NFT_SET_EVAL | NFT_SET_OBJECT)) ==
3138 (NFT_SET_EVAL | NFT_SET_OBJECT))
3139 return -EOPNOTSUPP;
3140 }
3141
3142 dtype = 0;
3143 if (nla[NFTA_SET_DATA_TYPE] != NULL) {
3144 if (!(flags & NFT_SET_MAP))
3145 return -EINVAL;
3146
3147 dtype = ntohl(nla_get_be32(nla[NFTA_SET_DATA_TYPE]));
3148 if ((dtype & NFT_DATA_RESERVED_MASK) == NFT_DATA_RESERVED_MASK &&
3149 dtype != NFT_DATA_VERDICT)
3150 return -EINVAL;
3151
3152 if (dtype != NFT_DATA_VERDICT) {
3153 if (nla[NFTA_SET_DATA_LEN] == NULL)
3154 return -EINVAL;
3155 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
3156 if (desc.dlen == 0 || desc.dlen > NFT_DATA_VALUE_MAXLEN)
3157 return -EINVAL;
3158 } else
3159 desc.dlen = sizeof(struct nft_verdict);
3160 } else if (flags & NFT_SET_MAP)
3161 return -EINVAL;
3162
3163 if (nla[NFTA_SET_OBJ_TYPE] != NULL) {
3164 if (!(flags & NFT_SET_OBJECT))
3165 return -EINVAL;
3166
3167 objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
3168 if (objtype == NFT_OBJECT_UNSPEC ||
3169 objtype > NFT_OBJECT_MAX)
3170 return -EINVAL;
3171 } else if (flags & NFT_SET_OBJECT)
3172 return -EINVAL;
3173 else
3174 objtype = NFT_OBJECT_UNSPEC;
3175
3176 timeout = 0;
3177 if (nla[NFTA_SET_TIMEOUT] != NULL) {
3178 if (!(flags & NFT_SET_TIMEOUT))
3179 return -EINVAL;
3180 timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
3181 nla[NFTA_SET_TIMEOUT])));
3182 }
3183 gc_int = 0;
3184 if (nla[NFTA_SET_GC_INTERVAL] != NULL) {
3185 if (!(flags & NFT_SET_TIMEOUT))
3186 return -EINVAL;
3187 gc_int = ntohl(nla_get_be32(nla[NFTA_SET_GC_INTERVAL]));
3188 }
3189
3190 policy = NFT_SET_POL_PERFORMANCE;
3191 if (nla[NFTA_SET_POLICY] != NULL)
3192 policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
3193
3194 if (nla[NFTA_SET_DESC] != NULL) {
3195 err = nf_tables_set_desc_parse(&ctx, &desc, nla[NFTA_SET_DESC]);
3196 if (err < 0)
3197 return err;
3198 }
3199
3200 create = nlh->nlmsg_flags & NLM_F_CREATE ? true : false;
3201
3202 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, create);
3203 if (IS_ERR(afi))
3204 return PTR_ERR(afi);
3205
3206 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE], genmask);
3207 if (IS_ERR(table))
3208 return PTR_ERR(table);
3209
3210 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
3211
3212 set = nf_tables_set_lookup(table, nla[NFTA_SET_NAME], genmask);
3213 if (IS_ERR(set)) {
3214 if (PTR_ERR(set) != -ENOENT)
3215 return PTR_ERR(set);
3216 } else {
3217 if (nlh->nlmsg_flags & NLM_F_EXCL)
3218 return -EEXIST;
3219 if (nlh->nlmsg_flags & NLM_F_REPLACE)
3220 return -EOPNOTSUPP;
3221 return 0;
3222 }
3223
3224 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
3225 return -ENOENT;
3226
3227 ops = nft_select_set_ops(&ctx, nla, &desc, policy);
3228 if (IS_ERR(ops))
3229 return PTR_ERR(ops);
3230
3231 udlen = 0;
3232 if (nla[NFTA_SET_USERDATA])
3233 udlen = nla_len(nla[NFTA_SET_USERDATA]);
3234
3235 size = 0;
3236 if (ops->privsize != NULL)
3237 size = ops->privsize(nla, &desc);
3238
3239 set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
3240 if (!set) {
3241 err = -ENOMEM;
3242 goto err1;
3243 }
3244
3245 name = nla_strdup(nla[NFTA_SET_NAME], GFP_KERNEL);
3246 if (!name) {
3247 err = -ENOMEM;
3248 goto err2;
3249 }
3250
3251 err = nf_tables_set_alloc_name(&ctx, set, name);
3252 kfree(name);
3253 if (err < 0)
3254 goto err2;
3255
3256 udata = NULL;
3257 if (udlen) {
3258 udata = set->data + size;
3259 nla_memcpy(udata, nla[NFTA_SET_USERDATA], udlen);
3260 }
3261
3262 INIT_LIST_HEAD(&set->bindings);
3263 set->ops = ops;
3264 set->ktype = ktype;
3265 set->klen = desc.klen;
3266 set->dtype = dtype;
3267 set->objtype = objtype;
3268 set->dlen = desc.dlen;
3269 set->flags = flags;
3270 set->size = desc.size;
3271 set->policy = policy;
3272 set->udlen = udlen;
3273 set->udata = udata;
3274 set->timeout = timeout;
3275 set->gc_int = gc_int;
3276
3277 err = ops->init(set, &desc, nla);
3278 if (err < 0)
3279 goto err3;
3280
3281 err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
3282 if (err < 0)
3283 goto err4;
3284
3285 list_add_tail_rcu(&set->list, &table->sets);
3286 table->use++;
3287 return 0;
3288
3289 err4:
3290 ops->destroy(set);
3291 err3:
3292 kfree(set->name);
3293 err2:
3294 kvfree(set);
3295 err1:
3296 module_put(ops->type->owner);
3297 return err;
3298 }
3299
nft_set_destroy(struct nft_set * set)3300 static void nft_set_destroy(struct nft_set *set)
3301 {
3302 set->ops->destroy(set);
3303 module_put(set->ops->type->owner);
3304 kfree(set->name);
3305 kvfree(set);
3306 }
3307
nf_tables_set_destroy(const struct nft_ctx * ctx,struct nft_set * set)3308 static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
3309 {
3310 list_del_rcu(&set->list);
3311 nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_ATOMIC);
3312 nft_set_destroy(set);
3313 }
3314
nf_tables_delset(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)3315 static int nf_tables_delset(struct net *net, struct sock *nlsk,
3316 struct sk_buff *skb, const struct nlmsghdr *nlh,
3317 const struct nlattr * const nla[],
3318 struct netlink_ext_ack *extack)
3319 {
3320 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
3321 u8 genmask = nft_genmask_next(net);
3322 struct nft_set *set;
3323 struct nft_ctx ctx;
3324 int err;
3325
3326 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
3327 return -EAFNOSUPPORT;
3328 if (nla[NFTA_SET_TABLE] == NULL)
3329 return -EINVAL;
3330
3331 err = nft_ctx_init_from_setattr(&ctx, net, skb, nlh, nla, genmask);
3332 if (err < 0)
3333 return err;
3334
3335 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME], genmask);
3336 if (IS_ERR(set))
3337 return PTR_ERR(set);
3338
3339 if (!list_empty(&set->bindings) ||
3340 (nlh->nlmsg_flags & NLM_F_NONREC && atomic_read(&set->nelems) > 0))
3341 return -EBUSY;
3342
3343 return nft_delset(&ctx, set);
3344 }
3345
nf_tables_bind_check_setelem(const struct nft_ctx * ctx,struct nft_set * set,const struct nft_set_iter * iter,struct nft_set_elem * elem)3346 static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
3347 struct nft_set *set,
3348 const struct nft_set_iter *iter,
3349 struct nft_set_elem *elem)
3350 {
3351 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
3352 enum nft_registers dreg;
3353
3354 dreg = nft_type_to_reg(set->dtype);
3355 return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
3356 set->dtype == NFT_DATA_VERDICT ?
3357 NFT_DATA_VERDICT : NFT_DATA_VALUE,
3358 set->dlen);
3359 }
3360
nf_tables_bind_set(const struct nft_ctx * ctx,struct nft_set * set,struct nft_set_binding * binding)3361 int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
3362 struct nft_set_binding *binding)
3363 {
3364 struct nft_set_binding *i;
3365 struct nft_set_iter iter;
3366
3367 if (!list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS)
3368 return -EBUSY;
3369
3370 if (binding->flags & NFT_SET_MAP) {
3371 /* If the set is already bound to the same chain all
3372 * jumps are already validated for that chain.
3373 */
3374 list_for_each_entry(i, &set->bindings, list) {
3375 if (i->flags & NFT_SET_MAP &&
3376 i->chain == binding->chain)
3377 goto bind;
3378 }
3379
3380 iter.genmask = nft_genmask_next(ctx->net);
3381 iter.skip = 0;
3382 iter.count = 0;
3383 iter.err = 0;
3384 iter.fn = nf_tables_bind_check_setelem;
3385
3386 set->ops->walk(ctx, set, &iter);
3387 if (iter.err < 0)
3388 return iter.err;
3389 }
3390 bind:
3391 binding->chain = ctx->chain;
3392 list_add_tail_rcu(&binding->list, &set->bindings);
3393 return 0;
3394 }
3395 EXPORT_SYMBOL_GPL(nf_tables_bind_set);
3396
nf_tables_unbind_set(const struct nft_ctx * ctx,struct nft_set * set,struct nft_set_binding * binding)3397 void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
3398 struct nft_set_binding *binding)
3399 {
3400 list_del_rcu(&binding->list);
3401
3402 if (list_empty(&set->bindings) && set->flags & NFT_SET_ANONYMOUS &&
3403 nft_is_active(ctx->net, set))
3404 nf_tables_set_destroy(ctx, set);
3405 }
3406 EXPORT_SYMBOL_GPL(nf_tables_unbind_set);
3407
3408 const struct nft_set_ext_type nft_set_ext_types[] = {
3409 [NFT_SET_EXT_KEY] = {
3410 .align = __alignof__(u32),
3411 },
3412 [NFT_SET_EXT_DATA] = {
3413 .align = __alignof__(u32),
3414 },
3415 [NFT_SET_EXT_EXPR] = {
3416 .align = __alignof__(struct nft_expr),
3417 },
3418 [NFT_SET_EXT_OBJREF] = {
3419 .len = sizeof(struct nft_object *),
3420 .align = __alignof__(struct nft_object *),
3421 },
3422 [NFT_SET_EXT_FLAGS] = {
3423 .len = sizeof(u8),
3424 .align = __alignof__(u8),
3425 },
3426 [NFT_SET_EXT_TIMEOUT] = {
3427 .len = sizeof(u64),
3428 .align = __alignof__(u64),
3429 },
3430 [NFT_SET_EXT_EXPIRATION] = {
3431 .len = sizeof(unsigned long),
3432 .align = __alignof__(unsigned long),
3433 },
3434 [NFT_SET_EXT_USERDATA] = {
3435 .len = sizeof(struct nft_userdata),
3436 .align = __alignof__(struct nft_userdata),
3437 },
3438 };
3439 EXPORT_SYMBOL_GPL(nft_set_ext_types);
3440
3441 /*
3442 * Set elements
3443 */
3444
3445 static const struct nla_policy nft_set_elem_policy[NFTA_SET_ELEM_MAX + 1] = {
3446 [NFTA_SET_ELEM_KEY] = { .type = NLA_NESTED },
3447 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED },
3448 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 },
3449 [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 },
3450 [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY,
3451 .len = NFT_USERDATA_MAXLEN },
3452 [NFTA_SET_ELEM_EXPR] = { .type = NLA_NESTED },
3453 [NFTA_SET_ELEM_OBJREF] = { .type = NLA_STRING },
3454 };
3455
3456 static const struct nla_policy nft_set_elem_list_policy[NFTA_SET_ELEM_LIST_MAX + 1] = {
3457 [NFTA_SET_ELEM_LIST_TABLE] = { .type = NLA_STRING,
3458 .len = NFT_TABLE_MAXNAMELEN - 1 },
3459 [NFTA_SET_ELEM_LIST_SET] = { .type = NLA_STRING,
3460 .len = NFT_SET_MAXNAMELEN - 1 },
3461 [NFTA_SET_ELEM_LIST_ELEMENTS] = { .type = NLA_NESTED },
3462 [NFTA_SET_ELEM_LIST_SET_ID] = { .type = NLA_U32 },
3463 };
3464
nft_ctx_init_from_elemattr(struct nft_ctx * ctx,struct net * net,const struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],u8 genmask)3465 static int nft_ctx_init_from_elemattr(struct nft_ctx *ctx, struct net *net,
3466 const struct sk_buff *skb,
3467 const struct nlmsghdr *nlh,
3468 const struct nlattr * const nla[],
3469 u8 genmask)
3470 {
3471 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
3472 struct nft_af_info *afi;
3473 struct nft_table *table;
3474
3475 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
3476 if (IS_ERR(afi))
3477 return PTR_ERR(afi);
3478
3479 table = nf_tables_table_lookup(afi, nla[NFTA_SET_ELEM_LIST_TABLE],
3480 genmask);
3481 if (IS_ERR(table))
3482 return PTR_ERR(table);
3483
3484 nft_ctx_init(ctx, net, skb, nlh, afi, table, NULL, nla);
3485 return 0;
3486 }
3487
nf_tables_fill_setelem(struct sk_buff * skb,const struct nft_set * set,const struct nft_set_elem * elem)3488 static int nf_tables_fill_setelem(struct sk_buff *skb,
3489 const struct nft_set *set,
3490 const struct nft_set_elem *elem)
3491 {
3492 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
3493 unsigned char *b = skb_tail_pointer(skb);
3494 struct nlattr *nest;
3495
3496 nest = nla_nest_start(skb, NFTA_LIST_ELEM);
3497 if (nest == NULL)
3498 goto nla_put_failure;
3499
3500 if (nft_data_dump(skb, NFTA_SET_ELEM_KEY, nft_set_ext_key(ext),
3501 NFT_DATA_VALUE, set->klen) < 0)
3502 goto nla_put_failure;
3503
3504 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
3505 nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext),
3506 set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE,
3507 set->dlen) < 0)
3508 goto nla_put_failure;
3509
3510 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) &&
3511 nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
3512 goto nla_put_failure;
3513
3514 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
3515 nla_put_string(skb, NFTA_SET_ELEM_OBJREF,
3516 (*nft_set_ext_obj(ext))->name) < 0)
3517 goto nla_put_failure;
3518
3519 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
3520 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
3521 htonl(*nft_set_ext_flags(ext))))
3522 goto nla_put_failure;
3523
3524 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT) &&
3525 nla_put_be64(skb, NFTA_SET_ELEM_TIMEOUT,
3526 cpu_to_be64(jiffies_to_msecs(
3527 *nft_set_ext_timeout(ext))),
3528 NFTA_SET_ELEM_PAD))
3529 goto nla_put_failure;
3530
3531 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
3532 unsigned long expires, now = jiffies;
3533
3534 expires = *nft_set_ext_expiration(ext);
3535 if (time_before(now, expires))
3536 expires -= now;
3537 else
3538 expires = 0;
3539
3540 if (nla_put_be64(skb, NFTA_SET_ELEM_EXPIRATION,
3541 cpu_to_be64(jiffies_to_msecs(expires)),
3542 NFTA_SET_ELEM_PAD))
3543 goto nla_put_failure;
3544 }
3545
3546 if (nft_set_ext_exists(ext, NFT_SET_EXT_USERDATA)) {
3547 struct nft_userdata *udata;
3548
3549 udata = nft_set_ext_userdata(ext);
3550 if (nla_put(skb, NFTA_SET_ELEM_USERDATA,
3551 udata->len + 1, udata->data))
3552 goto nla_put_failure;
3553 }
3554
3555 nla_nest_end(skb, nest);
3556 return 0;
3557
3558 nla_put_failure:
3559 nlmsg_trim(skb, b);
3560 return -EMSGSIZE;
3561 }
3562
3563 struct nft_set_dump_args {
3564 const struct netlink_callback *cb;
3565 struct nft_set_iter iter;
3566 struct sk_buff *skb;
3567 };
3568
nf_tables_dump_setelem(const struct nft_ctx * ctx,struct nft_set * set,const struct nft_set_iter * iter,struct nft_set_elem * elem)3569 static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
3570 struct nft_set *set,
3571 const struct nft_set_iter *iter,
3572 struct nft_set_elem *elem)
3573 {
3574 struct nft_set_dump_args *args;
3575
3576 args = container_of(iter, struct nft_set_dump_args, iter);
3577 return nf_tables_fill_setelem(args->skb, set, elem);
3578 }
3579
3580 struct nft_set_dump_ctx {
3581 const struct nft_set *set;
3582 struct nft_ctx ctx;
3583 };
3584
nf_tables_dump_set(struct sk_buff * skb,struct netlink_callback * cb)3585 static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
3586 {
3587 struct nft_set_dump_ctx *dump_ctx = cb->data;
3588 struct net *net = sock_net(skb->sk);
3589 struct nft_af_info *afi;
3590 struct nft_table *table;
3591 struct nft_set *set;
3592 struct nft_set_dump_args args;
3593 bool set_found = false;
3594 struct nfgenmsg *nfmsg;
3595 struct nlmsghdr *nlh;
3596 struct nlattr *nest;
3597 u32 portid, seq;
3598 int event;
3599
3600 rcu_read_lock();
3601 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
3602 if (afi != dump_ctx->ctx.afi)
3603 continue;
3604
3605 list_for_each_entry_rcu(table, &afi->tables, list) {
3606 if (table != dump_ctx->ctx.table)
3607 continue;
3608
3609 list_for_each_entry_rcu(set, &table->sets, list) {
3610 if (set == dump_ctx->set) {
3611 set_found = true;
3612 break;
3613 }
3614 }
3615 break;
3616 }
3617 break;
3618 }
3619
3620 if (!set_found) {
3621 rcu_read_unlock();
3622 return -ENOENT;
3623 }
3624
3625 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWSETELEM);
3626 portid = NETLINK_CB(cb->skb).portid;
3627 seq = cb->nlh->nlmsg_seq;
3628
3629 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3630 NLM_F_MULTI);
3631 if (nlh == NULL)
3632 goto nla_put_failure;
3633
3634 nfmsg = nlmsg_data(nlh);
3635 nfmsg->nfgen_family = afi->family;
3636 nfmsg->version = NFNETLINK_V0;
3637 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
3638
3639 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_TABLE, table->name))
3640 goto nla_put_failure;
3641 if (nla_put_string(skb, NFTA_SET_ELEM_LIST_SET, set->name))
3642 goto nla_put_failure;
3643
3644 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3645 if (nest == NULL)
3646 goto nla_put_failure;
3647
3648 args.cb = cb;
3649 args.skb = skb;
3650 args.iter.genmask = nft_genmask_cur(net);
3651 args.iter.skip = cb->args[0];
3652 args.iter.count = 0;
3653 args.iter.err = 0;
3654 args.iter.fn = nf_tables_dump_setelem;
3655 set->ops->walk(&dump_ctx->ctx, set, &args.iter);
3656 rcu_read_unlock();
3657
3658 nla_nest_end(skb, nest);
3659 nlmsg_end(skb, nlh);
3660
3661 if (args.iter.err && args.iter.err != -EMSGSIZE)
3662 return args.iter.err;
3663 if (args.iter.count == cb->args[0])
3664 return 0;
3665
3666 cb->args[0] = args.iter.count;
3667 return skb->len;
3668
3669 nla_put_failure:
3670 rcu_read_unlock();
3671 return -ENOSPC;
3672 }
3673
nf_tables_dump_set_done(struct netlink_callback * cb)3674 static int nf_tables_dump_set_done(struct netlink_callback *cb)
3675 {
3676 kfree(cb->data);
3677 return 0;
3678 }
3679
nf_tables_getsetelem(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)3680 static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
3681 struct sk_buff *skb, const struct nlmsghdr *nlh,
3682 const struct nlattr * const nla[],
3683 struct netlink_ext_ack *extack)
3684 {
3685 u8 genmask = nft_genmask_cur(net);
3686 const struct nft_set *set;
3687 struct nft_ctx ctx;
3688 int err;
3689
3690 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
3691 if (err < 0)
3692 return err;
3693
3694 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
3695 genmask);
3696 if (IS_ERR(set))
3697 return PTR_ERR(set);
3698
3699 if (nlh->nlmsg_flags & NLM_F_DUMP) {
3700 struct netlink_dump_control c = {
3701 .dump = nf_tables_dump_set,
3702 .done = nf_tables_dump_set_done,
3703 };
3704 struct nft_set_dump_ctx *dump_ctx;
3705
3706 dump_ctx = kmalloc(sizeof(*dump_ctx), GFP_KERNEL);
3707 if (!dump_ctx)
3708 return -ENOMEM;
3709
3710 dump_ctx->set = set;
3711 dump_ctx->ctx = ctx;
3712
3713 c.data = dump_ctx;
3714 return netlink_dump_start(nlsk, skb, nlh, &c);
3715 }
3716 return -EOPNOTSUPP;
3717 }
3718
nf_tables_fill_setelem_info(struct sk_buff * skb,const struct nft_ctx * ctx,u32 seq,u32 portid,int event,u16 flags,const struct nft_set * set,const struct nft_set_elem * elem)3719 static int nf_tables_fill_setelem_info(struct sk_buff *skb,
3720 const struct nft_ctx *ctx, u32 seq,
3721 u32 portid, int event, u16 flags,
3722 const struct nft_set *set,
3723 const struct nft_set_elem *elem)
3724 {
3725 struct nfgenmsg *nfmsg;
3726 struct nlmsghdr *nlh;
3727 struct nlattr *nest;
3728 int err;
3729
3730 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
3731 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg),
3732 flags);
3733 if (nlh == NULL)
3734 goto nla_put_failure;
3735
3736 nfmsg = nlmsg_data(nlh);
3737 nfmsg->nfgen_family = ctx->afi->family;
3738 nfmsg->version = NFNETLINK_V0;
3739 nfmsg->res_id = htons(ctx->net->nft.base_seq & 0xffff);
3740
3741 if (nla_put_string(skb, NFTA_SET_TABLE, ctx->table->name))
3742 goto nla_put_failure;
3743 if (nla_put_string(skb, NFTA_SET_NAME, set->name))
3744 goto nla_put_failure;
3745
3746 nest = nla_nest_start(skb, NFTA_SET_ELEM_LIST_ELEMENTS);
3747 if (nest == NULL)
3748 goto nla_put_failure;
3749
3750 err = nf_tables_fill_setelem(skb, set, elem);
3751 if (err < 0)
3752 goto nla_put_failure;
3753
3754 nla_nest_end(skb, nest);
3755
3756 nlmsg_end(skb, nlh);
3757 return 0;
3758
3759 nla_put_failure:
3760 nlmsg_trim(skb, nlh);
3761 return -1;
3762 }
3763
nf_tables_setelem_notify(const struct nft_ctx * ctx,const struct nft_set * set,const struct nft_set_elem * elem,int event,u16 flags)3764 static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
3765 const struct nft_set *set,
3766 const struct nft_set_elem *elem,
3767 int event, u16 flags)
3768 {
3769 struct net *net = ctx->net;
3770 u32 portid = ctx->portid;
3771 struct sk_buff *skb;
3772 int err;
3773
3774 if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
3775 return;
3776
3777 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
3778 if (skb == NULL)
3779 goto err;
3780
3781 err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
3782 set, elem);
3783 if (err < 0) {
3784 kfree_skb(skb);
3785 goto err;
3786 }
3787
3788 nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, ctx->report,
3789 GFP_KERNEL);
3790 return;
3791 err:
3792 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
3793 }
3794
nft_trans_elem_alloc(struct nft_ctx * ctx,int msg_type,struct nft_set * set)3795 static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
3796 int msg_type,
3797 struct nft_set *set)
3798 {
3799 struct nft_trans *trans;
3800
3801 trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_elem));
3802 if (trans == NULL)
3803 return NULL;
3804
3805 nft_trans_elem_set(trans) = set;
3806 return trans;
3807 }
3808
nft_set_elem_init(const struct nft_set * set,const struct nft_set_ext_tmpl * tmpl,const u32 * key,const u32 * data,u64 timeout,gfp_t gfp)3809 void *nft_set_elem_init(const struct nft_set *set,
3810 const struct nft_set_ext_tmpl *tmpl,
3811 const u32 *key, const u32 *data,
3812 u64 timeout, gfp_t gfp)
3813 {
3814 struct nft_set_ext *ext;
3815 void *elem;
3816
3817 elem = kzalloc(set->ops->elemsize + tmpl->len, gfp);
3818 if (elem == NULL)
3819 return NULL;
3820
3821 ext = nft_set_elem_ext(set, elem);
3822 nft_set_ext_init(ext, tmpl);
3823
3824 memcpy(nft_set_ext_key(ext), key, set->klen);
3825 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3826 memcpy(nft_set_ext_data(ext), data, set->dlen);
3827 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION))
3828 *nft_set_ext_expiration(ext) =
3829 jiffies + timeout;
3830 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT))
3831 *nft_set_ext_timeout(ext) = timeout;
3832
3833 return elem;
3834 }
3835
nft_set_elem_destroy(const struct nft_set * set,void * elem,bool destroy_expr)3836 void nft_set_elem_destroy(const struct nft_set *set, void *elem,
3837 bool destroy_expr)
3838 {
3839 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
3840
3841 nft_data_release(nft_set_ext_key(ext), NFT_DATA_VALUE);
3842 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3843 nft_data_release(nft_set_ext_data(ext), set->dtype);
3844 if (destroy_expr && nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
3845 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
3846 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
3847 (*nft_set_ext_obj(ext))->use--;
3848 kfree(elem);
3849 }
3850 EXPORT_SYMBOL_GPL(nft_set_elem_destroy);
3851
3852 /* Only called from commit path, nft_set_elem_deactivate() already deals with
3853 * the refcounting from the preparation phase.
3854 */
nf_tables_set_elem_destroy(const struct nft_set * set,void * elem)3855 static void nf_tables_set_elem_destroy(const struct nft_set *set, void *elem)
3856 {
3857 struct nft_set_ext *ext = nft_set_elem_ext(set, elem);
3858
3859 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
3860 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
3861 kfree(elem);
3862 }
3863
nft_setelem_parse_flags(const struct nft_set * set,const struct nlattr * attr,u32 * flags)3864 static int nft_setelem_parse_flags(const struct nft_set *set,
3865 const struct nlattr *attr, u32 *flags)
3866 {
3867 if (attr == NULL)
3868 return 0;
3869
3870 *flags = ntohl(nla_get_be32(attr));
3871 if (*flags & ~NFT_SET_ELEM_INTERVAL_END)
3872 return -EINVAL;
3873 if (!(set->flags & NFT_SET_INTERVAL) &&
3874 *flags & NFT_SET_ELEM_INTERVAL_END)
3875 return -EINVAL;
3876
3877 return 0;
3878 }
3879
nft_add_set_elem(struct nft_ctx * ctx,struct nft_set * set,const struct nlattr * attr,u32 nlmsg_flags)3880 static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3881 const struct nlattr *attr, u32 nlmsg_flags)
3882 {
3883 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
3884 u8 genmask = nft_genmask_next(ctx->net);
3885 struct nft_data_desc d1, d2;
3886 struct nft_set_ext_tmpl tmpl;
3887 struct nft_set_ext *ext, *ext2;
3888 struct nft_set_elem elem;
3889 struct nft_set_binding *binding;
3890 struct nft_object *obj = NULL;
3891 struct nft_userdata *udata;
3892 struct nft_data data;
3893 enum nft_registers dreg;
3894 struct nft_trans *trans;
3895 u32 flags = 0;
3896 u64 timeout;
3897 u8 ulen;
3898 int err;
3899
3900 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
3901 nft_set_elem_policy, NULL);
3902 if (err < 0)
3903 return err;
3904
3905 if (nla[NFTA_SET_ELEM_KEY] == NULL)
3906 return -EINVAL;
3907
3908 nft_set_ext_prepare(&tmpl);
3909
3910 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
3911 if (err < 0)
3912 return err;
3913 if (flags != 0)
3914 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
3915
3916 if (set->flags & NFT_SET_MAP) {
3917 if (nla[NFTA_SET_ELEM_DATA] == NULL &&
3918 !(flags & NFT_SET_ELEM_INTERVAL_END))
3919 return -EINVAL;
3920 } else {
3921 if (nla[NFTA_SET_ELEM_DATA] != NULL)
3922 return -EINVAL;
3923 }
3924
3925 if ((flags & NFT_SET_ELEM_INTERVAL_END) &&
3926 (nla[NFTA_SET_ELEM_DATA] ||
3927 nla[NFTA_SET_ELEM_OBJREF] ||
3928 nla[NFTA_SET_ELEM_TIMEOUT] ||
3929 nla[NFTA_SET_ELEM_EXPIRATION] ||
3930 nla[NFTA_SET_ELEM_USERDATA] ||
3931 nla[NFTA_SET_ELEM_EXPR]))
3932 return -EINVAL;
3933
3934 timeout = 0;
3935 if (nla[NFTA_SET_ELEM_TIMEOUT] != NULL) {
3936 if (!(set->flags & NFT_SET_TIMEOUT))
3937 return -EINVAL;
3938 timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
3939 nla[NFTA_SET_ELEM_TIMEOUT])));
3940 } else if (set->flags & NFT_SET_TIMEOUT) {
3941 timeout = set->timeout;
3942 }
3943
3944 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
3945 nla[NFTA_SET_ELEM_KEY]);
3946 if (err < 0)
3947 goto err1;
3948 err = -EINVAL;
3949 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
3950 goto err2;
3951
3952 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
3953 if (timeout > 0) {
3954 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
3955 if (timeout != set->timeout)
3956 nft_set_ext_add(&tmpl, NFT_SET_EXT_TIMEOUT);
3957 }
3958
3959 if (nla[NFTA_SET_ELEM_OBJREF] != NULL) {
3960 if (!(set->flags & NFT_SET_OBJECT)) {
3961 err = -EINVAL;
3962 goto err2;
3963 }
3964 obj = nf_tables_obj_lookup(ctx->table, nla[NFTA_SET_ELEM_OBJREF],
3965 set->objtype, genmask);
3966 if (IS_ERR(obj)) {
3967 err = PTR_ERR(obj);
3968 goto err2;
3969 }
3970 nft_set_ext_add(&tmpl, NFT_SET_EXT_OBJREF);
3971 }
3972
3973 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
3974 err = nft_data_init(ctx, &data, sizeof(data), &d2,
3975 nla[NFTA_SET_ELEM_DATA]);
3976 if (err < 0)
3977 goto err2;
3978
3979 err = -EINVAL;
3980 if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen)
3981 goto err3;
3982
3983 dreg = nft_type_to_reg(set->dtype);
3984 list_for_each_entry(binding, &set->bindings, list) {
3985 struct nft_ctx bind_ctx = {
3986 .net = ctx->net,
3987 .afi = ctx->afi,
3988 .table = ctx->table,
3989 .chain = (struct nft_chain *)binding->chain,
3990 };
3991
3992 if (!(binding->flags & NFT_SET_MAP))
3993 continue;
3994
3995 err = nft_validate_register_store(&bind_ctx, dreg,
3996 &data,
3997 d2.type, d2.len);
3998 if (err < 0)
3999 goto err3;
4000 }
4001
4002 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
4003 }
4004
4005 /* The full maximum length of userdata can exceed the maximum
4006 * offset value (U8_MAX) for following extensions, therefor it
4007 * must be the last extension added.
4008 */
4009 ulen = 0;
4010 if (nla[NFTA_SET_ELEM_USERDATA] != NULL) {
4011 ulen = nla_len(nla[NFTA_SET_ELEM_USERDATA]);
4012 if (ulen > 0)
4013 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_USERDATA,
4014 ulen);
4015 }
4016
4017 err = -ENOMEM;
4018 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
4019 timeout, GFP_KERNEL);
4020 if (elem.priv == NULL)
4021 goto err3;
4022
4023 ext = nft_set_elem_ext(set, elem.priv);
4024 if (flags)
4025 *nft_set_ext_flags(ext) = flags;
4026 if (ulen > 0) {
4027 udata = nft_set_ext_userdata(ext);
4028 udata->len = ulen - 1;
4029 nla_memcpy(&udata->data, nla[NFTA_SET_ELEM_USERDATA], ulen);
4030 }
4031 if (obj) {
4032 *nft_set_ext_obj(ext) = obj;
4033 obj->use++;
4034 }
4035
4036 trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
4037 if (trans == NULL)
4038 goto err4;
4039
4040 ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
4041 err = set->ops->insert(ctx->net, set, &elem, &ext2);
4042 if (err) {
4043 if (err == -EEXIST) {
4044 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) ^
4045 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) ||
4046 nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) ^
4047 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF)) {
4048 err = -EBUSY;
4049 goto err5;
4050 }
4051 if ((nft_set_ext_exists(ext, NFT_SET_EXT_DATA) &&
4052 nft_set_ext_exists(ext2, NFT_SET_EXT_DATA) &&
4053 memcmp(nft_set_ext_data(ext),
4054 nft_set_ext_data(ext2), set->dlen) != 0) ||
4055 (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF) &&
4056 nft_set_ext_exists(ext2, NFT_SET_EXT_OBJREF) &&
4057 *nft_set_ext_obj(ext) != *nft_set_ext_obj(ext2)))
4058 err = -EBUSY;
4059 else if (!(nlmsg_flags & NLM_F_EXCL))
4060 err = 0;
4061 }
4062 goto err5;
4063 }
4064
4065 if (set->size &&
4066 !atomic_add_unless(&set->nelems, 1, set->size + set->ndeact)) {
4067 err = -ENFILE;
4068 goto err6;
4069 }
4070
4071 nft_trans_elem(trans) = elem;
4072 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
4073 return 0;
4074
4075 err6:
4076 set->ops->remove(ctx->net, set, &elem);
4077 err5:
4078 kfree(trans);
4079 err4:
4080 if (obj)
4081 obj->use--;
4082 kfree(elem.priv);
4083 err3:
4084 if (nla[NFTA_SET_ELEM_DATA] != NULL)
4085 nft_data_release(&data, d2.type);
4086 err2:
4087 nft_data_release(&elem.key.val, d1.type);
4088 err1:
4089 return err;
4090 }
4091
nf_tables_newsetelem(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)4092 static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
4093 struct sk_buff *skb, const struct nlmsghdr *nlh,
4094 const struct nlattr * const nla[],
4095 struct netlink_ext_ack *extack)
4096 {
4097 u8 genmask = nft_genmask_next(net);
4098 const struct nlattr *attr;
4099 struct nft_set *set;
4100 struct nft_ctx ctx;
4101 int rem, err = 0;
4102
4103 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL)
4104 return -EINVAL;
4105
4106 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
4107 if (err < 0)
4108 return err;
4109
4110 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
4111 genmask);
4112 if (IS_ERR(set)) {
4113 if (nla[NFTA_SET_ELEM_LIST_SET_ID]) {
4114 set = nf_tables_set_lookup_byid(net,
4115 nla[NFTA_SET_ELEM_LIST_SET_ID],
4116 genmask);
4117 }
4118 if (IS_ERR(set))
4119 return PTR_ERR(set);
4120 }
4121
4122 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
4123 return -EBUSY;
4124
4125 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
4126 err = nft_add_set_elem(&ctx, set, attr, nlh->nlmsg_flags);
4127 if (err < 0)
4128 break;
4129 }
4130 return err;
4131 }
4132
4133 /**
4134 * nft_data_hold - hold a nft_data item
4135 *
4136 * @data: struct nft_data to release
4137 * @type: type of data
4138 *
4139 * Hold a nft_data item. NFT_DATA_VALUE types can be silently discarded,
4140 * NFT_DATA_VERDICT bumps the reference to chains in case of NFT_JUMP and
4141 * NFT_GOTO verdicts. This function must be called on active data objects
4142 * from the second phase of the commit protocol.
4143 */
nft_data_hold(const struct nft_data * data,enum nft_data_types type)4144 void nft_data_hold(const struct nft_data *data, enum nft_data_types type)
4145 {
4146 if (type == NFT_DATA_VERDICT) {
4147 switch (data->verdict.code) {
4148 case NFT_JUMP:
4149 case NFT_GOTO:
4150 data->verdict.chain->use++;
4151 break;
4152 }
4153 }
4154 }
4155
nft_set_elem_activate(const struct net * net,const struct nft_set * set,struct nft_set_elem * elem)4156 static void nft_set_elem_activate(const struct net *net,
4157 const struct nft_set *set,
4158 struct nft_set_elem *elem)
4159 {
4160 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
4161
4162 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4163 nft_data_hold(nft_set_ext_data(ext), set->dtype);
4164 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4165 (*nft_set_ext_obj(ext))->use++;
4166 }
4167
nft_set_elem_deactivate(const struct net * net,const struct nft_set * set,struct nft_set_elem * elem)4168 static void nft_set_elem_deactivate(const struct net *net,
4169 const struct nft_set *set,
4170 struct nft_set_elem *elem)
4171 {
4172 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
4173
4174 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
4175 nft_data_release(nft_set_ext_data(ext), set->dtype);
4176 if (nft_set_ext_exists(ext, NFT_SET_EXT_OBJREF))
4177 (*nft_set_ext_obj(ext))->use--;
4178 }
4179
nft_del_setelem(struct nft_ctx * ctx,struct nft_set * set,const struct nlattr * attr)4180 static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
4181 const struct nlattr *attr)
4182 {
4183 struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
4184 struct nft_set_ext_tmpl tmpl;
4185 struct nft_data_desc desc;
4186 struct nft_set_elem elem;
4187 struct nft_set_ext *ext;
4188 struct nft_trans *trans;
4189 u32 flags = 0;
4190 void *priv;
4191 int err;
4192
4193 err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
4194 nft_set_elem_policy, NULL);
4195 if (err < 0)
4196 goto err1;
4197
4198 err = -EINVAL;
4199 if (nla[NFTA_SET_ELEM_KEY] == NULL)
4200 goto err1;
4201
4202 nft_set_ext_prepare(&tmpl);
4203
4204 err = nft_setelem_parse_flags(set, nla[NFTA_SET_ELEM_FLAGS], &flags);
4205 if (err < 0)
4206 return err;
4207 if (flags != 0)
4208 nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
4209
4210 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
4211 nla[NFTA_SET_ELEM_KEY]);
4212 if (err < 0)
4213 goto err1;
4214
4215 err = -EINVAL;
4216 if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
4217 goto err2;
4218
4219 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
4220
4221 err = -ENOMEM;
4222 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
4223 GFP_KERNEL);
4224 if (elem.priv == NULL)
4225 goto err2;
4226
4227 ext = nft_set_elem_ext(set, elem.priv);
4228 if (flags)
4229 *nft_set_ext_flags(ext) = flags;
4230
4231 trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
4232 if (trans == NULL) {
4233 err = -ENOMEM;
4234 goto err3;
4235 }
4236
4237 priv = set->ops->deactivate(ctx->net, set, &elem);
4238 if (priv == NULL) {
4239 err = -ENOENT;
4240 goto err4;
4241 }
4242 kfree(elem.priv);
4243 elem.priv = priv;
4244
4245 nft_set_elem_deactivate(ctx->net, set, &elem);
4246
4247 nft_trans_elem(trans) = elem;
4248 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
4249 return 0;
4250
4251 err4:
4252 kfree(trans);
4253 err3:
4254 kfree(elem.priv);
4255 err2:
4256 nft_data_release(&elem.key.val, desc.type);
4257 err1:
4258 return err;
4259 }
4260
nft_flush_set(const struct nft_ctx * ctx,struct nft_set * set,const struct nft_set_iter * iter,struct nft_set_elem * elem)4261 static int nft_flush_set(const struct nft_ctx *ctx,
4262 struct nft_set *set,
4263 const struct nft_set_iter *iter,
4264 struct nft_set_elem *elem)
4265 {
4266 struct nft_trans *trans;
4267 int err;
4268
4269 trans = nft_trans_alloc_gfp(ctx, NFT_MSG_DELSETELEM,
4270 sizeof(struct nft_trans_elem), GFP_ATOMIC);
4271 if (!trans)
4272 return -ENOMEM;
4273
4274 if (!set->ops->flush(ctx->net, set, elem->priv)) {
4275 err = -ENOENT;
4276 goto err1;
4277 }
4278 set->ndeact++;
4279
4280 nft_set_elem_deactivate(ctx->net, set, elem);
4281 nft_trans_elem_set(trans) = set;
4282 nft_trans_elem(trans) = *elem;
4283 list_add_tail(&trans->list, &ctx->net->nft.commit_list);
4284
4285 return 0;
4286 err1:
4287 kfree(trans);
4288 return err;
4289 }
4290
nf_tables_delsetelem(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)4291 static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
4292 struct sk_buff *skb, const struct nlmsghdr *nlh,
4293 const struct nlattr * const nla[],
4294 struct netlink_ext_ack *extack)
4295 {
4296 u8 genmask = nft_genmask_next(net);
4297 const struct nlattr *attr;
4298 struct nft_set *set;
4299 struct nft_ctx ctx;
4300 int rem, err = 0;
4301
4302 err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla, genmask);
4303 if (err < 0)
4304 return err;
4305
4306 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_ELEM_LIST_SET],
4307 genmask);
4308 if (IS_ERR(set))
4309 return PTR_ERR(set);
4310 if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
4311 return -EBUSY;
4312
4313 if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
4314 struct nft_set_iter iter = {
4315 .genmask = genmask,
4316 .fn = nft_flush_set,
4317 };
4318 set->ops->walk(&ctx, set, &iter);
4319
4320 return iter.err;
4321 }
4322
4323 nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) {
4324 err = nft_del_setelem(&ctx, set, attr);
4325 if (err < 0)
4326 break;
4327
4328 set->ndeact++;
4329 }
4330 return err;
4331 }
4332
nft_set_gc_batch_release(struct rcu_head * rcu)4333 void nft_set_gc_batch_release(struct rcu_head *rcu)
4334 {
4335 struct nft_set_gc_batch *gcb;
4336 unsigned int i;
4337
4338 gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
4339 for (i = 0; i < gcb->head.cnt; i++)
4340 nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
4341 kfree(gcb);
4342 }
4343 EXPORT_SYMBOL_GPL(nft_set_gc_batch_release);
4344
nft_set_gc_batch_alloc(const struct nft_set * set,gfp_t gfp)4345 struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
4346 gfp_t gfp)
4347 {
4348 struct nft_set_gc_batch *gcb;
4349
4350 gcb = kzalloc(sizeof(*gcb), gfp);
4351 if (gcb == NULL)
4352 return gcb;
4353 gcb->head.set = set;
4354 return gcb;
4355 }
4356 EXPORT_SYMBOL_GPL(nft_set_gc_batch_alloc);
4357
4358 /*
4359 * Stateful objects
4360 */
4361
4362 /**
4363 * nft_register_obj- register nf_tables stateful object type
4364 * @obj: object type
4365 *
4366 * Registers the object type for use with nf_tables. Returns zero on
4367 * success or a negative errno code otherwise.
4368 */
nft_register_obj(struct nft_object_type * obj_type)4369 int nft_register_obj(struct nft_object_type *obj_type)
4370 {
4371 if (obj_type->type == NFT_OBJECT_UNSPEC)
4372 return -EINVAL;
4373
4374 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4375 list_add_rcu(&obj_type->list, &nf_tables_objects);
4376 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4377 return 0;
4378 }
4379 EXPORT_SYMBOL_GPL(nft_register_obj);
4380
4381 /**
4382 * nft_unregister_obj - unregister nf_tables object type
4383 * @obj: object type
4384 *
4385 * Unregisters the object type for use with nf_tables.
4386 */
nft_unregister_obj(struct nft_object_type * obj_type)4387 void nft_unregister_obj(struct nft_object_type *obj_type)
4388 {
4389 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4390 list_del_rcu(&obj_type->list);
4391 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4392 }
4393 EXPORT_SYMBOL_GPL(nft_unregister_obj);
4394
nf_tables_obj_lookup(const struct nft_table * table,const struct nlattr * nla,u32 objtype,u8 genmask)4395 struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
4396 const struct nlattr *nla,
4397 u32 objtype, u8 genmask)
4398 {
4399 struct nft_object *obj;
4400
4401 list_for_each_entry(obj, &table->objects, list) {
4402 if (!nla_strcmp(nla, obj->name) &&
4403 objtype == obj->ops->type->type &&
4404 nft_active_genmask(obj, genmask))
4405 return obj;
4406 }
4407 return ERR_PTR(-ENOENT);
4408 }
4409 EXPORT_SYMBOL_GPL(nf_tables_obj_lookup);
4410
4411 static const struct nla_policy nft_obj_policy[NFTA_OBJ_MAX + 1] = {
4412 [NFTA_OBJ_TABLE] = { .type = NLA_STRING,
4413 .len = NFT_TABLE_MAXNAMELEN - 1 },
4414 [NFTA_OBJ_NAME] = { .type = NLA_STRING,
4415 .len = NFT_OBJ_MAXNAMELEN - 1 },
4416 [NFTA_OBJ_TYPE] = { .type = NLA_U32 },
4417 [NFTA_OBJ_DATA] = { .type = NLA_NESTED },
4418 };
4419
nft_obj_init(const struct nft_ctx * ctx,const struct nft_object_type * type,const struct nlattr * attr)4420 static struct nft_object *nft_obj_init(const struct nft_ctx *ctx,
4421 const struct nft_object_type *type,
4422 const struct nlattr *attr)
4423 {
4424 struct nlattr *tb[type->maxattr + 1];
4425 const struct nft_object_ops *ops;
4426 struct nft_object *obj;
4427 int err;
4428
4429 if (attr) {
4430 err = nla_parse_nested(tb, type->maxattr, attr, type->policy,
4431 NULL);
4432 if (err < 0)
4433 goto err1;
4434 } else {
4435 memset(tb, 0, sizeof(tb[0]) * (type->maxattr + 1));
4436 }
4437
4438 if (type->select_ops) {
4439 ops = type->select_ops(ctx, (const struct nlattr * const *)tb);
4440 if (IS_ERR(ops)) {
4441 err = PTR_ERR(ops);
4442 goto err1;
4443 }
4444 } else {
4445 ops = type->ops;
4446 }
4447
4448 err = -ENOMEM;
4449 obj = kzalloc(sizeof(*obj) + ops->size, GFP_KERNEL);
4450 if (obj == NULL)
4451 goto err1;
4452
4453 err = ops->init(ctx, (const struct nlattr * const *)tb, obj);
4454 if (err < 0)
4455 goto err2;
4456
4457 obj->ops = ops;
4458
4459 return obj;
4460 err2:
4461 kfree(obj);
4462 err1:
4463 return ERR_PTR(err);
4464 }
4465
nft_object_dump(struct sk_buff * skb,unsigned int attr,struct nft_object * obj,bool reset)4466 static int nft_object_dump(struct sk_buff *skb, unsigned int attr,
4467 struct nft_object *obj, bool reset)
4468 {
4469 struct nlattr *nest;
4470
4471 nest = nla_nest_start(skb, attr);
4472 if (!nest)
4473 goto nla_put_failure;
4474 if (obj->ops->dump(skb, obj, reset) < 0)
4475 goto nla_put_failure;
4476 nla_nest_end(skb, nest);
4477 return 0;
4478
4479 nla_put_failure:
4480 return -1;
4481 }
4482
__nft_obj_type_get(u32 objtype)4483 static const struct nft_object_type *__nft_obj_type_get(u32 objtype)
4484 {
4485 const struct nft_object_type *type;
4486
4487 list_for_each_entry(type, &nf_tables_objects, list) {
4488 if (objtype == type->type)
4489 return type;
4490 }
4491 return NULL;
4492 }
4493
nft_obj_type_get(u32 objtype)4494 static const struct nft_object_type *nft_obj_type_get(u32 objtype)
4495 {
4496 const struct nft_object_type *type;
4497
4498 type = __nft_obj_type_get(objtype);
4499 if (type != NULL && try_module_get(type->owner))
4500 return type;
4501
4502 #ifdef CONFIG_MODULES
4503 if (type == NULL) {
4504 nfnl_unlock(NFNL_SUBSYS_NFTABLES);
4505 request_module("nft-obj-%u", objtype);
4506 nfnl_lock(NFNL_SUBSYS_NFTABLES);
4507 if (__nft_obj_type_get(objtype))
4508 return ERR_PTR(-EAGAIN);
4509 }
4510 #endif
4511 return ERR_PTR(-ENOENT);
4512 }
4513
nf_tables_newobj(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)4514 static int nf_tables_newobj(struct net *net, struct sock *nlsk,
4515 struct sk_buff *skb, const struct nlmsghdr *nlh,
4516 const struct nlattr * const nla[],
4517 struct netlink_ext_ack *extack)
4518 {
4519 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4520 const struct nft_object_type *type;
4521 u8 genmask = nft_genmask_next(net);
4522 int family = nfmsg->nfgen_family;
4523 struct nft_af_info *afi;
4524 struct nft_table *table;
4525 struct nft_object *obj;
4526 struct nft_ctx ctx;
4527 u32 objtype;
4528 int err;
4529
4530 if (!nla[NFTA_OBJ_TYPE] ||
4531 !nla[NFTA_OBJ_NAME] ||
4532 !nla[NFTA_OBJ_DATA])
4533 return -EINVAL;
4534
4535 afi = nf_tables_afinfo_lookup(net, family, true);
4536 if (IS_ERR(afi))
4537 return PTR_ERR(afi);
4538
4539 table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4540 if (IS_ERR(table))
4541 return PTR_ERR(table);
4542
4543 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4544 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4545 if (IS_ERR(obj)) {
4546 err = PTR_ERR(obj);
4547 if (err != -ENOENT)
4548 return err;
4549
4550 } else {
4551 if (nlh->nlmsg_flags & NLM_F_EXCL)
4552 return -EEXIST;
4553
4554 return 0;
4555 }
4556
4557 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
4558
4559 type = nft_obj_type_get(objtype);
4560 if (IS_ERR(type))
4561 return PTR_ERR(type);
4562
4563 obj = nft_obj_init(&ctx, type, nla[NFTA_OBJ_DATA]);
4564 if (IS_ERR(obj)) {
4565 err = PTR_ERR(obj);
4566 goto err1;
4567 }
4568 obj->table = table;
4569 obj->name = nla_strdup(nla[NFTA_OBJ_NAME], GFP_KERNEL);
4570 if (!obj->name) {
4571 err = -ENOMEM;
4572 goto err2;
4573 }
4574
4575 err = nft_trans_obj_add(&ctx, NFT_MSG_NEWOBJ, obj);
4576 if (err < 0)
4577 goto err3;
4578
4579 list_add_tail_rcu(&obj->list, &table->objects);
4580 table->use++;
4581 return 0;
4582 err3:
4583 kfree(obj->name);
4584 err2:
4585 if (obj->ops->destroy)
4586 obj->ops->destroy(obj);
4587 kfree(obj);
4588 err1:
4589 module_put(type->owner);
4590 return err;
4591 }
4592
nf_tables_fill_obj_info(struct sk_buff * skb,struct net * net,u32 portid,u32 seq,int event,u32 flags,int family,const struct nft_table * table,struct nft_object * obj,bool reset)4593 static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
4594 u32 portid, u32 seq, int event, u32 flags,
4595 int family, const struct nft_table *table,
4596 struct nft_object *obj, bool reset)
4597 {
4598 struct nfgenmsg *nfmsg;
4599 struct nlmsghdr *nlh;
4600
4601 event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, event);
4602 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), flags);
4603 if (nlh == NULL)
4604 goto nla_put_failure;
4605
4606 nfmsg = nlmsg_data(nlh);
4607 nfmsg->nfgen_family = family;
4608 nfmsg->version = NFNETLINK_V0;
4609 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
4610
4611 if (nla_put_string(skb, NFTA_OBJ_TABLE, table->name) ||
4612 nla_put_string(skb, NFTA_OBJ_NAME, obj->name) ||
4613 nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->ops->type->type)) ||
4614 nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
4615 nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset))
4616 goto nla_put_failure;
4617
4618 nlmsg_end(skb, nlh);
4619 return 0;
4620
4621 nla_put_failure:
4622 nlmsg_trim(skb, nlh);
4623 return -1;
4624 }
4625
4626 struct nft_obj_filter {
4627 char *table;
4628 u32 type;
4629 };
4630
nf_tables_dump_obj(struct sk_buff * skb,struct netlink_callback * cb)4631 static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
4632 {
4633 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
4634 const struct nft_af_info *afi;
4635 const struct nft_table *table;
4636 unsigned int idx = 0, s_idx = cb->args[0];
4637 struct nft_obj_filter *filter = cb->data;
4638 struct net *net = sock_net(skb->sk);
4639 int family = nfmsg->nfgen_family;
4640 struct nft_object *obj;
4641 bool reset = false;
4642
4643 if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4644 reset = true;
4645
4646 rcu_read_lock();
4647 cb->seq = net->nft.base_seq;
4648
4649 list_for_each_entry_rcu(afi, &net->nft.af_info, list) {
4650 if (family != NFPROTO_UNSPEC && family != afi->family)
4651 continue;
4652
4653 list_for_each_entry_rcu(table, &afi->tables, list) {
4654 list_for_each_entry_rcu(obj, &table->objects, list) {
4655 if (!nft_is_active(net, obj))
4656 goto cont;
4657 if (idx < s_idx)
4658 goto cont;
4659 if (idx > s_idx)
4660 memset(&cb->args[1], 0,
4661 sizeof(cb->args) - sizeof(cb->args[0]));
4662 if (filter && filter->table &&
4663 strcmp(filter->table, table->name))
4664 goto cont;
4665 if (filter &&
4666 filter->type != NFT_OBJECT_UNSPEC &&
4667 obj->ops->type->type != filter->type)
4668 goto cont;
4669
4670 if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
4671 cb->nlh->nlmsg_seq,
4672 NFT_MSG_NEWOBJ,
4673 NLM_F_MULTI | NLM_F_APPEND,
4674 afi->family, table, obj, reset) < 0)
4675 goto done;
4676
4677 nl_dump_check_consistent(cb, nlmsg_hdr(skb));
4678 cont:
4679 idx++;
4680 }
4681 }
4682 }
4683 done:
4684 rcu_read_unlock();
4685
4686 cb->args[0] = idx;
4687 return skb->len;
4688 }
4689
nf_tables_dump_obj_done(struct netlink_callback * cb)4690 static int nf_tables_dump_obj_done(struct netlink_callback *cb)
4691 {
4692 struct nft_obj_filter *filter = cb->data;
4693
4694 if (filter) {
4695 kfree(filter->table);
4696 kfree(filter);
4697 }
4698
4699 return 0;
4700 }
4701
4702 static struct nft_obj_filter *
nft_obj_filter_alloc(const struct nlattr * const nla[])4703 nft_obj_filter_alloc(const struct nlattr * const nla[])
4704 {
4705 struct nft_obj_filter *filter;
4706
4707 filter = kzalloc(sizeof(*filter), GFP_KERNEL);
4708 if (!filter)
4709 return ERR_PTR(-ENOMEM);
4710
4711 if (nla[NFTA_OBJ_TABLE]) {
4712 filter->table = nla_strdup(nla[NFTA_OBJ_TABLE], GFP_KERNEL);
4713 if (!filter->table) {
4714 kfree(filter);
4715 return ERR_PTR(-ENOMEM);
4716 }
4717 }
4718 if (nla[NFTA_OBJ_TYPE])
4719 filter->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4720
4721 return filter;
4722 }
4723
nf_tables_getobj(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)4724 static int nf_tables_getobj(struct net *net, struct sock *nlsk,
4725 struct sk_buff *skb, const struct nlmsghdr *nlh,
4726 const struct nlattr * const nla[],
4727 struct netlink_ext_ack *extack)
4728 {
4729 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4730 u8 genmask = nft_genmask_cur(net);
4731 int family = nfmsg->nfgen_family;
4732 const struct nft_af_info *afi;
4733 const struct nft_table *table;
4734 struct nft_object *obj;
4735 struct sk_buff *skb2;
4736 bool reset = false;
4737 u32 objtype;
4738 int err;
4739
4740 if (nlh->nlmsg_flags & NLM_F_DUMP) {
4741 struct netlink_dump_control c = {
4742 .dump = nf_tables_dump_obj,
4743 .done = nf_tables_dump_obj_done,
4744 };
4745
4746 if (nla[NFTA_OBJ_TABLE] ||
4747 nla[NFTA_OBJ_TYPE]) {
4748 struct nft_obj_filter *filter;
4749
4750 filter = nft_obj_filter_alloc(nla);
4751 if (IS_ERR(filter))
4752 return -ENOMEM;
4753
4754 c.data = filter;
4755 }
4756 return netlink_dump_start(nlsk, skb, nlh, &c);
4757 }
4758
4759 if (!nla[NFTA_OBJ_NAME] ||
4760 !nla[NFTA_OBJ_TYPE])
4761 return -EINVAL;
4762
4763 afi = nf_tables_afinfo_lookup(net, family, false);
4764 if (IS_ERR(afi))
4765 return PTR_ERR(afi);
4766
4767 table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4768 if (IS_ERR(table))
4769 return PTR_ERR(table);
4770
4771 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4772 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4773 if (IS_ERR(obj))
4774 return PTR_ERR(obj);
4775
4776 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
4777 if (!skb2)
4778 return -ENOMEM;
4779
4780 if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
4781 reset = true;
4782
4783 err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid,
4784 nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0,
4785 family, table, obj, reset);
4786 if (err < 0)
4787 goto err;
4788
4789 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
4790 err:
4791 kfree_skb(skb2);
4792 return err;
4793 }
4794
nft_obj_destroy(struct nft_object * obj)4795 static void nft_obj_destroy(struct nft_object *obj)
4796 {
4797 if (obj->ops->destroy)
4798 obj->ops->destroy(obj);
4799
4800 module_put(obj->ops->type->owner);
4801 kfree(obj->name);
4802 kfree(obj);
4803 }
4804
nf_tables_delobj(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)4805 static int nf_tables_delobj(struct net *net, struct sock *nlsk,
4806 struct sk_buff *skb, const struct nlmsghdr *nlh,
4807 const struct nlattr * const nla[],
4808 struct netlink_ext_ack *extack)
4809 {
4810 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
4811 u8 genmask = nft_genmask_next(net);
4812 int family = nfmsg->nfgen_family;
4813 struct nft_af_info *afi;
4814 struct nft_table *table;
4815 struct nft_object *obj;
4816 struct nft_ctx ctx;
4817 u32 objtype;
4818
4819 if (!nla[NFTA_OBJ_TYPE] ||
4820 !nla[NFTA_OBJ_NAME])
4821 return -EINVAL;
4822
4823 afi = nf_tables_afinfo_lookup(net, family, true);
4824 if (IS_ERR(afi))
4825 return PTR_ERR(afi);
4826
4827 table = nf_tables_table_lookup(afi, nla[NFTA_OBJ_TABLE], genmask);
4828 if (IS_ERR(table))
4829 return PTR_ERR(table);
4830
4831 objtype = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
4832 obj = nf_tables_obj_lookup(table, nla[NFTA_OBJ_NAME], objtype, genmask);
4833 if (IS_ERR(obj))
4834 return PTR_ERR(obj);
4835 if (obj->use > 0)
4836 return -EBUSY;
4837
4838 nft_ctx_init(&ctx, net, skb, nlh, afi, table, NULL, nla);
4839
4840 return nft_delobj(&ctx, obj);
4841 }
4842
nft_obj_notify(struct net * net,struct nft_table * table,struct nft_object * obj,u32 portid,u32 seq,int event,int family,int report,gfp_t gfp)4843 void nft_obj_notify(struct net *net, struct nft_table *table,
4844 struct nft_object *obj, u32 portid, u32 seq, int event,
4845 int family, int report, gfp_t gfp)
4846 {
4847 struct sk_buff *skb;
4848 int err;
4849
4850 if (!report &&
4851 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
4852 return;
4853
4854 skb = nlmsg_new(NLMSG_GOODSIZE, gfp);
4855 if (skb == NULL)
4856 goto err;
4857
4858 err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
4859 table, obj, false);
4860 if (err < 0) {
4861 kfree_skb(skb);
4862 goto err;
4863 }
4864
4865 nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
4866 return;
4867 err:
4868 nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
4869 }
4870 EXPORT_SYMBOL_GPL(nft_obj_notify);
4871
nf_tables_obj_notify(const struct nft_ctx * ctx,struct nft_object * obj,int event)4872 static void nf_tables_obj_notify(const struct nft_ctx *ctx,
4873 struct nft_object *obj, int event)
4874 {
4875 nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
4876 ctx->afi->family, ctx->report, GFP_KERNEL);
4877 }
4878
nf_tables_fill_gen_info(struct sk_buff * skb,struct net * net,u32 portid,u32 seq)4879 static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
4880 u32 portid, u32 seq)
4881 {
4882 struct nlmsghdr *nlh;
4883 struct nfgenmsg *nfmsg;
4884 char buf[TASK_COMM_LEN];
4885 int event = nfnl_msg_type(NFNL_SUBSYS_NFTABLES, NFT_MSG_NEWGEN);
4886
4887 nlh = nlmsg_put(skb, portid, seq, event, sizeof(struct nfgenmsg), 0);
4888 if (nlh == NULL)
4889 goto nla_put_failure;
4890
4891 nfmsg = nlmsg_data(nlh);
4892 nfmsg->nfgen_family = AF_UNSPEC;
4893 nfmsg->version = NFNETLINK_V0;
4894 nfmsg->res_id = htons(net->nft.base_seq & 0xffff);
4895
4896 if (nla_put_be32(skb, NFTA_GEN_ID, htonl(net->nft.base_seq)) ||
4897 nla_put_be32(skb, NFTA_GEN_PROC_PID, htonl(task_pid_nr(current))) ||
4898 nla_put_string(skb, NFTA_GEN_PROC_NAME, get_task_comm(buf, current)))
4899 goto nla_put_failure;
4900
4901 nlmsg_end(skb, nlh);
4902 return 0;
4903
4904 nla_put_failure:
4905 nlmsg_trim(skb, nlh);
4906 return -EMSGSIZE;
4907 }
4908
nf_tables_gen_notify(struct net * net,struct sk_buff * skb,int event)4909 static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb,
4910 int event)
4911 {
4912 struct nlmsghdr *nlh = nlmsg_hdr(skb);
4913 struct sk_buff *skb2;
4914 int err;
4915
4916 if (nlmsg_report(nlh) &&
4917 !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
4918 return;
4919
4920 skb2 = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
4921 if (skb2 == NULL)
4922 goto err;
4923
4924 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
4925 nlh->nlmsg_seq);
4926 if (err < 0) {
4927 kfree_skb(skb2);
4928 goto err;
4929 }
4930
4931 nfnetlink_send(skb2, net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
4932 nlmsg_report(nlh), GFP_KERNEL);
4933 return;
4934 err:
4935 nfnetlink_set_err(net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
4936 -ENOBUFS);
4937 }
4938
nf_tables_getgen(struct net * net,struct sock * nlsk,struct sk_buff * skb,const struct nlmsghdr * nlh,const struct nlattr * const nla[],struct netlink_ext_ack * extack)4939 static int nf_tables_getgen(struct net *net, struct sock *nlsk,
4940 struct sk_buff *skb, const struct nlmsghdr *nlh,
4941 const struct nlattr * const nla[],
4942 struct netlink_ext_ack *extack)
4943 {
4944 struct sk_buff *skb2;
4945 int err;
4946
4947 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
4948 if (skb2 == NULL)
4949 return -ENOMEM;
4950
4951 err = nf_tables_fill_gen_info(skb2, net, NETLINK_CB(skb).portid,
4952 nlh->nlmsg_seq);
4953 if (err < 0)
4954 goto err;
4955
4956 return nlmsg_unicast(nlsk, skb2, NETLINK_CB(skb).portid);
4957 err:
4958 kfree_skb(skb2);
4959 return err;
4960 }
4961
4962 static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
4963 [NFT_MSG_NEWTABLE] = {
4964 .call_batch = nf_tables_newtable,
4965 .attr_count = NFTA_TABLE_MAX,
4966 .policy = nft_table_policy,
4967 },
4968 [NFT_MSG_GETTABLE] = {
4969 .call = nf_tables_gettable,
4970 .attr_count = NFTA_TABLE_MAX,
4971 .policy = nft_table_policy,
4972 },
4973 [NFT_MSG_DELTABLE] = {
4974 .call_batch = nf_tables_deltable,
4975 .attr_count = NFTA_TABLE_MAX,
4976 .policy = nft_table_policy,
4977 },
4978 [NFT_MSG_NEWCHAIN] = {
4979 .call_batch = nf_tables_newchain,
4980 .attr_count = NFTA_CHAIN_MAX,
4981 .policy = nft_chain_policy,
4982 },
4983 [NFT_MSG_GETCHAIN] = {
4984 .call = nf_tables_getchain,
4985 .attr_count = NFTA_CHAIN_MAX,
4986 .policy = nft_chain_policy,
4987 },
4988 [NFT_MSG_DELCHAIN] = {
4989 .call_batch = nf_tables_delchain,
4990 .attr_count = NFTA_CHAIN_MAX,
4991 .policy = nft_chain_policy,
4992 },
4993 [NFT_MSG_NEWRULE] = {
4994 .call_batch = nf_tables_newrule,
4995 .attr_count = NFTA_RULE_MAX,
4996 .policy = nft_rule_policy,
4997 },
4998 [NFT_MSG_GETRULE] = {
4999 .call = nf_tables_getrule,
5000 .attr_count = NFTA_RULE_MAX,
5001 .policy = nft_rule_policy,
5002 },
5003 [NFT_MSG_DELRULE] = {
5004 .call_batch = nf_tables_delrule,
5005 .attr_count = NFTA_RULE_MAX,
5006 .policy = nft_rule_policy,
5007 },
5008 [NFT_MSG_NEWSET] = {
5009 .call_batch = nf_tables_newset,
5010 .attr_count = NFTA_SET_MAX,
5011 .policy = nft_set_policy,
5012 },
5013 [NFT_MSG_GETSET] = {
5014 .call = nf_tables_getset,
5015 .attr_count = NFTA_SET_MAX,
5016 .policy = nft_set_policy,
5017 },
5018 [NFT_MSG_DELSET] = {
5019 .call_batch = nf_tables_delset,
5020 .attr_count = NFTA_SET_MAX,
5021 .policy = nft_set_policy,
5022 },
5023 [NFT_MSG_NEWSETELEM] = {
5024 .call_batch = nf_tables_newsetelem,
5025 .attr_count = NFTA_SET_ELEM_LIST_MAX,
5026 .policy = nft_set_elem_list_policy,
5027 },
5028 [NFT_MSG_GETSETELEM] = {
5029 .call = nf_tables_getsetelem,
5030 .attr_count = NFTA_SET_ELEM_LIST_MAX,
5031 .policy = nft_set_elem_list_policy,
5032 },
5033 [NFT_MSG_DELSETELEM] = {
5034 .call_batch = nf_tables_delsetelem,
5035 .attr_count = NFTA_SET_ELEM_LIST_MAX,
5036 .policy = nft_set_elem_list_policy,
5037 },
5038 [NFT_MSG_GETGEN] = {
5039 .call = nf_tables_getgen,
5040 },
5041 [NFT_MSG_NEWOBJ] = {
5042 .call_batch = nf_tables_newobj,
5043 .attr_count = NFTA_OBJ_MAX,
5044 .policy = nft_obj_policy,
5045 },
5046 [NFT_MSG_GETOBJ] = {
5047 .call = nf_tables_getobj,
5048 .attr_count = NFTA_OBJ_MAX,
5049 .policy = nft_obj_policy,
5050 },
5051 [NFT_MSG_DELOBJ] = {
5052 .call_batch = nf_tables_delobj,
5053 .attr_count = NFTA_OBJ_MAX,
5054 .policy = nft_obj_policy,
5055 },
5056 [NFT_MSG_GETOBJ_RESET] = {
5057 .call = nf_tables_getobj,
5058 .attr_count = NFTA_OBJ_MAX,
5059 .policy = nft_obj_policy,
5060 },
5061 };
5062
nft_chain_commit_update(struct nft_trans * trans)5063 static void nft_chain_commit_update(struct nft_trans *trans)
5064 {
5065 struct nft_base_chain *basechain;
5066
5067 if (nft_trans_chain_name(trans))
5068 swap(trans->ctx.chain->name, nft_trans_chain_name(trans));
5069
5070 if (!nft_is_base_chain(trans->ctx.chain))
5071 return;
5072
5073 basechain = nft_base_chain(trans->ctx.chain);
5074 nft_chain_stats_replace(basechain, nft_trans_chain_stats(trans));
5075
5076 switch (nft_trans_chain_policy(trans)) {
5077 case NF_DROP:
5078 case NF_ACCEPT:
5079 basechain->policy = nft_trans_chain_policy(trans);
5080 break;
5081 }
5082 }
5083
nf_tables_commit_release(struct nft_trans * trans)5084 static void nf_tables_commit_release(struct nft_trans *trans)
5085 {
5086 switch (trans->msg_type) {
5087 case NFT_MSG_DELTABLE:
5088 nf_tables_table_destroy(&trans->ctx);
5089 break;
5090 case NFT_MSG_NEWCHAIN:
5091 kfree(nft_trans_chain_name(trans));
5092 break;
5093 case NFT_MSG_DELCHAIN:
5094 nf_tables_chain_destroy(trans->ctx.chain);
5095 break;
5096 case NFT_MSG_DELRULE:
5097 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
5098 break;
5099 case NFT_MSG_DELSET:
5100 nft_set_destroy(nft_trans_set(trans));
5101 break;
5102 case NFT_MSG_DELSETELEM:
5103 nf_tables_set_elem_destroy(nft_trans_elem_set(trans),
5104 nft_trans_elem(trans).priv);
5105 break;
5106 case NFT_MSG_DELOBJ:
5107 nft_obj_destroy(nft_trans_obj(trans));
5108 break;
5109 }
5110 kfree(trans);
5111 }
5112
nf_tables_commit(struct net * net,struct sk_buff * skb)5113 static int nf_tables_commit(struct net *net, struct sk_buff *skb)
5114 {
5115 struct nft_trans *trans, *next;
5116 struct nft_trans_elem *te;
5117
5118 /* Bump generation counter, invalidate any dump in progress */
5119 while (++net->nft.base_seq == 0);
5120
5121 /* A new generation has just started */
5122 net->nft.gencursor = nft_gencursor_next(net);
5123
5124 /* Make sure all packets have left the previous generation before
5125 * purging old rules.
5126 */
5127 synchronize_rcu();
5128
5129 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
5130 switch (trans->msg_type) {
5131 case NFT_MSG_NEWTABLE:
5132 if (nft_trans_table_update(trans)) {
5133 if (!nft_trans_table_enable(trans)) {
5134 nf_tables_table_disable(net,
5135 trans->ctx.afi,
5136 trans->ctx.table);
5137 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
5138 }
5139 } else {
5140 nft_clear(net, trans->ctx.table);
5141 }
5142 nf_tables_table_notify(&trans->ctx, NFT_MSG_NEWTABLE);
5143 nft_trans_destroy(trans);
5144 break;
5145 case NFT_MSG_DELTABLE:
5146 list_del_rcu(&trans->ctx.table->list);
5147 nf_tables_table_notify(&trans->ctx, NFT_MSG_DELTABLE);
5148 break;
5149 case NFT_MSG_NEWCHAIN:
5150 if (nft_trans_chain_update(trans)) {
5151 nft_chain_commit_update(trans);
5152 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
5153 /* trans destroyed after rcu grace period */
5154 } else {
5155 nft_clear(net, trans->ctx.chain);
5156 nf_tables_chain_notify(&trans->ctx, NFT_MSG_NEWCHAIN);
5157 nft_trans_destroy(trans);
5158 }
5159 break;
5160 case NFT_MSG_DELCHAIN:
5161 list_del_rcu(&trans->ctx.chain->list);
5162 nf_tables_chain_notify(&trans->ctx, NFT_MSG_DELCHAIN);
5163 nf_tables_unregister_hooks(trans->ctx.net,
5164 trans->ctx.table,
5165 trans->ctx.chain,
5166 trans->ctx.afi->nops);
5167 break;
5168 case NFT_MSG_NEWRULE:
5169 nft_clear(trans->ctx.net, nft_trans_rule(trans));
5170 nf_tables_rule_notify(&trans->ctx,
5171 nft_trans_rule(trans),
5172 NFT_MSG_NEWRULE);
5173 nft_trans_destroy(trans);
5174 break;
5175 case NFT_MSG_DELRULE:
5176 list_del_rcu(&nft_trans_rule(trans)->list);
5177 nf_tables_rule_notify(&trans->ctx,
5178 nft_trans_rule(trans),
5179 NFT_MSG_DELRULE);
5180 break;
5181 case NFT_MSG_NEWSET:
5182 nft_clear(net, nft_trans_set(trans));
5183 /* This avoids hitting -EBUSY when deleting the table
5184 * from the transaction.
5185 */
5186 if (nft_trans_set(trans)->flags & NFT_SET_ANONYMOUS &&
5187 !list_empty(&nft_trans_set(trans)->bindings))
5188 trans->ctx.table->use--;
5189
5190 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
5191 NFT_MSG_NEWSET, GFP_KERNEL);
5192 nft_trans_destroy(trans);
5193 break;
5194 case NFT_MSG_DELSET:
5195 list_del_rcu(&nft_trans_set(trans)->list);
5196 nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
5197 NFT_MSG_DELSET, GFP_KERNEL);
5198 break;
5199 case NFT_MSG_NEWSETELEM:
5200 te = (struct nft_trans_elem *)trans->data;
5201
5202 te->set->ops->activate(net, te->set, &te->elem);
5203 nf_tables_setelem_notify(&trans->ctx, te->set,
5204 &te->elem,
5205 NFT_MSG_NEWSETELEM, 0);
5206 nft_trans_destroy(trans);
5207 break;
5208 case NFT_MSG_DELSETELEM:
5209 te = (struct nft_trans_elem *)trans->data;
5210
5211 nf_tables_setelem_notify(&trans->ctx, te->set,
5212 &te->elem,
5213 NFT_MSG_DELSETELEM, 0);
5214 te->set->ops->remove(net, te->set, &te->elem);
5215 atomic_dec(&te->set->nelems);
5216 te->set->ndeact--;
5217 break;
5218 case NFT_MSG_NEWOBJ:
5219 nft_clear(net, nft_trans_obj(trans));
5220 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
5221 NFT_MSG_NEWOBJ);
5222 nft_trans_destroy(trans);
5223 break;
5224 case NFT_MSG_DELOBJ:
5225 list_del_rcu(&nft_trans_obj(trans)->list);
5226 nf_tables_obj_notify(&trans->ctx, nft_trans_obj(trans),
5227 NFT_MSG_DELOBJ);
5228 break;
5229 }
5230 }
5231
5232 synchronize_rcu();
5233
5234 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
5235 list_del(&trans->list);
5236 nf_tables_commit_release(trans);
5237 }
5238
5239 nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
5240
5241 return 0;
5242 }
5243
nf_tables_abort_release(struct nft_trans * trans)5244 static void nf_tables_abort_release(struct nft_trans *trans)
5245 {
5246 switch (trans->msg_type) {
5247 case NFT_MSG_NEWTABLE:
5248 nf_tables_table_destroy(&trans->ctx);
5249 break;
5250 case NFT_MSG_NEWCHAIN:
5251 nf_tables_chain_destroy(trans->ctx.chain);
5252 break;
5253 case NFT_MSG_NEWRULE:
5254 nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
5255 break;
5256 case NFT_MSG_NEWSET:
5257 nft_set_destroy(nft_trans_set(trans));
5258 break;
5259 case NFT_MSG_NEWSETELEM:
5260 nft_set_elem_destroy(nft_trans_elem_set(trans),
5261 nft_trans_elem(trans).priv, true);
5262 break;
5263 case NFT_MSG_NEWOBJ:
5264 nft_obj_destroy(nft_trans_obj(trans));
5265 break;
5266 }
5267 kfree(trans);
5268 }
5269
nf_tables_abort(struct net * net,struct sk_buff * skb)5270 static int nf_tables_abort(struct net *net, struct sk_buff *skb)
5271 {
5272 struct nft_trans *trans, *next;
5273 struct nft_trans_elem *te;
5274
5275 list_for_each_entry_safe_reverse(trans, next, &net->nft.commit_list,
5276 list) {
5277 switch (trans->msg_type) {
5278 case NFT_MSG_NEWTABLE:
5279 if (nft_trans_table_update(trans)) {
5280 if (nft_trans_table_enable(trans)) {
5281 nf_tables_table_disable(net,
5282 trans->ctx.afi,
5283 trans->ctx.table);
5284 trans->ctx.table->flags |= NFT_TABLE_F_DORMANT;
5285 }
5286 nft_trans_destroy(trans);
5287 } else {
5288 list_del_rcu(&trans->ctx.table->list);
5289 }
5290 break;
5291 case NFT_MSG_DELTABLE:
5292 nft_clear(trans->ctx.net, trans->ctx.table);
5293 nft_trans_destroy(trans);
5294 break;
5295 case NFT_MSG_NEWCHAIN:
5296 if (nft_trans_chain_update(trans)) {
5297 free_percpu(nft_trans_chain_stats(trans));
5298 kfree(nft_trans_chain_name(trans));
5299 nft_trans_destroy(trans);
5300 } else {
5301 trans->ctx.table->use--;
5302 list_del_rcu(&trans->ctx.chain->list);
5303 nf_tables_unregister_hooks(trans->ctx.net,
5304 trans->ctx.table,
5305 trans->ctx.chain,
5306 trans->ctx.afi->nops);
5307 }
5308 break;
5309 case NFT_MSG_DELCHAIN:
5310 trans->ctx.table->use++;
5311 nft_clear(trans->ctx.net, trans->ctx.chain);
5312 nft_trans_destroy(trans);
5313 break;
5314 case NFT_MSG_NEWRULE:
5315 trans->ctx.chain->use--;
5316 list_del_rcu(&nft_trans_rule(trans)->list);
5317 nft_rule_expr_deactivate(&trans->ctx, nft_trans_rule(trans));
5318 break;
5319 case NFT_MSG_DELRULE:
5320 trans->ctx.chain->use++;
5321 nft_clear(trans->ctx.net, nft_trans_rule(trans));
5322 nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
5323 nft_trans_destroy(trans);
5324 break;
5325 case NFT_MSG_NEWSET:
5326 trans->ctx.table->use--;
5327 list_del_rcu(&nft_trans_set(trans)->list);
5328 break;
5329 case NFT_MSG_DELSET:
5330 trans->ctx.table->use++;
5331 nft_clear(trans->ctx.net, nft_trans_set(trans));
5332 nft_trans_destroy(trans);
5333 break;
5334 case NFT_MSG_NEWSETELEM:
5335 te = (struct nft_trans_elem *)trans->data;
5336
5337 te->set->ops->remove(net, te->set, &te->elem);
5338 atomic_dec(&te->set->nelems);
5339 break;
5340 case NFT_MSG_DELSETELEM:
5341 te = (struct nft_trans_elem *)trans->data;
5342
5343 nft_set_elem_activate(net, te->set, &te->elem);
5344 te->set->ops->activate(net, te->set, &te->elem);
5345 te->set->ndeact--;
5346
5347 nft_trans_destroy(trans);
5348 break;
5349 case NFT_MSG_NEWOBJ:
5350 trans->ctx.table->use--;
5351 list_del_rcu(&nft_trans_obj(trans)->list);
5352 break;
5353 case NFT_MSG_DELOBJ:
5354 trans->ctx.table->use++;
5355 nft_clear(trans->ctx.net, nft_trans_obj(trans));
5356 nft_trans_destroy(trans);
5357 break;
5358 }
5359 }
5360
5361 synchronize_rcu();
5362
5363 list_for_each_entry_safe_reverse(trans, next,
5364 &net->nft.commit_list, list) {
5365 list_del(&trans->list);
5366 nf_tables_abort_release(trans);
5367 }
5368
5369 return 0;
5370 }
5371
nf_tables_valid_genid(struct net * net,u32 genid)5372 static bool nf_tables_valid_genid(struct net *net, u32 genid)
5373 {
5374 return net->nft.base_seq == genid;
5375 }
5376
5377 static const struct nfnetlink_subsystem nf_tables_subsys = {
5378 .name = "nf_tables",
5379 .subsys_id = NFNL_SUBSYS_NFTABLES,
5380 .cb_count = NFT_MSG_MAX,
5381 .cb = nf_tables_cb,
5382 .commit = nf_tables_commit,
5383 .abort = nf_tables_abort,
5384 .valid_genid = nf_tables_valid_genid,
5385 };
5386
nft_chain_validate_dependency(const struct nft_chain * chain,enum nft_chain_type type)5387 int nft_chain_validate_dependency(const struct nft_chain *chain,
5388 enum nft_chain_type type)
5389 {
5390 const struct nft_base_chain *basechain;
5391
5392 if (nft_is_base_chain(chain)) {
5393 basechain = nft_base_chain(chain);
5394 if (basechain->type->type != type)
5395 return -EOPNOTSUPP;
5396 }
5397 return 0;
5398 }
5399 EXPORT_SYMBOL_GPL(nft_chain_validate_dependency);
5400
nft_chain_validate_hooks(const struct nft_chain * chain,unsigned int hook_flags)5401 int nft_chain_validate_hooks(const struct nft_chain *chain,
5402 unsigned int hook_flags)
5403 {
5404 struct nft_base_chain *basechain;
5405
5406 if (nft_is_base_chain(chain)) {
5407 basechain = nft_base_chain(chain);
5408
5409 if ((1 << basechain->ops[0].hooknum) & hook_flags)
5410 return 0;
5411
5412 return -EOPNOTSUPP;
5413 }
5414
5415 return 0;
5416 }
5417 EXPORT_SYMBOL_GPL(nft_chain_validate_hooks);
5418
5419 /*
5420 * Loop detection - walk through the ruleset beginning at the destination chain
5421 * of a new jump until either the source chain is reached (loop) or all
5422 * reachable chains have been traversed.
5423 *
5424 * The loop check is performed whenever a new jump verdict is added to an
5425 * expression or verdict map or a verdict map is bound to a new chain.
5426 */
5427
5428 static int nf_tables_check_loops(const struct nft_ctx *ctx,
5429 const struct nft_chain *chain);
5430
nf_tables_loop_check_setelem(const struct nft_ctx * ctx,struct nft_set * set,const struct nft_set_iter * iter,struct nft_set_elem * elem)5431 static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
5432 struct nft_set *set,
5433 const struct nft_set_iter *iter,
5434 struct nft_set_elem *elem)
5435 {
5436 const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
5437 const struct nft_data *data;
5438
5439 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
5440 *nft_set_ext_flags(ext) & NFT_SET_ELEM_INTERVAL_END)
5441 return 0;
5442
5443 data = nft_set_ext_data(ext);
5444 switch (data->verdict.code) {
5445 case NFT_JUMP:
5446 case NFT_GOTO:
5447 return nf_tables_check_loops(ctx, data->verdict.chain);
5448 default:
5449 return 0;
5450 }
5451 }
5452
nf_tables_check_loops(const struct nft_ctx * ctx,const struct nft_chain * chain)5453 static int nf_tables_check_loops(const struct nft_ctx *ctx,
5454 const struct nft_chain *chain)
5455 {
5456 const struct nft_rule *rule;
5457 const struct nft_expr *expr, *last;
5458 struct nft_set *set;
5459 struct nft_set_binding *binding;
5460 struct nft_set_iter iter;
5461
5462 if (ctx->chain == chain)
5463 return -ELOOP;
5464
5465 list_for_each_entry(rule, &chain->rules, list) {
5466 nft_rule_for_each_expr(expr, last, rule) {
5467 const struct nft_data *data = NULL;
5468 int err;
5469
5470 if (!expr->ops->validate)
5471 continue;
5472
5473 err = expr->ops->validate(ctx, expr, &data);
5474 if (err < 0)
5475 return err;
5476
5477 if (data == NULL)
5478 continue;
5479
5480 switch (data->verdict.code) {
5481 case NFT_JUMP:
5482 case NFT_GOTO:
5483 err = nf_tables_check_loops(ctx,
5484 data->verdict.chain);
5485 if (err < 0)
5486 return err;
5487 default:
5488 break;
5489 }
5490 }
5491 }
5492
5493 list_for_each_entry(set, &ctx->table->sets, list) {
5494 if (!nft_is_active_next(ctx->net, set))
5495 continue;
5496 if (!(set->flags & NFT_SET_MAP) ||
5497 set->dtype != NFT_DATA_VERDICT)
5498 continue;
5499
5500 list_for_each_entry(binding, &set->bindings, list) {
5501 if (!(binding->flags & NFT_SET_MAP) ||
5502 binding->chain != chain)
5503 continue;
5504
5505 iter.genmask = nft_genmask_next(ctx->net);
5506 iter.skip = 0;
5507 iter.count = 0;
5508 iter.err = 0;
5509 iter.fn = nf_tables_loop_check_setelem;
5510
5511 set->ops->walk(ctx, set, &iter);
5512 if (iter.err < 0)
5513 return iter.err;
5514 }
5515 }
5516
5517 return 0;
5518 }
5519
5520 /**
5521 * nft_parse_u32_check - fetch u32 attribute and check for maximum value
5522 *
5523 * @attr: netlink attribute to fetch value from
5524 * @max: maximum value to be stored in dest
5525 * @dest: pointer to the variable
5526 *
5527 * Parse, check and store a given u32 netlink attribute into variable.
5528 * This function returns -ERANGE if the value goes over maximum value.
5529 * Otherwise a 0 is returned and the attribute value is stored in the
5530 * destination variable.
5531 */
nft_parse_u32_check(const struct nlattr * attr,int max,u32 * dest)5532 int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest)
5533 {
5534 u32 val;
5535
5536 val = ntohl(nla_get_be32(attr));
5537 if (val > max)
5538 return -ERANGE;
5539
5540 *dest = val;
5541 return 0;
5542 }
5543 EXPORT_SYMBOL_GPL(nft_parse_u32_check);
5544
5545 /**
5546 * nft_parse_register - parse a register value from a netlink attribute
5547 *
5548 * @attr: netlink attribute
5549 *
5550 * Parse and translate a register value from a netlink attribute.
5551 * Registers used to be 128 bit wide, these register numbers will be
5552 * mapped to the corresponding 32 bit register numbers.
5553 */
nft_parse_register(const struct nlattr * attr)5554 unsigned int nft_parse_register(const struct nlattr *attr)
5555 {
5556 unsigned int reg;
5557
5558 reg = ntohl(nla_get_be32(attr));
5559 switch (reg) {
5560 case NFT_REG_VERDICT...NFT_REG_4:
5561 return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
5562 default:
5563 return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
5564 }
5565 }
5566 EXPORT_SYMBOL_GPL(nft_parse_register);
5567
5568 /**
5569 * nft_dump_register - dump a register value to a netlink attribute
5570 *
5571 * @skb: socket buffer
5572 * @attr: attribute number
5573 * @reg: register number
5574 *
5575 * Construct a netlink attribute containing the register number. For
5576 * compatibility reasons, register numbers being a multiple of 4 are
5577 * translated to the corresponding 128 bit register numbers.
5578 */
nft_dump_register(struct sk_buff * skb,unsigned int attr,unsigned int reg)5579 int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
5580 {
5581 if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
5582 reg = reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
5583 else
5584 reg = reg - NFT_REG_SIZE / NFT_REG32_SIZE + NFT_REG32_00;
5585
5586 return nla_put_be32(skb, attr, htonl(reg));
5587 }
5588 EXPORT_SYMBOL_GPL(nft_dump_register);
5589
5590 /**
5591 * nft_validate_register_load - validate a load from a register
5592 *
5593 * @reg: the register number
5594 * @len: the length of the data
5595 *
5596 * Validate that the input register is one of the general purpose
5597 * registers and that the length of the load is within the bounds.
5598 */
nft_validate_register_load(enum nft_registers reg,unsigned int len)5599 int nft_validate_register_load(enum nft_registers reg, unsigned int len)
5600 {
5601 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
5602 return -EINVAL;
5603 if (len == 0)
5604 return -EINVAL;
5605 if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
5606 return -ERANGE;
5607
5608 return 0;
5609 }
5610 EXPORT_SYMBOL_GPL(nft_validate_register_load);
5611
5612 /**
5613 * nft_validate_register_store - validate an expressions' register store
5614 *
5615 * @ctx: context of the expression performing the load
5616 * @reg: the destination register number
5617 * @data: the data to load
5618 * @type: the data type
5619 * @len: the length of the data
5620 *
5621 * Validate that a data load uses the appropriate data type for
5622 * the destination register and the length is within the bounds.
5623 * A value of NULL for the data means that its runtime gathered
5624 * data.
5625 */
nft_validate_register_store(const struct nft_ctx * ctx,enum nft_registers reg,const struct nft_data * data,enum nft_data_types type,unsigned int len)5626 int nft_validate_register_store(const struct nft_ctx *ctx,
5627 enum nft_registers reg,
5628 const struct nft_data *data,
5629 enum nft_data_types type, unsigned int len)
5630 {
5631 int err;
5632
5633 switch (reg) {
5634 case NFT_REG_VERDICT:
5635 if (type != NFT_DATA_VERDICT)
5636 return -EINVAL;
5637
5638 if (data != NULL &&
5639 (data->verdict.code == NFT_GOTO ||
5640 data->verdict.code == NFT_JUMP)) {
5641 err = nf_tables_check_loops(ctx, data->verdict.chain);
5642 if (err < 0)
5643 return err;
5644
5645 if (ctx->chain->level + 1 >
5646 data->verdict.chain->level) {
5647 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
5648 return -EMLINK;
5649 data->verdict.chain->level = ctx->chain->level + 1;
5650 }
5651 }
5652
5653 return 0;
5654 default:
5655 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
5656 return -EINVAL;
5657 if (len == 0)
5658 return -EINVAL;
5659 if (reg * NFT_REG32_SIZE + len >
5660 FIELD_SIZEOF(struct nft_regs, data))
5661 return -ERANGE;
5662
5663 if (data != NULL && type != NFT_DATA_VALUE)
5664 return -EINVAL;
5665 return 0;
5666 }
5667 }
5668 EXPORT_SYMBOL_GPL(nft_validate_register_store);
5669
5670 static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
5671 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
5672 [NFTA_VERDICT_CHAIN] = { .type = NLA_STRING,
5673 .len = NFT_CHAIN_MAXNAMELEN - 1 },
5674 };
5675
nft_verdict_init(const struct nft_ctx * ctx,struct nft_data * data,struct nft_data_desc * desc,const struct nlattr * nla)5676 static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
5677 struct nft_data_desc *desc, const struct nlattr *nla)
5678 {
5679 u8 genmask = nft_genmask_next(ctx->net);
5680 struct nlattr *tb[NFTA_VERDICT_MAX + 1];
5681 struct nft_chain *chain;
5682 int err;
5683
5684 err = nla_parse_nested(tb, NFTA_VERDICT_MAX, nla, nft_verdict_policy,
5685 NULL);
5686 if (err < 0)
5687 return err;
5688
5689 if (!tb[NFTA_VERDICT_CODE])
5690 return -EINVAL;
5691 data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
5692
5693 switch (data->verdict.code) {
5694 default:
5695 switch (data->verdict.code & NF_VERDICT_MASK) {
5696 case NF_ACCEPT:
5697 case NF_DROP:
5698 case NF_QUEUE:
5699 break;
5700 default:
5701 return -EINVAL;
5702 }
5703 /* fall through */
5704 case NFT_CONTINUE:
5705 case NFT_BREAK:
5706 case NFT_RETURN:
5707 break;
5708 case NFT_JUMP:
5709 case NFT_GOTO:
5710 if (!tb[NFTA_VERDICT_CHAIN])
5711 return -EINVAL;
5712 chain = nf_tables_chain_lookup(ctx->table,
5713 tb[NFTA_VERDICT_CHAIN], genmask);
5714 if (IS_ERR(chain))
5715 return PTR_ERR(chain);
5716 if (nft_is_base_chain(chain))
5717 return -EOPNOTSUPP;
5718
5719 chain->use++;
5720 data->verdict.chain = chain;
5721 break;
5722 }
5723
5724 desc->len = sizeof(data->verdict);
5725 desc->type = NFT_DATA_VERDICT;
5726 return 0;
5727 }
5728
nft_verdict_uninit(const struct nft_data * data)5729 static void nft_verdict_uninit(const struct nft_data *data)
5730 {
5731 switch (data->verdict.code) {
5732 case NFT_JUMP:
5733 case NFT_GOTO:
5734 data->verdict.chain->use--;
5735 break;
5736 }
5737 }
5738
nft_verdict_dump(struct sk_buff * skb,int type,const struct nft_verdict * v)5739 int nft_verdict_dump(struct sk_buff *skb, int type, const struct nft_verdict *v)
5740 {
5741 struct nlattr *nest;
5742
5743 nest = nla_nest_start(skb, type);
5744 if (!nest)
5745 goto nla_put_failure;
5746
5747 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(v->code)))
5748 goto nla_put_failure;
5749
5750 switch (v->code) {
5751 case NFT_JUMP:
5752 case NFT_GOTO:
5753 if (nla_put_string(skb, NFTA_VERDICT_CHAIN,
5754 v->chain->name))
5755 goto nla_put_failure;
5756 }
5757 nla_nest_end(skb, nest);
5758 return 0;
5759
5760 nla_put_failure:
5761 return -1;
5762 }
5763
nft_value_init(const struct nft_ctx * ctx,struct nft_data * data,unsigned int size,struct nft_data_desc * desc,const struct nlattr * nla)5764 static int nft_value_init(const struct nft_ctx *ctx,
5765 struct nft_data *data, unsigned int size,
5766 struct nft_data_desc *desc, const struct nlattr *nla)
5767 {
5768 unsigned int len;
5769
5770 len = nla_len(nla);
5771 if (len == 0)
5772 return -EINVAL;
5773 if (len > size)
5774 return -EOVERFLOW;
5775
5776 nla_memcpy(data->data, nla, len);
5777 desc->type = NFT_DATA_VALUE;
5778 desc->len = len;
5779 return 0;
5780 }
5781
nft_value_dump(struct sk_buff * skb,const struct nft_data * data,unsigned int len)5782 static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
5783 unsigned int len)
5784 {
5785 return nla_put(skb, NFTA_DATA_VALUE, len, data->data);
5786 }
5787
5788 static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
5789 [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
5790 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
5791 };
5792
5793 /**
5794 * nft_data_init - parse nf_tables data netlink attributes
5795 *
5796 * @ctx: context of the expression using the data
5797 * @data: destination struct nft_data
5798 * @size: maximum data length
5799 * @desc: data description
5800 * @nla: netlink attribute containing data
5801 *
5802 * Parse the netlink data attributes and initialize a struct nft_data.
5803 * The type and length of data are returned in the data description.
5804 *
5805 * The caller can indicate that it only wants to accept data of type
5806 * NFT_DATA_VALUE by passing NULL for the ctx argument.
5807 */
nft_data_init(const struct nft_ctx * ctx,struct nft_data * data,unsigned int size,struct nft_data_desc * desc,const struct nlattr * nla)5808 int nft_data_init(const struct nft_ctx *ctx,
5809 struct nft_data *data, unsigned int size,
5810 struct nft_data_desc *desc, const struct nlattr *nla)
5811 {
5812 struct nlattr *tb[NFTA_DATA_MAX + 1];
5813 int err;
5814
5815 err = nla_parse_nested(tb, NFTA_DATA_MAX, nla, nft_data_policy, NULL);
5816 if (err < 0)
5817 return err;
5818
5819 if (tb[NFTA_DATA_VALUE])
5820 return nft_value_init(ctx, data, size, desc,
5821 tb[NFTA_DATA_VALUE]);
5822 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
5823 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
5824 return -EINVAL;
5825 }
5826 EXPORT_SYMBOL_GPL(nft_data_init);
5827
5828 /**
5829 * nft_data_release - release a nft_data item
5830 *
5831 * @data: struct nft_data to release
5832 * @type: type of data
5833 *
5834 * Release a nft_data item. NFT_DATA_VALUE types can be silently discarded,
5835 * all others need to be released by calling this function.
5836 */
nft_data_release(const struct nft_data * data,enum nft_data_types type)5837 void nft_data_release(const struct nft_data *data, enum nft_data_types type)
5838 {
5839 if (type < NFT_DATA_VERDICT)
5840 return;
5841 switch (type) {
5842 case NFT_DATA_VERDICT:
5843 return nft_verdict_uninit(data);
5844 default:
5845 WARN_ON(1);
5846 }
5847 }
5848 EXPORT_SYMBOL_GPL(nft_data_release);
5849
nft_data_dump(struct sk_buff * skb,int attr,const struct nft_data * data,enum nft_data_types type,unsigned int len)5850 int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
5851 enum nft_data_types type, unsigned int len)
5852 {
5853 struct nlattr *nest;
5854 int err;
5855
5856 nest = nla_nest_start(skb, attr);
5857 if (nest == NULL)
5858 return -1;
5859
5860 switch (type) {
5861 case NFT_DATA_VALUE:
5862 err = nft_value_dump(skb, data, len);
5863 break;
5864 case NFT_DATA_VERDICT:
5865 err = nft_verdict_dump(skb, NFTA_DATA_VERDICT, &data->verdict);
5866 break;
5867 default:
5868 err = -EINVAL;
5869 WARN_ON(1);
5870 }
5871
5872 nla_nest_end(skb, nest);
5873 return err;
5874 }
5875 EXPORT_SYMBOL_GPL(nft_data_dump);
5876
nf_tables_init_net(struct net * net)5877 static int __net_init nf_tables_init_net(struct net *net)
5878 {
5879 INIT_LIST_HEAD(&net->nft.af_info);
5880 INIT_LIST_HEAD(&net->nft.commit_list);
5881 net->nft.base_seq = 1;
5882 return 0;
5883 }
5884
__nft_release_basechain(struct nft_ctx * ctx)5885 int __nft_release_basechain(struct nft_ctx *ctx)
5886 {
5887 struct nft_rule *rule, *nr;
5888
5889 BUG_ON(!nft_is_base_chain(ctx->chain));
5890
5891 nf_tables_unregister_hooks(ctx->net, ctx->chain->table, ctx->chain,
5892 ctx->afi->nops);
5893 list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
5894 list_del(&rule->list);
5895 ctx->chain->use--;
5896 nf_tables_rule_release(ctx, rule);
5897 }
5898 list_del(&ctx->chain->list);
5899 ctx->table->use--;
5900 nf_tables_chain_destroy(ctx->chain);
5901
5902 return 0;
5903 }
5904 EXPORT_SYMBOL_GPL(__nft_release_basechain);
5905
5906 /* Called by nft_unregister_afinfo() from __net_exit path, nfnl_lock is held. */
__nft_release_afinfo(struct net * net,struct nft_af_info * afi)5907 static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi)
5908 {
5909 struct nft_table *table, *nt;
5910 struct nft_chain *chain, *nc;
5911 struct nft_object *obj, *ne;
5912 struct nft_rule *rule, *nr;
5913 struct nft_set *set, *ns;
5914 struct nft_ctx ctx = {
5915 .net = net,
5916 .afi = afi,
5917 };
5918
5919 list_for_each_entry_safe(table, nt, &afi->tables, list) {
5920 list_for_each_entry(chain, &table->chains, list)
5921 nf_tables_unregister_hooks(net, table, chain,
5922 afi->nops);
5923 /* No packets are walking on these chains anymore. */
5924 ctx.table = table;
5925 list_for_each_entry(chain, &table->chains, list) {
5926 ctx.chain = chain;
5927 list_for_each_entry_safe(rule, nr, &chain->rules, list) {
5928 list_del(&rule->list);
5929 chain->use--;
5930 nf_tables_rule_release(&ctx, rule);
5931 }
5932 }
5933 list_for_each_entry_safe(set, ns, &table->sets, list) {
5934 list_del(&set->list);
5935 table->use--;
5936 nft_set_destroy(set);
5937 }
5938 list_for_each_entry_safe(obj, ne, &table->objects, list) {
5939 list_del(&obj->list);
5940 table->use--;
5941 nft_obj_destroy(obj);
5942 }
5943 list_for_each_entry_safe(chain, nc, &table->chains, list) {
5944 list_del(&chain->list);
5945 table->use--;
5946 nf_tables_chain_destroy(chain);
5947 }
5948 list_del(&table->list);
5949 nf_tables_table_destroy(&ctx);
5950 }
5951 }
5952
5953 static struct pernet_operations nf_tables_net_ops = {
5954 .init = nf_tables_init_net,
5955 };
5956
nf_tables_module_init(void)5957 static int __init nf_tables_module_init(void)
5958 {
5959 int err;
5960
5961 info = kmalloc(sizeof(struct nft_expr_info) * NFT_RULE_MAXEXPRS,
5962 GFP_KERNEL);
5963 if (info == NULL) {
5964 err = -ENOMEM;
5965 goto err1;
5966 }
5967
5968 err = nf_tables_core_module_init();
5969 if (err < 0)
5970 goto err2;
5971
5972 err = nfnetlink_subsys_register(&nf_tables_subsys);
5973 if (err < 0)
5974 goto err3;
5975
5976 pr_info("nf_tables: (c) 2007-2009 Patrick McHardy <kaber@trash.net>\n");
5977 return register_pernet_subsys(&nf_tables_net_ops);
5978 err3:
5979 nf_tables_core_module_exit();
5980 err2:
5981 kfree(info);
5982 err1:
5983 return err;
5984 }
5985
nf_tables_module_exit(void)5986 static void __exit nf_tables_module_exit(void)
5987 {
5988 unregister_pernet_subsys(&nf_tables_net_ops);
5989 nfnetlink_subsys_unregister(&nf_tables_subsys);
5990 rcu_barrier();
5991 nf_tables_core_module_exit();
5992 kfree(info);
5993 }
5994
5995 module_init(nf_tables_module_init);
5996 module_exit(nf_tables_module_exit);
5997
5998 MODULE_LICENSE("GPL");
5999 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
6000 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFTABLES);
6001