netfilter: nft_ct: add zone id get support
authorFlorian Westphal <fw@strlen.de>
Fri, 3 Feb 2017 12:35:48 +0000 (13:35 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 8 Feb 2017 13:16:22 +0000 (14:16 +0100)
Just like with counters the direction attribute is optional.
We set priv->dir to MAX unconditionally to avoid duplicating the assignment
for all keys with optional direction.

For keys where direction is mandatory, existing code already returns
an error.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/uapi/linux/netfilter/nf_tables.h
net/netfilter/nft_ct.c

index 53aac8b8ed6b7c5c5bf2f4533abf65b11f0ea055..3e60ed78c538baba378f6c5a1f5f83992c06740e 100644 (file)
@@ -870,6 +870,7 @@ enum nft_rt_attributes {
  * @NFT_CT_PKTS: conntrack packets
  * @NFT_CT_BYTES: conntrack bytes
  * @NFT_CT_AVGPKT: conntrack average bytes per packet
+ * @NFT_CT_ZONE: conntrack zone
  */
 enum nft_ct_keys {
        NFT_CT_STATE,
@@ -889,6 +890,7 @@ enum nft_ct_keys {
        NFT_CT_PKTS,
        NFT_CT_BYTES,
        NFT_CT_AVGPKT,
+       NFT_CT_ZONE,
 };
 
 /**
index 66a2377510e17526bf14c93b5db2acbe9d0ee1dd..5bd4cdfdcda512b9021faac17b66144492c33deb 100644 (file)
@@ -151,6 +151,18 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
        case NFT_CT_PROTOCOL:
                *dest = nf_ct_protonum(ct);
                return;
+#ifdef CONFIG_NF_CONNTRACK_ZONES
+       case NFT_CT_ZONE: {
+               const struct nf_conntrack_zone *zone = nf_ct_zone(ct);
+
+               if (priv->dir < IP_CT_DIR_MAX)
+                       *dest = nf_ct_zone_id(zone, priv->dir);
+               else
+                       *dest = zone->id;
+
+               return;
+       }
+#endif
        default:
                break;
        }
@@ -266,6 +278,7 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
        int err;
 
        priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
+       priv->dir = IP_CT_DIR_MAX;
        switch (priv->key) {
        case NFT_CT_DIRECTION:
                if (tb[NFTA_CT_DIRECTION] != NULL)
@@ -333,11 +346,13 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
        case NFT_CT_BYTES:
        case NFT_CT_PKTS:
        case NFT_CT_AVGPKT:
-               /* no direction? return sum of original + reply */
-               if (tb[NFTA_CT_DIRECTION] == NULL)
-                       priv->dir = IP_CT_DIR_MAX;
                len = sizeof(u64);
                break;
+#ifdef CONFIG_NF_CONNTRACK_ZONES
+       case NFT_CT_ZONE:
+               len = sizeof(u16);
+               break;
+#endif
        default:
                return -EOPNOTSUPP;
        }
@@ -465,6 +480,7 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
        case NFT_CT_BYTES:
        case NFT_CT_PKTS:
        case NFT_CT_AVGPKT:
+       case NFT_CT_ZONE:
                if (priv->dir < IP_CT_DIR_MAX &&
                    nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))
                        goto nla_put_failure;