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
537537 TCA_FLOWER_KEY_PORT_DST_MIN, /* be16 */
538538 TCA_FLOWER_KEY_PORT_DST_MAX, /* be16 */
539539
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+
540549 __TCA_FLOWER_MAX,
541550 };
542551
543552 #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1)
544553
554+enum {
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+
545561 enum {
546562 TCA_FLOWER_KEY_ENC_OPTS_UNSPEC,
547563 TCA_FLOWER_KEY_ENC_OPTS_GENEVE, /* Nested
net/sched/cls_flower.c+122−5
@@ -26,6 +26,8 @@ · 25 unmodified lines
2626 #include <net/dst.h>
2727 #include <net/dst_metadata.h>
2828
29+#include <uapi/linux/netfilter/nf_conntrack_common.h>
30+
2931 struct fl_flow_key {
3032 struct flow_dissector_key_meta meta;
3133 struct flow_dissector_key_control control;
@@ -54,6 +56,7 @@ struct fl_flow_key { · 22 unmodified lines
5456 struct flow_dissector_key_enc_opts enc_opts;
5557 struct flow_dissector_key_ports tp_min;
5658 struct flow_dissector_key_ports tp_max;
59+ struct flow_dissector_key_ct ct;
5760 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
5861
5962 struct fl_flow_mask_range {
@@ -272,14 +275,27 @@ static struct cls_fl_filter *fl_lookup(struct fl_flow_mask *mask, · 212 unmodified lines
272275 return __fl_lookup(mask, mkey);
273276 }
274277
278+static 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+
275291 static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp,
276292 struct tcf_result *res)
277293 {
278294 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;
282295 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;
283299
284300 list_for_each_entry_rcu(mask, &head->masks, list) {
285301 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
290306 */
291307 skb_key.basic.n_proto = skb->protocol;
292308 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));
293312 skb_flow_dissect(skb, &mask->dissector, &skb_key, 0);
294313
295314 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
686705 [TCA_FLOWER_KEY_ENC_IP_TTL_MASK] = { .type = NLA_U8 },
687706 [TCA_FLOWER_KEY_ENC_OPTS] = { .type = NLA_NESTED },
688707 [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 },
689718 };
690719
691720 static const struct nla_policy
@@ -707,11 +736,11 @@ static void fl_set_key_val(struct nlattr **tb, · 15 unmodified lines
707736 {
708737 if (!tb[val_type])
709738 return;
710− memcpy(val, nla_data(tb[val_type]), len);
739+ nla_memcpy(val, tb[val_type], len);
711740 if (mask_type == TCA_FLOWER_UNSPEC || !tb[mask_type])
712741 memset(mask, 0xff, len);
713742 else
714− memcpy(mask, nla_data(tb[mask_type]), len);
743+ nla_memcpy(mask, tb[mask_type], len);
715744 }
716745
717746 static 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
9971026 return 0;
9981027 }
9991028
1029+static 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+
10001074 static int fl_set_key(struct net *net, struct nlattr **tb,
10011075 struct fl_flow_key *key, struct fl_flow_key *mask,
10021076 struct netlink_ext_ack *extack)
@@ -1206,6 +1280,10 @@ static int fl_set_key(struct net *net, struct nlattr **tb, · 203 unmodified lines
12061280 return ret;
12071281 }
12081282
1283+ ret = fl_set_key_ct(tb, &key->ct, &mask->ct, extack);
1284+ if (ret)
1285+ return ret;
1286+
12091287 if (tb[TCA_FLOWER_KEY_FLAGS])
12101288 ret = fl_set_key_flags(tb, &key->control.flags, &mask->control.flags);
12111289
@@ -1306,6 +1384,8 @@ static void fl_init_dissector(struct flow_dissector *dissector, · 94 unmodified lines
13061384 FLOW_DISSECTOR_KEY_ENC_IP, enc_ip);
13071385 FL_KEY_SET_IF_MASKED(mask, keys, cnt,
13081386 FLOW_DISSECTOR_KEY_ENC_OPTS, enc_opts);
1387+ FL_KEY_SET_IF_MASKED(mask, keys, cnt,
1388+ FLOW_DISSECTOR_KEY_CT, ct);
13091389
13101390 skb_flow_dissector_init(dissector, keys, cnt);
13111391 }
@@ -2065,6 +2145,40 @@ nla_put_failure: · 753 unmodified lines
20652145 return -EMSGSIZE;
20662146 }
20672147
2148+static 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+
2178+nla_put_failure:
2179+ return -EMSGSIZE;
2180+}
2181+
20682182 static int fl_dump_key_options(struct sk_buff *skb, int enc_opt_type,
20692183 struct flow_dissector_key_enc_opts *enc_opts)
20702184 {
@@ -2298,6 +2412,9 @@ static int fl_dump_key(struct sk_buff *skb, struct net *net, · 227 unmodified lines
22982412 fl_dump_key_enc_opt(skb, &key->enc_opts, &mask->enc_opts))
22992413 goto nla_put_failure;
23002414
2415+ if (fl_dump_key_ct(skb, &key->ct, &mask->ct))
2416+ goto nla_put_failure;
2417+
23012418 if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags))
23022419 goto nla_put_failure;
23032420

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