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) |