History

netfilter: nf_tables: add stateful object reference expression

This new expression allows us to refer to existing stateful objects from rules.

Pablo Neira Ayuso committed 9 years ago

Commit c97d22e1 parent 173705d4 files · +133 −0Browse files

Unified · Split

4 files
  1. include/uapi/linux/netfilter/nf_tables.h +14 −0
  2. net/netfilter/Kconfig +6 −0
  3. net/netfilter/Makefile +1 −0
  4. net/netfilter/nft_objref.c +112 −0
include/uapi/linux/netfilter/nf_tables.h+14−0
@@ -1137,6 +1137,20 @@ enum nft_fwd_attributes { · 1136 unmodified lines
1137};1137};
1138#define NFTA_FWD_MAX (__NFTA_FWD_MAX - 1)1138#define NFTA_FWD_MAX (__NFTA_FWD_MAX - 1)
1139 1139
1140/**
1141 * enum nft_objref_attributes - nf_tables stateful object expression netlink attributes
1142 *
1143 * @NFTA_OBJREF_IMM_TYPE: object type for immediate reference (NLA_U32: nft_register)
1144 * @NFTA_OBJREF_IMM_NAME: object name for immediate reference (NLA_STRING)
1145 */
1146enum nft_objref_attributes {
1147 NFTA_OBJREF_UNSPEC,
1148 NFTA_OBJREF_IMM_TYPE,
1149 NFTA_OBJREF_IMM_NAME,
1150 __NFTA_OBJREF_MAX
1151};
1152#define NFTA_OBJREF_MAX (__NFTA_OBJREF_MAX - 1)
1153
1140/**1154/**
1141 * enum nft_gen_attributes - nf_tables ruleset generation attributes1155 * enum nft_gen_attributes - nf_tables ruleset generation attributes
1142 *1156 *
net/netfilter/Kconfig+6−0
@@ -551,6 +551,12 @@ config NFT_NAT · 550 unmodified lines
551 This option adds the "nat" expression that you can use to perform551 This option adds the "nat" expression that you can use to perform
552 typical Network Address Translation (NAT) packet transformations.552 typical Network Address Translation (NAT) packet transformations.
553 553
554config NFT_OBJREF
555 tristate "Netfilter nf_tables stateful object reference module"
556 help
557 This option adds the "objref" expression that allows you to refer to
558 stateful objects, such as counters and quotas.
559
554config NFT_QUEUE560config NFT_QUEUE
555 depends on NETFILTER_NETLINK_QUEUE561 depends on NETFILTER_NETLINK_QUEUE
556 tristate "Netfilter nf_tables queue module"562 tristate "Netfilter nf_tables queue module"
net/netfilter/Makefile+1−0
@@ -88,6 +88,7 @@ obj-$(CONFIG_NFT_NUMGEN) += nft_numgen.o · 87 unmodified lines
88obj-$(CONFIG_NFT_CT) += nft_ct.o88obj-$(CONFIG_NFT_CT) += nft_ct.o
89obj-$(CONFIG_NFT_LIMIT) += nft_limit.o89obj-$(CONFIG_NFT_LIMIT) += nft_limit.o
90obj-$(CONFIG_NFT_NAT) += nft_nat.o90obj-$(CONFIG_NFT_NAT) += nft_nat.o
91obj-$(CONFIG_NFT_OBJREF) += nft_objref.o
91obj-$(CONFIG_NFT_QUEUE) += nft_queue.o92obj-$(CONFIG_NFT_QUEUE) += nft_queue.o
92obj-$(CONFIG_NFT_QUOTA) += nft_quota.o93obj-$(CONFIG_NFT_QUOTA) += nft_quota.o
93obj-$(CONFIG_NFT_REJECT) += nft_reject.o94obj-$(CONFIG_NFT_REJECT) += nft_reject.o
net/netfilter/nft_objref.c+112−0
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 2012-2016 Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 */
8
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/skbuff.h>
12#include <linux/netlink.h>
13#include <linux/netfilter.h>
14#include <linux/netfilter/nf_tables.h>
15#include <net/netfilter/nf_tables.h>
16
17#define nft_objref_priv(expr) *((struct nft_object **)nft_expr_priv(expr))
18
19static void nft_objref_eval(const struct nft_expr *expr,
20 struct nft_regs *regs,
21 const struct nft_pktinfo *pkt)
22{
23 struct nft_object *obj = nft_objref_priv(expr);
24
25 obj->type->eval(obj, regs, pkt);
26}
27
28static int nft_objref_init(const struct nft_ctx *ctx,
29 const struct nft_expr *expr,
30 const struct nlattr * const tb[])
31{
32 struct nft_object *obj = nft_objref_priv(expr);
33 u8 genmask = nft_genmask_next(ctx->net);
34 u32 objtype;
35
36 if (!tb[NFTA_OBJREF_IMM_NAME] ||
37 !tb[NFTA_OBJREF_IMM_TYPE])
38 return -EINVAL;
39
40 objtype = ntohl(nla_get_be32(tb[NFTA_OBJREF_IMM_TYPE]));
41 obj = nf_tables_obj_lookup(ctx->table, tb[NFTA_OBJREF_IMM_NAME], objtype,
42 genmask);
43 if (IS_ERR(obj))
44 return -ENOENT;
45
46 nft_objref_priv(expr) = obj;
47 obj->use++;
48
49 return 0;
50}
51
52static int nft_objref_dump(struct sk_buff *skb, const struct nft_expr *expr)
53{
54 const struct nft_object *obj = nft_objref_priv(expr);
55
56 if (nla_put_string(skb, NFTA_OBJREF_IMM_NAME, obj->name) ||
57 nla_put_be32(skb, NFTA_OBJREF_IMM_TYPE, htonl(obj->type->type)))
58 goto nla_put_failure;
59
60 return 0;
61
62nla_put_failure:
63 return -1;
64}
65
66static void nft_objref_destroy(const struct nft_ctx *ctx,
67 const struct nft_expr *expr)
68{
69 struct nft_object *obj = nft_objref_priv(expr);
70
71 obj->use--;
72}
73
74static struct nft_expr_type nft_objref_type;
75static const struct nft_expr_ops nft_objref_ops = {
76 .type = &nft_objref_type,
77 .size = NFT_EXPR_SIZE(sizeof(struct nft_object *)),
78 .eval = nft_objref_eval,
79 .init = nft_objref_init,
80 .destroy = nft_objref_destroy,
81 .dump = nft_objref_dump,
82};
83
84static const struct nla_policy nft_objref_policy[NFTA_OBJREF_MAX + 1] = {
85 [NFTA_OBJREF_IMM_NAME] = { .type = NLA_STRING },
86 [NFTA_OBJREF_IMM_TYPE] = { .type = NLA_U32 },
87};
88
89static struct nft_expr_type nft_objref_type __read_mostly = {
90 .name = "objref",
91 .ops = &nft_objref_ops,
92 .policy = nft_objref_policy,
93 .maxattr = NFTA_OBJREF_MAX,
94 .owner = THIS_MODULE,
95};
96
97static int __init nft_objref_module_init(void)
98{
99 return nft_register_expr(&nft_objref_type);
100}
101
102static void __exit nft_objref_module_exit(void)
103{
104 nft_unregister_expr(&nft_objref_type);
105}
106
107module_init(nft_objref_module_init);
108module_exit(nft_objref_module_exit);
109
110MODULE_LICENSE("GPL");
111MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
112MODULE_ALIAS_NFT_EXPR("objref");