};
 #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_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:
  *
        NFTA_BITWISE_LEN,
        NFTA_BITWISE_MASK,
        NFTA_BITWISE_XOR,
+       NFTA_BITWISE_OP,
        __NFTA_BITWISE_MAX
 };
 #define NFTA_BITWISE_MAX       (__NFTA_BITWISE_MAX - 1)
 
 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;
        [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,
        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)
                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)