History

net/sched: cls_flower: Add matching on conntrack info

New matches for conntrack mark, label, zone, and state.

Paul Blakey committed 7 years ago

Commit e0ace681 parent 75a56752 files · +138 −5Browse files

Unified · Split

2 files
  1. include/uapi/linux/pkt_cls.h +16 −0
  2. net/sched/cls_flower.c +122 −5
include/uapi/linux/pkt_cls.h+16−0
@@ -537,11 +537,27 @@ enum { · 536 unmodified lines
537 TCA_FLOWER_KEY_PORT_DST_MIN, /* be16 */537 TCA_FLOWER_KEY_PORT_DST_MIN, /* be16 */
538 TCA_FLOWER_KEY_PORT_DST_MAX, /* be16 */538 TCA_FLOWER_KEY_PORT_DST_MAX, /* be16 */
539 539
540 TCA_FLOWER_KEY_CT_STATE, /* u16 */
541 TCA_FLOWER_KEY_CT_STATE_MASK, /* u16 */
542 TCA_FLOWER_KEY_CT_ZONE, /* u16 */
543 TCA_FLOWER_KEY_CT_ZONE_MASK, /* u16 */
544 TCA_FLOWER_KEY_CT_MARK, /* u32 */
545 TCA_FLOWER_KEY_CT_MARK_MASK, /* u32 */
546 TCA_FLOWER_KEY_CT_LABELS, /* u128 */
547 TCA_FLOWER_KEY_CT_LABELS_MASK, /* u128 */
548
540 __TCA_FLOWER_MAX,549 __TCA_FLOWER_MAX,
541};550};
542 551
543#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)552#define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
544 553
554enum {
555 TCA_FLOWER_KEY_CT_FLAGS_NEW = 1 << 0, /* Beginning of a new connection. */
556 TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED = 1 << 1, /* Part of an existing connection. */
557 TCA_FLOWER_KEY_CT_FLAGS_RELATED = 1 << 2, /* Related to an established connection. */
558 TCA_FLOWER_KEY_CT_FLAGS_TRACKED = 1 << 3, /* Conntrack has occurred. */
559};
560
545enum {561enum {
546 TCA_FLOWER_KEY_ENC_OPTS_UNSPEC,562 TCA_FLOWER_KEY_ENC_OPTS_UNSPEC,
547 TCA_FLOWER_KEY_ENC_OPTS_GENEVE, /* Nested563 TCA_FLOWER_KEY_ENC_OPTS_GENEVE, /* Nested
net/sched/cls_flower.c+122−5
@@ -26,6 +26,8 @@ · 25 unmodified lines
26#include <net/dst.h>26#include <net/dst.h>
27#include <net/dst_metadata.h>27#include <net/dst_metadata.h>
28 28
29#include <uapi/linux/netfilter/nf_conntrack_common.h>
30
29struct fl_flow_key {31struct fl_flow_key {
30 struct flow_dissector_key_meta meta;32 struct flow_dissector_key_meta meta;
31 struct flow_dissector_key_control control;33 struct flow_dissector_key_control control;
@@ -54,6 +56,7 @@ struct fl_flow_key { · 22 unmodified lines
54 struct flow_dissector_key_enc_opts enc_opts;56 struct flow_dissector_key_enc_opts enc_opts;
55 struct flow_dissector_key_ports tp_min;57 struct flow_dissector_key_ports tp_min;
56 struct flow_dissector_key_ports tp_max;58 struct flow_dissector_key_ports tp_max;
59 struct flow_dissector_key_ct ct;
57} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */60} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
58 61
59struct fl_flow_mask_range {62struct fl_flow_mask_range {
@@ -272,14 +275,27 @@ static struct cls_fl_filter *fl_lookup(struct fl_flow_mask *mask, · 212 unmodified lines
272 return __fl_lookup(mask, mkey);275 return __fl_lookup(mask, mkey);
273}276}
274 277
278static u16 fl_ct_info_to_flower_map[] = {
279 [IP_CT_ESTABLISHED] = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
280 TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED,
281 [IP_CT_RELATED] = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
282 TCA_FLOWER_KEY_CT_FLAGS_RELATED,
283 [IP_CT_ESTABLISHED_REPLY] = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
284 TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED,
285 [IP_CT_RELATED_REPLY] = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
286 TCA_FLOWER_KEY_CT_FLAGS_RELATED,
287 [IP_CT_NEW] = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
288 TCA_FLOWER_KEY_CT_FLAGS_NEW,
289};
290
275static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,291static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
276 struct tcf_result *res)292 struct tcf_result *res)
277{293{
278 struct cls_fl_head *head = rcu_dereference_bh(tp->root);294 struct cls_fl_head *head = rcu_dereference_bh(tp->root);
279 struct cls_fl_filter *f;
280 struct fl_flow_mask *mask;
281 struct fl_flow_key skb_key;
282 struct fl_flow_key skb_mkey;295 struct fl_flow_key skb_mkey;
296 struct fl_flow_key skb_key;
297 struct fl_flow_mask *mask;
298 struct cls_fl_filter *f;
283 299
284 list_for_each_entry_rcu(mask, &head->masks, list) {300 list_for_each_entry_rcu(mask, &head->masks, list) {
285 fl_clear_masked_range(&skb_key, mask);301 fl_clear_masked_range(&skb_key, mask);
@@ -290,6 +306,9 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp, · 4 unmodified lines
290 */306 */
291 skb_key.basic.n_proto = skb->protocol;307 skb_key.basic.n_proto = skb->protocol;
292 skb_flow_dissect_tunnel_info(skb, &mask->dissector, &skb_key);308 skb_flow_dissect_tunnel_info(skb, &mask->dissector, &skb_key);
309 skb_flow_dissect_ct(skb, &mask->dissector, &skb_key,
310 fl_ct_info_to_flower_map,
311 ARRAY_SIZE(fl_ct_info_to_flower_map));
293 skb_flow_dissect(skb, &mask->dissector, &skb_key, 0);312 skb_flow_dissect(skb, &mask->dissector, &skb_key, 0);
294 313
295 fl_set_masked_key(&skb_mkey, &skb_key, mask);314 fl_set_masked_key(&skb_mkey, &skb_key, mask);
@@ -686,6 +705,16 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = { · 390 unmodified lines
686 [TCA_FLOWER_KEY_ENC_IP_TTL_MASK] = { .type = NLA_U8 },705 [TCA_FLOWER_KEY_ENC_IP_TTL_MASK] = { .type = NLA_U8 },
687 [TCA_FLOWER_KEY_ENC_OPTS] = { .type = NLA_NESTED },706 [TCA_FLOWER_KEY_ENC_OPTS] = { .type = NLA_NESTED },
688 [TCA_FLOWER_KEY_ENC_OPTS_MASK] = { .type = NLA_NESTED },707 [TCA_FLOWER_KEY_ENC_OPTS_MASK] = { .type = NLA_NESTED },
708 [TCA_FLOWER_KEY_CT_STATE] = { .type = NLA_U16 },
709 [TCA_FLOWER_KEY_CT_STATE_MASK] = { .type = NLA_U16 },
710 [TCA_FLOWER_KEY_CT_ZONE] = { .type = NLA_U16 },
711 [TCA_FLOWER_KEY_CT_ZONE_MASK] = { .type = NLA_U16 },
712 [TCA_FLOWER_KEY_CT_MARK] = { .type = NLA_U32 },
713 [TCA_FLOWER_KEY_CT_MARK_MASK] = { .type = NLA_U32 },
714 [TCA_FLOWER_KEY_CT_LABELS] = { .type = NLA_BINARY,
715 .len = 128 / BITS_PER_BYTE },
716 [TCA_FLOWER_KEY_CT_LABELS_MASK] = { .type = NLA_BINARY,
717 .len = 128 / BITS_PER_BYTE },
689};718};
690 719
691static const struct nla_policy720static const struct nla_policy
@@ -707,11 +736,11 @@ static void fl_set_key_val(struct nlattr **tb, · 15 unmodified lines
707{736{
708 if (!tb[val_type])737 if (!tb[val_type])
709 return;738 return;
710 memcpy(val, nla_data(tb[val_type]), len);739 nla_memcpy(val, tb[val_type], len);
711 if (mask_type == TCA_FLOWER_UNSPEC || !tb[mask_type])740 if (mask_type == TCA_FLOWER_UNSPEC || !tb[mask_type])
712 memset(mask, 0xff, len);741 memset(mask, 0xff, len);
713 else742 else
714 memcpy(mask, nla_data(tb[mask_type]), len);743 nla_memcpy(mask, tb[mask_type], len);
715}744}
716 745
717static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,746static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,
@@ -997,6 +1026,51 @@ static int fl_set_enc_opt(struct nlattr **tb, struct fl_flow_key *key, · 279 unmodified lines
997 return 0;1026 return 0;
998}1027}
999 1028
1029static int fl_set_key_ct(struct nlattr **tb,
1030 struct flow_dissector_key_ct *key,
1031 struct flow_dissector_key_ct *mask,
1032 struct netlink_ext_ack *extack)
1033{
1034 if (tb[TCA_FLOWER_KEY_CT_STATE]) {
1035 if (!IS_ENABLED(CONFIG_NF_CONNTRACK)) {
1036 NL_SET_ERR_MSG(extack, "Conntrack isn't enabled");
1037 return -EOPNOTSUPP;
1038 }
1039 fl_set_key_val(tb, &key->ct_state, TCA_FLOWER_KEY_CT_STATE,
1040 &mask->ct_state, TCA_FLOWER_KEY_CT_STATE_MASK,
1041 sizeof(key->ct_state));
1042 }
1043 if (tb[TCA_FLOWER_KEY_CT_ZONE]) {
1044 if (!IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES)) {
1045 NL_SET_ERR_MSG(extack, "Conntrack zones isn't enabled");
1046 return -EOPNOTSUPP;
1047 }
1048 fl_set_key_val(tb, &key->ct_zone, TCA_FLOWER_KEY_CT_ZONE,
1049 &mask->ct_zone, TCA_FLOWER_KEY_CT_ZONE_MASK,
1050 sizeof(key->ct_zone));
1051 }
1052 if (tb[TCA_FLOWER_KEY_CT_MARK]) {
1053 if (!IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)) {
1054 NL_SET_ERR_MSG(extack, "Conntrack mark isn't enabled");
1055 return -EOPNOTSUPP;
1056 }
1057 fl_set_key_val(tb, &key->ct_mark, TCA_FLOWER_KEY_CT_MARK,
1058 &mask->ct_mark, TCA_FLOWER_KEY_CT_MARK_MASK,
1059 sizeof(key->ct_mark));
1060 }
1061 if (tb[TCA_FLOWER_KEY_CT_LABELS]) {
1062 if (!IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS)) {
1063 NL_SET_ERR_MSG(extack, "Conntrack labels aren't enabled");
1064 return -EOPNOTSUPP;
1065 }
1066 fl_set_key_val(tb, key->ct_labels, TCA_FLOWER_KEY_CT_LABELS,
1067 mask->ct_labels, TCA_FLOWER_KEY_CT_LABELS_MASK,
1068 sizeof(key->ct_labels));
1069 }
1070
1071 return 0;
1072}
1073
1000static int fl_set_key(struct net *net, struct nlattr **tb,1074static int fl_set_key(struct net *net, struct nlattr **tb,
1001 struct fl_flow_key *key, struct fl_flow_key *mask,1075 struct fl_flow_key *key, struct fl_flow_key *mask,
1002 struct netlink_ext_ack *extack)1076 struct netlink_ext_ack *extack)
@@ -1206,6 +1280,10 @@ static int fl_set_key(struct net *net, struct nlattr **tb, · 203 unmodified lines
1206 return ret;1280 return ret;
1207 }1281 }
1208 1282
1283 ret = fl_set_key_ct(tb, &key->ct, &mask->ct, extack);
1284 if (ret)
1285 return ret;
1286
1209 if (tb[TCA_FLOWER_KEY_FLAGS])1287 if (tb[TCA_FLOWER_KEY_FLAGS])
1210 ret = fl_set_key_flags(tb, &key->control.flags, &mask->control.flags);1288 ret = fl_set_key_flags(tb, &key->control.flags, &mask->control.flags);
1211 1289
@@ -1306,6 +1384,8 @@ static void fl_init_dissector(struct flow_dissector *dissector, · 94 unmodified lines
1306 FLOW_DISSECTOR_KEY_ENC_IP, enc_ip);1384 FLOW_DISSECTOR_KEY_ENC_IP, enc_ip);
1307 FL_KEY_SET_IF_MASKED(mask, keys, cnt,1385 FL_KEY_SET_IF_MASKED(mask, keys, cnt,
1308 FLOW_DISSECTOR_KEY_ENC_OPTS, enc_opts);1386 FLOW_DISSECTOR_KEY_ENC_OPTS, enc_opts);
1387 FL_KEY_SET_IF_MASKED(mask, keys, cnt,
1388 FLOW_DISSECTOR_KEY_CT, ct);
1309 1389
1310 skb_flow_dissector_init(dissector, keys, cnt);1390 skb_flow_dissector_init(dissector, keys, cnt);
1311}1391}
@@ -2065,6 +2145,40 @@ nla_put_failure: · 753 unmodified lines
2065 return -EMSGSIZE;2145 return -EMSGSIZE;
2066}2146}
2067 2147
2148static int fl_dump_key_ct(struct sk_buff *skb,
2149 struct flow_dissector_key_ct *key,
2150 struct flow_dissector_key_ct *mask)
2151{
2152 if (IS_ENABLED(CONFIG_NF_CONNTRACK) &&
2153 fl_dump_key_val(skb, &key->ct_state, TCA_FLOWER_KEY_CT_STATE,
2154 &mask->ct_state, TCA_FLOWER_KEY_CT_STATE_MASK,
2155 sizeof(key->ct_state)))
2156 goto nla_put_failure;
2157
2158 if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES) &&
2159 fl_dump_key_val(skb, &key->ct_zone, TCA_FLOWER_KEY_CT_ZONE,
2160 &mask->ct_zone, TCA_FLOWER_KEY_CT_ZONE_MASK,
2161 sizeof(key->ct_zone)))
2162 goto nla_put_failure;
2163
2164 if (IS_ENABLED(CONFIG_NF_CONNTRACK_MARK) &&
2165 fl_dump_key_val(skb, &key->ct_mark, TCA_FLOWER_KEY_CT_MARK,
2166 &mask->ct_mark, TCA_FLOWER_KEY_CT_MARK_MASK,
2167 sizeof(key->ct_mark)))
2168 goto nla_put_failure;
2169
2170 if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
2171 fl_dump_key_val(skb, &key->ct_labels, TCA_FLOWER_KEY_CT_LABELS,
2172 &mask->ct_labels, TCA_FLOWER_KEY_CT_LABELS_MASK,
2173 sizeof(key->ct_labels)))
2174 goto nla_put_failure;
2175
2176 return 0;
2177
2178nla_put_failure:
2179 return -EMSGSIZE;
2180}
2181
2068static int fl_dump_key_options(struct sk_buff *skb, int enc_opt_type,2182static int fl_dump_key_options(struct sk_buff *skb, int enc_opt_type,
2069 struct flow_dissector_key_enc_opts *enc_opts)2183 struct flow_dissector_key_enc_opts *enc_opts)
2070{2184{
@@ -2298,6 +2412,9 @@ static int fl_dump_key(struct sk_buff *skb, struct net *net, · 227 unmodified lines
2298 fl_dump_key_enc_opt(skb, &key->enc_opts, &mask->enc_opts))2412 fl_dump_key_enc_opt(skb, &key->enc_opts, &mask->enc_opts))
2299 goto nla_put_failure;2413 goto nla_put_failure;
2300 2414
2415 if (fl_dump_key_ct(skb, &key->ct, &mask->ct))
2416 goto nla_put_failure;
2417
2301 if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags))2418 if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags))
2302 goto nla_put_failure;2419 goto nla_put_failure;
2303 2420

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t