aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/nft_ct.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2018-03-09 11:57:20 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2018-03-20 13:27:19 +0100
commitd719e3f21cf91d3f82bd827d46199ba41af2f73a (patch)
tree143e281daf395720f4ba2561bd8190fba39df6ae /net/netfilter/nft_ct.c
parent35d8deb80c30fdb2dee3e2dac71eab00d8a6fed5 (diff)
downloadlinux-d719e3f21cf91d3f82bd827d46199ba41af2f73a.tar.gz
netfilter: nft_ct: add NFT_CT_{SRC,DST}_{IP,IP6}
All existing keys, except the NFT_CT_SRC and NFT_CT_DST are assumed to have strict datatypes. This is causing problems with sets and concatenations given the specific length of these keys is not known. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Acked-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'net/netfilter/nft_ct.c')
-rw-r--r--net/netfilter/nft_ct.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 6ab274b144840..ea737fd789e87 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -196,6 +196,26 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
case NFT_CT_PROTO_DST:
nft_reg_store16(dest, (__force u16)tuple->dst.u.all);
return;
+ case NFT_CT_SRC_IP:
+ if (nf_ct_l3num(ct) != NFPROTO_IPV4)
+ goto err;
+ *dest = tuple->src.u3.ip;
+ return;
+ case NFT_CT_DST_IP:
+ if (nf_ct_l3num(ct) != NFPROTO_IPV4)
+ goto err;
+ *dest = tuple->dst.u3.ip;
+ return;
+ case NFT_CT_SRC_IP6:
+ if (nf_ct_l3num(ct) != NFPROTO_IPV6)
+ goto err;
+ memcpy(dest, tuple->src.u3.ip6, sizeof(struct in6_addr));
+ return;
+ case NFT_CT_DST_IP6:
+ if (nf_ct_l3num(ct) != NFPROTO_IPV6)
+ goto err;
+ memcpy(dest, tuple->dst.u3.ip6, sizeof(struct in6_addr));
+ return;
default:
break;
}
@@ -419,6 +439,20 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
return -EAFNOSUPPORT;
}
break;
+ case NFT_CT_SRC_IP:
+ case NFT_CT_DST_IP:
+ if (tb[NFTA_CT_DIRECTION] == NULL)
+ return -EINVAL;
+
+ len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip);
+ break;
+ case NFT_CT_SRC_IP6:
+ case NFT_CT_DST_IP6:
+ if (tb[NFTA_CT_DIRECTION] == NULL)
+ return -EINVAL;
+
+ len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip6);
+ break;
case NFT_CT_PROTO_SRC:
case NFT_CT_PROTO_DST:
if (tb[NFTA_CT_DIRECTION] == NULL)
@@ -588,6 +622,10 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
switch (priv->key) {
case NFT_CT_SRC:
case NFT_CT_DST:
+ case NFT_CT_SRC_IP:
+ case NFT_CT_DST_IP:
+ case NFT_CT_SRC_IP6:
+ case NFT_CT_DST_IP6:
case NFT_CT_PROTO_SRC:
case NFT_CT_PROTO_DST:
if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))