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

netfilter: nft_ct: labels get support

This also adds NF_CT_LABELS_MAX_SIZE so it can be re-used
as BUILD_BUG_ON in nft_ct.

At this time, nft doesn't yet support writing to the label area;
when this changes the label->words handling needs to be moved
out of xt_connlabel.c into nf_conntrack_labels.c.

Also removes a useless run-time check: words cannot grow beyond
4 (32 bit) or 2 (64bit) since xt_connlabel enforces a maximum of
128 labels.

Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
d2bf2f34 2ba436fc

+30 -4
+3 -1
include/net/netfilter/nf_conntrack_labels.h
··· 7 7 8 8 #include <uapi/linux/netfilter/xt_connlabel.h> 9 9 10 + #define NF_CT_LABELS_MAX_SIZE ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE) 11 + 10 12 struct nf_conn_labels { 11 13 u8 words; 12 14 unsigned long bits[]; ··· 31 29 u8 words; 32 30 33 31 words = ACCESS_ONCE(net->ct.label_words); 34 - if (words == 0 || WARN_ON_ONCE(words > 8)) 32 + if (words == 0) 35 33 return NULL; 36 34 37 35 cl_ext = nf_ct_ext_add_length(ct, NF_CT_EXT_LABELS,
+1
include/uapi/linux/netfilter/nf_tables.h
··· 601 601 NFT_CT_PROTOCOL, 602 602 NFT_CT_PROTO_SRC, 603 603 NFT_CT_PROTO_DST, 604 + NFT_CT_LABELS, 604 605 }; 605 606 606 607 /**
+2 -3
net/netfilter/nf_conntrack_netlink.c
··· 966 966 return 0; 967 967 } 968 968 969 - #define __CTA_LABELS_MAX_LENGTH ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE) 970 969 static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { 971 970 [CTA_TUPLE_ORIG] = { .type = NLA_NESTED }, 972 971 [CTA_TUPLE_REPLY] = { .type = NLA_NESTED }, ··· 983 984 [CTA_ZONE] = { .type = NLA_U16 }, 984 985 [CTA_MARK_MASK] = { .type = NLA_U32 }, 985 986 [CTA_LABELS] = { .type = NLA_BINARY, 986 - .len = __CTA_LABELS_MAX_LENGTH }, 987 + .len = NF_CT_LABELS_MAX_SIZE }, 987 988 [CTA_LABELS_MASK] = { .type = NLA_BINARY, 988 - .len = __CTA_LABELS_MAX_LENGTH }, 989 + .len = NF_CT_LABELS_MAX_SIZE }, 989 990 }; 990 991 991 992 static int
+24
net/netfilter/nft_ct.c
··· 19 19 #include <net/netfilter/nf_conntrack_tuple.h> 20 20 #include <net/netfilter/nf_conntrack_helper.h> 21 21 #include <net/netfilter/nf_conntrack_ecache.h> 22 + #include <net/netfilter/nf_conntrack_labels.h> 22 23 23 24 struct nft_ct { 24 25 enum nft_ct_keys key:8; ··· 98 97 goto err; 99 98 strncpy((char *)dest->data, helper->name, sizeof(dest->data)); 100 99 return; 100 + #ifdef CONFIG_NF_CONNTRACK_LABELS 101 + case NFT_CT_LABELS: { 102 + struct nf_conn_labels *labels = nf_ct_labels_find(ct); 103 + unsigned int size; 104 + 105 + if (!labels) { 106 + memset(dest->data, 0, sizeof(dest->data)); 107 + return; 108 + } 109 + 110 + BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > sizeof(dest->data)); 111 + size = labels->words * sizeof(long); 112 + 113 + memcpy(dest->data, labels->bits, size); 114 + if (size < sizeof(dest->data)) 115 + memset(((char *) dest->data) + size, 0, 116 + sizeof(dest->data) - size); 117 + return; 118 + } 119 + #endif 101 120 } 102 121 103 122 tuple = &ct->tuplehash[priv->dir].tuple; ··· 241 220 #endif 242 221 #ifdef CONFIG_NF_CONNTRACK_SECMARK 243 222 case NFT_CT_SECMARK: 223 + #endif 224 + #ifdef CONFIG_NF_CONNTRACK_LABELS 225 + case NFT_CT_LABELS: 244 226 #endif 245 227 case NFT_CT_EXPIRATION: 246 228 case NFT_CT_HELPER: