aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-04-14 18:51:19 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-14 18:51:19 -0400
commitbae97d84100ae7a8dc3b79233ecd3a8f7c19ea57 (patch)
tree975f812d346f61d988a8dc5a0989539293700ad9 /net
parent87ffabb1f055e14e7d171c6599539a154d647904 (diff)
parent97bb43c3e06e9bfdc9e3140a312004df462685b9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next A final pull request, I know it's very late but this time I think it's worth a bit of rush. The following patchset contains Netfilter/nf_tables updates for net-next, more specifically concatenation support and dynamic stateful expression instantiation. This also comes with a couple of small patches. One to fix the ebtables.h userspace header and another to get rid of an obsolete example file in tree that describes a nf_tables expression. This time, I decided to paste the original descriptions. This will result in a rather large commit description, but I think these bytes to keep. Patrick McHardy says: ==================== netfilter: nf_tables: concatenation support The following patches add support for concatenations, which allow multi dimensional exact matches in O(1). The basic idea is to split the data registers, currently consisting of 4 registers of 16 bytes each, into smaller units, 16 registers of 4 bytes each, and making sure each register store always leaves the full 32 bit in a well defined state, meaning smaller stores will zero the remaining bits. Based on that, we can load multiple adjacent registers with different values, thereby building a concatenated bigger value, and use that value for set lookups. Sets are changed to use variable sized extensions for their key and data values, removing the fixed limit of 16 bytes while saving memory if less space is needed. As a side effect, these patches will allow some nice optimizations in the future, like using jhash2 in nft_hash, removing the masking in nft_cmp_fast, optimized data comparison using 32 bit word size etc. These are not done so far however. The patches are split up as follows: * the first five patches add length validation to register loads and stores to make sure we stay within bounds and prepare the validation functions for the new addressing mode * the next patches prepare for changing to 32 bit addressing by introducing a struct nft_regs, which holds the verdict register as well as the data registers. The verdict members are moved to a new struct nft_verdict to allow to pull struct nft_data out of the stack. * the next patches contain preparatory conversions of expressions and sets to use 32 bit addressing * the next patch introduces so far unused register conversion helpers for parsing and dumping register numbers over netlink * following is the real conversion to 32 bit addressing, consisting of replacing struct nft_data in struct nft_regs by an array of u32s and actually translating and validating the new register numbers. * the final two patches add support for variable sized data items and variable sized keys / data in set elements The patches have been verified to work correctly with nft binaries using both old and new addressing. ==================== Patrick McHardy says: ==================== netfilter: nf_tables: dynamic stateful expression instantiation The following patches are the grand finale of my nf_tables set work, using all the building blocks put in place by the previous patches to support something like iptables hashlimit, but a lot more powerful. Sets are extended to allow attaching expressions to set elements. The dynset expression dynamically instantiates these expressions based on a template when creating new set elements and evaluates them for all new or updated set members. In combination with concatenations this effectively creates state tables for arbitrary combinations of keys, using the existing expression types to maintain that state. Regular set GC takes care of purging expired states. We currently support two different stateful expressions, counter and limit. Using limit as a template we can express the functionality of hashlimit, but completely unrestricted in the combination of keys. Using counter we can perform accounting for arbitrary flows. The following examples from patch 5/5 show some possibilities. Userspace syntax is still WIP, especially the listing of state tables will most likely be seperated from normal set listings and use a more structured format: 1. Limit the rate of new SSH connections per host, similar to iptables hashlimit: flow ip saddr timeout 60s \ limit 10/second \ accept 2. Account network traffic between each set of /24 networks: flow ip saddr & 255.255.255.0 . ip daddr & 255.255.255.0 \ counter 3. Account traffic to each host per user: flow skuid . ip daddr \ counter 4. Account traffic for each combination of source address and TCP flags: flow ip saddr . tcp flags \ counter The resulting set content after a Xmas-scan look like this: { 192.168.122.1 . fin | psh | urg : counter packets 1001 bytes 40040, 192.168.122.1 . ack : counter packets 74 bytes 3848, 192.168.122.1 . psh | ack : counter packets 35 bytes 3144 } In the future the "expressions attached to elements" will be extended to also support user created non-stateful expressions to allow to efficiently select beween a set of parameter sets, f.i. a set of log statements with different prefixes based on the interface, which currently require one rule each. This will most likely have to wait until the next kernel version though. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/bridge/netfilter/nft_meta_bridge.c26
-rw-r--r--net/bridge/netfilter/nft_reject_bridge.c6
-rw-r--r--net/ipv4/netfilter/nft_masq_ipv4.c9
-rw-r--r--net/ipv4/netfilter/nft_redir_ipv4.c11
-rw-r--r--net/ipv4/netfilter/nft_reject_ipv4.c4
-rw-r--r--net/ipv6/netfilter/nft_masq_ipv6.c7
-rw-r--r--net/ipv6/netfilter/nft_redir_ipv6.c11
-rw-r--r--net/ipv6/netfilter/nft_reject_ipv6.c4
-rw-r--r--net/netfilter/nf_tables_api.c271
-rw-r--r--net/netfilter/nf_tables_core.c41
-rw-r--r--net/netfilter/nft_bitwise.c37
-rw-r--r--net/netfilter/nft_byteorder.c40
-rw-r--r--net/netfilter/nft_cmp.c44
-rw-r--r--net/netfilter/nft_compat.c26
-rw-r--r--net/netfilter/nft_counter.c3
-rw-r--r--net/netfilter/nft_ct.c110
-rw-r--r--net/netfilter/nft_dynset.c79
-rw-r--r--net/netfilter/nft_expr_template.c94
-rw-r--r--net/netfilter/nft_exthdr.c23
-rw-r--r--net/netfilter/nft_hash.c19
-rw-r--r--net/netfilter/nft_immediate.c18
-rw-r--r--net/netfilter/nft_limit.c5
-rw-r--r--net/netfilter/nft_log.c2
-rw-r--r--net/netfilter/nft_lookup.c31
-rw-r--r--net/netfilter/nft_meta.c107
-rw-r--r--net/netfilter/nft_nat.c71
-rw-r--r--net/netfilter/nft_payload.c24
-rw-r--r--net/netfilter/nft_queue.c4
-rw-r--r--net/netfilter/nft_rbtree.c15
-rw-r--r--net/netfilter/nft_redir.c19
-rw-r--r--net/netfilter/nft_reject_inet.c5
31 files changed, 623 insertions, 543 deletions
diff --git a/net/bridge/netfilter/nft_meta_bridge.c b/net/bridge/netfilter/nft_meta_bridge.c
index 4f02109d708f..a21269b83f16 100644
--- a/net/bridge/netfilter/nft_meta_bridge.c
+++ b/net/bridge/netfilter/nft_meta_bridge.c
@@ -19,12 +19,12 @@
19#include "../br_private.h" 19#include "../br_private.h"
20 20
21static void nft_meta_bridge_get_eval(const struct nft_expr *expr, 21static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
22 struct nft_data data[NFT_REG_MAX + 1], 22 struct nft_regs *regs,
23 const struct nft_pktinfo *pkt) 23 const struct nft_pktinfo *pkt)
24{ 24{
25 const struct nft_meta *priv = nft_expr_priv(expr); 25 const struct nft_meta *priv = nft_expr_priv(expr);
26 const struct net_device *in = pkt->in, *out = pkt->out; 26 const struct net_device *in = pkt->in, *out = pkt->out;
27 struct nft_data *dest = &data[priv->dreg]; 27 u32 *dest = &regs->data[priv->dreg];
28 const struct net_bridge_port *p; 28 const struct net_bridge_port *p;
29 29
30 switch (priv->key) { 30 switch (priv->key) {
@@ -40,12 +40,12 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
40 goto out; 40 goto out;
41 } 41 }
42 42
43 strncpy((char *)dest->data, p->br->dev->name, sizeof(dest->data)); 43 strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
44 return; 44 return;
45out: 45out:
46 return nft_meta_get_eval(expr, data, pkt); 46 return nft_meta_get_eval(expr, regs, pkt);
47err: 47err:
48 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 48 regs->verdict.code = NFT_BREAK;
49} 49}
50 50
51static int nft_meta_bridge_get_init(const struct nft_ctx *ctx, 51static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
@@ -53,27 +53,21 @@ static int nft_meta_bridge_get_init(const struct nft_ctx *ctx,
53 const struct nlattr * const tb[]) 53 const struct nlattr * const tb[])
54{ 54{
55 struct nft_meta *priv = nft_expr_priv(expr); 55 struct nft_meta *priv = nft_expr_priv(expr);
56 int err; 56 unsigned int len;
57 57
58 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); 58 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
59 switch (priv->key) { 59 switch (priv->key) {
60 case NFT_META_BRI_IIFNAME: 60 case NFT_META_BRI_IIFNAME:
61 case NFT_META_BRI_OIFNAME: 61 case NFT_META_BRI_OIFNAME:
62 len = IFNAMSIZ;
62 break; 63 break;
63 default: 64 default:
64 return nft_meta_get_init(ctx, expr, tb); 65 return nft_meta_get_init(ctx, expr, tb);
65 } 66 }
66 67
67 priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); 68 priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
68 err = nft_validate_output_register(priv->dreg); 69 return nft_validate_register_store(ctx, priv->dreg, NULL,
69 if (err < 0) 70 NFT_DATA_VALUE, len);
70 return err;
71
72 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
73 if (err < 0)
74 return err;
75
76 return 0;
77} 71}
78 72
79static struct nft_expr_type nft_meta_bridge_type; 73static struct nft_expr_type nft_meta_bridge_type;
diff --git a/net/bridge/netfilter/nft_reject_bridge.c b/net/bridge/netfilter/nft_reject_bridge.c
index ae8141f409d9..858d848564ee 100644
--- a/net/bridge/netfilter/nft_reject_bridge.c
+++ b/net/bridge/netfilter/nft_reject_bridge.c
@@ -257,8 +257,8 @@ static void nft_reject_br_send_v6_unreach(struct net *net,
257} 257}
258 258
259static void nft_reject_bridge_eval(const struct nft_expr *expr, 259static void nft_reject_bridge_eval(const struct nft_expr *expr,
260 struct nft_data data[NFT_REG_MAX + 1], 260 struct nft_regs *regs,
261 const struct nft_pktinfo *pkt) 261 const struct nft_pktinfo *pkt)
262{ 262{
263 struct nft_reject *priv = nft_expr_priv(expr); 263 struct nft_reject *priv = nft_expr_priv(expr);
264 struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out); 264 struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);
@@ -310,7 +310,7 @@ static void nft_reject_bridge_eval(const struct nft_expr *expr,
310 break; 310 break;
311 } 311 }
312out: 312out:
313 data[NFT_REG_VERDICT].verdict = NF_DROP; 313 regs->verdict.code = NF_DROP;
314} 314}
315 315
316static int nft_reject_bridge_validate(const struct nft_ctx *ctx, 316static int nft_reject_bridge_validate(const struct nft_ctx *ctx,
diff --git a/net/ipv4/netfilter/nft_masq_ipv4.c b/net/ipv4/netfilter/nft_masq_ipv4.c
index 665de06561cd..40e414c4ca56 100644
--- a/net/ipv4/netfilter/nft_masq_ipv4.c
+++ b/net/ipv4/netfilter/nft_masq_ipv4.c
@@ -17,20 +17,17 @@
17#include <net/netfilter/ipv4/nf_nat_masquerade.h> 17#include <net/netfilter/ipv4/nf_nat_masquerade.h>
18 18
19static void nft_masq_ipv4_eval(const struct nft_expr *expr, 19static void nft_masq_ipv4_eval(const struct nft_expr *expr,
20 struct nft_data data[NFT_REG_MAX + 1], 20 struct nft_regs *regs,
21 const struct nft_pktinfo *pkt) 21 const struct nft_pktinfo *pkt)
22{ 22{
23 struct nft_masq *priv = nft_expr_priv(expr); 23 struct nft_masq *priv = nft_expr_priv(expr);
24 struct nf_nat_range range; 24 struct nf_nat_range range;
25 unsigned int verdict;
26 25
27 memset(&range, 0, sizeof(range)); 26 memset(&range, 0, sizeof(range));
28 range.flags = priv->flags; 27 range.flags = priv->flags;
29 28
30 verdict = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum, 29 regs->verdict.code = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum,
31 &range, pkt->out); 30 &range, pkt->out);
32
33 data[NFT_REG_VERDICT].verdict = verdict;
34} 31}
35 32
36static struct nft_expr_type nft_masq_ipv4_type; 33static struct nft_expr_type nft_masq_ipv4_type;
diff --git a/net/ipv4/netfilter/nft_redir_ipv4.c b/net/ipv4/netfilter/nft_redir_ipv4.c
index 6ecfce63201a..d8d795df9c13 100644
--- a/net/ipv4/netfilter/nft_redir_ipv4.c
+++ b/net/ipv4/netfilter/nft_redir_ipv4.c
@@ -18,26 +18,25 @@
18#include <net/netfilter/nft_redir.h> 18#include <net/netfilter/nft_redir.h>
19 19
20static void nft_redir_ipv4_eval(const struct nft_expr *expr, 20static void nft_redir_ipv4_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 struct nft_redir *priv = nft_expr_priv(expr); 24 struct nft_redir *priv = nft_expr_priv(expr);
25 struct nf_nat_ipv4_multi_range_compat mr; 25 struct nf_nat_ipv4_multi_range_compat mr;
26 unsigned int verdict;
27 26
28 memset(&mr, 0, sizeof(mr)); 27 memset(&mr, 0, sizeof(mr));
29 if (priv->sreg_proto_min) { 28 if (priv->sreg_proto_min) {
30 mr.range[0].min.all = 29 mr.range[0].min.all =
31 *(__be16 *)&data[priv->sreg_proto_min].data[0]; 30 *(__be16 *)&regs->data[priv->sreg_proto_min];
32 mr.range[0].max.all = 31 mr.range[0].max.all =
33 *(__be16 *)&data[priv->sreg_proto_max].data[0]; 32 *(__be16 *)&regs->data[priv->sreg_proto_max];
34 mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED; 33 mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
35 } 34 }
36 35
37 mr.range[0].flags |= priv->flags; 36 mr.range[0].flags |= priv->flags;
38 37
39 verdict = nf_nat_redirect_ipv4(pkt->skb, &mr, pkt->ops->hooknum); 38 regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &mr,
40 data[NFT_REG_VERDICT].verdict = verdict; 39 pkt->ops->hooknum);
41} 40}
42 41
43static struct nft_expr_type nft_redir_ipv4_type; 42static struct nft_expr_type nft_redir_ipv4_type;
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c
index a7621faa9678..b07e58b51158 100644
--- a/net/ipv4/netfilter/nft_reject_ipv4.c
+++ b/net/ipv4/netfilter/nft_reject_ipv4.c
@@ -20,7 +20,7 @@
20#include <net/netfilter/nft_reject.h> 20#include <net/netfilter/nft_reject.h>
21 21
22static void nft_reject_ipv4_eval(const struct nft_expr *expr, 22static void nft_reject_ipv4_eval(const struct nft_expr *expr,
23 struct nft_data data[NFT_REG_MAX + 1], 23 struct nft_regs *regs,
24 const struct nft_pktinfo *pkt) 24 const struct nft_pktinfo *pkt)
25{ 25{
26 struct nft_reject *priv = nft_expr_priv(expr); 26 struct nft_reject *priv = nft_expr_priv(expr);
@@ -37,7 +37,7 @@ static void nft_reject_ipv4_eval(const struct nft_expr *expr,
37 break; 37 break;
38 } 38 }
39 39
40 data[NFT_REG_VERDICT].verdict = NF_DROP; 40 regs->verdict.code = NF_DROP;
41} 41}
42 42
43static struct nft_expr_type nft_reject_ipv4_type; 43static struct nft_expr_type nft_reject_ipv4_type;
diff --git a/net/ipv6/netfilter/nft_masq_ipv6.c b/net/ipv6/netfilter/nft_masq_ipv6.c
index 529c119cbb14..cd1ac1637a05 100644
--- a/net/ipv6/netfilter/nft_masq_ipv6.c
+++ b/net/ipv6/netfilter/nft_masq_ipv6.c
@@ -18,19 +18,16 @@
18#include <net/netfilter/ipv6/nf_nat_masquerade.h> 18#include <net/netfilter/ipv6/nf_nat_masquerade.h>
19 19
20static void nft_masq_ipv6_eval(const struct nft_expr *expr, 20static void nft_masq_ipv6_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 struct nft_masq *priv = nft_expr_priv(expr); 24 struct nft_masq *priv = nft_expr_priv(expr);
25 struct nf_nat_range range; 25 struct nf_nat_range range;
26 unsigned int verdict;
27 26
28 memset(&range, 0, sizeof(range)); 27 memset(&range, 0, sizeof(range));
29 range.flags = priv->flags; 28 range.flags = priv->flags;
30 29
31 verdict = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out); 30 regs->verdict.code = nf_nat_masquerade_ipv6(pkt->skb, &range, pkt->out);
32
33 data[NFT_REG_VERDICT].verdict = verdict;
34} 31}
35 32
36static struct nft_expr_type nft_masq_ipv6_type; 33static struct nft_expr_type nft_masq_ipv6_type;
diff --git a/net/ipv6/netfilter/nft_redir_ipv6.c b/net/ipv6/netfilter/nft_redir_ipv6.c
index 11820b6b3613..effd393bd517 100644
--- a/net/ipv6/netfilter/nft_redir_ipv6.c
+++ b/net/ipv6/netfilter/nft_redir_ipv6.c
@@ -18,26 +18,25 @@
18#include <net/netfilter/nf_nat_redirect.h> 18#include <net/netfilter/nf_nat_redirect.h>
19 19
20static void nft_redir_ipv6_eval(const struct nft_expr *expr, 20static void nft_redir_ipv6_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 struct nft_redir *priv = nft_expr_priv(expr); 24 struct nft_redir *priv = nft_expr_priv(expr);
25 struct nf_nat_range range; 25 struct nf_nat_range range;
26 unsigned int verdict;
27 26
28 memset(&range, 0, sizeof(range)); 27 memset(&range, 0, sizeof(range));
29 if (priv->sreg_proto_min) { 28 if (priv->sreg_proto_min) {
30 range.min_proto.all = 29 range.min_proto.all =
31 *(__be16 *)&data[priv->sreg_proto_min].data[0]; 30 *(__be16 *)&regs->data[priv->sreg_proto_min],
32 range.max_proto.all = 31 range.max_proto.all =
33 *(__be16 *)&data[priv->sreg_proto_max].data[0]; 32 *(__be16 *)&regs->data[priv->sreg_proto_max],
34 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; 33 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
35 } 34 }
36 35
37 range.flags |= priv->flags; 36 range.flags |= priv->flags;
38 37
39 verdict = nf_nat_redirect_ipv6(pkt->skb, &range, pkt->ops->hooknum); 38 regs->verdict.code = nf_nat_redirect_ipv6(pkt->skb, &range,
40 data[NFT_REG_VERDICT].verdict = verdict; 39 pkt->ops->hooknum);
41} 40}
42 41
43static struct nft_expr_type nft_redir_ipv6_type; 42static struct nft_expr_type nft_redir_ipv6_type;
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c
index 71c7be5ee43a..d0d1540ecf87 100644
--- a/net/ipv6/netfilter/nft_reject_ipv6.c
+++ b/net/ipv6/netfilter/nft_reject_ipv6.c
@@ -20,7 +20,7 @@
20#include <net/netfilter/ipv6/nf_reject.h> 20#include <net/netfilter/ipv6/nf_reject.h>
21 21
22static void nft_reject_ipv6_eval(const struct nft_expr *expr, 22static void nft_reject_ipv6_eval(const struct nft_expr *expr,
23 struct nft_data data[NFT_REG_MAX + 1], 23 struct nft_regs *regs,
24 const struct nft_pktinfo *pkt) 24 const struct nft_pktinfo *pkt)
25{ 25{
26 struct nft_reject *priv = nft_expr_priv(expr); 26 struct nft_reject *priv = nft_expr_priv(expr);
@@ -38,7 +38,7 @@ static void nft_reject_ipv6_eval(const struct nft_expr *expr,
38 break; 38 break;
39 } 39 }
40 40
41 data[NFT_REG_VERDICT].verdict = NF_DROP; 41 regs->verdict.code = NF_DROP;
42} 42}
43 43
44static struct nft_expr_type nft_reject_ipv6_type; 44static struct nft_expr_type nft_reject_ipv6_type;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 0b96fa0d64b2..78af83bc9c8e 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1545,6 +1545,23 @@ nla_put_failure:
1545 return -1; 1545 return -1;
1546}; 1546};
1547 1547
1548int nft_expr_dump(struct sk_buff *skb, unsigned int attr,
1549 const struct nft_expr *expr)
1550{
1551 struct nlattr *nest;
1552
1553 nest = nla_nest_start(skb, attr);
1554 if (!nest)
1555 goto nla_put_failure;
1556 if (nf_tables_fill_expr_info(skb, expr) < 0)
1557 goto nla_put_failure;
1558 nla_nest_end(skb, nest);
1559 return 0;
1560
1561nla_put_failure:
1562 return -1;
1563}
1564
1548struct nft_expr_info { 1565struct nft_expr_info {
1549 const struct nft_expr_ops *ops; 1566 const struct nft_expr_ops *ops;
1550 struct nlattr *tb[NFT_EXPR_MAXATTR + 1]; 1567 struct nlattr *tb[NFT_EXPR_MAXATTR + 1];
@@ -1622,6 +1639,39 @@ static void nf_tables_expr_destroy(const struct nft_ctx *ctx,
1622 module_put(expr->ops->type->owner); 1639 module_put(expr->ops->type->owner);
1623} 1640}
1624 1641
1642struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
1643 const struct nlattr *nla)
1644{
1645 struct nft_expr_info info;
1646 struct nft_expr *expr;
1647 int err;
1648
1649 err = nf_tables_expr_parse(ctx, nla, &info);
1650 if (err < 0)
1651 goto err1;
1652
1653 err = -ENOMEM;
1654 expr = kzalloc(info.ops->size, GFP_KERNEL);
1655 if (expr == NULL)
1656 goto err2;
1657
1658 err = nf_tables_newexpr(ctx, &info, expr);
1659 if (err < 0)
1660 goto err2;
1661
1662 return expr;
1663err2:
1664 module_put(info.ops->type->owner);
1665err1:
1666 return ERR_PTR(err);
1667}
1668
1669void nft_expr_destroy(const struct nft_ctx *ctx, struct nft_expr *expr)
1670{
1671 nf_tables_expr_destroy(ctx, expr);
1672 kfree(expr);
1673}
1674
1625/* 1675/*
1626 * Rules 1676 * Rules
1627 */ 1677 */
@@ -1703,12 +1753,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
1703 if (list == NULL) 1753 if (list == NULL)
1704 goto nla_put_failure; 1754 goto nla_put_failure;
1705 nft_rule_for_each_expr(expr, next, rule) { 1755 nft_rule_for_each_expr(expr, next, rule) {
1706 struct nlattr *elem = nla_nest_start(skb, NFTA_LIST_ELEM); 1756 if (nft_expr_dump(skb, NFTA_LIST_ELEM, expr) < 0)
1707 if (elem == NULL)
1708 goto nla_put_failure; 1757 goto nla_put_failure;
1709 if (nf_tables_fill_expr_info(skb, expr) < 0)
1710 goto nla_put_failure;
1711 nla_nest_end(skb, elem);
1712 } 1758 }
1713 nla_nest_end(skb, list); 1759 nla_nest_end(skb, list);
1714 1760
@@ -2608,16 +2654,20 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2608 } 2654 }
2609 2655
2610 desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN])); 2656 desc.klen = ntohl(nla_get_be32(nla[NFTA_SET_KEY_LEN]));
2611 if (desc.klen == 0 || desc.klen > FIELD_SIZEOF(struct nft_data, data)) 2657 if (desc.klen == 0 || desc.klen > NFT_DATA_VALUE_MAXLEN)
2612 return -EINVAL; 2658 return -EINVAL;
2613 2659
2614 flags = 0; 2660 flags = 0;
2615 if (nla[NFTA_SET_FLAGS] != NULL) { 2661 if (nla[NFTA_SET_FLAGS] != NULL) {
2616 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS])); 2662 flags = ntohl(nla_get_be32(nla[NFTA_SET_FLAGS]));
2617 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT | 2663 if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
2618 NFT_SET_INTERVAL | NFT_SET_MAP | 2664 NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
2619 NFT_SET_TIMEOUT)) 2665 NFT_SET_MAP | NFT_SET_EVAL))
2620 return -EINVAL; 2666 return -EINVAL;
2667 /* Only one of both operations is supported */
2668 if ((flags & (NFT_SET_MAP | NFT_SET_EVAL)) ==
2669 (NFT_SET_MAP | NFT_SET_EVAL))
2670 return -EOPNOTSUPP;
2621 } 2671 }
2622 2672
2623 dtype = 0; 2673 dtype = 0;
@@ -2634,11 +2684,10 @@ static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
2634 if (nla[NFTA_SET_DATA_LEN] == NULL) 2684 if (nla[NFTA_SET_DATA_LEN] == NULL)
2635 return -EINVAL; 2685 return -EINVAL;
2636 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN])); 2686 desc.dlen = ntohl(nla_get_be32(nla[NFTA_SET_DATA_LEN]));
2637 if (desc.dlen == 0 || 2687 if (desc.dlen == 0 || desc.dlen > NFT_DATA_VALUE_MAXLEN)
2638 desc.dlen > FIELD_SIZEOF(struct nft_data, data))
2639 return -EINVAL; 2688 return -EINVAL;
2640 } else 2689 } else
2641 desc.dlen = sizeof(struct nft_data); 2690 desc.dlen = sizeof(struct nft_verdict);
2642 } else if (flags & NFT_SET_MAP) 2691 } else if (flags & NFT_SET_MAP)
2643 return -EINVAL; 2692 return -EINVAL;
2644 2693
@@ -2797,9 +2846,10 @@ static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,
2797 enum nft_registers dreg; 2846 enum nft_registers dreg;
2798 2847
2799 dreg = nft_type_to_reg(set->dtype); 2848 dreg = nft_type_to_reg(set->dtype);
2800 return nft_validate_data_load(ctx, dreg, nft_set_ext_data(ext), 2849 return nft_validate_register_store(ctx, dreg, nft_set_ext_data(ext),
2801 set->dtype == NFT_DATA_VERDICT ? 2850 set->dtype == NFT_DATA_VERDICT ?
2802 NFT_DATA_VERDICT : NFT_DATA_VALUE); 2851 NFT_DATA_VERDICT : NFT_DATA_VALUE,
2852 set->dlen);
2803} 2853}
2804 2854
2805int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set, 2855int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
@@ -2853,12 +2903,13 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
2853 2903
2854const struct nft_set_ext_type nft_set_ext_types[] = { 2904const struct nft_set_ext_type nft_set_ext_types[] = {
2855 [NFT_SET_EXT_KEY] = { 2905 [NFT_SET_EXT_KEY] = {
2856 .len = sizeof(struct nft_data), 2906 .align = __alignof__(u32),
2857 .align = __alignof__(struct nft_data),
2858 }, 2907 },
2859 [NFT_SET_EXT_DATA] = { 2908 [NFT_SET_EXT_DATA] = {
2860 .len = sizeof(struct nft_data), 2909 .align = __alignof__(u32),
2861 .align = __alignof__(struct nft_data), 2910 },
2911 [NFT_SET_EXT_EXPR] = {
2912 .align = __alignof__(struct nft_expr),
2862 }, 2913 },
2863 [NFT_SET_EXT_FLAGS] = { 2914 [NFT_SET_EXT_FLAGS] = {
2864 .len = sizeof(u8), 2915 .len = sizeof(u8),
@@ -2946,6 +2997,10 @@ static int nf_tables_fill_setelem(struct sk_buff *skb,
2946 set->dlen) < 0) 2997 set->dlen) < 0)
2947 goto nla_put_failure; 2998 goto nla_put_failure;
2948 2999
3000 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) &&
3001 nft_expr_dump(skb, NFTA_SET_ELEM_EXPR, nft_set_ext_expr(ext)) < 0)
3002 goto nla_put_failure;
3003
2949 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) && 3004 if (nft_set_ext_exists(ext, NFT_SET_EXT_FLAGS) &&
2950 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS, 3005 nla_put_be32(skb, NFTA_SET_ELEM_FLAGS,
2951 htonl(*nft_set_ext_flags(ext)))) 3006 htonl(*nft_set_ext_flags(ext))))
@@ -3200,8 +3255,7 @@ static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
3200 3255
3201void *nft_set_elem_init(const struct nft_set *set, 3256void *nft_set_elem_init(const struct nft_set *set,
3202 const struct nft_set_ext_tmpl *tmpl, 3257 const struct nft_set_ext_tmpl *tmpl,
3203 const struct nft_data *key, 3258 const u32 *key, const u32 *data,
3204 const struct nft_data *data,
3205 u64 timeout, gfp_t gfp) 3259 u64 timeout, gfp_t gfp)
3206{ 3260{
3207 struct nft_set_ext *ext; 3261 struct nft_set_ext *ext;
@@ -3233,6 +3287,8 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem)
3233 nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE); 3287 nft_data_uninit(nft_set_ext_key(ext), NFT_DATA_VALUE);
3234 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) 3288 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA))
3235 nft_data_uninit(nft_set_ext_data(ext), set->dtype); 3289 nft_data_uninit(nft_set_ext_data(ext), set->dtype);
3290 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
3291 nf_tables_expr_destroy(NULL, nft_set_ext_expr(ext));
3236 3292
3237 kfree(elem); 3293 kfree(elem);
3238} 3294}
@@ -3299,14 +3355,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3299 timeout = set->timeout; 3355 timeout = set->timeout;
3300 } 3356 }
3301 3357
3302 err = nft_data_init(ctx, &elem.key, &d1, nla[NFTA_SET_ELEM_KEY]); 3358 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
3359 nla[NFTA_SET_ELEM_KEY]);
3303 if (err < 0) 3360 if (err < 0)
3304 goto err1; 3361 goto err1;
3305 err = -EINVAL; 3362 err = -EINVAL;
3306 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen) 3363 if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
3307 goto err2; 3364 goto err2;
3308 3365
3309 nft_set_ext_add(&tmpl, NFT_SET_EXT_KEY); 3366 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
3310 if (timeout > 0) { 3367 if (timeout > 0) {
3311 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION); 3368 nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
3312 if (timeout != set->timeout) 3369 if (timeout != set->timeout)
@@ -3314,7 +3371,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3314 } 3371 }
3315 3372
3316 if (nla[NFTA_SET_ELEM_DATA] != NULL) { 3373 if (nla[NFTA_SET_ELEM_DATA] != NULL) {
3317 err = nft_data_init(ctx, &data, &d2, nla[NFTA_SET_ELEM_DATA]); 3374 err = nft_data_init(ctx, &data, sizeof(data), &d2,
3375 nla[NFTA_SET_ELEM_DATA]);
3318 if (err < 0) 3376 if (err < 0)
3319 goto err2; 3377 goto err2;
3320 3378
@@ -3333,13 +3391,14 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3333 if (!(binding->flags & NFT_SET_MAP)) 3391 if (!(binding->flags & NFT_SET_MAP))
3334 continue; 3392 continue;
3335 3393
3336 err = nft_validate_data_load(&bind_ctx, dreg, 3394 err = nft_validate_register_store(&bind_ctx, dreg,
3337 &data, d2.type); 3395 &data,
3396 d2.type, d2.len);
3338 if (err < 0) 3397 if (err < 0)
3339 goto err3; 3398 goto err3;
3340 } 3399 }
3341 3400
3342 nft_set_ext_add(&tmpl, NFT_SET_EXT_DATA); 3401 nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
3343 } 3402 }
3344 3403
3345 /* The full maximum length of userdata can exceed the maximum 3404 /* The full maximum length of userdata can exceed the maximum
@@ -3355,7 +3414,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
3355 } 3414 }
3356 3415
3357 err = -ENOMEM; 3416 err = -ENOMEM;
3358 elem.priv = nft_set_elem_init(set, &tmpl, &elem.key, &data, 3417 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
3359 timeout, GFP_KERNEL); 3418 timeout, GFP_KERNEL);
3360 if (elem.priv == NULL) 3419 if (elem.priv == NULL)
3361 goto err3; 3420 goto err3;
@@ -3390,7 +3449,7 @@ err3:
3390 if (nla[NFTA_SET_ELEM_DATA] != NULL) 3449 if (nla[NFTA_SET_ELEM_DATA] != NULL)
3391 nft_data_uninit(&data, d2.type); 3450 nft_data_uninit(&data, d2.type);
3392err2: 3451err2:
3393 nft_data_uninit(&elem.key, d1.type); 3452 nft_data_uninit(&elem.key.val, d1.type);
3394err1: 3453err1:
3395 return err; 3454 return err;
3396} 3455}
@@ -3457,7 +3516,8 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
3457 if (nla[NFTA_SET_ELEM_KEY] == NULL) 3516 if (nla[NFTA_SET_ELEM_KEY] == NULL)
3458 goto err1; 3517 goto err1;
3459 3518
3460 err = nft_data_init(ctx, &elem.key, &desc, nla[NFTA_SET_ELEM_KEY]); 3519 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
3520 nla[NFTA_SET_ELEM_KEY]);
3461 if (err < 0) 3521 if (err < 0)
3462 goto err1; 3522 goto err1;
3463 3523
@@ -3484,7 +3544,7 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
3484err3: 3544err3:
3485 kfree(trans); 3545 kfree(trans);
3486err2: 3546err2:
3487 nft_data_uninit(&elem.key, desc.type); 3547 nft_data_uninit(&elem.key.val, desc.type);
3488err1: 3548err1:
3489 return err; 3549 return err;
3490} 3550}
@@ -4047,10 +4107,10 @@ static int nf_tables_loop_check_setelem(const struct nft_ctx *ctx,
4047 return 0; 4107 return 0;
4048 4108
4049 data = nft_set_ext_data(ext); 4109 data = nft_set_ext_data(ext);
4050 switch (data->verdict) { 4110 switch (data->verdict.code) {
4051 case NFT_JUMP: 4111 case NFT_JUMP:
4052 case NFT_GOTO: 4112 case NFT_GOTO:
4053 return nf_tables_check_loops(ctx, data->chain); 4113 return nf_tables_check_loops(ctx, data->verdict.chain);
4054 default: 4114 default:
4055 return 0; 4115 return 0;
4056 } 4116 }
@@ -4083,10 +4143,11 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
4083 if (data == NULL) 4143 if (data == NULL)
4084 continue; 4144 continue;
4085 4145
4086 switch (data->verdict) { 4146 switch (data->verdict.code) {
4087 case NFT_JUMP: 4147 case NFT_JUMP:
4088 case NFT_GOTO: 4148 case NFT_GOTO:
4089 err = nf_tables_check_loops(ctx, data->chain); 4149 err = nf_tables_check_loops(ctx,
4150 data->verdict.chain);
4090 if (err < 0) 4151 if (err < 0)
4091 return err; 4152 return err;
4092 default: 4153 default:
@@ -4120,85 +4181,129 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
4120} 4181}
4121 4182
4122/** 4183/**
4123 * nft_validate_input_register - validate an expressions' input register 4184 * nft_parse_register - parse a register value from a netlink attribute
4124 * 4185 *
4125 * @reg: the register number 4186 * @attr: netlink attribute
4126 * 4187 *
4127 * Validate that the input register is one of the general purpose 4188 * Parse and translate a register value from a netlink attribute.
4128 * registers. 4189 * Registers used to be 128 bit wide, these register numbers will be
4190 * mapped to the corresponding 32 bit register numbers.
4129 */ 4191 */
4130int nft_validate_input_register(enum nft_registers reg) 4192unsigned int nft_parse_register(const struct nlattr *attr)
4131{ 4193{
4132 if (reg <= NFT_REG_VERDICT) 4194 unsigned int reg;
4133 return -EINVAL; 4195
4134 if (reg > NFT_REG_MAX) 4196 reg = ntohl(nla_get_be32(attr));
4135 return -ERANGE; 4197 switch (reg) {
4136 return 0; 4198 case NFT_REG_VERDICT...NFT_REG_4:
4199 return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
4200 default:
4201 return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
4202 }
4137} 4203}
4138EXPORT_SYMBOL_GPL(nft_validate_input_register); 4204EXPORT_SYMBOL_GPL(nft_parse_register);
4139 4205
4140/** 4206/**
4141 * nft_validate_output_register - validate an expressions' output register 4207 * nft_dump_register - dump a register value to a netlink attribute
4208 *
4209 * @skb: socket buffer
4210 * @attr: attribute number
4211 * @reg: register number
4212 *
4213 * Construct a netlink attribute containing the register number. For
4214 * compatibility reasons, register numbers being a multiple of 4 are
4215 * translated to the corresponding 128 bit register numbers.
4216 */
4217int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg)
4218{
4219 if (reg % (NFT_REG_SIZE / NFT_REG32_SIZE) == 0)
4220 reg = reg / (NFT_REG_SIZE / NFT_REG32_SIZE);
4221 else
4222 reg = reg - NFT_REG_SIZE / NFT_REG32_SIZE + NFT_REG32_00;
4223
4224 return nla_put_be32(skb, attr, htonl(reg));
4225}
4226EXPORT_SYMBOL_GPL(nft_dump_register);
4227
4228/**
4229 * nft_validate_register_load - validate a load from a register
4142 * 4230 *
4143 * @reg: the register number 4231 * @reg: the register number
4232 * @len: the length of the data
4144 * 4233 *
4145 * Validate that the output register is one of the general purpose 4234 * Validate that the input register is one of the general purpose
4146 * registers or the verdict register. 4235 * registers and that the length of the load is within the bounds.
4147 */ 4236 */
4148int nft_validate_output_register(enum nft_registers reg) 4237int nft_validate_register_load(enum nft_registers reg, unsigned int len)
4149{ 4238{
4150 if (reg < NFT_REG_VERDICT) 4239 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
4240 return -EINVAL;
4241 if (len == 0)
4151 return -EINVAL; 4242 return -EINVAL;
4152 if (reg > NFT_REG_MAX) 4243 if (reg * NFT_REG32_SIZE + len > FIELD_SIZEOF(struct nft_regs, data))
4153 return -ERANGE; 4244 return -ERANGE;
4245
4154 return 0; 4246 return 0;
4155} 4247}
4156EXPORT_SYMBOL_GPL(nft_validate_output_register); 4248EXPORT_SYMBOL_GPL(nft_validate_register_load);
4157 4249
4158/** 4250/**
4159 * nft_validate_data_load - validate an expressions' data load 4251 * nft_validate_register_store - validate an expressions' register store
4160 * 4252 *
4161 * @ctx: context of the expression performing the load 4253 * @ctx: context of the expression performing the load
4162 * @reg: the destination register number 4254 * @reg: the destination register number
4163 * @data: the data to load 4255 * @data: the data to load
4164 * @type: the data type 4256 * @type: the data type
4257 * @len: the length of the data
4165 * 4258 *
4166 * Validate that a data load uses the appropriate data type for 4259 * Validate that a data load uses the appropriate data type for
4167 * the destination register. A value of NULL for the data means 4260 * the destination register and the length is within the bounds.
4168 * that its runtime gathered data, which is always of type 4261 * A value of NULL for the data means that its runtime gathered
4169 * NFT_DATA_VALUE. 4262 * data.
4170 */ 4263 */
4171int nft_validate_data_load(const struct nft_ctx *ctx, enum nft_registers reg, 4264int nft_validate_register_store(const struct nft_ctx *ctx,
4172 const struct nft_data *data, 4265 enum nft_registers reg,
4173 enum nft_data_types type) 4266 const struct nft_data *data,
4267 enum nft_data_types type, unsigned int len)
4174{ 4268{
4175 int err; 4269 int err;
4176 4270
4177 switch (reg) { 4271 switch (reg) {
4178 case NFT_REG_VERDICT: 4272 case NFT_REG_VERDICT:
4179 if (data == NULL || type != NFT_DATA_VERDICT) 4273 if (type != NFT_DATA_VERDICT)
4180 return -EINVAL; 4274 return -EINVAL;
4181 4275
4182 if (data->verdict == NFT_GOTO || data->verdict == NFT_JUMP) { 4276 if (data != NULL &&
4183 err = nf_tables_check_loops(ctx, data->chain); 4277 (data->verdict.code == NFT_GOTO ||
4278 data->verdict.code == NFT_JUMP)) {
4279 err = nf_tables_check_loops(ctx, data->verdict.chain);
4184 if (err < 0) 4280 if (err < 0)
4185 return err; 4281 return err;
4186 4282
4187 if (ctx->chain->level + 1 > data->chain->level) { 4283 if (ctx->chain->level + 1 >
4284 data->verdict.chain->level) {
4188 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE) 4285 if (ctx->chain->level + 1 == NFT_JUMP_STACK_SIZE)
4189 return -EMLINK; 4286 return -EMLINK;
4190 data->chain->level = ctx->chain->level + 1; 4287 data->verdict.chain->level = ctx->chain->level + 1;
4191 } 4288 }
4192 } 4289 }
4193 4290
4194 return 0; 4291 return 0;
4195 default: 4292 default:
4293 if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE)
4294 return -EINVAL;
4295 if (len == 0)
4296 return -EINVAL;
4297 if (reg * NFT_REG32_SIZE + len >
4298 FIELD_SIZEOF(struct nft_regs, data))
4299 return -ERANGE;
4300
4196 if (data != NULL && type != NFT_DATA_VALUE) 4301 if (data != NULL && type != NFT_DATA_VALUE)
4197 return -EINVAL; 4302 return -EINVAL;
4198 return 0; 4303 return 0;
4199 } 4304 }
4200} 4305}
4201EXPORT_SYMBOL_GPL(nft_validate_data_load); 4306EXPORT_SYMBOL_GPL(nft_validate_register_store);
4202 4307
4203static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = { 4308static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX + 1] = {
4204 [NFTA_VERDICT_CODE] = { .type = NLA_U32 }, 4309 [NFTA_VERDICT_CODE] = { .type = NLA_U32 },
@@ -4219,11 +4324,11 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
4219 4324
4220 if (!tb[NFTA_VERDICT_CODE]) 4325 if (!tb[NFTA_VERDICT_CODE])
4221 return -EINVAL; 4326 return -EINVAL;
4222 data->verdict = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE])); 4327 data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));
4223 4328
4224 switch (data->verdict) { 4329 switch (data->verdict.code) {
4225 default: 4330 default:
4226 switch (data->verdict & NF_VERDICT_MASK) { 4331 switch (data->verdict.code & NF_VERDICT_MASK) {
4227 case NF_ACCEPT: 4332 case NF_ACCEPT:
4228 case NF_DROP: 4333 case NF_DROP:
4229 case NF_QUEUE: 4334 case NF_QUEUE:
@@ -4249,7 +4354,7 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
4249 return -EOPNOTSUPP; 4354 return -EOPNOTSUPP;
4250 4355
4251 chain->use++; 4356 chain->use++;
4252 data->chain = chain; 4357 data->verdict.chain = chain;
4253 desc->len = sizeof(data); 4358 desc->len = sizeof(data);
4254 break; 4359 break;
4255 } 4360 }
@@ -4260,10 +4365,10 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
4260 4365
4261static void nft_verdict_uninit(const struct nft_data *data) 4366static void nft_verdict_uninit(const struct nft_data *data)
4262{ 4367{
4263 switch (data->verdict) { 4368 switch (data->verdict.code) {
4264 case NFT_JUMP: 4369 case NFT_JUMP:
4265 case NFT_GOTO: 4370 case NFT_GOTO:
4266 data->chain->use--; 4371 data->verdict.chain->use--;
4267 break; 4372 break;
4268 } 4373 }
4269} 4374}
@@ -4276,13 +4381,14 @@ static int nft_verdict_dump(struct sk_buff *skb, const struct nft_data *data)
4276 if (!nest) 4381 if (!nest)
4277 goto nla_put_failure; 4382 goto nla_put_failure;
4278 4383
4279 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict))) 4384 if (nla_put_be32(skb, NFTA_VERDICT_CODE, htonl(data->verdict.code)))
4280 goto nla_put_failure; 4385 goto nla_put_failure;
4281 4386
4282 switch (data->verdict) { 4387 switch (data->verdict.code) {
4283 case NFT_JUMP: 4388 case NFT_JUMP:
4284 case NFT_GOTO: 4389 case NFT_GOTO:
4285 if (nla_put_string(skb, NFTA_VERDICT_CHAIN, data->chain->name)) 4390 if (nla_put_string(skb, NFTA_VERDICT_CHAIN,
4391 data->verdict.chain->name))
4286 goto nla_put_failure; 4392 goto nla_put_failure;
4287 } 4393 }
4288 nla_nest_end(skb, nest); 4394 nla_nest_end(skb, nest);
@@ -4292,7 +4398,8 @@ nla_put_failure:
4292 return -1; 4398 return -1;
4293} 4399}
4294 4400
4295static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data, 4401static int nft_value_init(const struct nft_ctx *ctx,
4402 struct nft_data *data, unsigned int size,
4296 struct nft_data_desc *desc, const struct nlattr *nla) 4403 struct nft_data_desc *desc, const struct nlattr *nla)
4297{ 4404{
4298 unsigned int len; 4405 unsigned int len;
@@ -4300,10 +4407,10 @@ static int nft_value_init(const struct nft_ctx *ctx, struct nft_data *data,
4300 len = nla_len(nla); 4407 len = nla_len(nla);
4301 if (len == 0) 4408 if (len == 0)
4302 return -EINVAL; 4409 return -EINVAL;
4303 if (len > sizeof(data->data)) 4410 if (len > size)
4304 return -EOVERFLOW; 4411 return -EOVERFLOW;
4305 4412
4306 nla_memcpy(data->data, nla, sizeof(data->data)); 4413 nla_memcpy(data->data, nla, len);
4307 desc->type = NFT_DATA_VALUE; 4414 desc->type = NFT_DATA_VALUE;
4308 desc->len = len; 4415 desc->len = len;
4309 return 0; 4416 return 0;
@@ -4316,8 +4423,7 @@ static int nft_value_dump(struct sk_buff *skb, const struct nft_data *data,
4316} 4423}
4317 4424
4318static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = { 4425static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
4319 [NFTA_DATA_VALUE] = { .type = NLA_BINARY, 4426 [NFTA_DATA_VALUE] = { .type = NLA_BINARY },
4320 .len = FIELD_SIZEOF(struct nft_data, data) },
4321 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED }, 4427 [NFTA_DATA_VERDICT] = { .type = NLA_NESTED },
4322}; 4428};
4323 4429
@@ -4326,6 +4432,7 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
4326 * 4432 *
4327 * @ctx: context of the expression using the data 4433 * @ctx: context of the expression using the data
4328 * @data: destination struct nft_data 4434 * @data: destination struct nft_data
4435 * @size: maximum data length
4329 * @desc: data description 4436 * @desc: data description
4330 * @nla: netlink attribute containing data 4437 * @nla: netlink attribute containing data
4331 * 4438 *
@@ -4335,7 +4442,8 @@ static const struct nla_policy nft_data_policy[NFTA_DATA_MAX + 1] = {
4335 * The caller can indicate that it only wants to accept data of type 4442 * The caller can indicate that it only wants to accept data of type
4336 * NFT_DATA_VALUE by passing NULL for the ctx argument. 4443 * NFT_DATA_VALUE by passing NULL for the ctx argument.
4337 */ 4444 */
4338int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data, 4445int nft_data_init(const struct nft_ctx *ctx,
4446 struct nft_data *data, unsigned int size,
4339 struct nft_data_desc *desc, const struct nlattr *nla) 4447 struct nft_data_desc *desc, const struct nlattr *nla)
4340{ 4448{
4341 struct nlattr *tb[NFTA_DATA_MAX + 1]; 4449 struct nlattr *tb[NFTA_DATA_MAX + 1];
@@ -4346,7 +4454,8 @@ int nft_data_init(const struct nft_ctx *ctx, struct nft_data *data,
4346 return err; 4454 return err;
4347 4455
4348 if (tb[NFTA_DATA_VALUE]) 4456 if (tb[NFTA_DATA_VALUE])
4349 return nft_value_init(ctx, data, desc, tb[NFTA_DATA_VALUE]); 4457 return nft_value_init(ctx, data, size, desc,
4458 tb[NFTA_DATA_VALUE]);
4350 if (tb[NFTA_DATA_VERDICT] && ctx != NULL) 4459 if (tb[NFTA_DATA_VERDICT] && ctx != NULL)
4351 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]); 4460 return nft_verdict_init(ctx, data, desc, tb[NFTA_DATA_VERDICT]);
4352 return -EINVAL; 4461 return -EINVAL;
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index 7caf08a9225d..f153b07073af 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -65,23 +65,23 @@ static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
65} 65}
66 66
67static void nft_cmp_fast_eval(const struct nft_expr *expr, 67static void nft_cmp_fast_eval(const struct nft_expr *expr,
68 struct nft_data data[NFT_REG_MAX + 1]) 68 struct nft_regs *regs)
69{ 69{
70 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); 70 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
71 u32 mask = nft_cmp_fast_mask(priv->len); 71 u32 mask = nft_cmp_fast_mask(priv->len);
72 72
73 if ((data[priv->sreg].data[0] & mask) == priv->data) 73 if ((regs->data[priv->sreg] & mask) == priv->data)
74 return; 74 return;
75 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 75 regs->verdict.code = NFT_BREAK;
76} 76}
77 77
78static bool nft_payload_fast_eval(const struct nft_expr *expr, 78static bool nft_payload_fast_eval(const struct nft_expr *expr,
79 struct nft_data data[NFT_REG_MAX + 1], 79 struct nft_regs *regs,
80 const struct nft_pktinfo *pkt) 80 const struct nft_pktinfo *pkt)
81{ 81{
82 const struct nft_payload *priv = nft_expr_priv(expr); 82 const struct nft_payload *priv = nft_expr_priv(expr);
83 const struct sk_buff *skb = pkt->skb; 83 const struct sk_buff *skb = pkt->skb;
84 struct nft_data *dest = &data[priv->dreg]; 84 u32 *dest = &regs->data[priv->dreg];
85 unsigned char *ptr; 85 unsigned char *ptr;
86 86
87 if (priv->base == NFT_PAYLOAD_NETWORK_HEADER) 87 if (priv->base == NFT_PAYLOAD_NETWORK_HEADER)
@@ -94,12 +94,13 @@ static bool nft_payload_fast_eval(const struct nft_expr *expr,
94 if (unlikely(ptr + priv->len >= skb_tail_pointer(skb))) 94 if (unlikely(ptr + priv->len >= skb_tail_pointer(skb)))
95 return false; 95 return false;
96 96
97 *dest = 0;
97 if (priv->len == 2) 98 if (priv->len == 2)
98 *(u16 *)dest->data = *(u16 *)ptr; 99 *(u16 *)dest = *(u16 *)ptr;
99 else if (priv->len == 4) 100 else if (priv->len == 4)
100 *(u32 *)dest->data = *(u32 *)ptr; 101 *(u32 *)dest = *(u32 *)ptr;
101 else 102 else
102 *(u8 *)dest->data = *(u8 *)ptr; 103 *(u8 *)dest = *(u8 *)ptr;
103 return true; 104 return true;
104} 105}
105 106
@@ -116,7 +117,7 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
116 const struct net *net = read_pnet(&nft_base_chain(basechain)->pnet); 117 const struct net *net = read_pnet(&nft_base_chain(basechain)->pnet);
117 const struct nft_rule *rule; 118 const struct nft_rule *rule;
118 const struct nft_expr *expr, *last; 119 const struct nft_expr *expr, *last;
119 struct nft_data data[NFT_REG_MAX + 1]; 120 struct nft_regs regs;
120 unsigned int stackptr = 0; 121 unsigned int stackptr = 0;
121 struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE]; 122 struct nft_jumpstack jumpstack[NFT_JUMP_STACK_SIZE];
122 struct nft_stats *stats; 123 struct nft_stats *stats;
@@ -127,7 +128,7 @@ do_chain:
127 rulenum = 0; 128 rulenum = 0;
128 rule = list_entry(&chain->rules, struct nft_rule, list); 129 rule = list_entry(&chain->rules, struct nft_rule, list);
129next_rule: 130next_rule:
130 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 131 regs.verdict.code = NFT_CONTINUE;
131 list_for_each_entry_continue_rcu(rule, &chain->rules, list) { 132 list_for_each_entry_continue_rcu(rule, &chain->rules, list) {
132 133
133 /* This rule is not active, skip. */ 134 /* This rule is not active, skip. */
@@ -138,18 +139,18 @@ next_rule:
138 139
139 nft_rule_for_each_expr(expr, last, rule) { 140 nft_rule_for_each_expr(expr, last, rule) {
140 if (expr->ops == &nft_cmp_fast_ops) 141 if (expr->ops == &nft_cmp_fast_ops)
141 nft_cmp_fast_eval(expr, data); 142 nft_cmp_fast_eval(expr, &regs);
142 else if (expr->ops != &nft_payload_fast_ops || 143 else if (expr->ops != &nft_payload_fast_ops ||
143 !nft_payload_fast_eval(expr, data, pkt)) 144 !nft_payload_fast_eval(expr, &regs, pkt))
144 expr->ops->eval(expr, data, pkt); 145 expr->ops->eval(expr, &regs, pkt);
145 146
146 if (data[NFT_REG_VERDICT].verdict != NFT_CONTINUE) 147 if (regs.verdict.code != NFT_CONTINUE)
147 break; 148 break;
148 } 149 }
149 150
150 switch (data[NFT_REG_VERDICT].verdict) { 151 switch (regs.verdict.code) {
151 case NFT_BREAK: 152 case NFT_BREAK:
152 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 153 regs.verdict.code = NFT_CONTINUE;
153 continue; 154 continue;
154 case NFT_CONTINUE: 155 case NFT_CONTINUE:
155 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); 156 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
@@ -158,15 +159,15 @@ next_rule:
158 break; 159 break;
159 } 160 }
160 161
161 switch (data[NFT_REG_VERDICT].verdict & NF_VERDICT_MASK) { 162 switch (regs.verdict.code & NF_VERDICT_MASK) {
162 case NF_ACCEPT: 163 case NF_ACCEPT:
163 case NF_DROP: 164 case NF_DROP:
164 case NF_QUEUE: 165 case NF_QUEUE:
165 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); 166 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
166 return data[NFT_REG_VERDICT].verdict; 167 return regs.verdict.code;
167 } 168 }
168 169
169 switch (data[NFT_REG_VERDICT].verdict) { 170 switch (regs.verdict.code) {
170 case NFT_JUMP: 171 case NFT_JUMP:
171 BUG_ON(stackptr >= NFT_JUMP_STACK_SIZE); 172 BUG_ON(stackptr >= NFT_JUMP_STACK_SIZE);
172 jumpstack[stackptr].chain = chain; 173 jumpstack[stackptr].chain = chain;
@@ -177,7 +178,7 @@ next_rule:
177 case NFT_GOTO: 178 case NFT_GOTO:
178 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE); 179 nft_trace_packet(pkt, chain, rulenum, NFT_TRACE_RULE);
179 180
180 chain = data[NFT_REG_VERDICT].chain; 181 chain = regs.verdict.chain;
181 goto do_chain; 182 goto do_chain;
182 case NFT_CONTINUE: 183 case NFT_CONTINUE:
183 rulenum++; 184 rulenum++;
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 4fb6ee2c1106..d71cc18fa35d 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -26,18 +26,16 @@ struct nft_bitwise {
26}; 26};
27 27
28static void nft_bitwise_eval(const struct nft_expr *expr, 28static void nft_bitwise_eval(const struct nft_expr *expr,
29 struct nft_data data[NFT_REG_MAX + 1], 29 struct nft_regs *regs,
30 const struct nft_pktinfo *pkt) 30 const struct nft_pktinfo *pkt)
31{ 31{
32 const struct nft_bitwise *priv = nft_expr_priv(expr); 32 const struct nft_bitwise *priv = nft_expr_priv(expr);
33 const struct nft_data *src = &data[priv->sreg]; 33 const u32 *src = &regs->data[priv->sreg];
34 struct nft_data *dst = &data[priv->dreg]; 34 u32 *dst = &regs->data[priv->dreg];
35 unsigned int i; 35 unsigned int i;
36 36
37 for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++) { 37 for (i = 0; i < DIV_ROUND_UP(priv->len, 4); i++)
38 dst->data[i] = (src->data[i] & priv->mask.data[i]) ^ 38 dst[i] = (src[i] & priv->mask.data[i]) ^ priv->xor.data[i];
39 priv->xor.data[i];
40 }
41} 39}
42 40
43static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = { 41static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
@@ -63,28 +61,27 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
63 tb[NFTA_BITWISE_XOR] == NULL) 61 tb[NFTA_BITWISE_XOR] == NULL)
64 return -EINVAL; 62 return -EINVAL;
65 63
66 priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG])); 64 priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
67 err = nft_validate_input_register(priv->sreg); 65 priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]);
66 err = nft_validate_register_load(priv->sreg, priv->len);
68 if (err < 0) 67 if (err < 0)
69 return err; 68 return err;
70 69
71 priv->dreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_DREG])); 70 priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]);
72 err = nft_validate_output_register(priv->dreg); 71 err = nft_validate_register_store(ctx, priv->dreg, NULL,
72 NFT_DATA_VALUE, priv->len);
73 if (err < 0) 73 if (err < 0)
74 return err; 74 return err;
75 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
76 if (err < 0)
77 return err;
78
79 priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
80 75
81 err = nft_data_init(NULL, &priv->mask, &d1, tb[NFTA_BITWISE_MASK]); 76 err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &d1,
77 tb[NFTA_BITWISE_MASK]);
82 if (err < 0) 78 if (err < 0)
83 return err; 79 return err;
84 if (d1.len != priv->len) 80 if (d1.len != priv->len)
85 return -EINVAL; 81 return -EINVAL;
86 82
87 err = nft_data_init(NULL, &priv->xor, &d2, tb[NFTA_BITWISE_XOR]); 83 err = nft_data_init(NULL, &priv->xor, sizeof(priv->xor), &d2,
84 tb[NFTA_BITWISE_XOR]);
88 if (err < 0) 85 if (err < 0)
89 return err; 86 return err;
90 if (d2.len != priv->len) 87 if (d2.len != priv->len)
@@ -97,9 +94,9 @@ static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr)
97{ 94{
98 const struct nft_bitwise *priv = nft_expr_priv(expr); 95 const struct nft_bitwise *priv = nft_expr_priv(expr);
99 96
100 if (nla_put_be32(skb, NFTA_BITWISE_SREG, htonl(priv->sreg))) 97 if (nft_dump_register(skb, NFTA_BITWISE_SREG, priv->sreg))
101 goto nla_put_failure; 98 goto nla_put_failure;
102 if (nla_put_be32(skb, NFTA_BITWISE_DREG, htonl(priv->dreg))) 99 if (nft_dump_register(skb, NFTA_BITWISE_DREG, priv->dreg))
103 goto nla_put_failure; 100 goto nla_put_failure;
104 if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len))) 101 if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len)))
105 goto nla_put_failure; 102 goto nla_put_failure;
diff --git a/net/netfilter/nft_byteorder.c b/net/netfilter/nft_byteorder.c
index c39ed8d29df1..fde5145f2e36 100644
--- a/net/netfilter/nft_byteorder.c
+++ b/net/netfilter/nft_byteorder.c
@@ -26,16 +26,17 @@ struct nft_byteorder {
26}; 26};
27 27
28static void nft_byteorder_eval(const struct nft_expr *expr, 28static void nft_byteorder_eval(const struct nft_expr *expr,
29 struct nft_data data[NFT_REG_MAX + 1], 29 struct nft_regs *regs,
30 const struct nft_pktinfo *pkt) 30 const struct nft_pktinfo *pkt)
31{ 31{
32 const struct nft_byteorder *priv = nft_expr_priv(expr); 32 const struct nft_byteorder *priv = nft_expr_priv(expr);
33 struct nft_data *src = &data[priv->sreg], *dst = &data[priv->dreg]; 33 u32 *src = &regs->data[priv->sreg];
34 u32 *dst = &regs->data[priv->dreg];
34 union { u32 u32; u16 u16; } *s, *d; 35 union { u32 u32; u16 u16; } *s, *d;
35 unsigned int i; 36 unsigned int i;
36 37
37 s = (void *)src->data; 38 s = (void *)src;
38 d = (void *)dst->data; 39 d = (void *)dst;
39 40
40 switch (priv->size) { 41 switch (priv->size) {
41 case 4: 42 case 4:
@@ -87,19 +88,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
87 tb[NFTA_BYTEORDER_OP] == NULL) 88 tb[NFTA_BYTEORDER_OP] == NULL)
88 return -EINVAL; 89 return -EINVAL;
89 90
90 priv->sreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SREG]));
91 err = nft_validate_input_register(priv->sreg);
92 if (err < 0)
93 return err;
94
95 priv->dreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_DREG]));
96 err = nft_validate_output_register(priv->dreg);
97 if (err < 0)
98 return err;
99 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
100 if (err < 0)
101 return err;
102
103 priv->op = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_OP])); 91 priv->op = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_OP]));
104 switch (priv->op) { 92 switch (priv->op) {
105 case NFT_BYTEORDER_NTOH: 93 case NFT_BYTEORDER_NTOH:
@@ -109,10 +97,6 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
109 return -EINVAL; 97 return -EINVAL;
110 } 98 }
111 99
112 priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
113 if (priv->len == 0 || priv->len > FIELD_SIZEOF(struct nft_data, data))
114 return -EINVAL;
115
116 priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE])); 100 priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
117 switch (priv->size) { 101 switch (priv->size) {
118 case 2: 102 case 2:
@@ -122,16 +106,24 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,
122 return -EINVAL; 106 return -EINVAL;
123 } 107 }
124 108
125 return 0; 109 priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
110 priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
111 err = nft_validate_register_load(priv->sreg, priv->len);
112 if (err < 0)
113 return err;
114
115 priv->dreg = nft_parse_register(tb[NFTA_BYTEORDER_DREG]);
116 return nft_validate_register_store(ctx, priv->dreg, NULL,
117 NFT_DATA_VALUE, priv->len);
126} 118}
127 119
128static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr) 120static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr)
129{ 121{
130 const struct nft_byteorder *priv = nft_expr_priv(expr); 122 const struct nft_byteorder *priv = nft_expr_priv(expr);
131 123
132 if (nla_put_be32(skb, NFTA_BYTEORDER_SREG, htonl(priv->sreg))) 124 if (nft_dump_register(skb, NFTA_BYTEORDER_SREG, priv->sreg))
133 goto nla_put_failure; 125 goto nla_put_failure;
134 if (nla_put_be32(skb, NFTA_BYTEORDER_DREG, htonl(priv->dreg))) 126 if (nft_dump_register(skb, NFTA_BYTEORDER_DREG, priv->dreg))
135 goto nla_put_failure; 127 goto nla_put_failure;
136 if (nla_put_be32(skb, NFTA_BYTEORDER_OP, htonl(priv->op))) 128 if (nla_put_be32(skb, NFTA_BYTEORDER_OP, htonl(priv->op)))
137 goto nla_put_failure; 129 goto nla_put_failure;
diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c
index e2b3f51c81f1..e25b35d70e4d 100644
--- a/net/netfilter/nft_cmp.c
+++ b/net/netfilter/nft_cmp.c
@@ -25,13 +25,13 @@ struct nft_cmp_expr {
25}; 25};
26 26
27static void nft_cmp_eval(const struct nft_expr *expr, 27static void nft_cmp_eval(const struct nft_expr *expr,
28 struct nft_data data[NFT_REG_MAX + 1], 28 struct nft_regs *regs,
29 const struct nft_pktinfo *pkt) 29 const struct nft_pktinfo *pkt)
30{ 30{
31 const struct nft_cmp_expr *priv = nft_expr_priv(expr); 31 const struct nft_cmp_expr *priv = nft_expr_priv(expr);
32 int d; 32 int d;
33 33
34 d = nft_data_cmp(&data[priv->sreg], &priv->data, priv->len); 34 d = memcmp(&regs->data[priv->sreg], &priv->data, priv->len);
35 switch (priv->op) { 35 switch (priv->op) {
36 case NFT_CMP_EQ: 36 case NFT_CMP_EQ:
37 if (d != 0) 37 if (d != 0)
@@ -59,7 +59,7 @@ static void nft_cmp_eval(const struct nft_expr *expr,
59 return; 59 return;
60 60
61mismatch: 61mismatch:
62 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 62 regs->verdict.code = NFT_BREAK;
63} 63}
64 64
65static const struct nla_policy nft_cmp_policy[NFTA_CMP_MAX + 1] = { 65static const struct nla_policy nft_cmp_policy[NFTA_CMP_MAX + 1] = {
@@ -75,12 +75,16 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
75 struct nft_data_desc desc; 75 struct nft_data_desc desc;
76 int err; 76 int err;
77 77
78 priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG])); 78 err = nft_data_init(NULL, &priv->data, sizeof(priv->data), &desc,
79 priv->op = ntohl(nla_get_be32(tb[NFTA_CMP_OP])); 79 tb[NFTA_CMP_DATA]);
80
81 err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]);
82 BUG_ON(err < 0); 80 BUG_ON(err < 0);
83 81
82 priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
83 err = nft_validate_register_load(priv->sreg, desc.len);
84 if (err < 0)
85 return err;
86
87 priv->op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
84 priv->len = desc.len; 88 priv->len = desc.len;
85 return 0; 89 return 0;
86} 90}
@@ -89,7 +93,7 @@ static int nft_cmp_dump(struct sk_buff *skb, const struct nft_expr *expr)
89{ 93{
90 const struct nft_cmp_expr *priv = nft_expr_priv(expr); 94 const struct nft_cmp_expr *priv = nft_expr_priv(expr);
91 95
92 if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg))) 96 if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg))
93 goto nla_put_failure; 97 goto nla_put_failure;
94 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(priv->op))) 98 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(priv->op)))
95 goto nla_put_failure; 99 goto nla_put_failure;
@@ -122,13 +126,18 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,
122 u32 mask; 126 u32 mask;
123 int err; 127 int err;
124 128
125 priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG])); 129 err = nft_data_init(NULL, &data, sizeof(data), &desc,
126 130 tb[NFTA_CMP_DATA]);
127 err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]);
128 BUG_ON(err < 0); 131 BUG_ON(err < 0);
129 desc.len *= BITS_PER_BYTE;
130 132
133 priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]);
134 err = nft_validate_register_load(priv->sreg, desc.len);
135 if (err < 0)
136 return err;
137
138 desc.len *= BITS_PER_BYTE;
131 mask = nft_cmp_fast_mask(desc.len); 139 mask = nft_cmp_fast_mask(desc.len);
140
132 priv->data = data.data[0] & mask; 141 priv->data = data.data[0] & mask;
133 priv->len = desc.len; 142 priv->len = desc.len;
134 return 0; 143 return 0;
@@ -139,7 +148,7 @@ static int nft_cmp_fast_dump(struct sk_buff *skb, const struct nft_expr *expr)
139 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); 148 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr);
140 struct nft_data data; 149 struct nft_data data;
141 150
142 if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg))) 151 if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg))
143 goto nla_put_failure; 152 goto nla_put_failure;
144 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(NFT_CMP_EQ))) 153 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(NFT_CMP_EQ)))
145 goto nla_put_failure; 154 goto nla_put_failure;
@@ -167,7 +176,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
167{ 176{
168 struct nft_data_desc desc; 177 struct nft_data_desc desc;
169 struct nft_data data; 178 struct nft_data data;
170 enum nft_registers sreg;
171 enum nft_cmp_ops op; 179 enum nft_cmp_ops op;
172 int err; 180 int err;
173 181
@@ -176,11 +184,6 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
176 tb[NFTA_CMP_DATA] == NULL) 184 tb[NFTA_CMP_DATA] == NULL)
177 return ERR_PTR(-EINVAL); 185 return ERR_PTR(-EINVAL);
178 186
179 sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
180 err = nft_validate_input_register(sreg);
181 if (err < 0)
182 return ERR_PTR(err);
183
184 op = ntohl(nla_get_be32(tb[NFTA_CMP_OP])); 187 op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
185 switch (op) { 188 switch (op) {
186 case NFT_CMP_EQ: 189 case NFT_CMP_EQ:
@@ -194,7 +197,8 @@ nft_cmp_select_ops(const struct nft_ctx *ctx, const struct nlattr * const tb[])
194 return ERR_PTR(-EINVAL); 197 return ERR_PTR(-EINVAL);
195 } 198 }
196 199
197 err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]); 200 err = nft_data_init(NULL, &data, sizeof(data), &desc,
201 tb[NFTA_CMP_DATA]);
198 if (err < 0) 202 if (err < 0)
199 return ERR_PTR(err); 203 return ERR_PTR(err);
200 204
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 0d137c1ac889..7f29cfc76349 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -55,7 +55,7 @@ nft_compat_set_par(struct xt_action_param *par, void *xt, const void *xt_info)
55} 55}
56 56
57static void nft_target_eval_xt(const struct nft_expr *expr, 57static void nft_target_eval_xt(const struct nft_expr *expr,
58 struct nft_data data[NFT_REG_MAX + 1], 58 struct nft_regs *regs,
59 const struct nft_pktinfo *pkt) 59 const struct nft_pktinfo *pkt)
60{ 60{
61 void *info = nft_expr_priv(expr); 61 void *info = nft_expr_priv(expr);
@@ -72,16 +72,16 @@ static void nft_target_eval_xt(const struct nft_expr *expr,
72 72
73 switch (ret) { 73 switch (ret) {
74 case XT_CONTINUE: 74 case XT_CONTINUE:
75 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 75 regs->verdict.code = NFT_CONTINUE;
76 break; 76 break;
77 default: 77 default:
78 data[NFT_REG_VERDICT].verdict = ret; 78 regs->verdict.code = ret;
79 break; 79 break;
80 } 80 }
81} 81}
82 82
83static void nft_target_eval_bridge(const struct nft_expr *expr, 83static void nft_target_eval_bridge(const struct nft_expr *expr,
84 struct nft_data data[NFT_REG_MAX + 1], 84 struct nft_regs *regs,
85 const struct nft_pktinfo *pkt) 85 const struct nft_pktinfo *pkt)
86{ 86{
87 void *info = nft_expr_priv(expr); 87 void *info = nft_expr_priv(expr);
@@ -98,19 +98,19 @@ static void nft_target_eval_bridge(const struct nft_expr *expr,
98 98
99 switch (ret) { 99 switch (ret) {
100 case EBT_ACCEPT: 100 case EBT_ACCEPT:
101 data[NFT_REG_VERDICT].verdict = NF_ACCEPT; 101 regs->verdict.code = NF_ACCEPT;
102 break; 102 break;
103 case EBT_DROP: 103 case EBT_DROP:
104 data[NFT_REG_VERDICT].verdict = NF_DROP; 104 regs->verdict.code = NF_DROP;
105 break; 105 break;
106 case EBT_CONTINUE: 106 case EBT_CONTINUE:
107 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 107 regs->verdict.code = NFT_CONTINUE;
108 break; 108 break;
109 case EBT_RETURN: 109 case EBT_RETURN:
110 data[NFT_REG_VERDICT].verdict = NFT_RETURN; 110 regs->verdict.code = NFT_RETURN;
111 break; 111 break;
112 default: 112 default:
113 data[NFT_REG_VERDICT].verdict = ret; 113 regs->verdict.code = ret;
114 break; 114 break;
115 } 115 }
116} 116}
@@ -304,7 +304,7 @@ static int nft_target_validate(const struct nft_ctx *ctx,
304} 304}
305 305
306static void nft_match_eval(const struct nft_expr *expr, 306static void nft_match_eval(const struct nft_expr *expr,
307 struct nft_data data[NFT_REG_MAX + 1], 307 struct nft_regs *regs,
308 const struct nft_pktinfo *pkt) 308 const struct nft_pktinfo *pkt)
309{ 309{
310 void *info = nft_expr_priv(expr); 310 void *info = nft_expr_priv(expr);
@@ -317,16 +317,16 @@ static void nft_match_eval(const struct nft_expr *expr,
317 ret = match->match(skb, (struct xt_action_param *)&pkt->xt); 317 ret = match->match(skb, (struct xt_action_param *)&pkt->xt);
318 318
319 if (pkt->xt.hotdrop) { 319 if (pkt->xt.hotdrop) {
320 data[NFT_REG_VERDICT].verdict = NF_DROP; 320 regs->verdict.code = NF_DROP;
321 return; 321 return;
322 } 322 }
323 323
324 switch (ret ? 1 : 0) { 324 switch (ret ? 1 : 0) {
325 case 1: 325 case 1:
326 data[NFT_REG_VERDICT].verdict = NFT_CONTINUE; 326 regs->verdict.code = NFT_CONTINUE;
327 break; 327 break;
328 case 0: 328 case 0:
329 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 329 regs->verdict.code = NFT_BREAK;
330 break; 330 break;
331 } 331 }
332} 332}
diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c
index c89ee486ce54..17591239229f 100644
--- a/net/netfilter/nft_counter.c
+++ b/net/netfilter/nft_counter.c
@@ -24,7 +24,7 @@ struct nft_counter {
24}; 24};
25 25
26static void nft_counter_eval(const struct nft_expr *expr, 26static void nft_counter_eval(const struct nft_expr *expr,
27 struct nft_data data[NFT_REG_MAX + 1], 27 struct nft_regs *regs,
28 const struct nft_pktinfo *pkt) 28 const struct nft_pktinfo *pkt)
29{ 29{
30 struct nft_counter *priv = nft_expr_priv(expr); 30 struct nft_counter *priv = nft_expr_priv(expr);
@@ -92,6 +92,7 @@ static struct nft_expr_type nft_counter_type __read_mostly = {
92 .ops = &nft_counter_ops, 92 .ops = &nft_counter_ops,
93 .policy = nft_counter_policy, 93 .policy = nft_counter_policy,
94 .maxattr = NFTA_COUNTER_MAX, 94 .maxattr = NFTA_COUNTER_MAX,
95 .flags = NFT_EXPR_STATEFUL,
95 .owner = THIS_MODULE, 96 .owner = THIS_MODULE,
96}; 97};
97 98
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 18d520e0ca0a..8cbca3432f90 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -31,11 +31,11 @@ struct nft_ct {
31}; 31};
32 32
33static void nft_ct_get_eval(const struct nft_expr *expr, 33static void nft_ct_get_eval(const struct nft_expr *expr,
34 struct nft_data data[NFT_REG_MAX + 1], 34 struct nft_regs *regs,
35 const struct nft_pktinfo *pkt) 35 const struct nft_pktinfo *pkt)
36{ 36{
37 const struct nft_ct *priv = nft_expr_priv(expr); 37 const struct nft_ct *priv = nft_expr_priv(expr);
38 struct nft_data *dest = &data[priv->dreg]; 38 u32 *dest = &regs->data[priv->dreg];
39 enum ip_conntrack_info ctinfo; 39 enum ip_conntrack_info ctinfo;
40 const struct nf_conn *ct; 40 const struct nf_conn *ct;
41 const struct nf_conn_help *help; 41 const struct nf_conn_help *help;
@@ -54,7 +54,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
54 state = NF_CT_STATE_UNTRACKED_BIT; 54 state = NF_CT_STATE_UNTRACKED_BIT;
55 else 55 else
56 state = NF_CT_STATE_BIT(ctinfo); 56 state = NF_CT_STATE_BIT(ctinfo);
57 dest->data[0] = state; 57 *dest = state;
58 return; 58 return;
59 default: 59 default:
60 break; 60 break;
@@ -65,26 +65,26 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
65 65
66 switch (priv->key) { 66 switch (priv->key) {
67 case NFT_CT_DIRECTION: 67 case NFT_CT_DIRECTION:
68 dest->data[0] = CTINFO2DIR(ctinfo); 68 *dest = CTINFO2DIR(ctinfo);
69 return; 69 return;
70 case NFT_CT_STATUS: 70 case NFT_CT_STATUS:
71 dest->data[0] = ct->status; 71 *dest = ct->status;
72 return; 72 return;
73#ifdef CONFIG_NF_CONNTRACK_MARK 73#ifdef CONFIG_NF_CONNTRACK_MARK
74 case NFT_CT_MARK: 74 case NFT_CT_MARK:
75 dest->data[0] = ct->mark; 75 *dest = ct->mark;
76 return; 76 return;
77#endif 77#endif
78#ifdef CONFIG_NF_CONNTRACK_SECMARK 78#ifdef CONFIG_NF_CONNTRACK_SECMARK
79 case NFT_CT_SECMARK: 79 case NFT_CT_SECMARK:
80 dest->data[0] = ct->secmark; 80 *dest = ct->secmark;
81 return; 81 return;
82#endif 82#endif
83 case NFT_CT_EXPIRATION: 83 case NFT_CT_EXPIRATION:
84 diff = (long)jiffies - (long)ct->timeout.expires; 84 diff = (long)jiffies - (long)ct->timeout.expires;
85 if (diff < 0) 85 if (diff < 0)
86 diff = 0; 86 diff = 0;
87 dest->data[0] = jiffies_to_msecs(diff); 87 *dest = jiffies_to_msecs(diff);
88 return; 88 return;
89 case NFT_CT_HELPER: 89 case NFT_CT_HELPER:
90 if (ct->master == NULL) 90 if (ct->master == NULL)
@@ -95,9 +95,7 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
95 helper = rcu_dereference(help->helper); 95 helper = rcu_dereference(help->helper);
96 if (helper == NULL) 96 if (helper == NULL)
97 goto err; 97 goto err;
98 if (strlen(helper->name) >= sizeof(dest->data)) 98 strncpy((char *)dest, helper->name, NF_CT_HELPER_NAME_LEN);
99 goto err;
100 strncpy((char *)dest->data, helper->name, sizeof(dest->data));
101 return; 99 return;
102#ifdef CONFIG_NF_CONNTRACK_LABELS 100#ifdef CONFIG_NF_CONNTRACK_LABELS
103 case NFT_CT_LABELS: { 101 case NFT_CT_LABELS: {
@@ -105,17 +103,15 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
105 unsigned int size; 103 unsigned int size;
106 104
107 if (!labels) { 105 if (!labels) {
108 memset(dest->data, 0, sizeof(dest->data)); 106 memset(dest, 0, NF_CT_LABELS_MAX_SIZE);
109 return; 107 return;
110 } 108 }
111 109
112 BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > sizeof(dest->data));
113 size = labels->words * sizeof(long); 110 size = labels->words * sizeof(long);
114 111 memcpy(dest, labels->bits, size);
115 memcpy(dest->data, labels->bits, size); 112 if (size < NF_CT_LABELS_MAX_SIZE)
116 if (size < sizeof(dest->data)) 113 memset(((char *) dest) + size, 0,
117 memset(((char *) dest->data) + size, 0, 114 NF_CT_LABELS_MAX_SIZE - size);
118 sizeof(dest->data) - size);
119 return; 115 return;
120 } 116 }
121#endif 117#endif
@@ -126,41 +122,41 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
126 tuple = &ct->tuplehash[priv->dir].tuple; 122 tuple = &ct->tuplehash[priv->dir].tuple;
127 switch (priv->key) { 123 switch (priv->key) {
128 case NFT_CT_L3PROTOCOL: 124 case NFT_CT_L3PROTOCOL:
129 dest->data[0] = nf_ct_l3num(ct); 125 *dest = nf_ct_l3num(ct);
130 return; 126 return;
131 case NFT_CT_SRC: 127 case NFT_CT_SRC:
132 memcpy(dest->data, tuple->src.u3.all, 128 memcpy(dest, tuple->src.u3.all,
133 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); 129 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
134 return; 130 return;
135 case NFT_CT_DST: 131 case NFT_CT_DST:
136 memcpy(dest->data, tuple->dst.u3.all, 132 memcpy(dest, tuple->dst.u3.all,
137 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16); 133 nf_ct_l3num(ct) == NFPROTO_IPV4 ? 4 : 16);
138 return; 134 return;
139 case NFT_CT_PROTOCOL: 135 case NFT_CT_PROTOCOL:
140 dest->data[0] = nf_ct_protonum(ct); 136 *dest = nf_ct_protonum(ct);
141 return; 137 return;
142 case NFT_CT_PROTO_SRC: 138 case NFT_CT_PROTO_SRC:
143 dest->data[0] = (__force __u16)tuple->src.u.all; 139 *dest = (__force __u16)tuple->src.u.all;
144 return; 140 return;
145 case NFT_CT_PROTO_DST: 141 case NFT_CT_PROTO_DST:
146 dest->data[0] = (__force __u16)tuple->dst.u.all; 142 *dest = (__force __u16)tuple->dst.u.all;
147 return; 143 return;
148 default: 144 default:
149 break; 145 break;
150 } 146 }
151 return; 147 return;
152err: 148err:
153 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 149 regs->verdict.code = NFT_BREAK;
154} 150}
155 151
156static void nft_ct_set_eval(const struct nft_expr *expr, 152static void nft_ct_set_eval(const struct nft_expr *expr,
157 struct nft_data data[NFT_REG_MAX + 1], 153 struct nft_regs *regs,
158 const struct nft_pktinfo *pkt) 154 const struct nft_pktinfo *pkt)
159{ 155{
160 const struct nft_ct *priv = nft_expr_priv(expr); 156 const struct nft_ct *priv = nft_expr_priv(expr);
161 struct sk_buff *skb = pkt->skb; 157 struct sk_buff *skb = pkt->skb;
162#ifdef CONFIG_NF_CONNTRACK_MARK 158#ifdef CONFIG_NF_CONNTRACK_MARK
163 u32 value = data[priv->sreg].data[0]; 159 u32 value = regs->data[priv->sreg];
164#endif 160#endif
165 enum ip_conntrack_info ctinfo; 161 enum ip_conntrack_info ctinfo;
166 struct nf_conn *ct; 162 struct nf_conn *ct;
@@ -228,12 +224,17 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
228 const struct nlattr * const tb[]) 224 const struct nlattr * const tb[])
229{ 225{
230 struct nft_ct *priv = nft_expr_priv(expr); 226 struct nft_ct *priv = nft_expr_priv(expr);
227 unsigned int len;
231 int err; 228 int err;
232 229
233 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); 230 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
234 switch (priv->key) { 231 switch (priv->key) {
235 case NFT_CT_STATE:
236 case NFT_CT_DIRECTION: 232 case NFT_CT_DIRECTION:
233 if (tb[NFTA_CT_DIRECTION] != NULL)
234 return -EINVAL;
235 len = sizeof(u8);
236 break;
237 case NFT_CT_STATE:
237 case NFT_CT_STATUS: 238 case NFT_CT_STATUS:
238#ifdef CONFIG_NF_CONNTRACK_MARK 239#ifdef CONFIG_NF_CONNTRACK_MARK
239 case NFT_CT_MARK: 240 case NFT_CT_MARK:
@@ -241,22 +242,54 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
241#ifdef CONFIG_NF_CONNTRACK_SECMARK 242#ifdef CONFIG_NF_CONNTRACK_SECMARK
242 case NFT_CT_SECMARK: 243 case NFT_CT_SECMARK:
243#endif 244#endif
245 case NFT_CT_EXPIRATION:
246 if (tb[NFTA_CT_DIRECTION] != NULL)
247 return -EINVAL;
248 len = sizeof(u32);
249 break;
244#ifdef CONFIG_NF_CONNTRACK_LABELS 250#ifdef CONFIG_NF_CONNTRACK_LABELS
245 case NFT_CT_LABELS: 251 case NFT_CT_LABELS:
252 if (tb[NFTA_CT_DIRECTION] != NULL)
253 return -EINVAL;
254 len = NF_CT_LABELS_MAX_SIZE;
255 break;
246#endif 256#endif
247 case NFT_CT_EXPIRATION:
248 case NFT_CT_HELPER: 257 case NFT_CT_HELPER:
249 if (tb[NFTA_CT_DIRECTION] != NULL) 258 if (tb[NFTA_CT_DIRECTION] != NULL)
250 return -EINVAL; 259 return -EINVAL;
260 len = NF_CT_HELPER_NAME_LEN;
251 break; 261 break;
262
252 case NFT_CT_L3PROTOCOL: 263 case NFT_CT_L3PROTOCOL:
253 case NFT_CT_PROTOCOL: 264 case NFT_CT_PROTOCOL:
265 if (tb[NFTA_CT_DIRECTION] == NULL)
266 return -EINVAL;
267 len = sizeof(u8);
268 break;
254 case NFT_CT_SRC: 269 case NFT_CT_SRC:
255 case NFT_CT_DST: 270 case NFT_CT_DST:
271 if (tb[NFTA_CT_DIRECTION] == NULL)
272 return -EINVAL;
273
274 switch (ctx->afi->family) {
275 case NFPROTO_IPV4:
276 len = FIELD_SIZEOF(struct nf_conntrack_tuple,
277 src.u3.ip);
278 break;
279 case NFPROTO_IPV6:
280 case NFPROTO_INET:
281 len = FIELD_SIZEOF(struct nf_conntrack_tuple,
282 src.u3.ip6);
283 break;
284 default:
285 return -EAFNOSUPPORT;
286 }
287 break;
256 case NFT_CT_PROTO_SRC: 288 case NFT_CT_PROTO_SRC:
257 case NFT_CT_PROTO_DST: 289 case NFT_CT_PROTO_DST:
258 if (tb[NFTA_CT_DIRECTION] == NULL) 290 if (tb[NFTA_CT_DIRECTION] == NULL)
259 return -EINVAL; 291 return -EINVAL;
292 len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
260 break; 293 break;
261 default: 294 default:
262 return -EOPNOTSUPP; 295 return -EOPNOTSUPP;
@@ -273,12 +306,9 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
273 } 306 }
274 } 307 }
275 308
276 priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG])); 309 priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
277 err = nft_validate_output_register(priv->dreg); 310 err = nft_validate_register_store(ctx, priv->dreg, NULL,
278 if (err < 0) 311 NFT_DATA_VALUE, len);
279 return err;
280
281 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
282 if (err < 0) 312 if (err < 0)
283 return err; 313 return err;
284 314
@@ -294,20 +324,22 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
294 const struct nlattr * const tb[]) 324 const struct nlattr * const tb[])
295{ 325{
296 struct nft_ct *priv = nft_expr_priv(expr); 326 struct nft_ct *priv = nft_expr_priv(expr);
327 unsigned int len;
297 int err; 328 int err;
298 329
299 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); 330 priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
300 switch (priv->key) { 331 switch (priv->key) {
301#ifdef CONFIG_NF_CONNTRACK_MARK 332#ifdef CONFIG_NF_CONNTRACK_MARK
302 case NFT_CT_MARK: 333 case NFT_CT_MARK:
334 len = FIELD_SIZEOF(struct nf_conn, mark);
303 break; 335 break;
304#endif 336#endif
305 default: 337 default:
306 return -EOPNOTSUPP; 338 return -EOPNOTSUPP;
307 } 339 }
308 340
309 priv->sreg = ntohl(nla_get_be32(tb[NFTA_CT_SREG])); 341 priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
310 err = nft_validate_input_register(priv->sreg); 342 err = nft_validate_register_load(priv->sreg, len);
311 if (err < 0) 343 if (err < 0)
312 return err; 344 return err;
313 345
@@ -328,7 +360,7 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
328{ 360{
329 const struct nft_ct *priv = nft_expr_priv(expr); 361 const struct nft_ct *priv = nft_expr_priv(expr);
330 362
331 if (nla_put_be32(skb, NFTA_CT_DREG, htonl(priv->dreg))) 363 if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg))
332 goto nla_put_failure; 364 goto nla_put_failure;
333 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 365 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
334 goto nla_put_failure; 366 goto nla_put_failure;
@@ -355,7 +387,7 @@ static int nft_ct_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
355{ 387{
356 const struct nft_ct *priv = nft_expr_priv(expr); 388 const struct nft_ct *priv = nft_expr_priv(expr);
357 389
358 if (nla_put_be32(skb, NFTA_CT_SREG, htonl(priv->sreg))) 390 if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg))
359 goto nla_put_failure; 391 goto nla_put_failure;
360 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 392 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key)))
361 goto nla_put_failure; 393 goto nla_put_failure;
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index eeb72dee78ef..513a8ef60a59 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -23,13 +23,15 @@ struct nft_dynset {
23 enum nft_registers sreg_key:8; 23 enum nft_registers sreg_key:8;
24 enum nft_registers sreg_data:8; 24 enum nft_registers sreg_data:8;
25 u64 timeout; 25 u64 timeout;
26 struct nft_expr *expr;
26 struct nft_set_binding binding; 27 struct nft_set_binding binding;
27}; 28};
28 29
29static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr, 30static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
30 struct nft_data data[NFT_REG_MAX + 1]) 31 struct nft_regs *regs)
31{ 32{
32 const struct nft_dynset *priv = nft_expr_priv(expr); 33 const struct nft_dynset *priv = nft_expr_priv(expr);
34 struct nft_set_ext *ext;
33 u64 timeout; 35 u64 timeout;
34 void *elem; 36 void *elem;
35 37
@@ -38,35 +40,51 @@ static void *nft_dynset_new(struct nft_set *set, const struct nft_expr *expr,
38 40
39 timeout = priv->timeout ? : set->timeout; 41 timeout = priv->timeout ? : set->timeout;
40 elem = nft_set_elem_init(set, &priv->tmpl, 42 elem = nft_set_elem_init(set, &priv->tmpl,
41 &data[priv->sreg_key], &data[priv->sreg_data], 43 &regs->data[priv->sreg_key],
44 &regs->data[priv->sreg_data],
42 timeout, GFP_ATOMIC); 45 timeout, GFP_ATOMIC);
43 if (elem == NULL) { 46 if (elem == NULL) {
44 if (set->size) 47 if (set->size)
45 atomic_dec(&set->nelems); 48 atomic_dec(&set->nelems);
49 return NULL;
46 } 50 }
51
52 ext = nft_set_elem_ext(set, elem);
53 if (priv->expr != NULL)
54 nft_expr_clone(nft_set_ext_expr(ext), priv->expr);
55
47 return elem; 56 return elem;
48} 57}
49 58
50static void nft_dynset_eval(const struct nft_expr *expr, 59static void nft_dynset_eval(const struct nft_expr *expr,
51 struct nft_data data[NFT_REG_MAX + 1], 60 struct nft_regs *regs,
52 const struct nft_pktinfo *pkt) 61 const struct nft_pktinfo *pkt)
53{ 62{
54 const struct nft_dynset *priv = nft_expr_priv(expr); 63 const struct nft_dynset *priv = nft_expr_priv(expr);
55 struct nft_set *set = priv->set; 64 struct nft_set *set = priv->set;
56 const struct nft_set_ext *ext; 65 const struct nft_set_ext *ext;
66 const struct nft_expr *sexpr;
57 u64 timeout; 67 u64 timeout;
58 68
59 if (set->ops->update(set, &data[priv->sreg_key], nft_dynset_new, 69 if (set->ops->update(set, &regs->data[priv->sreg_key], nft_dynset_new,
60 expr, data, &ext)) { 70 expr, regs, &ext)) {
71 sexpr = NULL;
72 if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR))
73 sexpr = nft_set_ext_expr(ext);
74
61 if (priv->op == NFT_DYNSET_OP_UPDATE && 75 if (priv->op == NFT_DYNSET_OP_UPDATE &&
62 nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) { 76 nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) {
63 timeout = priv->timeout ? : set->timeout; 77 timeout = priv->timeout ? : set->timeout;
64 *nft_set_ext_expiration(ext) = jiffies + timeout; 78 *nft_set_ext_expiration(ext) = jiffies + timeout;
65 return; 79 } else if (sexpr == NULL)
66 } 80 goto out;
67 }
68 81
69 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 82 if (sexpr != NULL)
83 sexpr->ops->eval(sexpr, regs, pkt);
84 return;
85 }
86out:
87 regs->verdict.code = NFT_BREAK;
70} 88}
71 89
72static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = { 90static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = {
@@ -76,6 +94,7 @@ static const struct nla_policy nft_dynset_policy[NFTA_DYNSET_MAX + 1] = {
76 [NFTA_DYNSET_SREG_KEY] = { .type = NLA_U32 }, 94 [NFTA_DYNSET_SREG_KEY] = { .type = NLA_U32 },
77 [NFTA_DYNSET_SREG_DATA] = { .type = NLA_U32 }, 95 [NFTA_DYNSET_SREG_DATA] = { .type = NLA_U32 },
78 [NFTA_DYNSET_TIMEOUT] = { .type = NLA_U64 }, 96 [NFTA_DYNSET_TIMEOUT] = { .type = NLA_U64 },
97 [NFTA_DYNSET_EXPR] = { .type = NLA_NESTED },
79}; 98};
80 99
81static int nft_dynset_init(const struct nft_ctx *ctx, 100static int nft_dynset_init(const struct nft_ctx *ctx,
@@ -123,8 +142,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
123 timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT])); 142 timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT]));
124 } 143 }
125 144
126 priv->sreg_key = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_KEY])); 145 priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]);
127 err = nft_validate_input_register(priv->sreg_key); 146 err = nft_validate_register_load(priv->sreg_key, set->klen);;
128 if (err < 0) 147 if (err < 0)
129 return err; 148 return err;
130 149
@@ -134,17 +153,36 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
134 if (set->dtype == NFT_DATA_VERDICT) 153 if (set->dtype == NFT_DATA_VERDICT)
135 return -EOPNOTSUPP; 154 return -EOPNOTSUPP;
136 155
137 priv->sreg_data = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_DATA])); 156 priv->sreg_data = nft_parse_register(tb[NFTA_DYNSET_SREG_DATA]);
138 err = nft_validate_input_register(priv->sreg_data); 157 err = nft_validate_register_load(priv->sreg_data, set->dlen);
139 if (err < 0) 158 if (err < 0)
140 return err; 159 return err;
141 } else if (set->flags & NFT_SET_MAP) 160 } else if (set->flags & NFT_SET_MAP)
142 return -EINVAL; 161 return -EINVAL;
143 162
163 if (tb[NFTA_DYNSET_EXPR] != NULL) {
164 if (!(set->flags & NFT_SET_EVAL))
165 return -EINVAL;
166 if (!(set->flags & NFT_SET_ANONYMOUS))
167 return -EOPNOTSUPP;
168
169 priv->expr = nft_expr_init(ctx, tb[NFTA_DYNSET_EXPR]);
170 if (IS_ERR(priv->expr))
171 return PTR_ERR(priv->expr);
172
173 err = -EOPNOTSUPP;
174 if (!(priv->expr->ops->type->flags & NFT_EXPR_STATEFUL))
175 goto err1;
176 } else if (set->flags & NFT_SET_EVAL)
177 return -EINVAL;
178
144 nft_set_ext_prepare(&priv->tmpl); 179 nft_set_ext_prepare(&priv->tmpl);
145 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen); 180 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen);
146 if (set->flags & NFT_SET_MAP) 181 if (set->flags & NFT_SET_MAP)
147 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_DATA, set->dlen); 182 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_DATA, set->dlen);
183 if (priv->expr != NULL)
184 nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_EXPR,
185 priv->expr->ops->size);
148 if (set->flags & NFT_SET_TIMEOUT) { 186 if (set->flags & NFT_SET_TIMEOUT) {
149 if (timeout || set->timeout) 187 if (timeout || set->timeout)
150 nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION); 188 nft_set_ext_add(&priv->tmpl, NFT_SET_EXT_EXPIRATION);
@@ -154,10 +192,15 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
154 192
155 err = nf_tables_bind_set(ctx, set, &priv->binding); 193 err = nf_tables_bind_set(ctx, set, &priv->binding);
156 if (err < 0) 194 if (err < 0)
157 return err; 195 goto err1;
158 196
159 priv->set = set; 197 priv->set = set;
160 return 0; 198 return 0;
199
200err1:
201 if (priv->expr != NULL)
202 nft_expr_destroy(ctx, priv->expr);
203 return err;
161} 204}
162 205
163static void nft_dynset_destroy(const struct nft_ctx *ctx, 206static void nft_dynset_destroy(const struct nft_ctx *ctx,
@@ -166,16 +209,18 @@ static void nft_dynset_destroy(const struct nft_ctx *ctx,
166 struct nft_dynset *priv = nft_expr_priv(expr); 209 struct nft_dynset *priv = nft_expr_priv(expr);
167 210
168 nf_tables_unbind_set(ctx, priv->set, &priv->binding); 211 nf_tables_unbind_set(ctx, priv->set, &priv->binding);
212 if (priv->expr != NULL)
213 nft_expr_destroy(ctx, priv->expr);
169} 214}
170 215
171static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr) 216static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
172{ 217{
173 const struct nft_dynset *priv = nft_expr_priv(expr); 218 const struct nft_dynset *priv = nft_expr_priv(expr);
174 219
175 if (nla_put_be32(skb, NFTA_DYNSET_SREG_KEY, htonl(priv->sreg_key))) 220 if (nft_dump_register(skb, NFTA_DYNSET_SREG_KEY, priv->sreg_key))
176 goto nla_put_failure; 221 goto nla_put_failure;
177 if (priv->set->flags & NFT_SET_MAP && 222 if (priv->set->flags & NFT_SET_MAP &&
178 nla_put_be32(skb, NFTA_DYNSET_SREG_DATA, htonl(priv->sreg_data))) 223 nft_dump_register(skb, NFTA_DYNSET_SREG_DATA, priv->sreg_data))
179 goto nla_put_failure; 224 goto nla_put_failure;
180 if (nla_put_be32(skb, NFTA_DYNSET_OP, htonl(priv->op))) 225 if (nla_put_be32(skb, NFTA_DYNSET_OP, htonl(priv->op)))
181 goto nla_put_failure; 226 goto nla_put_failure;
@@ -183,6 +228,8 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
183 goto nla_put_failure; 228 goto nla_put_failure;
184 if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout))) 229 if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout)))
185 goto nla_put_failure; 230 goto nla_put_failure;
231 if (priv->expr && nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr))
232 goto nla_put_failure;
186 return 0; 233 return 0;
187 234
188nla_put_failure: 235nla_put_failure:
diff --git a/net/netfilter/nft_expr_template.c b/net/netfilter/nft_expr_template.c
deleted file mode 100644
index b6eed4d5a096..000000000000
--- a/net/netfilter/nft_expr_template.c
+++ /dev/null
@@ -1,94 +0,0 @@
1/*
2 * Copyright (c) 2008-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/kernel.h>
12#include <linux/init.h>
13#include <linux/netlink.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter/nf_tables.h>
16#include <net/netfilter/nf_tables.h>
17
18struct nft_template {
19
20};
21
22static void nft_template_eval(const struct nft_expr *expr,
23 struct nft_data data[NFT_REG_MAX + 1],
24 const struct nft_pktinfo *pkt)
25{
26 struct nft_template *priv = nft_expr_priv(expr);
27
28}
29
30static const struct nla_policy nft_template_policy[NFTA_TEMPLATE_MAX + 1] = {
31 [NFTA_TEMPLATE_ATTR] = { .type = NLA_U32 },
32};
33
34static int nft_template_init(const struct nft_ctx *ctx,
35 const struct nft_expr *expr,
36 const struct nlattr * const tb[])
37{
38 struct nft_template *priv = nft_expr_priv(expr);
39
40 return 0;
41}
42
43static void nft_template_destroy(const struct nft_ctx *ctx,
44 const struct nft_expr *expr)
45{
46 struct nft_template *priv = nft_expr_priv(expr);
47
48}
49
50static int nft_template_dump(struct sk_buff *skb, const struct nft_expr *expr)
51{
52 const struct nft_template *priv = nft_expr_priv(expr);
53
54 NLA_PUT_BE32(skb, NFTA_TEMPLATE_ATTR, priv->field);
55 return 0;
56
57nla_put_failure:
58 return -1;
59}
60
61static struct nft_expr_type nft_template_type;
62static const struct nft_expr_ops nft_template_ops = {
63 .type = &nft_template_type,
64 .size = NFT_EXPR_SIZE(sizeof(struct nft_template)),
65 .eval = nft_template_eval,
66 .init = nft_template_init,
67 .destroy = nft_template_destroy,
68 .dump = nft_template_dump,
69};
70
71static struct nft_expr_type nft_template_type __read_mostly = {
72 .name = "template",
73 .ops = &nft_template_ops,
74 .policy = nft_template_policy,
75 .maxattr = NFTA_TEMPLATE_MAX,
76 .owner = THIS_MODULE,
77};
78
79static int __init nft_template_module_init(void)
80{
81 return nft_register_expr(&nft_template_type);
82}
83
84static void __exit nft_template_module_exit(void)
85{
86 nft_unregister_expr(&nft_template_type);
87}
88
89module_init(nft_template_module_init);
90module_exit(nft_template_module_exit);
91
92MODULE_LICENSE("GPL");
93MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
94MODULE_ALIAS_NFT_EXPR("template");
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c
index 55c939f5371f..ba7aed13e174 100644
--- a/net/netfilter/nft_exthdr.c
+++ b/net/netfilter/nft_exthdr.c
@@ -26,11 +26,11 @@ struct nft_exthdr {
26}; 26};
27 27
28static void nft_exthdr_eval(const struct nft_expr *expr, 28static void nft_exthdr_eval(const struct nft_expr *expr,
29 struct nft_data data[NFT_REG_MAX + 1], 29 struct nft_regs *regs,
30 const struct nft_pktinfo *pkt) 30 const struct nft_pktinfo *pkt)
31{ 31{
32 struct nft_exthdr *priv = nft_expr_priv(expr); 32 struct nft_exthdr *priv = nft_expr_priv(expr);
33 struct nft_data *dest = &data[priv->dreg]; 33 u32 *dest = &regs->data[priv->dreg];
34 unsigned int offset = 0; 34 unsigned int offset = 0;
35 int err; 35 int err;
36 36
@@ -39,11 +39,12 @@ static void nft_exthdr_eval(const struct nft_expr *expr,
39 goto err; 39 goto err;
40 offset += priv->offset; 40 offset += priv->offset;
41 41
42 if (skb_copy_bits(pkt->skb, offset, dest->data, priv->len) < 0) 42 dest[priv->len / NFT_REG32_SIZE] = 0;
43 if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0)
43 goto err; 44 goto err;
44 return; 45 return;
45err: 46err:
46 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 47 regs->verdict.code = NFT_BREAK;
47} 48}
48 49
49static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = { 50static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = {
@@ -58,7 +59,6 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
58 const struct nlattr * const tb[]) 59 const struct nlattr * const tb[])
59{ 60{
60 struct nft_exthdr *priv = nft_expr_priv(expr); 61 struct nft_exthdr *priv = nft_expr_priv(expr);
61 int err;
62 62
63 if (tb[NFTA_EXTHDR_DREG] == NULL || 63 if (tb[NFTA_EXTHDR_DREG] == NULL ||
64 tb[NFTA_EXTHDR_TYPE] == NULL || 64 tb[NFTA_EXTHDR_TYPE] == NULL ||
@@ -69,22 +69,17 @@ static int nft_exthdr_init(const struct nft_ctx *ctx,
69 priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); 69 priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]);
70 priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET])); 70 priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET]));
71 priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN])); 71 priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN]));
72 if (priv->len == 0 || 72 priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]);
73 priv->len > FIELD_SIZEOF(struct nft_data, data))
74 return -EINVAL;
75 73
76 priv->dreg = ntohl(nla_get_be32(tb[NFTA_EXTHDR_DREG])); 74 return nft_validate_register_store(ctx, priv->dreg, NULL,
77 err = nft_validate_output_register(priv->dreg); 75 NFT_DATA_VALUE, priv->len);
78 if (err < 0)
79 return err;
80 return nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
81} 76}
82 77
83static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr) 78static int nft_exthdr_dump(struct sk_buff *skb, const struct nft_expr *expr)
84{ 79{
85 const struct nft_exthdr *priv = nft_expr_priv(expr); 80 const struct nft_exthdr *priv = nft_expr_priv(expr);
86 81
87 if (nla_put_be32(skb, NFTA_EXTHDR_DREG, htonl(priv->dreg))) 82 if (nft_dump_register(skb, NFTA_EXTHDR_DREG, priv->dreg))
88 goto nla_put_failure; 83 goto nla_put_failure;
89 if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type)) 84 if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type))
90 goto nla_put_failure; 85 goto nla_put_failure;
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c
index bc23806b7fbe..3f9d45d3d9b7 100644
--- a/net/netfilter/nft_hash.c
+++ b/net/netfilter/nft_hash.c
@@ -36,7 +36,7 @@ struct nft_hash_elem {
36 36
37struct nft_hash_cmp_arg { 37struct nft_hash_cmp_arg {
38 const struct nft_set *set; 38 const struct nft_set *set;
39 const struct nft_data *key; 39 const u32 *key;
40 u8 genmask; 40 u8 genmask;
41}; 41};
42 42
@@ -62,7 +62,7 @@ static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg,
62 const struct nft_hash_cmp_arg *x = arg->key; 62 const struct nft_hash_cmp_arg *x = arg->key;
63 const struct nft_hash_elem *he = ptr; 63 const struct nft_hash_elem *he = ptr;
64 64
65 if (nft_data_cmp(nft_set_ext_key(&he->ext), x->key, x->set->klen)) 65 if (memcmp(nft_set_ext_key(&he->ext), x->key, x->set->klen))
66 return 1; 66 return 1;
67 if (nft_set_elem_expired(&he->ext)) 67 if (nft_set_elem_expired(&he->ext))
68 return 1; 68 return 1;
@@ -71,8 +71,7 @@ static inline int nft_hash_cmp(struct rhashtable_compare_arg *arg,
71 return 0; 71 return 0;
72} 72}
73 73
74static bool nft_hash_lookup(const struct nft_set *set, 74static bool nft_hash_lookup(const struct nft_set *set, const u32 *key,
75 const struct nft_data *key,
76 const struct nft_set_ext **ext) 75 const struct nft_set_ext **ext)
77{ 76{
78 struct nft_hash *priv = nft_set_priv(set); 77 struct nft_hash *priv = nft_set_priv(set);
@@ -90,12 +89,12 @@ static bool nft_hash_lookup(const struct nft_set *set,
90 return !!he; 89 return !!he;
91} 90}
92 91
93static bool nft_hash_update(struct nft_set *set, const struct nft_data *key, 92static bool nft_hash_update(struct nft_set *set, const u32 *key,
94 void *(*new)(struct nft_set *, 93 void *(*new)(struct nft_set *,
95 const struct nft_expr *, 94 const struct nft_expr *,
96 struct nft_data []), 95 struct nft_regs *regs),
97 const struct nft_expr *expr, 96 const struct nft_expr *expr,
98 struct nft_data data[], 97 struct nft_regs *regs,
99 const struct nft_set_ext **ext) 98 const struct nft_set_ext **ext)
100{ 99{
101 struct nft_hash *priv = nft_set_priv(set); 100 struct nft_hash *priv = nft_set_priv(set);
@@ -110,7 +109,7 @@ static bool nft_hash_update(struct nft_set *set, const struct nft_data *key,
110 if (he != NULL) 109 if (he != NULL)
111 goto out; 110 goto out;
112 111
113 he = new(set, expr, data); 112 he = new(set, expr, regs);
114 if (he == NULL) 113 if (he == NULL)
115 goto err1; 114 goto err1;
116 if (rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node, 115 if (rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
@@ -134,7 +133,7 @@ static int nft_hash_insert(const struct nft_set *set,
134 struct nft_hash_cmp_arg arg = { 133 struct nft_hash_cmp_arg arg = {
135 .genmask = nft_genmask_next(read_pnet(&set->pnet)), 134 .genmask = nft_genmask_next(read_pnet(&set->pnet)),
136 .set = set, 135 .set = set,
137 .key = &elem->key, 136 .key = elem->key.val.data,
138 }; 137 };
139 138
140 return rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node, 139 return rhashtable_lookup_insert_key(&priv->ht, &arg, &he->node,
@@ -158,7 +157,7 @@ static void *nft_hash_deactivate(const struct nft_set *set,
158 struct nft_hash_cmp_arg arg = { 157 struct nft_hash_cmp_arg arg = {
159 .genmask = nft_genmask_next(read_pnet(&set->pnet)), 158 .genmask = nft_genmask_next(read_pnet(&set->pnet)),
160 .set = set, 159 .set = set,
161 .key = &elem->key, 160 .key = elem->key.val.data,
162 }; 161 };
163 162
164 rcu_read_lock(); 163 rcu_read_lock();
diff --git a/net/netfilter/nft_immediate.c b/net/netfilter/nft_immediate.c
index 810385eb7249..db3b746858e3 100644
--- a/net/netfilter/nft_immediate.c
+++ b/net/netfilter/nft_immediate.c
@@ -24,12 +24,12 @@ struct nft_immediate_expr {
24}; 24};
25 25
26static void nft_immediate_eval(const struct nft_expr *expr, 26static void nft_immediate_eval(const struct nft_expr *expr,
27 struct nft_data data[NFT_REG_MAX + 1], 27 struct nft_regs *regs,
28 const struct nft_pktinfo *pkt) 28 const struct nft_pktinfo *pkt)
29{ 29{
30 const struct nft_immediate_expr *priv = nft_expr_priv(expr); 30 const struct nft_immediate_expr *priv = nft_expr_priv(expr);
31 31
32 nft_data_copy(&data[priv->dreg], &priv->data); 32 nft_data_copy(&regs->data[priv->dreg], &priv->data, priv->dlen);
33} 33}
34 34
35static const struct nla_policy nft_immediate_policy[NFTA_IMMEDIATE_MAX + 1] = { 35static const struct nla_policy nft_immediate_policy[NFTA_IMMEDIATE_MAX + 1] = {
@@ -49,17 +49,15 @@ static int nft_immediate_init(const struct nft_ctx *ctx,
49 tb[NFTA_IMMEDIATE_DATA] == NULL) 49 tb[NFTA_IMMEDIATE_DATA] == NULL)
50 return -EINVAL; 50 return -EINVAL;
51 51
52 priv->dreg = ntohl(nla_get_be32(tb[NFTA_IMMEDIATE_DREG])); 52 err = nft_data_init(ctx, &priv->data, sizeof(priv->data), &desc,
53 err = nft_validate_output_register(priv->dreg); 53 tb[NFTA_IMMEDIATE_DATA]);
54 if (err < 0)
55 return err;
56
57 err = nft_data_init(ctx, &priv->data, &desc, tb[NFTA_IMMEDIATE_DATA]);
58 if (err < 0) 54 if (err < 0)
59 return err; 55 return err;
60 priv->dlen = desc.len; 56 priv->dlen = desc.len;
61 57
62 err = nft_validate_data_load(ctx, priv->dreg, &priv->data, desc.type); 58 priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]);
59 err = nft_validate_register_store(ctx, priv->dreg, &priv->data,
60 desc.type, desc.len);
63 if (err < 0) 61 if (err < 0)
64 goto err1; 62 goto err1;
65 63
@@ -81,7 +79,7 @@ static int nft_immediate_dump(struct sk_buff *skb, const struct nft_expr *expr)
81{ 79{
82 const struct nft_immediate_expr *priv = nft_expr_priv(expr); 80 const struct nft_immediate_expr *priv = nft_expr_priv(expr);
83 81
84 if (nla_put_be32(skb, NFTA_IMMEDIATE_DREG, htonl(priv->dreg))) 82 if (nft_dump_register(skb, NFTA_IMMEDIATE_DREG, priv->dreg))
85 goto nla_put_failure; 83 goto nla_put_failure;
86 84
87 return nft_data_dump(skb, NFTA_IMMEDIATE_DATA, &priv->data, 85 return nft_data_dump(skb, NFTA_IMMEDIATE_DATA, &priv->data,
diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
index 85da5bd02f64..435c1ccd6c0e 100644
--- a/net/netfilter/nft_limit.c
+++ b/net/netfilter/nft_limit.c
@@ -27,7 +27,7 @@ struct nft_limit {
27}; 27};
28 28
29static void nft_limit_eval(const struct nft_expr *expr, 29static void nft_limit_eval(const struct nft_expr *expr,
30 struct nft_data data[NFT_REG_MAX + 1], 30 struct nft_regs *regs,
31 const struct nft_pktinfo *pkt) 31 const struct nft_pktinfo *pkt)
32{ 32{
33 struct nft_limit *priv = nft_expr_priv(expr); 33 struct nft_limit *priv = nft_expr_priv(expr);
@@ -45,7 +45,7 @@ static void nft_limit_eval(const struct nft_expr *expr,
45 } 45 }
46 spin_unlock_bh(&limit_lock); 46 spin_unlock_bh(&limit_lock);
47 47
48 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 48 regs->verdict.code = NFT_BREAK;
49} 49}
50 50
51static const struct nla_policy nft_limit_policy[NFTA_LIMIT_MAX + 1] = { 51static const struct nla_policy nft_limit_policy[NFTA_LIMIT_MAX + 1] = {
@@ -98,6 +98,7 @@ static struct nft_expr_type nft_limit_type __read_mostly = {
98 .ops = &nft_limit_ops, 98 .ops = &nft_limit_ops,
99 .policy = nft_limit_policy, 99 .policy = nft_limit_policy,
100 .maxattr = NFTA_LIMIT_MAX, 100 .maxattr = NFTA_LIMIT_MAX,
101 .flags = NFT_EXPR_STATEFUL,
101 .owner = THIS_MODULE, 102 .owner = THIS_MODULE,
102}; 103};
103 104
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
index e18af9db2f04..a13d6a386d63 100644
--- a/net/netfilter/nft_log.c
+++ b/net/netfilter/nft_log.c
@@ -27,7 +27,7 @@ struct nft_log {
27}; 27};
28 28
29static void nft_log_eval(const struct nft_expr *expr, 29static void nft_log_eval(const struct nft_expr *expr,
30 struct nft_data data[NFT_REG_MAX + 1], 30 struct nft_regs *regs,
31 const struct nft_pktinfo *pkt) 31 const struct nft_pktinfo *pkt)
32{ 32{
33 const struct nft_log *priv = nft_expr_priv(expr); 33 const struct nft_log *priv = nft_expr_priv(expr);
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index d8cf86fb30fc..b3c31ef8015d 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -26,19 +26,20 @@ struct nft_lookup {
26}; 26};
27 27
28static void nft_lookup_eval(const struct nft_expr *expr, 28static void nft_lookup_eval(const struct nft_expr *expr,
29 struct nft_data data[NFT_REG_MAX + 1], 29 struct nft_regs *regs,
30 const struct nft_pktinfo *pkt) 30 const struct nft_pktinfo *pkt)
31{ 31{
32 const struct nft_lookup *priv = nft_expr_priv(expr); 32 const struct nft_lookup *priv = nft_expr_priv(expr);
33 const struct nft_set *set = priv->set; 33 const struct nft_set *set = priv->set;
34 const struct nft_set_ext *ext; 34 const struct nft_set_ext *ext;
35 35
36 if (set->ops->lookup(set, &data[priv->sreg], &ext)) { 36 if (set->ops->lookup(set, &regs->data[priv->sreg], &ext)) {
37 if (set->flags & NFT_SET_MAP) 37 if (set->flags & NFT_SET_MAP)
38 nft_data_copy(&data[priv->dreg], nft_set_ext_data(ext)); 38 nft_data_copy(&regs->data[priv->dreg],
39 nft_set_ext_data(ext), set->dlen);
39 return; 40 return;
40 } 41 }
41 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 42 regs->verdict.code = NFT_BREAK;
42} 43}
43 44
44static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = { 45static const struct nla_policy nft_lookup_policy[NFTA_LOOKUP_MAX + 1] = {
@@ -70,8 +71,11 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
70 return PTR_ERR(set); 71 return PTR_ERR(set);
71 } 72 }
72 73
73 priv->sreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_SREG])); 74 if (set->flags & NFT_SET_EVAL)
74 err = nft_validate_input_register(priv->sreg); 75 return -EOPNOTSUPP;
76
77 priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]);
78 err = nft_validate_register_load(priv->sreg, set->klen);
75 if (err < 0) 79 if (err < 0)
76 return err; 80 return err;
77 81
@@ -79,16 +83,11 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
79 if (!(set->flags & NFT_SET_MAP)) 83 if (!(set->flags & NFT_SET_MAP))
80 return -EINVAL; 84 return -EINVAL;
81 85
82 priv->dreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_DREG])); 86 priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]);
83 err = nft_validate_output_register(priv->dreg); 87 err = nft_validate_register_store(ctx, priv->dreg, NULL,
88 set->dtype, set->dlen);
84 if (err < 0) 89 if (err < 0)
85 return err; 90 return err;
86
87 if (priv->dreg == NFT_REG_VERDICT) {
88 if (set->dtype != NFT_DATA_VERDICT)
89 return -EINVAL;
90 } else if (set->dtype == NFT_DATA_VERDICT)
91 return -EINVAL;
92 } else if (set->flags & NFT_SET_MAP) 91 } else if (set->flags & NFT_SET_MAP)
93 return -EINVAL; 92 return -EINVAL;
94 93
@@ -116,10 +115,10 @@ static int nft_lookup_dump(struct sk_buff *skb, const struct nft_expr *expr)
116 115
117 if (nla_put_string(skb, NFTA_LOOKUP_SET, priv->set->name)) 116 if (nla_put_string(skb, NFTA_LOOKUP_SET, priv->set->name))
118 goto nla_put_failure; 117 goto nla_put_failure;
119 if (nla_put_be32(skb, NFTA_LOOKUP_SREG, htonl(priv->sreg))) 118 if (nft_dump_register(skb, NFTA_LOOKUP_SREG, priv->sreg))
120 goto nla_put_failure; 119 goto nla_put_failure;
121 if (priv->set->flags & NFT_SET_MAP) 120 if (priv->set->flags & NFT_SET_MAP)
122 if (nla_put_be32(skb, NFTA_LOOKUP_DREG, htonl(priv->dreg))) 121 if (nft_dump_register(skb, NFTA_LOOKUP_DREG, priv->dreg))
123 goto nla_put_failure; 122 goto nla_put_failure;
124 return 0; 123 return 0;
125 124
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index d79ce88be77f..52561e1c31e2 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -25,62 +25,65 @@
25#include <net/netfilter/nft_meta.h> 25#include <net/netfilter/nft_meta.h>
26 26
27void nft_meta_get_eval(const struct nft_expr *expr, 27void nft_meta_get_eval(const struct nft_expr *expr,
28 struct nft_data data[NFT_REG_MAX + 1], 28 struct nft_regs *regs,
29 const struct nft_pktinfo *pkt) 29 const struct nft_pktinfo *pkt)
30{ 30{
31 const struct nft_meta *priv = nft_expr_priv(expr); 31 const struct nft_meta *priv = nft_expr_priv(expr);
32 const struct sk_buff *skb = pkt->skb; 32 const struct sk_buff *skb = pkt->skb;
33 const struct net_device *in = pkt->in, *out = pkt->out; 33 const struct net_device *in = pkt->in, *out = pkt->out;
34 struct nft_data *dest = &data[priv->dreg]; 34 u32 *dest = &regs->data[priv->dreg];
35 35
36 switch (priv->key) { 36 switch (priv->key) {
37 case NFT_META_LEN: 37 case NFT_META_LEN:
38 dest->data[0] = skb->len; 38 *dest = skb->len;
39 break; 39 break;
40 case NFT_META_PROTOCOL: 40 case NFT_META_PROTOCOL:
41 *(__be16 *)dest->data = skb->protocol; 41 *dest = 0;
42 *(__be16 *)dest = skb->protocol;
42 break; 43 break;
43 case NFT_META_NFPROTO: 44 case NFT_META_NFPROTO:
44 dest->data[0] = pkt->ops->pf; 45 *dest = pkt->ops->pf;
45 break; 46 break;
46 case NFT_META_L4PROTO: 47 case NFT_META_L4PROTO:
47 dest->data[0] = pkt->tprot; 48 *dest = pkt->tprot;
48 break; 49 break;
49 case NFT_META_PRIORITY: 50 case NFT_META_PRIORITY:
50 dest->data[0] = skb->priority; 51 *dest = skb->priority;
51 break; 52 break;
52 case NFT_META_MARK: 53 case NFT_META_MARK:
53 dest->data[0] = skb->mark; 54 *dest = skb->mark;
54 break; 55 break;
55 case NFT_META_IIF: 56 case NFT_META_IIF:
56 if (in == NULL) 57 if (in == NULL)
57 goto err; 58 goto err;
58 dest->data[0] = in->ifindex; 59 *dest = in->ifindex;
59 break; 60 break;
60 case NFT_META_OIF: 61 case NFT_META_OIF:
61 if (out == NULL) 62 if (out == NULL)
62 goto err; 63 goto err;
63 dest->data[0] = out->ifindex; 64 *dest = out->ifindex;
64 break; 65 break;
65 case NFT_META_IIFNAME: 66 case NFT_META_IIFNAME:
66 if (in == NULL) 67 if (in == NULL)
67 goto err; 68 goto err;
68 strncpy((char *)dest->data, in->name, sizeof(dest->data)); 69 strncpy((char *)dest, in->name, IFNAMSIZ);
69 break; 70 break;
70 case NFT_META_OIFNAME: 71 case NFT_META_OIFNAME:
71 if (out == NULL) 72 if (out == NULL)
72 goto err; 73 goto err;
73 strncpy((char *)dest->data, out->name, sizeof(dest->data)); 74 strncpy((char *)dest, out->name, IFNAMSIZ);
74 break; 75 break;
75 case NFT_META_IIFTYPE: 76 case NFT_META_IIFTYPE:
76 if (in == NULL) 77 if (in == NULL)
77 goto err; 78 goto err;
78 *(u16 *)dest->data = in->type; 79 *dest = 0;
80 *(u16 *)dest = in->type;
79 break; 81 break;
80 case NFT_META_OIFTYPE: 82 case NFT_META_OIFTYPE:
81 if (out == NULL) 83 if (out == NULL)
82 goto err; 84 goto err;
83 *(u16 *)dest->data = out->type; 85 *dest = 0;
86 *(u16 *)dest = out->type;
84 break; 87 break;
85 case NFT_META_SKUID: 88 case NFT_META_SKUID:
86 if (skb->sk == NULL || !sk_fullsock(skb->sk)) 89 if (skb->sk == NULL || !sk_fullsock(skb->sk))
@@ -93,8 +96,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
93 goto err; 96 goto err;
94 } 97 }
95 98
96 dest->data[0] = 99 *dest = from_kuid_munged(&init_user_ns,
97 from_kuid_munged(&init_user_ns,
98 skb->sk->sk_socket->file->f_cred->fsuid); 100 skb->sk->sk_socket->file->f_cred->fsuid);
99 read_unlock_bh(&skb->sk->sk_callback_lock); 101 read_unlock_bh(&skb->sk->sk_callback_lock);
100 break; 102 break;
@@ -108,8 +110,7 @@ void nft_meta_get_eval(const struct nft_expr *expr,
108 read_unlock_bh(&skb->sk->sk_callback_lock); 110 read_unlock_bh(&skb->sk->sk_callback_lock);
109 goto err; 111 goto err;
110 } 112 }
111 dest->data[0] = 113 *dest = from_kgid_munged(&init_user_ns,
112 from_kgid_munged(&init_user_ns,
113 skb->sk->sk_socket->file->f_cred->fsgid); 114 skb->sk->sk_socket->file->f_cred->fsgid);
114 read_unlock_bh(&skb->sk->sk_callback_lock); 115 read_unlock_bh(&skb->sk->sk_callback_lock);
115 break; 116 break;
@@ -119,33 +120,33 @@ void nft_meta_get_eval(const struct nft_expr *expr,
119 120
120 if (dst == NULL) 121 if (dst == NULL)
121 goto err; 122 goto err;
122 dest->data[0] = dst->tclassid; 123 *dest = dst->tclassid;
123 break; 124 break;
124 } 125 }
125#endif 126#endif
126#ifdef CONFIG_NETWORK_SECMARK 127#ifdef CONFIG_NETWORK_SECMARK
127 case NFT_META_SECMARK: 128 case NFT_META_SECMARK:
128 dest->data[0] = skb->secmark; 129 *dest = skb->secmark;
129 break; 130 break;
130#endif 131#endif
131 case NFT_META_PKTTYPE: 132 case NFT_META_PKTTYPE:
132 if (skb->pkt_type != PACKET_LOOPBACK) { 133 if (skb->pkt_type != PACKET_LOOPBACK) {
133 dest->data[0] = skb->pkt_type; 134 *dest = skb->pkt_type;
134 break; 135 break;
135 } 136 }
136 137
137 switch (pkt->ops->pf) { 138 switch (pkt->ops->pf) {
138 case NFPROTO_IPV4: 139 case NFPROTO_IPV4:
139 if (ipv4_is_multicast(ip_hdr(skb)->daddr)) 140 if (ipv4_is_multicast(ip_hdr(skb)->daddr))
140 dest->data[0] = PACKET_MULTICAST; 141 *dest = PACKET_MULTICAST;
141 else 142 else
142 dest->data[0] = PACKET_BROADCAST; 143 *dest = PACKET_BROADCAST;
143 break; 144 break;
144 case NFPROTO_IPV6: 145 case NFPROTO_IPV6:
145 if (ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF) 146 if (ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF)
146 dest->data[0] = PACKET_MULTICAST; 147 *dest = PACKET_MULTICAST;
147 else 148 else
148 dest->data[0] = PACKET_BROADCAST; 149 *dest = PACKET_BROADCAST;
149 break; 150 break;
150 default: 151 default:
151 WARN_ON(1); 152 WARN_ON(1);
@@ -153,22 +154,22 @@ void nft_meta_get_eval(const struct nft_expr *expr,
153 } 154 }
154 break; 155 break;
155 case NFT_META_CPU: 156 case NFT_META_CPU:
156 dest->data[0] = raw_smp_processor_id(); 157 *dest = raw_smp_processor_id();
157 break; 158 break;
158 case NFT_META_IIFGROUP: 159 case NFT_META_IIFGROUP:
159 if (in == NULL) 160 if (in == NULL)
160 goto err; 161 goto err;
161 dest->data[0] = in->group; 162 *dest = in->group;
162 break; 163 break;
163 case NFT_META_OIFGROUP: 164 case NFT_META_OIFGROUP:
164 if (out == NULL) 165 if (out == NULL)
165 goto err; 166 goto err;
166 dest->data[0] = out->group; 167 *dest = out->group;
167 break; 168 break;
168 case NFT_META_CGROUP: 169 case NFT_META_CGROUP:
169 if (skb->sk == NULL || !sk_fullsock(skb->sk)) 170 if (skb->sk == NULL || !sk_fullsock(skb->sk))
170 goto err; 171 goto err;
171 dest->data[0] = skb->sk->sk_classid; 172 *dest = skb->sk->sk_classid;
172 break; 173 break;
173 default: 174 default:
174 WARN_ON(1); 175 WARN_ON(1);
@@ -177,17 +178,17 @@ void nft_meta_get_eval(const struct nft_expr *expr,
177 return; 178 return;
178 179
179err: 180err:
180 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 181 regs->verdict.code = NFT_BREAK;
181} 182}
182EXPORT_SYMBOL_GPL(nft_meta_get_eval); 183EXPORT_SYMBOL_GPL(nft_meta_get_eval);
183 184
184void nft_meta_set_eval(const struct nft_expr *expr, 185void nft_meta_set_eval(const struct nft_expr *expr,
185 struct nft_data data[NFT_REG_MAX + 1], 186 struct nft_regs *regs,
186 const struct nft_pktinfo *pkt) 187 const struct nft_pktinfo *pkt)
187{ 188{
188 const struct nft_meta *meta = nft_expr_priv(expr); 189 const struct nft_meta *meta = nft_expr_priv(expr);
189 struct sk_buff *skb = pkt->skb; 190 struct sk_buff *skb = pkt->skb;
190 u32 value = data[meta->sreg].data[0]; 191 u32 value = regs->data[meta->sreg];
191 192
192 switch (meta->key) { 193 switch (meta->key) {
193 case NFT_META_MARK: 194 case NFT_META_MARK:
@@ -217,22 +218,22 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
217 const struct nlattr * const tb[]) 218 const struct nlattr * const tb[])
218{ 219{
219 struct nft_meta *priv = nft_expr_priv(expr); 220 struct nft_meta *priv = nft_expr_priv(expr);
220 int err; 221 unsigned int len;
221 222
222 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); 223 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
223 switch (priv->key) { 224 switch (priv->key) {
224 case NFT_META_LEN:
225 case NFT_META_PROTOCOL: 225 case NFT_META_PROTOCOL:
226 case NFT_META_IIFTYPE:
227 case NFT_META_OIFTYPE:
228 len = sizeof(u16);
229 break;
226 case NFT_META_NFPROTO: 230 case NFT_META_NFPROTO:
227 case NFT_META_L4PROTO: 231 case NFT_META_L4PROTO:
232 case NFT_META_LEN:
228 case NFT_META_PRIORITY: 233 case NFT_META_PRIORITY:
229 case NFT_META_MARK: 234 case NFT_META_MARK:
230 case NFT_META_IIF: 235 case NFT_META_IIF:
231 case NFT_META_OIF: 236 case NFT_META_OIF:
232 case NFT_META_IIFNAME:
233 case NFT_META_OIFNAME:
234 case NFT_META_IIFTYPE:
235 case NFT_META_OIFTYPE:
236 case NFT_META_SKUID: 237 case NFT_META_SKUID:
237 case NFT_META_SKGID: 238 case NFT_META_SKGID:
238#ifdef CONFIG_IP_ROUTE_CLASSID 239#ifdef CONFIG_IP_ROUTE_CLASSID
@@ -246,21 +247,19 @@ int nft_meta_get_init(const struct nft_ctx *ctx,
246 case NFT_META_IIFGROUP: 247 case NFT_META_IIFGROUP:
247 case NFT_META_OIFGROUP: 248 case NFT_META_OIFGROUP:
248 case NFT_META_CGROUP: 249 case NFT_META_CGROUP:
250 len = sizeof(u32);
251 break;
252 case NFT_META_IIFNAME:
253 case NFT_META_OIFNAME:
254 len = IFNAMSIZ;
249 break; 255 break;
250 default: 256 default:
251 return -EOPNOTSUPP; 257 return -EOPNOTSUPP;
252 } 258 }
253 259
254 priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); 260 priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
255 err = nft_validate_output_register(priv->dreg); 261 return nft_validate_register_store(ctx, priv->dreg, NULL,
256 if (err < 0) 262 NFT_DATA_VALUE, len);
257 return err;
258
259 err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
260 if (err < 0)
261 return err;
262
263 return 0;
264} 263}
265EXPORT_SYMBOL_GPL(nft_meta_get_init); 264EXPORT_SYMBOL_GPL(nft_meta_get_init);
266 265
@@ -269,20 +268,24 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
269 const struct nlattr * const tb[]) 268 const struct nlattr * const tb[])
270{ 269{
271 struct nft_meta *priv = nft_expr_priv(expr); 270 struct nft_meta *priv = nft_expr_priv(expr);
271 unsigned int len;
272 int err; 272 int err;
273 273
274 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); 274 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
275 switch (priv->key) { 275 switch (priv->key) {
276 case NFT_META_MARK: 276 case NFT_META_MARK:
277 case NFT_META_PRIORITY: 277 case NFT_META_PRIORITY:
278 len = sizeof(u32);
279 break;
278 case NFT_META_NFTRACE: 280 case NFT_META_NFTRACE:
281 len = sizeof(u8);
279 break; 282 break;
280 default: 283 default:
281 return -EOPNOTSUPP; 284 return -EOPNOTSUPP;
282 } 285 }
283 286
284 priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG])); 287 priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
285 err = nft_validate_input_register(priv->sreg); 288 err = nft_validate_register_load(priv->sreg, len);
286 if (err < 0) 289 if (err < 0)
287 return err; 290 return err;
288 291
@@ -297,7 +300,7 @@ int nft_meta_get_dump(struct sk_buff *skb,
297 300
298 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) 301 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
299 goto nla_put_failure; 302 goto nla_put_failure;
300 if (nla_put_be32(skb, NFTA_META_DREG, htonl(priv->dreg))) 303 if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg))
301 goto nla_put_failure; 304 goto nla_put_failure;
302 return 0; 305 return 0;
303 306
@@ -313,7 +316,7 @@ int nft_meta_set_dump(struct sk_buff *skb,
313 316
314 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) 317 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
315 goto nla_put_failure; 318 goto nla_put_failure;
316 if (nla_put_be32(skb, NFTA_META_SREG, htonl(priv->sreg))) 319 if (nft_dump_register(skb, NFTA_META_SREG, priv->sreg))
317 goto nla_put_failure; 320 goto nla_put_failure;
318 321
319 return 0; 322 return 0;
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index a0837c6c9283..ee2d71753746 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -37,7 +37,7 @@ struct nft_nat {
37}; 37};
38 38
39static void nft_nat_eval(const struct nft_expr *expr, 39static void nft_nat_eval(const struct nft_expr *expr,
40 struct nft_data data[NFT_REG_MAX + 1], 40 struct nft_regs *regs,
41 const struct nft_pktinfo *pkt) 41 const struct nft_pktinfo *pkt)
42{ 42{
43 const struct nft_nat *priv = nft_expr_priv(expr); 43 const struct nft_nat *priv = nft_expr_priv(expr);
@@ -49,33 +49,32 @@ static void nft_nat_eval(const struct nft_expr *expr,
49 if (priv->sreg_addr_min) { 49 if (priv->sreg_addr_min) {
50 if (priv->family == AF_INET) { 50 if (priv->family == AF_INET) {
51 range.min_addr.ip = (__force __be32) 51 range.min_addr.ip = (__force __be32)
52 data[priv->sreg_addr_min].data[0]; 52 regs->data[priv->sreg_addr_min];
53 range.max_addr.ip = (__force __be32) 53 range.max_addr.ip = (__force __be32)
54 data[priv->sreg_addr_max].data[0]; 54 regs->data[priv->sreg_addr_max];
55 55
56 } else { 56 } else {
57 memcpy(range.min_addr.ip6, 57 memcpy(range.min_addr.ip6,
58 data[priv->sreg_addr_min].data, 58 &regs->data[priv->sreg_addr_min],
59 sizeof(struct nft_data)); 59 sizeof(range.min_addr.ip6));
60 memcpy(range.max_addr.ip6, 60 memcpy(range.max_addr.ip6,
61 data[priv->sreg_addr_max].data, 61 &regs->data[priv->sreg_addr_max],
62 sizeof(struct nft_data)); 62 sizeof(range.max_addr.ip6));
63 } 63 }
64 range.flags |= NF_NAT_RANGE_MAP_IPS; 64 range.flags |= NF_NAT_RANGE_MAP_IPS;
65 } 65 }
66 66
67 if (priv->sreg_proto_min) { 67 if (priv->sreg_proto_min) {
68 range.min_proto.all = 68 range.min_proto.all =
69 *(__be16 *)&data[priv->sreg_proto_min].data[0]; 69 *(__be16 *)&regs->data[priv->sreg_proto_min];
70 range.max_proto.all = 70 range.max_proto.all =
71 *(__be16 *)&data[priv->sreg_proto_max].data[0]; 71 *(__be16 *)&regs->data[priv->sreg_proto_max];
72 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED; 72 range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
73 } 73 }
74 74
75 range.flags |= priv->flags; 75 range.flags |= priv->flags;
76 76
77 data[NFT_REG_VERDICT].verdict = 77 regs->verdict.code = nf_nat_setup_info(ct, &range, priv->type);
78 nf_nat_setup_info(ct, &range, priv->type);
79} 78}
80 79
81static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = { 80static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = {
@@ -119,6 +118,7 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
119 const struct nlattr * const tb[]) 118 const struct nlattr * const tb[])
120{ 119{
121 struct nft_nat *priv = nft_expr_priv(expr); 120 struct nft_nat *priv = nft_expr_priv(expr);
121 unsigned int alen, plen;
122 u32 family; 122 u32 family;
123 int err; 123 int err;
124 124
@@ -146,25 +146,34 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
146 return -EINVAL; 146 return -EINVAL;
147 147
148 family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY])); 148 family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY]));
149 if (family != AF_INET && family != AF_INET6)
150 return -EAFNOSUPPORT;
151 if (family != ctx->afi->family) 149 if (family != ctx->afi->family)
152 return -EOPNOTSUPP; 150 return -EOPNOTSUPP;
151
152 switch (family) {
153 case NFPROTO_IPV4:
154 alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip);
155 break;
156 case NFPROTO_IPV6:
157 alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip6);
158 break;
159 default:
160 return -EAFNOSUPPORT;
161 }
153 priv->family = family; 162 priv->family = family;
154 163
155 if (tb[NFTA_NAT_REG_ADDR_MIN]) { 164 if (tb[NFTA_NAT_REG_ADDR_MIN]) {
156 priv->sreg_addr_min = 165 priv->sreg_addr_min =
157 ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MIN])); 166 nft_parse_register(tb[NFTA_NAT_REG_ADDR_MIN]);
158 167 err = nft_validate_register_load(priv->sreg_addr_min, alen);
159 err = nft_validate_input_register(priv->sreg_addr_min);
160 if (err < 0) 168 if (err < 0)
161 return err; 169 return err;
162 170
163 if (tb[NFTA_NAT_REG_ADDR_MAX]) { 171 if (tb[NFTA_NAT_REG_ADDR_MAX]) {
164 priv->sreg_addr_max = 172 priv->sreg_addr_max =
165 ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MAX])); 173 nft_parse_register(tb[NFTA_NAT_REG_ADDR_MAX]);
166 174
167 err = nft_validate_input_register(priv->sreg_addr_max); 175 err = nft_validate_register_load(priv->sreg_addr_max,
176 alen);
168 if (err < 0) 177 if (err < 0)
169 return err; 178 return err;
170 } else { 179 } else {
@@ -172,19 +181,21 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
172 } 181 }
173 } 182 }
174 183
184 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
175 if (tb[NFTA_NAT_REG_PROTO_MIN]) { 185 if (tb[NFTA_NAT_REG_PROTO_MIN]) {
176 priv->sreg_proto_min = 186 priv->sreg_proto_min =
177 ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MIN])); 187 nft_parse_register(tb[NFTA_NAT_REG_PROTO_MIN]);
178 188
179 err = nft_validate_input_register(priv->sreg_proto_min); 189 err = nft_validate_register_load(priv->sreg_proto_min, plen);
180 if (err < 0) 190 if (err < 0)
181 return err; 191 return err;
182 192
183 if (tb[NFTA_NAT_REG_PROTO_MAX]) { 193 if (tb[NFTA_NAT_REG_PROTO_MAX]) {
184 priv->sreg_proto_max = 194 priv->sreg_proto_max =
185 ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MAX])); 195 nft_parse_register(tb[NFTA_NAT_REG_PROTO_MAX]);
186 196
187 err = nft_validate_input_register(priv->sreg_proto_max); 197 err = nft_validate_register_load(priv->sreg_proto_max,
198 plen);
188 if (err < 0) 199 if (err < 0)
189 return err; 200 return err;
190 } else { 201 } else {
@@ -220,18 +231,18 @@ static int nft_nat_dump(struct sk_buff *skb, const struct nft_expr *expr)
220 goto nla_put_failure; 231 goto nla_put_failure;
221 232
222 if (priv->sreg_addr_min) { 233 if (priv->sreg_addr_min) {
223 if (nla_put_be32(skb, NFTA_NAT_REG_ADDR_MIN, 234 if (nft_dump_register(skb, NFTA_NAT_REG_ADDR_MIN,
224 htonl(priv->sreg_addr_min)) || 235 priv->sreg_addr_min) ||
225 nla_put_be32(skb, NFTA_NAT_REG_ADDR_MAX, 236 nft_dump_register(skb, NFTA_NAT_REG_ADDR_MAX,
226 htonl(priv->sreg_addr_max))) 237 priv->sreg_addr_max))
227 goto nla_put_failure; 238 goto nla_put_failure;
228 } 239 }
229 240
230 if (priv->sreg_proto_min) { 241 if (priv->sreg_proto_min) {
231 if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MIN, 242 if (nft_dump_register(skb, NFTA_NAT_REG_PROTO_MIN,
232 htonl(priv->sreg_proto_min)) || 243 priv->sreg_proto_min) ||
233 nla_put_be32(skb, NFTA_NAT_REG_PROTO_MAX, 244 nft_dump_register(skb, NFTA_NAT_REG_PROTO_MAX,
234 htonl(priv->sreg_proto_max))) 245 priv->sreg_proto_max))
235 goto nla_put_failure; 246 goto nla_put_failure;
236 } 247 }
237 248
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c
index 85daa84bfdfe..94fb3b27a2c5 100644
--- a/net/netfilter/nft_payload.c
+++ b/net/netfilter/nft_payload.c
@@ -18,12 +18,12 @@
18#include <net/netfilter/nf_tables.h> 18#include <net/netfilter/nf_tables.h>
19 19
20static void nft_payload_eval(const struct nft_expr *expr, 20static void nft_payload_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 const struct nft_payload *priv = nft_expr_priv(expr); 24 const struct nft_payload *priv = nft_expr_priv(expr);
25 const struct sk_buff *skb = pkt->skb; 25 const struct sk_buff *skb = pkt->skb;
26 struct nft_data *dest = &data[priv->dreg]; 26 u32 *dest = &regs->data[priv->dreg];
27 int offset; 27 int offset;
28 28
29 switch (priv->base) { 29 switch (priv->base) {
@@ -43,11 +43,12 @@ static void nft_payload_eval(const struct nft_expr *expr,
43 } 43 }
44 offset += priv->offset; 44 offset += priv->offset;
45 45
46 if (skb_copy_bits(skb, offset, dest->data, priv->len) < 0) 46 dest[priv->len / NFT_REG32_SIZE] = 0;
47 if (skb_copy_bits(skb, offset, dest, priv->len) < 0)
47 goto err; 48 goto err;
48 return; 49 return;
49err: 50err:
50 data[NFT_REG_VERDICT].verdict = NFT_BREAK; 51 regs->verdict.code = NFT_BREAK;
51} 52}
52 53
53static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = { 54static const struct nla_policy nft_payload_policy[NFTA_PAYLOAD_MAX + 1] = {
@@ -62,24 +63,21 @@ static int nft_payload_init(const struct nft_ctx *ctx,
62 const struct nlattr * const tb[]) 63 const struct nlattr * const tb[])
63{ 64{
64 struct nft_payload *priv = nft_expr_priv(expr); 65 struct nft_payload *priv = nft_expr_priv(expr);
65 int err;
66 66
67 priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE])); 67 priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE]));
68 priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); 68 priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
69 priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); 69 priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
70 priv->dreg = nft_parse_register(tb[NFTA_PAYLOAD_DREG]);
70 71
71 priv->dreg = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_DREG])); 72 return nft_validate_register_store(ctx, priv->dreg, NULL,
72 err = nft_validate_output_register(priv->dreg); 73 NFT_DATA_VALUE, priv->len);
73 if (err < 0)
74 return err;
75 return nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE);
76} 74}
77 75
78static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr) 76static int nft_payload_dump(struct sk_buff *skb, const struct nft_expr *expr)
79{ 77{
80 const struct nft_payload *priv = nft_expr_priv(expr); 78 const struct nft_payload *priv = nft_expr_priv(expr);
81 79
82 if (nla_put_be32(skb, NFTA_PAYLOAD_DREG, htonl(priv->dreg)) || 80 if (nft_dump_register(skb, NFTA_PAYLOAD_DREG, priv->dreg) ||
83 nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) || 81 nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) ||
84 nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) || 82 nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) ||
85 nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len))) 83 nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)))
@@ -131,9 +129,7 @@ nft_payload_select_ops(const struct nft_ctx *ctx,
131 } 129 }
132 130
133 offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); 131 offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET]));
134 len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); 132 len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN]));
135 if (len == 0 || len > FIELD_SIZEOF(struct nft_data, data))
136 return ERR_PTR(-EINVAL);
137 133
138 if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) && 134 if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) &&
139 base != NFT_PAYLOAD_LL_HEADER) 135 base != NFT_PAYLOAD_LL_HEADER)
diff --git a/net/netfilter/nft_queue.c b/net/netfilter/nft_queue.c
index e8ae2f6bf232..96805d21d618 100644
--- a/net/netfilter/nft_queue.c
+++ b/net/netfilter/nft_queue.c
@@ -28,7 +28,7 @@ struct nft_queue {
28}; 28};
29 29
30static void nft_queue_eval(const struct nft_expr *expr, 30static void nft_queue_eval(const struct nft_expr *expr,
31 struct nft_data data[NFT_REG_MAX + 1], 31 struct nft_regs *regs,
32 const struct nft_pktinfo *pkt) 32 const struct nft_pktinfo *pkt)
33{ 33{
34 struct nft_queue *priv = nft_expr_priv(expr); 34 struct nft_queue *priv = nft_expr_priv(expr);
@@ -51,7 +51,7 @@ static void nft_queue_eval(const struct nft_expr *expr,
51 if (priv->flags & NFT_QUEUE_FLAG_BYPASS) 51 if (priv->flags & NFT_QUEUE_FLAG_BYPASS)
52 ret |= NF_VERDICT_FLAG_QUEUE_BYPASS; 52 ret |= NF_VERDICT_FLAG_QUEUE_BYPASS;
53 53
54 data[NFT_REG_VERDICT].verdict = ret; 54 regs->verdict.code = ret;
55} 55}
56 56
57static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = { 57static const struct nla_policy nft_queue_policy[NFTA_QUEUE_MAX + 1] = {
diff --git a/net/netfilter/nft_rbtree.c b/net/netfilter/nft_rbtree.c
index 42d0ca45fb9e..1c30f41cff5b 100644
--- a/net/netfilter/nft_rbtree.c
+++ b/net/netfilter/nft_rbtree.c
@@ -30,8 +30,7 @@ struct nft_rbtree_elem {
30}; 30};
31 31
32 32
33static bool nft_rbtree_lookup(const struct nft_set *set, 33static bool nft_rbtree_lookup(const struct nft_set *set, const u32 *key,
34 const struct nft_data *key,
35 const struct nft_set_ext **ext) 34 const struct nft_set_ext **ext)
36{ 35{
37 const struct nft_rbtree *priv = nft_set_priv(set); 36 const struct nft_rbtree *priv = nft_set_priv(set);
@@ -45,7 +44,7 @@ static bool nft_rbtree_lookup(const struct nft_set *set,
45 while (parent != NULL) { 44 while (parent != NULL) {
46 rbe = rb_entry(parent, struct nft_rbtree_elem, node); 45 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
47 46
48 d = nft_data_cmp(nft_set_ext_key(&rbe->ext), key, set->klen); 47 d = memcmp(nft_set_ext_key(&rbe->ext), key, set->klen);
49 if (d < 0) { 48 if (d < 0) {
50 parent = parent->rb_left; 49 parent = parent->rb_left;
51 interval = rbe; 50 interval = rbe;
@@ -91,9 +90,9 @@ static int __nft_rbtree_insert(const struct nft_set *set,
91 while (*p != NULL) { 90 while (*p != NULL) {
92 parent = *p; 91 parent = *p;
93 rbe = rb_entry(parent, struct nft_rbtree_elem, node); 92 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
94 d = nft_data_cmp(nft_set_ext_key(&rbe->ext), 93 d = memcmp(nft_set_ext_key(&rbe->ext),
95 nft_set_ext_key(&new->ext), 94 nft_set_ext_key(&new->ext),
96 set->klen); 95 set->klen);
97 if (d < 0) 96 if (d < 0)
98 p = &parent->rb_left; 97 p = &parent->rb_left;
99 else if (d > 0) 98 else if (d > 0)
@@ -153,8 +152,8 @@ static void *nft_rbtree_deactivate(const struct nft_set *set,
153 while (parent != NULL) { 152 while (parent != NULL) {
154 rbe = rb_entry(parent, struct nft_rbtree_elem, node); 153 rbe = rb_entry(parent, struct nft_rbtree_elem, node);
155 154
156 d = nft_data_cmp(nft_set_ext_key(&rbe->ext), &elem->key, 155 d = memcmp(nft_set_ext_key(&rbe->ext), &elem->key.val,
157 set->klen); 156 set->klen);
158 if (d < 0) 157 if (d < 0)
159 parent = parent->rb_left; 158 parent = parent->rb_left;
160 else if (d > 0) 159 else if (d > 0)
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
index d7e9e93a4e90..03f7bf40ae75 100644
--- a/net/netfilter/nft_redir.c
+++ b/net/netfilter/nft_redir.c
@@ -44,25 +44,28 @@ int nft_redir_init(const struct nft_ctx *ctx,
44 const struct nlattr * const tb[]) 44 const struct nlattr * const tb[])
45{ 45{
46 struct nft_redir *priv = nft_expr_priv(expr); 46 struct nft_redir *priv = nft_expr_priv(expr);
47 unsigned int plen;
47 int err; 48 int err;
48 49
49 err = nft_redir_validate(ctx, expr, NULL); 50 err = nft_redir_validate(ctx, expr, NULL);
50 if (err < 0) 51 if (err < 0)
51 return err; 52 return err;
52 53
54 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
53 if (tb[NFTA_REDIR_REG_PROTO_MIN]) { 55 if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
54 priv->sreg_proto_min = 56 priv->sreg_proto_min =
55 ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN])); 57 nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MIN]);
56 58
57 err = nft_validate_input_register(priv->sreg_proto_min); 59 err = nft_validate_register_load(priv->sreg_proto_min, plen);
58 if (err < 0) 60 if (err < 0)
59 return err; 61 return err;
60 62
61 if (tb[NFTA_REDIR_REG_PROTO_MAX]) { 63 if (tb[NFTA_REDIR_REG_PROTO_MAX]) {
62 priv->sreg_proto_max = 64 priv->sreg_proto_max =
63 ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX])); 65 nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MAX]);
64 66
65 err = nft_validate_input_register(priv->sreg_proto_max); 67 err = nft_validate_register_load(priv->sreg_proto_max,
68 plen);
66 if (err < 0) 69 if (err < 0)
67 return err; 70 return err;
68 } else { 71 } else {
@@ -85,11 +88,11 @@ int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr)
85 const struct nft_redir *priv = nft_expr_priv(expr); 88 const struct nft_redir *priv = nft_expr_priv(expr);
86 89
87 if (priv->sreg_proto_min) { 90 if (priv->sreg_proto_min) {
88 if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MIN, 91 if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MIN,
89 htonl(priv->sreg_proto_min))) 92 priv->sreg_proto_min))
90 goto nla_put_failure; 93 goto nla_put_failure;
91 if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MAX, 94 if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MAX,
92 htonl(priv->sreg_proto_max))) 95 priv->sreg_proto_max))
93 goto nla_put_failure; 96 goto nla_put_failure;
94 } 97 }
95 98
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c
index 92877114aff4..62cabee42fbe 100644
--- a/net/netfilter/nft_reject_inet.c
+++ b/net/netfilter/nft_reject_inet.c
@@ -18,7 +18,7 @@
18#include <net/netfilter/ipv6/nf_reject.h> 18#include <net/netfilter/ipv6/nf_reject.h>
19 19
20static void nft_reject_inet_eval(const struct nft_expr *expr, 20static void nft_reject_inet_eval(const struct nft_expr *expr,
21 struct nft_data data[NFT_REG_MAX + 1], 21 struct nft_regs *regs,
22 const struct nft_pktinfo *pkt) 22 const struct nft_pktinfo *pkt)
23{ 23{
24 struct nft_reject *priv = nft_expr_priv(expr); 24 struct nft_reject *priv = nft_expr_priv(expr);
@@ -58,7 +58,8 @@ static void nft_reject_inet_eval(const struct nft_expr *expr,
58 } 58 }
59 break; 59 break;
60 } 60 }
61 data[NFT_REG_VERDICT].verdict = NF_DROP; 61
62 regs->verdict.code = NF_DROP;
62} 63}
63 64
64static int nft_reject_inet_init(const struct nft_ctx *ctx, 65static int nft_reject_inet_init(const struct nft_ctx *ctx,