aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/net/netfilter/nft_meta.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2015-04-11 02:27:37 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2015-04-13 17:17:29 +0200
commit49499c3e6e18b7677a63316f3ff54a16533dc28f (patch)
treee31908a41ad9ef0b575a466c2d8b2a9ca2b3bbe6 /net/netfilter/nft_meta.c
parentnetfilter: nf_tables: add register parsing/dumping helpers (diff)
downloadwireguard-linux-49499c3e6e18b7677a63316f3ff54a16533dc28f.tar.xz
wireguard-linux-49499c3e6e18b7677a63316f3ff54a16533dc28f.zip
netfilter: nf_tables: switch registers to 32 bit addressing
Switch the nf_tables registers from 128 bit addressing to 32 bit addressing to support so called concatenations, where multiple values can be concatenated over multiple registers for O(1) exact matches of multiple dimensions using sets. The old register values are mapped to areas of 128 bits for compatibility. When dumping register numbers, values are expressed using the old values if they refer to the beginning of a 128 bit area for compatibility. To support concatenations, register loads of less than a full 32 bit value need to be padded. This mainly affects the payload and exthdr expressions, which both unconditionally zero the last word before copying the data. Userspace fully passes the testsuite using both old and new register addressing. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nft_meta.c')
-rw-r--r--net/netfilter/nft_meta.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 5f744eb61de5..52561e1c31e2 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -31,13 +31,14 @@ void nft_meta_get_eval(const struct nft_expr *expr,
const struct nft_meta *priv = nft_expr_priv(expr);
const struct sk_buff *skb = pkt->skb;
const struct net_device *in = pkt->in, *out = pkt->out;
- u32 *dest = &regs->data[priv->dreg].data[0];
+ u32 *dest = &regs->data[priv->dreg];
switch (priv->key) {
case NFT_META_LEN:
*dest = skb->len;
break;
case NFT_META_PROTOCOL:
+ *dest = 0;
*(__be16 *)dest = skb->protocol;
break;
case NFT_META_NFPROTO:
@@ -75,11 +76,13 @@ void nft_meta_get_eval(const struct nft_expr *expr,
case NFT_META_IIFTYPE:
if (in == NULL)
goto err;
+ *dest = 0;
*(u16 *)dest = in->type;
break;
case NFT_META_OIFTYPE:
if (out == NULL)
goto err;
+ *dest = 0;
*(u16 *)dest = out->type;
break;
case NFT_META_SKUID:
@@ -185,7 +188,7 @@ void nft_meta_set_eval(const struct nft_expr *expr,
{
const struct nft_meta *meta = nft_expr_priv(expr);
struct sk_buff *skb = pkt->skb;
- u32 value = regs->data[meta->sreg].data[0];
+ u32 value = regs->data[meta->sreg];
switch (meta->key) {
case NFT_META_MARK: