netfilter: bitwise: add NFTA_BITWISE_OP netlink attribute.
authorJeremy Sowden <jeremy@azazel.net>
Wed, 15 Jan 2020 20:05:51 +0000 (20:05 +0000)
committerPablo Neira Ayuso <pablo@netfilter.org>
Thu, 16 Jan 2020 14:51:57 +0000 (15:51 +0100)
Add a new bitwise netlink attribute, NFTA_BITWISE_OP, which is set to a
value of a new enum, nft_bitwise_ops.  It describes the type of
operation an expression contains.  Currently, it only has one value:
NFT_BITWISE_BOOL.  More values will be added later to implement shifts.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/uapi/linux/netfilter/nf_tables.h
net/netfilter/nft_bitwise.c

index dd46117..0cddf35 100644 (file)
@@ -485,6 +485,16 @@ enum nft_immediate_attributes {
 #define NFTA_IMMEDIATE_MAX     (__NFTA_IMMEDIATE_MAX - 1)
 
 /**
+ * enum nft_bitwise_ops - nf_tables bitwise operations
+ *
+ * @NFT_BITWISE_BOOL: mask-and-xor operation used to implement NOT, AND, OR and
+ *                    XOR boolean operations
+ */
+enum nft_bitwise_ops {
+       NFT_BITWISE_BOOL,
+};
+
+/**
  * enum nft_bitwise_attributes - nf_tables bitwise expression netlink attributes
  *
  * @NFTA_BITWISE_SREG: source register (NLA_U32: nft_registers)
@@ -492,6 +502,7 @@ enum nft_immediate_attributes {
  * @NFTA_BITWISE_LEN: length of operands (NLA_U32)
  * @NFTA_BITWISE_MASK: mask value (NLA_NESTED: nft_data_attributes)
  * @NFTA_BITWISE_XOR: xor value (NLA_NESTED: nft_data_attributes)
+ * @NFTA_BITWISE_OP: type of operation (NLA_U32: nft_bitwise_ops)
  *
  * The bitwise expression performs the following operation:
  *
@@ -512,6 +523,7 @@ enum nft_bitwise_attributes {
        NFTA_BITWISE_LEN,
        NFTA_BITWISE_MASK,
        NFTA_BITWISE_XOR,
+       NFTA_BITWISE_OP,
        __NFTA_BITWISE_MAX
 };
 #define NFTA_BITWISE_MAX       (__NFTA_BITWISE_MAX - 1)
index c15e9be..6948df7 100644 (file)
@@ -18,6 +18,7 @@
 struct nft_bitwise {
        enum nft_registers      sreg:8;
        enum nft_registers      dreg:8;
+       enum nft_bitwise_ops    op:8;
        u8                      len;
        struct nft_data         mask;
        struct nft_data         xor;
@@ -41,6 +42,7 @@ static const struct nla_policy nft_bitwise_policy[NFTA_BITWISE_MAX + 1] = {
        [NFTA_BITWISE_LEN]      = { .type = NLA_U32 },
        [NFTA_BITWISE_MASK]     = { .type = NLA_NESTED },
        [NFTA_BITWISE_XOR]      = { .type = NLA_NESTED },
+       [NFTA_BITWISE_OP]       = { .type = NLA_U32 },
 };
 
 static int nft_bitwise_init(const struct nft_ctx *ctx,
@@ -76,6 +78,18 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
        if (err < 0)
                return err;
 
+       if (tb[NFTA_BITWISE_OP]) {
+               priv->op = ntohl(nla_get_be32(tb[NFTA_BITWISE_OP]));
+               switch (priv->op) {
+               case NFT_BITWISE_BOOL:
+                       break;
+               default:
+                       return -EOPNOTSUPP;
+               }
+       } else {
+               priv->op = NFT_BITWISE_BOOL;
+       }
+
        err = nft_data_init(NULL, &priv->mask, sizeof(priv->mask), &d1,
                            tb[NFTA_BITWISE_MASK]);
        if (err < 0)
@@ -112,6 +126,8 @@ static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr)
                return -1;
        if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len)))
                return -1;
+       if (nla_put_be32(skb, NFTA_BITWISE_OP, htonl(priv->op)))
+               return -1;
 
        if (nft_data_dump(skb, NFTA_BITWISE_MASK, &priv->mask,
                          NFT_DATA_VALUE, priv->len) < 0)