Commit 4d80cc0a authored by Or Gerlitz's avatar Or Gerlitz Committed by David S. Miller

net/sched: cls_flower: add support for matching on ip tos and ttl

Benefit from the support of ip header fields dissection and
allow users to set rules matching on ipv4 tos and ttl or
ipv6 traffic-class and hoplimit.
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 518d8a2e
...@@ -454,6 +454,11 @@ enum { ...@@ -454,6 +454,11 @@ enum {
TCA_FLOWER_KEY_TCP_FLAGS, /* be16 */ TCA_FLOWER_KEY_TCP_FLAGS, /* be16 */
TCA_FLOWER_KEY_TCP_FLAGS_MASK, /* be16 */ TCA_FLOWER_KEY_TCP_FLAGS_MASK, /* be16 */
TCA_FLOWER_KEY_IP_TOS, /* u8 */
TCA_FLOWER_KEY_IP_TOS_MASK, /* u8 */
TCA_FLOWER_KEY_IP_TTL, /* u8 */
TCA_FLOWER_KEY_IP_TTL_MASK, /* u8 */
__TCA_FLOWER_MAX, __TCA_FLOWER_MAX,
}; };
......
...@@ -50,6 +50,7 @@ struct fl_flow_key { ...@@ -50,6 +50,7 @@ struct fl_flow_key {
struct flow_dissector_key_ports enc_tp; struct flow_dissector_key_ports enc_tp;
struct flow_dissector_key_mpls mpls; struct flow_dissector_key_mpls mpls;
struct flow_dissector_key_tcp tcp; struct flow_dissector_key_tcp tcp;
struct flow_dissector_key_ip ip;
} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */ } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
struct fl_flow_mask_range { struct fl_flow_mask_range {
...@@ -427,6 +428,10 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = { ...@@ -427,6 +428,10 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
[TCA_FLOWER_KEY_MPLS_LABEL] = { .type = NLA_U32 }, [TCA_FLOWER_KEY_MPLS_LABEL] = { .type = NLA_U32 },
[TCA_FLOWER_KEY_TCP_FLAGS] = { .type = NLA_U16 }, [TCA_FLOWER_KEY_TCP_FLAGS] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_TCP_FLAGS_MASK] = { .type = NLA_U16 }, [TCA_FLOWER_KEY_TCP_FLAGS_MASK] = { .type = NLA_U16 },
[TCA_FLOWER_KEY_IP_TOS] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_IP_TOS_MASK] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_IP_TTL] = { .type = NLA_U8 },
[TCA_FLOWER_KEY_IP_TTL_MASK] = { .type = NLA_U8 },
}; };
static void fl_set_key_val(struct nlattr **tb, static void fl_set_key_val(struct nlattr **tb,
...@@ -528,6 +533,19 @@ static int fl_set_key_flags(struct nlattr **tb, ...@@ -528,6 +533,19 @@ static int fl_set_key_flags(struct nlattr **tb,
return 0; return 0;
} }
static void fl_set_key_ip(struct nlattr **tb,
struct flow_dissector_key_ip *key,
struct flow_dissector_key_ip *mask)
{
fl_set_key_val(tb, &key->tos, TCA_FLOWER_KEY_IP_TOS,
&mask->tos, TCA_FLOWER_KEY_IP_TOS_MASK,
sizeof(key->tos));
fl_set_key_val(tb, &key->ttl, TCA_FLOWER_KEY_IP_TTL,
&mask->ttl, TCA_FLOWER_KEY_IP_TTL_MASK,
sizeof(key->ttl));
}
static int fl_set_key(struct net *net, struct nlattr **tb, static int fl_set_key(struct net *net, struct nlattr **tb,
struct fl_flow_key *key, struct fl_flow_key *mask) struct fl_flow_key *key, struct fl_flow_key *mask)
{ {
...@@ -570,6 +588,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb, ...@@ -570,6 +588,7 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
fl_set_key_val(tb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO, fl_set_key_val(tb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
&mask->basic.ip_proto, TCA_FLOWER_UNSPEC, &mask->basic.ip_proto, TCA_FLOWER_UNSPEC,
sizeof(key->basic.ip_proto)); sizeof(key->basic.ip_proto));
fl_set_key_ip(tb, &key->ip, &mask->ip);
} }
if (tb[TCA_FLOWER_KEY_IPV4_SRC] || tb[TCA_FLOWER_KEY_IPV4_DST]) { if (tb[TCA_FLOWER_KEY_IPV4_SRC] || tb[TCA_FLOWER_KEY_IPV4_DST]) {
...@@ -772,6 +791,8 @@ static void fl_init_dissector(struct cls_fl_head *head, ...@@ -772,6 +791,8 @@ static void fl_init_dissector(struct cls_fl_head *head,
FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6); FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_PORTS, tp); FLOW_DISSECTOR_KEY_PORTS, tp);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_IP, ip);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_TCP, tcp); FLOW_DISSECTOR_KEY_TCP, tcp);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt, FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
...@@ -1082,6 +1103,19 @@ static int fl_dump_key_mpls(struct sk_buff *skb, ...@@ -1082,6 +1103,19 @@ static int fl_dump_key_mpls(struct sk_buff *skb,
return 0; return 0;
} }
static int fl_dump_key_ip(struct sk_buff *skb,
struct flow_dissector_key_ip *key,
struct flow_dissector_key_ip *mask)
{
if (fl_dump_key_val(skb, &key->tos, TCA_FLOWER_KEY_IP_TOS, &mask->tos,
TCA_FLOWER_KEY_IP_TOS_MASK, sizeof(key->tos)) ||
fl_dump_key_val(skb, &key->ttl, TCA_FLOWER_KEY_IP_TTL, &mask->ttl,
TCA_FLOWER_KEY_IP_TTL_MASK, sizeof(key->ttl)))
return -1;
return 0;
}
static int fl_dump_key_vlan(struct sk_buff *skb, static int fl_dump_key_vlan(struct sk_buff *skb,
struct flow_dissector_key_vlan *vlan_key, struct flow_dissector_key_vlan *vlan_key,
struct flow_dissector_key_vlan *vlan_mask) struct flow_dissector_key_vlan *vlan_mask)
...@@ -1195,9 +1229,10 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, ...@@ -1195,9 +1229,10 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, unsigned long fh,
if ((key->basic.n_proto == htons(ETH_P_IP) || if ((key->basic.n_proto == htons(ETH_P_IP) ||
key->basic.n_proto == htons(ETH_P_IPV6)) && key->basic.n_proto == htons(ETH_P_IPV6)) &&
fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO, (fl_dump_key_val(skb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
&mask->basic.ip_proto, TCA_FLOWER_UNSPEC, &mask->basic.ip_proto, TCA_FLOWER_UNSPEC,
sizeof(key->basic.ip_proto))) sizeof(key->basic.ip_proto)) ||
fl_dump_key_ip(skb, &key->ip, &mask->ip)))
goto nla_put_failure; goto nla_put_failure;
if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS && if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS &&
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment