diff options
| author | Florian Westphal <fw@strlen.de> | 2014-02-18 09:25:32 -0500 |
|---|---|---|
| committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-02-19 05:41:25 -0500 |
| commit | d2bf2f34cc1a8304a5dab0d42e7a2ae58ede94cd (patch) | |
| tree | 886fd9d2a812e9c6ecb5c90a08abf1a7fb1e6b56 | |
| parent | 2ba436fc02f95446bfcb7138db44920ab63deb61 (diff) | |
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>
| -rw-r--r-- | include/net/netfilter/nf_conntrack_labels.h | 4 | ||||
| -rw-r--r-- | include/uapi/linux/netfilter/nf_tables.h | 1 | ||||
| -rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 5 | ||||
| -rw-r--r-- | net/netfilter/nft_ct.c | 24 |
4 files changed, 30 insertions, 4 deletions
diff --git a/include/net/netfilter/nf_conntrack_labels.h b/include/net/netfilter/nf_conntrack_labels.h index c985695283b3..dec6336bf850 100644 --- a/include/net/netfilter/nf_conntrack_labels.h +++ b/include/net/netfilter/nf_conntrack_labels.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | 7 | ||
| 8 | #include <uapi/linux/netfilter/xt_connlabel.h> | 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 | struct nf_conn_labels { | 12 | struct nf_conn_labels { |
| 11 | u8 words; | 13 | u8 words; |
| 12 | unsigned long bits[]; | 14 | unsigned long bits[]; |
| @@ -29,7 +31,7 @@ static inline struct nf_conn_labels *nf_ct_labels_ext_add(struct nf_conn *ct) | |||
| 29 | u8 words; | 31 | u8 words; |
| 30 | 32 | ||
| 31 | words = ACCESS_ONCE(net->ct.label_words); | 33 | words = ACCESS_ONCE(net->ct.label_words); |
| 32 | if (words == 0 || WARN_ON_ONCE(words > 8)) | 34 | if (words == 0) |
| 33 | return NULL; | 35 | return NULL; |
| 34 | 36 | ||
| 35 | cl_ext = nf_ct_ext_add_length(ct, NF_CT_EXT_LABELS, | 37 | cl_ext = nf_ct_ext_add_length(ct, NF_CT_EXT_LABELS, |
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 83c985a6170b..c84c452c62a7 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h | |||
| @@ -601,6 +601,7 @@ enum nft_ct_keys { | |||
| 601 | NFT_CT_PROTOCOL, | 601 | NFT_CT_PROTOCOL, |
| 602 | NFT_CT_PROTO_SRC, | 602 | NFT_CT_PROTO_SRC, |
| 603 | NFT_CT_PROTO_DST, | 603 | NFT_CT_PROTO_DST, |
| 604 | NFT_CT_LABELS, | ||
| 604 | }; | 605 | }; |
| 605 | 606 | ||
| 606 | /** | 607 | /** |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index bb322d0beb48..47e9369997ef 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -966,7 +966,6 @@ ctnetlink_parse_help(const struct nlattr *attr, char **helper_name, | |||
| 966 | return 0; | 966 | return 0; |
| 967 | } | 967 | } |
| 968 | 968 | ||
| 969 | #define __CTA_LABELS_MAX_LENGTH ((XT_CONNLABEL_MAXBIT + 1) / BITS_PER_BYTE) | ||
| 970 | static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { | 969 | static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { |
| 971 | [CTA_TUPLE_ORIG] = { .type = NLA_NESTED }, | 970 | [CTA_TUPLE_ORIG] = { .type = NLA_NESTED }, |
| 972 | [CTA_TUPLE_REPLY] = { .type = NLA_NESTED }, | 971 | [CTA_TUPLE_REPLY] = { .type = NLA_NESTED }, |
| @@ -984,9 +983,9 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = { | |||
| 984 | [CTA_ZONE] = { .type = NLA_U16 }, | 983 | [CTA_ZONE] = { .type = NLA_U16 }, |
| 985 | [CTA_MARK_MASK] = { .type = NLA_U32 }, | 984 | [CTA_MARK_MASK] = { .type = NLA_U32 }, |
| 986 | [CTA_LABELS] = { .type = NLA_BINARY, | 985 | [CTA_LABELS] = { .type = NLA_BINARY, |
| 987 | .len = __CTA_LABELS_MAX_LENGTH }, | 986 | .len = NF_CT_LABELS_MAX_SIZE }, |
| 988 | [CTA_LABELS_MASK] = { .type = NLA_BINARY, | 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 | static int | 991 | static int |
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 46e275403838..e59b08f9ccbd 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <net/netfilter/nf_conntrack_tuple.h> | 19 | #include <net/netfilter/nf_conntrack_tuple.h> |
| 20 | #include <net/netfilter/nf_conntrack_helper.h> | 20 | #include <net/netfilter/nf_conntrack_helper.h> |
| 21 | #include <net/netfilter/nf_conntrack_ecache.h> | 21 | #include <net/netfilter/nf_conntrack_ecache.h> |
| 22 | #include <net/netfilter/nf_conntrack_labels.h> | ||
| 22 | 23 | ||
| 23 | struct nft_ct { | 24 | struct nft_ct { |
| 24 | enum nft_ct_keys key:8; | 25 | enum nft_ct_keys key:8; |
| @@ -97,6 +98,26 @@ static void nft_ct_get_eval(const struct nft_expr *expr, | |||
| 97 | goto err; | 98 | goto err; |
| 98 | strncpy((char *)dest->data, helper->name, sizeof(dest->data)); | 99 | strncpy((char *)dest->data, helper->name, sizeof(dest->data)); |
| 99 | return; | 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 | tuple = &ct->tuplehash[priv->dir].tuple; | 123 | tuple = &ct->tuplehash[priv->dir].tuple; |
| @@ -221,6 +242,9 @@ static int nft_ct_init_validate_get(const struct nft_expr *expr, | |||
| 221 | #ifdef CONFIG_NF_CONNTRACK_SECMARK | 242 | #ifdef CONFIG_NF_CONNTRACK_SECMARK |
| 222 | case NFT_CT_SECMARK: | 243 | case NFT_CT_SECMARK: |
| 223 | #endif | 244 | #endif |
| 245 | #ifdef CONFIG_NF_CONNTRACK_LABELS | ||
| 246 | case NFT_CT_LABELS: | ||
| 247 | #endif | ||
| 224 | case NFT_CT_EXPIRATION: | 248 | case NFT_CT_EXPIRATION: |
| 225 | case NFT_CT_HELPER: | 249 | case NFT_CT_HELPER: |
| 226 | if (tb[NFTA_CT_DIRECTION] != NULL) | 250 | if (tb[NFTA_CT_DIRECTION] != NULL) |
