Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+48 -2
+10 -2
include/uapi/linux/netfilter/nf_tables.h
··· 909 909 * @NFT_CT_EXPIRATION: relative conntrack expiration time in ms 910 910 * @NFT_CT_HELPER: connection tracking helper assigned to conntrack 911 911 * @NFT_CT_L3PROTOCOL: conntrack layer 3 protocol 912 - * @NFT_CT_SRC: conntrack layer 3 protocol source (IPv4/IPv6 address) 913 - * @NFT_CT_DST: conntrack layer 3 protocol destination (IPv4/IPv6 address) 912 + * @NFT_CT_SRC: conntrack layer 3 protocol source (IPv4/IPv6 address, deprecated) 913 + * @NFT_CT_DST: conntrack layer 3 protocol destination (IPv4/IPv6 address, deprecated) 914 914 * @NFT_CT_PROTOCOL: conntrack layer 4 protocol 915 915 * @NFT_CT_PROTO_SRC: conntrack layer 4 protocol source 916 916 * @NFT_CT_PROTO_DST: conntrack layer 4 protocol destination ··· 920 920 * @NFT_CT_AVGPKT: conntrack average bytes per packet 921 921 * @NFT_CT_ZONE: conntrack zone 922 922 * @NFT_CT_EVENTMASK: ctnetlink events to be generated for this conntrack 923 + * @NFT_CT_SRC_IP: conntrack layer 3 protocol source (IPv4 address) 924 + * @NFT_CT_DST_IP: conntrack layer 3 protocol destination (IPv4 address) 925 + * @NFT_CT_SRC_IP6: conntrack layer 3 protocol source (IPv6 address) 926 + * @NFT_CT_DST_IP6: conntrack layer 3 protocol destination (IPv6 address) 923 927 */ 924 928 enum nft_ct_keys { 925 929 NFT_CT_STATE, ··· 945 941 NFT_CT_AVGPKT, 946 942 NFT_CT_ZONE, 947 943 NFT_CT_EVENTMASK, 944 + NFT_CT_SRC_IP, 945 + NFT_CT_DST_IP, 946 + NFT_CT_SRC_IP6, 947 + NFT_CT_DST_IP6, 948 948 }; 949 949 950 950 /**
+38
net/netfilter/nft_ct.c
··· 196 196 case NFT_CT_PROTO_DST: 197 197 nft_reg_store16(dest, (__force u16)tuple->dst.u.all); 198 198 return; 199 + case NFT_CT_SRC_IP: 200 + if (nf_ct_l3num(ct) != NFPROTO_IPV4) 201 + goto err; 202 + *dest = tuple->src.u3.ip; 203 + return; 204 + case NFT_CT_DST_IP: 205 + if (nf_ct_l3num(ct) != NFPROTO_IPV4) 206 + goto err; 207 + *dest = tuple->dst.u3.ip; 208 + return; 209 + case NFT_CT_SRC_IP6: 210 + if (nf_ct_l3num(ct) != NFPROTO_IPV6) 211 + goto err; 212 + memcpy(dest, tuple->src.u3.ip6, sizeof(struct in6_addr)); 213 + return; 214 + case NFT_CT_DST_IP6: 215 + if (nf_ct_l3num(ct) != NFPROTO_IPV6) 216 + goto err; 217 + memcpy(dest, tuple->dst.u3.ip6, sizeof(struct in6_addr)); 218 + return; 199 219 default: 200 220 break; 201 221 } ··· 439 419 return -EAFNOSUPPORT; 440 420 } 441 421 break; 422 + case NFT_CT_SRC_IP: 423 + case NFT_CT_DST_IP: 424 + if (tb[NFTA_CT_DIRECTION] == NULL) 425 + return -EINVAL; 426 + 427 + len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip); 428 + break; 429 + case NFT_CT_SRC_IP6: 430 + case NFT_CT_DST_IP6: 431 + if (tb[NFTA_CT_DIRECTION] == NULL) 432 + return -EINVAL; 433 + 434 + len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u3.ip6); 435 + break; 442 436 case NFT_CT_PROTO_SRC: 443 437 case NFT_CT_PROTO_DST: 444 438 if (tb[NFTA_CT_DIRECTION] == NULL) ··· 622 588 switch (priv->key) { 623 589 case NFT_CT_SRC: 624 590 case NFT_CT_DST: 591 + case NFT_CT_SRC_IP: 592 + case NFT_CT_DST_IP: 593 + case NFT_CT_SRC_IP6: 594 + case NFT_CT_DST_IP6: 625 595 case NFT_CT_PROTO_SRC: 626 596 case NFT_CT_PROTO_DST: 627 597 if (nla_put_u8(skb, NFTA_CT_DIRECTION, priv->dir))