Commit 4fb56d85 authored by David S. Miller's avatar David S. Miller

Merge branch 'prestera-port-range-filters'

Maksym Glubokiy says:

====================
net: prestera: add support for port range filters

This adds support for port-range rules:

  $ tc qdisc add ... clsact
  $ tc filter add ... flower ... src_port <PMIN>-<PMAX> ...
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Co-developed-by: default avatarVolodymyr Mytnyk <volodymyr.mytnyk@plvision.eu>
Signed-off-by: default avatarVolodymyr Mytnyk <volodymyr.mytnyk@plvision.eu>
Signed-off-by: default avatarMaksym Glubokiy <maksym.glubokiy@plvision.eu>
parents dd517237 551871bf
...@@ -202,6 +202,7 @@ static int prestera_flower_parse(struct prestera_flow_block *block, ...@@ -202,6 +202,7 @@ static int prestera_flower_parse(struct prestera_flow_block *block,
BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
BIT(FLOW_DISSECTOR_KEY_ICMP) | BIT(FLOW_DISSECTOR_KEY_ICMP) |
BIT(FLOW_DISSECTOR_KEY_PORTS) | BIT(FLOW_DISSECTOR_KEY_PORTS) |
BIT(FLOW_DISSECTOR_KEY_PORTS_RANGE) |
BIT(FLOW_DISSECTOR_KEY_VLAN))) { BIT(FLOW_DISSECTOR_KEY_VLAN))) {
NL_SET_ERR_MSG_MOD(f->common.extack, "Unsupported key"); NL_SET_ERR_MSG_MOD(f->common.extack, "Unsupported key");
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -301,6 +302,29 @@ static int prestera_flower_parse(struct prestera_flow_block *block, ...@@ -301,6 +302,29 @@ static int prestera_flower_parse(struct prestera_flow_block *block,
rule_match_set(r_match->mask, L4_PORT_DST, match.mask->dst); rule_match_set(r_match->mask, L4_PORT_DST, match.mask->dst);
} }
if (flow_rule_match_key(f_rule, FLOW_DISSECTOR_KEY_PORTS_RANGE)) {
struct flow_match_ports_range match;
__be32 tp_key, tp_mask;
flow_rule_match_ports_range(f_rule, &match);
/* src port range (min, max) */
tp_key = htonl(ntohs(match.key->tp_min.src) |
(ntohs(match.key->tp_max.src) << 16));
tp_mask = htonl(ntohs(match.mask->tp_min.src) |
(ntohs(match.mask->tp_max.src) << 16));
rule_match_set(r_match->key, L4_PORT_RANGE_SRC, tp_key);
rule_match_set(r_match->mask, L4_PORT_RANGE_SRC, tp_mask);
/* dst port range (min, max) */
tp_key = htonl(ntohs(match.key->tp_min.dst) |
(ntohs(match.key->tp_max.dst) << 16));
tp_mask = htonl(ntohs(match.mask->tp_min.dst) |
(ntohs(match.mask->tp_max.dst) << 16));
rule_match_set(r_match->key, L4_PORT_RANGE_DST, tp_key);
rule_match_set(r_match->mask, L4_PORT_RANGE_DST, tp_mask);
}
if (flow_rule_match_key(f_rule, FLOW_DISSECTOR_KEY_VLAN)) { if (flow_rule_match_key(f_rule, FLOW_DISSECTOR_KEY_VLAN)) {
struct flow_match_vlan match; struct flow_match_vlan match;
......
...@@ -178,6 +178,22 @@ struct flow_dissector_key_ports { ...@@ -178,6 +178,22 @@ struct flow_dissector_key_ports {
}; };
}; };
/**
* struct flow_dissector_key_ports_range
* @tp: port number from packet
* @tp_min: min port number in range
* @tp_max: max port number in range
*/
struct flow_dissector_key_ports_range {
union {
struct flow_dissector_key_ports tp;
struct {
struct flow_dissector_key_ports tp_min;
struct flow_dissector_key_ports tp_max;
};
};
};
/** /**
* flow_dissector_key_icmp: * flow_dissector_key_icmp:
* type: ICMP type * type: ICMP type
......
...@@ -48,6 +48,10 @@ struct flow_match_ports { ...@@ -48,6 +48,10 @@ struct flow_match_ports {
struct flow_dissector_key_ports *key, *mask; struct flow_dissector_key_ports *key, *mask;
}; };
struct flow_match_ports_range {
struct flow_dissector_key_ports_range *key, *mask;
};
struct flow_match_icmp { struct flow_match_icmp {
struct flow_dissector_key_icmp *key, *mask; struct flow_dissector_key_icmp *key, *mask;
}; };
...@@ -94,6 +98,8 @@ void flow_rule_match_ip(const struct flow_rule *rule, ...@@ -94,6 +98,8 @@ void flow_rule_match_ip(const struct flow_rule *rule,
struct flow_match_ip *out); struct flow_match_ip *out);
void flow_rule_match_ports(const struct flow_rule *rule, void flow_rule_match_ports(const struct flow_rule *rule,
struct flow_match_ports *out); struct flow_match_ports *out);
void flow_rule_match_ports_range(const struct flow_rule *rule,
struct flow_match_ports_range *out);
void flow_rule_match_tcp(const struct flow_rule *rule, void flow_rule_match_tcp(const struct flow_rule *rule,
struct flow_match_tcp *out); struct flow_match_tcp *out);
void flow_rule_match_icmp(const struct flow_rule *rule, void flow_rule_match_icmp(const struct flow_rule *rule,
......
...@@ -125,6 +125,13 @@ void flow_rule_match_ports(const struct flow_rule *rule, ...@@ -125,6 +125,13 @@ void flow_rule_match_ports(const struct flow_rule *rule,
} }
EXPORT_SYMBOL(flow_rule_match_ports); EXPORT_SYMBOL(flow_rule_match_ports);
void flow_rule_match_ports_range(const struct flow_rule *rule,
struct flow_match_ports_range *out)
{
FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_PORTS_RANGE, out);
}
EXPORT_SYMBOL(flow_rule_match_ports_range);
void flow_rule_match_tcp(const struct flow_rule *rule, void flow_rule_match_tcp(const struct flow_rule *rule,
struct flow_match_tcp *out) struct flow_match_tcp *out)
{ {
......
...@@ -63,13 +63,7 @@ struct fl_flow_key { ...@@ -63,13 +63,7 @@ struct fl_flow_key {
struct flow_dissector_key_ip ip; struct flow_dissector_key_ip ip;
struct flow_dissector_key_ip enc_ip; struct flow_dissector_key_ip enc_ip;
struct flow_dissector_key_enc_opts enc_opts; struct flow_dissector_key_enc_opts enc_opts;
union { struct flow_dissector_key_ports_range tp_range;
struct flow_dissector_key_ports tp;
struct {
struct flow_dissector_key_ports tp_min;
struct flow_dissector_key_ports tp_max;
};
} tp_range;
struct flow_dissector_key_ct ct; struct flow_dissector_key_ct ct;
struct flow_dissector_key_hash hash; struct flow_dissector_key_hash hash;
struct flow_dissector_key_num_of_vlans num_of_vlans; struct flow_dissector_key_num_of_vlans num_of_vlans;
......
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