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.
Unified · Split
| @@ -7,6 +7,8 @@ · 6 unmodified lines | ||
| 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[]; |
| @@ -29,7 +31,7 @@ static inline struct nf_conn_labels *nf_ct_labels_ext_add(struct nf_conn *ct) · 16 unmodified lines | ||
| 29 | 31 | u8 words; |
| 30 | 32 | |
| 31 | 33 | words = ACCESS_ONCE(net->ct.label_words); |
| 32 | − if (words == 0 || WARN_ON_ONCE(words > 8)) | |
| 34 | + if (words == 0) | |
| 33 | 35 | return NULL; |
| 34 | 36 | |
| 35 | 37 | cl_ext = nf_ct_ext_add_length(ct, NF_CT_EXT_LABELS, |
| @@ -601,6 +601,7 @@ enum nft_ct_keys { · 600 unmodified lines | ||
| 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 | /** |
| @@ -966,7 +966,6 @@ ctnetlink_parse_help(const struct nlattr *attr, char **helper_name, · 965 unmodified lines | ||
| 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 }, |
| @@ -984,9 +983,9 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { · 11 unmodified lines | ||
| 984 | 983 | [CTA_ZONE] = { .type = NLA_U16 }, |
| 985 | 984 | [CTA_MARK_MASK] = { .type = NLA_U32 }, |
| 986 | 985 | [CTA_LABELS] = { .type = NLA_BINARY, |
| 987 | − .len = __CTA_LABELS_MAX_LENGTH }, | |
| 986 | + .len = NF_CT_LABELS_MAX_SIZE }, | |
| 988 | 987 | [CTA_LABELS_MASK] = { .type = NLA_BINARY, |
| 989 | − .len = __CTA_LABELS_MAX_LENGTH }, | |
| 988 | + .len = NF_CT_LABELS_MAX_SIZE }, | |
| 990 | 989 | }; |
| 991 | 990 | |
| 992 | 991 | static int |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 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; |
| @@ -97,6 +98,26 @@ static void nft_ct_get_eval(const struct nft_expr *expr, · 72 unmodified lines | ||
| 97 | 98 | goto err; |
| 98 | 99 | strncpy((char *)dest->data, helper->name, sizeof(dest->data)); |
| 99 | 100 | return; |
| 101 | +#ifdef CONFIG_NF_CONNTRACK_LABELS | |
| 102 | + case NFT_CT_LABELS: { | |
| 103 | + struct nf_conn_labels *labels = nf_ct_labels_find(ct); | |
| 104 | + unsigned int size; | |
| 105 | + | |
| 106 | + if (!labels) { | |
| 107 | + memset(dest->data, 0, sizeof(dest->data)); | |
| 108 | + return; | |
| 109 | + } | |
| 110 | + | |
| 111 | + BUILD_BUG_ON(NF_CT_LABELS_MAX_SIZE > sizeof(dest->data)); | |
| 112 | + size = labels->words * sizeof(long); | |
| 113 | + | |
| 114 | + memcpy(dest->data, labels->bits, size); | |
| 115 | + if (size < sizeof(dest->data)) | |
| 116 | + memset(((char *) dest->data) + size, 0, | |
| 117 | + sizeof(dest->data) - size); | |
| 118 | + return; | |
| 119 | + } | |
| 120 | +#endif | |
| 100 | 121 | } |
| 101 | 122 | |
| 102 | 123 | tuple = &ct->tuplehash[priv->dir].tuple; |
| @@ -220,6 +241,9 @@ static int nft_ct_init_validate_get(const struct nft_expr *expr, · 117 unmodified lines | ||
| 220 | 241 | #endif |
| 221 | 242 | #ifdef CONFIG_NF_CONNTRACK_SECMARK |
| 222 | 243 | case NFT_CT_SECMARK: |
| 244 | +#endif | |
| 245 | +#ifdef CONFIG_NF_CONNTRACK_LABELS | |
| 246 | + case NFT_CT_LABELS: | |
| 223 | 247 | #endif |
| 224 | 248 | case NFT_CT_EXPIRATION: |
| 225 | 249 | case NFT_CT_HELPER: |