Skip to content

Commit

Permalink
Merge branch 'prestera-port-range-filters'
Browse files Browse the repository at this point in the history
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: David S. Miller <davem@davemloft.net>
Co-developed-by: Volodymyr Mytnyk <volodymyr.mytnyk@plvision.eu>
Signed-off-by: Volodymyr Mytnyk <volodymyr.mytnyk@plvision.eu>
Signed-off-by: Maksym Glubokiy <maksym.glubokiy@plvision.eu>
  • Loading branch information
David S. Miller committed Jul 13, 2022
2 parents dd51723 + 551871b commit 4fb56d8
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 7 deletions.
24 changes: 24 additions & 0 deletions drivers/net/ethernet/marvell/prestera/prestera_flower.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ static int prestera_flower_parse(struct prestera_flow_block *block,
BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
BIT(FLOW_DISSECTOR_KEY_ICMP) |
BIT(FLOW_DISSECTOR_KEY_PORTS) |
BIT(FLOW_DISSECTOR_KEY_PORTS_RANGE) |
BIT(FLOW_DISSECTOR_KEY_VLAN))) {
NL_SET_ERR_MSG_MOD(f->common.extack, "Unsupported key");
return -EOPNOTSUPP;
Expand Down Expand Up @@ -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);
}

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)) {
struct flow_match_vlan match;

Expand Down
16 changes: 16 additions & 0 deletions include/net/flow_dissector.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
* type: ICMP type
Expand Down
6 changes: 6 additions & 0 deletions include/net/flow_offload.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ struct flow_match_ports {
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_dissector_key_icmp *key, *mask;
};
Expand Down Expand Up @@ -94,6 +98,8 @@ void flow_rule_match_ip(const struct flow_rule *rule,
struct flow_match_ip *out);
void flow_rule_match_ports(const struct flow_rule *rule,
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,
struct flow_match_tcp *out);
void flow_rule_match_icmp(const struct flow_rule *rule,
Expand Down
7 changes: 7 additions & 0 deletions net/core/flow_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ void flow_rule_match_ports(const struct flow_rule *rule,
}
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,
struct flow_match_tcp *out)
{
Expand Down
8 changes: 1 addition & 7 deletions net/sched/cls_flower.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,7 @@ struct fl_flow_key {
struct flow_dissector_key_ip ip;
struct flow_dissector_key_ip enc_ip;
struct flow_dissector_key_enc_opts enc_opts;
union {
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_ports_range tp_range;
struct flow_dissector_key_ct ct;
struct flow_dissector_key_hash hash;
struct flow_dissector_key_num_of_vlans num_of_vlans;
Expand Down

0 comments on commit 4fb56d8

Please sign in to comment.