flow_offload: add flow_rule and flow_match structures and use them
This patch wraps the dissector key and mask - that flower uses to represent the matching side - around the flow_match structure. To avoid a follow up patch that would edit the same LoCs in the drivers, this patch also wraps this new flow match structure around the flow rule object. This new structure will also contain the flow actions in follow up patches. This introduces two new interfaces: bool flow_rule_match_key(rule, dissector_id) that returns true if a given matching key is set on, and: flow_rule_match_XYZ(rule, &match); To fetch the matching side XYZ into the match container structure, to retrieve the key and the mask with one single call. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
d9b5a67522
commit
8f2566225a
@@ -2581,9 +2581,11 @@ static int igb_parse_cls_flower(struct igb_adapter *adapter,
|
||||
int traffic_class,
|
||||
struct igb_nfc_filter *input)
|
||||
{
|
||||
struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f);
|
||||
struct flow_dissector *dissector = rule->match.dissector;
|
||||
struct netlink_ext_ack *extack = f->common.extack;
|
||||
|
||||
if (f->dissector->used_keys &
|
||||
if (dissector->used_keys &
|
||||
~(BIT(FLOW_DISSECTOR_KEY_BASIC) |
|
||||
BIT(FLOW_DISSECTOR_KEY_CONTROL) |
|
||||
BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
|
||||
@@ -2593,78 +2595,60 @@ static int igb_parse_cls_flower(struct igb_adapter *adapter,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
|
||||
struct flow_dissector_key_eth_addrs *key, *mask;
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
|
||||
struct flow_match_eth_addrs match;
|
||||
|
||||
key = skb_flow_dissector_target(f->dissector,
|
||||
FLOW_DISSECTOR_KEY_ETH_ADDRS,
|
||||
f->key);
|
||||
mask = skb_flow_dissector_target(f->dissector,
|
||||
FLOW_DISSECTOR_KEY_ETH_ADDRS,
|
||||
f->mask);
|
||||
|
||||
if (!is_zero_ether_addr(mask->dst)) {
|
||||
if (!is_broadcast_ether_addr(mask->dst)) {
|
||||
flow_rule_match_eth_addrs(rule, &match);
|
||||
if (!is_zero_ether_addr(match.mask->dst)) {
|
||||
if (!is_broadcast_ether_addr(match.mask->dst)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Only full masks are supported for destination MAC address");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
input->filter.match_flags |=
|
||||
IGB_FILTER_FLAG_DST_MAC_ADDR;
|
||||
ether_addr_copy(input->filter.dst_addr, key->dst);
|
||||
ether_addr_copy(input->filter.dst_addr, match.key->dst);
|
||||
}
|
||||
|
||||
if (!is_zero_ether_addr(mask->src)) {
|
||||
if (!is_broadcast_ether_addr(mask->src)) {
|
||||
if (!is_zero_ether_addr(match.mask->src)) {
|
||||
if (!is_broadcast_ether_addr(match.mask->src)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Only full masks are supported for source MAC address");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
input->filter.match_flags |=
|
||||
IGB_FILTER_FLAG_SRC_MAC_ADDR;
|
||||
ether_addr_copy(input->filter.src_addr, key->src);
|
||||
ether_addr_copy(input->filter.src_addr, match.key->src);
|
||||
}
|
||||
}
|
||||
|
||||
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
|
||||
struct flow_dissector_key_basic *key, *mask;
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
|
||||
struct flow_match_basic match;
|
||||
|
||||
key = skb_flow_dissector_target(f->dissector,
|
||||
FLOW_DISSECTOR_KEY_BASIC,
|
||||
f->key);
|
||||
mask = skb_flow_dissector_target(f->dissector,
|
||||
FLOW_DISSECTOR_KEY_BASIC,
|
||||
f->mask);
|
||||
|
||||
if (mask->n_proto) {
|
||||
if (mask->n_proto != ETHER_TYPE_FULL_MASK) {
|
||||
flow_rule_match_basic(rule, &match);
|
||||
if (match.mask->n_proto) {
|
||||
if (match.mask->n_proto != ETHER_TYPE_FULL_MASK) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Only full mask is supported for EtherType filter");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
input->filter.match_flags |= IGB_FILTER_FLAG_ETHER_TYPE;
|
||||
input->filter.etype = key->n_proto;
|
||||
input->filter.etype = match.key->n_proto;
|
||||
}
|
||||
}
|
||||
|
||||
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
|
||||
struct flow_dissector_key_vlan *key, *mask;
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
|
||||
struct flow_match_vlan match;
|
||||
|
||||
key = skb_flow_dissector_target(f->dissector,
|
||||
FLOW_DISSECTOR_KEY_VLAN,
|
||||
f->key);
|
||||
mask = skb_flow_dissector_target(f->dissector,
|
||||
FLOW_DISSECTOR_KEY_VLAN,
|
||||
f->mask);
|
||||
|
||||
if (mask->vlan_priority) {
|
||||
if (mask->vlan_priority != VLAN_PRIO_FULL_MASK) {
|
||||
flow_rule_match_vlan(rule, &match);
|
||||
if (match.mask->vlan_priority) {
|
||||
if (match.mask->vlan_priority != VLAN_PRIO_FULL_MASK) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Only full mask is supported for VLAN priority");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
input->filter.match_flags |= IGB_FILTER_FLAG_VLAN_TCI;
|
||||
input->filter.vlan_tci = key->vlan_priority;
|
||||
input->filter.vlan_tci = match.key->vlan_priority;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user