summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/netronome/nfp/flower
diff options
context:
space:
mode:
authorPablo Neira Ayuso2019-02-02 12:50:43 +0100
committerDavid S. Miller2019-02-06 19:38:25 +0100
commit8f2566225ae2d62d532bb1810ed74fa4bbc5bbdb (patch)
tree4a3319b905ef761d89f106e64982ddaac2765273 /drivers/net/ethernet/netronome/nfp/flower
parentMerge branch 'net-phy-add-and-use-further-MMD-accessors' (diff)
downloadkernel-qcow2-linux-8f2566225ae2d62d532bb1810ed74fa4bbc5bbdb.tar.gz
kernel-qcow2-linux-8f2566225ae2d62d532bb1810ed74fa4bbc5bbdb.tar.xz
kernel-qcow2-linux-8f2566225ae2d62d532bb1810ed74fa4bbc5bbdb.zip
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>
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/flower')
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/action.c11
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/match.c417
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/offload.c149
3 files changed, 271 insertions, 306 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/flower/action.c b/drivers/net/ethernet/netronome/nfp/flower/action.c
index 8d54b36afee8..43192640bdd1 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/action.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/action.c
@@ -587,6 +587,7 @@ static int
nfp_fl_pedit(const struct tc_action *action, struct tc_cls_flower_offload *flow,
char *nfp_action, int *a_len, u32 *csum_updated)
{
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow);
struct nfp_fl_set_ipv6_addr set_ip6_dst, set_ip6_src;
struct nfp_fl_set_ipv6_tc_hl_fl set_ip6_tc_hl_fl;
struct nfp_fl_set_ip4_ttl_tos set_ip_ttl_tos;
@@ -643,13 +644,11 @@ nfp_fl_pedit(const struct tc_action *action, struct tc_cls_flower_offload *flow,
return err;
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
- struct flow_dissector_key_basic *basic;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
+ struct flow_match_basic match;
- basic = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC,
- flow->key);
- ip_proto = basic->ip_proto;
+ flow_rule_match_basic(rule, &match);
+ ip_proto = match.key->ip_proto;
}
if (set_eth.head.len_lw) {
diff --git a/drivers/net/ethernet/netronome/nfp/flower/match.c b/drivers/net/ethernet/netronome/nfp/flower/match.c
index c04a0d6b0184..1279fa5da9e1 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/match.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/match.c
@@ -8,31 +8,41 @@
#include "main.h"
static void
-nfp_flower_compile_meta_tci(struct nfp_flower_meta_tci *frame,
- struct tc_cls_flower_offload *flow, u8 key_type,
- bool mask_version)
+nfp_flower_compile_meta_tci(struct nfp_flower_meta_tci *ext,
+ struct nfp_flower_meta_tci *msk,
+ struct tc_cls_flower_offload *flow, u8 key_type)
{
- struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_vlan *flow_vlan;
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow);
u16 tmp_tci;
- memset(frame, 0, sizeof(struct nfp_flower_meta_tci));
+ memset(ext, 0, sizeof(struct nfp_flower_meta_tci));
+ memset(msk, 0, sizeof(struct nfp_flower_meta_tci));
+
/* Populate the metadata frame. */
- frame->nfp_flow_key_layer = key_type;
- frame->mask_id = ~0;
+ ext->nfp_flow_key_layer = key_type;
+ ext->mask_id = ~0;
+
+ msk->nfp_flow_key_layer = key_type;
+ msk->mask_id = ~0;
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
- flow_vlan = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_VLAN,
- target);
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
+ struct flow_match_vlan match;
+
+ flow_rule_match_vlan(rule, &match);
/* Populate the tci field. */
- if (flow_vlan->vlan_id || flow_vlan->vlan_priority) {
+ if (match.key->vlan_id || match.key->vlan_priority) {
+ tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
+ match.key->vlan_priority) |
+ FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
+ match.key->vlan_id) |
+ NFP_FLOWER_MASK_VLAN_CFI;
+ ext->tci = cpu_to_be16(tmp_tci);
tmp_tci = FIELD_PREP(NFP_FLOWER_MASK_VLAN_PRIO,
- flow_vlan->vlan_priority) |
+ match.mask->vlan_priority) |
FIELD_PREP(NFP_FLOWER_MASK_VLAN_VID,
- flow_vlan->vlan_id) |
+ match.mask->vlan_id) |
NFP_FLOWER_MASK_VLAN_CFI;
- frame->tci = cpu_to_be16(tmp_tci);
+ msk->tci = cpu_to_be16(tmp_tci);
}
}
}
@@ -64,231 +74,244 @@ nfp_flower_compile_port(struct nfp_flower_in_port *frame, u32 cmsg_port,
}
static void
-nfp_flower_compile_mac(struct nfp_flower_mac_mpls *frame,
- struct tc_cls_flower_offload *flow,
- bool mask_version)
+nfp_flower_compile_mac(struct nfp_flower_mac_mpls *ext,
+ struct nfp_flower_mac_mpls *msk,
+ struct tc_cls_flower_offload *flow)
{
- struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_eth_addrs *addr;
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow);
- memset(frame, 0, sizeof(struct nfp_flower_mac_mpls));
+ memset(ext, 0, sizeof(struct nfp_flower_mac_mpls));
+ memset(msk, 0, sizeof(struct nfp_flower_mac_mpls));
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
- addr = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ETH_ADDRS,
- target);
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
+ struct flow_match_eth_addrs match;
+
+ flow_rule_match_eth_addrs(rule, &match);
/* Populate mac frame. */
- ether_addr_copy(frame->mac_dst, &addr->dst[0]);
- ether_addr_copy(frame->mac_src, &addr->src[0]);
+ ether_addr_copy(ext->mac_dst, &match.key->dst[0]);
+ ether_addr_copy(ext->mac_src, &match.key->src[0]);
+ ether_addr_copy(msk->mac_dst, &match.mask->dst[0]);
+ ether_addr_copy(msk->mac_src, &match.mask->src[0]);
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_MPLS)) {
- struct flow_dissector_key_mpls *mpls;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS)) {
+ struct flow_match_mpls match;
u32 t_mpls;
- mpls = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_MPLS,
- target);
-
- t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, mpls->mpls_label) |
- FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, mpls->mpls_tc) |
- FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, mpls->mpls_bos) |
+ flow_rule_match_mpls(rule, &match);
+ t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.key->mpls_label) |
+ FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.key->mpls_tc) |
+ FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.key->mpls_bos) |
NFP_FLOWER_MASK_MPLS_Q;
-
- frame->mpls_lse = cpu_to_be32(t_mpls);
- } else if (dissector_uses_key(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC)) {
+ ext->mpls_lse = cpu_to_be32(t_mpls);
+ t_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB, match.mask->mpls_label) |
+ FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC, match.mask->mpls_tc) |
+ FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS, match.mask->mpls_bos) |
+ NFP_FLOWER_MASK_MPLS_Q;
+ msk->mpls_lse = cpu_to_be32(t_mpls);
+ } else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
/* Check for mpls ether type and set NFP_FLOWER_MASK_MPLS_Q
* bit, which indicates an mpls ether type but without any
* mpls fields.
*/
- struct flow_dissector_key_basic *key_basic;
-
- key_basic = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC,
- flow->key);
- if (key_basic->n_proto == cpu_to_be16(ETH_P_MPLS_UC) ||
- key_basic->n_proto == cpu_to_be16(ETH_P_MPLS_MC))
- frame->mpls_lse = cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
+ struct flow_match_basic match;
+
+ flow_rule_match_basic(rule, &match);
+ if (match.key->n_proto == cpu_to_be16(ETH_P_MPLS_UC) ||
+ match.key->n_proto == cpu_to_be16(ETH_P_MPLS_MC)) {
+ ext->mpls_lse = cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
+ msk->mpls_lse = cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
+ }
}
}
static void
-nfp_flower_compile_tport(struct nfp_flower_tp_ports *frame,
- struct tc_cls_flower_offload *flow,
- bool mask_version)
+nfp_flower_compile_tport(struct nfp_flower_tp_ports *ext,
+ struct nfp_flower_tp_ports *msk,
+ struct tc_cls_flower_offload *flow)
{
- struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_ports *tp;
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow);
- memset(frame, 0, sizeof(struct nfp_flower_tp_ports));
+ memset(ext, 0, sizeof(struct nfp_flower_tp_ports));
+ memset(msk, 0, sizeof(struct nfp_flower_tp_ports));
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_PORTS)) {
- tp = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_PORTS,
- target);
- frame->port_src = tp->src;
- frame->port_dst = tp->dst;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
+ struct flow_match_ports match;
+
+ flow_rule_match_ports(rule, &match);
+ ext->port_src = match.key->src;
+ ext->port_dst = match.key->dst;
+ msk->port_src = match.mask->src;
+ msk->port_dst = match.mask->dst;
}
}
static void
-nfp_flower_compile_ip_ext(struct nfp_flower_ip_ext *frame,
- struct tc_cls_flower_offload *flow,
- bool mask_version)
+nfp_flower_compile_ip_ext(struct nfp_flower_ip_ext *ext,
+ struct nfp_flower_ip_ext *msk,
+ struct tc_cls_flower_offload *flow)
{
- struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow);
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
- struct flow_dissector_key_basic *basic;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
+ struct flow_match_basic match;
- basic = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC,
- target);
- frame->proto = basic->ip_proto;
+ flow_rule_match_basic(rule, &match);
+ ext->proto = match.key->ip_proto;
+ msk->proto = match.mask->ip_proto;
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_IP)) {
- struct flow_dissector_key_ip *flow_ip;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
+ struct flow_match_ip match;
- flow_ip = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_IP,
- target);
- frame->tos = flow_ip->tos;
- frame->ttl = flow_ip->ttl;
+ flow_rule_match_ip(rule, &match);
+ ext->tos = match.key->tos;
+ ext->ttl = match.key->ttl;
+ msk->tos = match.mask->tos;
+ msk->ttl = match.mask->ttl;
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_TCP)) {
- struct flow_dissector_key_tcp *tcp;
- u32 tcp_flags;
-
- tcp = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_TCP, target);
- tcp_flags = be16_to_cpu(tcp->flags);
-
- if (tcp_flags & TCPHDR_FIN)
- frame->flags |= NFP_FL_TCP_FLAG_FIN;
- if (tcp_flags & TCPHDR_SYN)
- frame->flags |= NFP_FL_TCP_FLAG_SYN;
- if (tcp_flags & TCPHDR_RST)
- frame->flags |= NFP_FL_TCP_FLAG_RST;
- if (tcp_flags & TCPHDR_PSH)
- frame->flags |= NFP_FL_TCP_FLAG_PSH;
- if (tcp_flags & TCPHDR_URG)
- frame->flags |= NFP_FL_TCP_FLAG_URG;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_TCP)) {
+ struct flow_match_tcp match;
+ u16 tcp_flags;
+
+ flow_rule_match_tcp(rule, &match);
+ tcp_flags = be16_to_cpu(match.key->flags);
+
+ if (tcp_flags & TCPHDR_FIN) {
+ ext->flags |= NFP_FL_TCP_FLAG_FIN;
+ msk->flags |= NFP_FL_TCP_FLAG_FIN;
+ }
+ if (tcp_flags & TCPHDR_SYN) {
+ ext->flags |= NFP_FL_TCP_FLAG_SYN;
+ msk->flags |= NFP_FL_TCP_FLAG_SYN;
+ }
+ if (tcp_flags & TCPHDR_RST) {
+ ext->flags |= NFP_FL_TCP_FLAG_RST;
+ msk->flags |= NFP_FL_TCP_FLAG_RST;
+ }
+ if (tcp_flags & TCPHDR_PSH) {
+ ext->flags |= NFP_FL_TCP_FLAG_PSH;
+ msk->flags |= NFP_FL_TCP_FLAG_PSH;
+ }
+ if (tcp_flags & TCPHDR_URG) {
+ ext->flags |= NFP_FL_TCP_FLAG_URG;
+ msk->flags |= NFP_FL_TCP_FLAG_URG;
+ }
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
- struct flow_dissector_key_control *key;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
+ struct flow_match_control match;
- key = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_CONTROL,
- target);
- if (key->flags & FLOW_DIS_IS_FRAGMENT)
- frame->flags |= NFP_FL_IP_FRAGMENTED;
- if (key->flags & FLOW_DIS_FIRST_FRAG)
- frame->flags |= NFP_FL_IP_FRAG_FIRST;
+ flow_rule_match_control(rule, &match);
+ if (match.key->flags & FLOW_DIS_IS_FRAGMENT) {
+ ext->flags |= NFP_FL_IP_FRAGMENTED;
+ msk->flags |= NFP_FL_IP_FRAGMENTED;
+ }
+ if (match.key->flags & FLOW_DIS_FIRST_FRAG) {
+ ext->flags |= NFP_FL_IP_FRAG_FIRST;
+ msk->flags |= NFP_FL_IP_FRAG_FIRST;
+ }
}
}
static void
-nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *frame,
- struct tc_cls_flower_offload *flow,
- bool mask_version)
+nfp_flower_compile_ipv4(struct nfp_flower_ipv4 *ext,
+ struct nfp_flower_ipv4 *msk,
+ struct tc_cls_flower_offload *flow)
{
- struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_ipv4_addrs *addr;
-
- memset(frame, 0, sizeof(struct nfp_flower_ipv4));
-
- if (dissector_uses_key(flow->dissector,
- FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
- addr = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_IPV4_ADDRS,
- target);
- frame->ipv4_src = addr->src;
- frame->ipv4_dst = addr->dst;
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow);
+ struct flow_match_ipv4_addrs match;
+
+ memset(ext, 0, sizeof(struct nfp_flower_ipv4));
+ memset(msk, 0, sizeof(struct nfp_flower_ipv4));
+
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
+ flow_rule_match_ipv4_addrs(rule, &match);
+ ext->ipv4_src = match.key->src;
+ ext->ipv4_dst = match.key->dst;
+ msk->ipv4_src = match.mask->src;
+ msk->ipv4_dst = match.mask->dst;
}
- nfp_flower_compile_ip_ext(&frame->ip_ext, flow, mask_version);
+ nfp_flower_compile_ip_ext(&ext->ip_ext, &msk->ip_ext, flow);
}
static void
-nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *frame,
- struct tc_cls_flower_offload *flow,
- bool mask_version)
+nfp_flower_compile_ipv6(struct nfp_flower_ipv6 *ext,
+ struct nfp_flower_ipv6 *msk,
+ struct tc_cls_flower_offload *flow)
{
- struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_ipv6_addrs *addr;
-
- memset(frame, 0, sizeof(struct nfp_flower_ipv6));
-
- if (dissector_uses_key(flow->dissector,
- FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
- addr = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_IPV6_ADDRS,
- target);
- frame->ipv6_src = addr->src;
- frame->ipv6_dst = addr->dst;
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow);
+
+ memset(ext, 0, sizeof(struct nfp_flower_ipv6));
+ memset(msk, 0, sizeof(struct nfp_flower_ipv6));
+
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
+ struct flow_match_ipv6_addrs match;
+
+ flow_rule_match_ipv6_addrs(rule, &match);
+ ext->ipv6_src = match.key->src;
+ ext->ipv6_dst = match.key->dst;
+ msk->ipv6_src = match.mask->src;
+ msk->ipv6_dst = match.mask->dst;
}
- nfp_flower_compile_ip_ext(&frame->ip_ext, flow, mask_version);
+ nfp_flower_compile_ip_ext(&ext->ip_ext, &msk->ip_ext, flow);
}
static int
-nfp_flower_compile_geneve_opt(void *key_buf, struct tc_cls_flower_offload *flow,
- bool mask_version)
+nfp_flower_compile_geneve_opt(void *ext, void *msk,
+ struct tc_cls_flower_offload *flow)
{
- struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_enc_opts *opts;
+ struct flow_match_enc_opts match;
- opts = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_OPTS,
- target);
- memcpy(key_buf, opts->data, opts->len);
+ flow_rule_match_enc_opts(flow->rule, &match);
+ memcpy(ext, match.key->data, match.key->len);
+ memcpy(msk, match.mask->data, match.mask->len);
return 0;
}
static void
-nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *frame,
- struct tc_cls_flower_offload *flow,
- bool mask_version)
+nfp_flower_compile_ipv4_udp_tun(struct nfp_flower_ipv4_udp_tun *ext,
+ struct nfp_flower_ipv4_udp_tun *msk,
+ struct tc_cls_flower_offload *flow)
{
- struct fl_flow_key *target = mask_version ? flow->mask : flow->key;
- struct flow_dissector_key_ipv4_addrs *tun_ips;
- struct flow_dissector_key_keyid *vni;
- struct flow_dissector_key_ip *ip;
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow);
- memset(frame, 0, sizeof(struct nfp_flower_ipv4_udp_tun));
+ memset(ext, 0, sizeof(struct nfp_flower_ipv4_udp_tun));
+ memset(msk, 0, sizeof(struct nfp_flower_ipv4_udp_tun));
- if (dissector_uses_key(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_KEYID)) {
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
+ struct flow_match_enc_keyid match;
u32 temp_vni;
- vni = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_KEYID,
- target);
- temp_vni = be32_to_cpu(vni->keyid) << NFP_FL_TUN_VNI_OFFSET;
- frame->tun_id = cpu_to_be32(temp_vni);
+ flow_rule_match_enc_keyid(rule, &match);
+ temp_vni = be32_to_cpu(match.key->keyid) << NFP_FL_TUN_VNI_OFFSET;
+ ext->tun_id = cpu_to_be32(temp_vni);
+ temp_vni = be32_to_cpu(match.mask->keyid) << NFP_FL_TUN_VNI_OFFSET;
+ msk->tun_id = cpu_to_be32(temp_vni);
}
- if (dissector_uses_key(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
- tun_ips =
- skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
- target);
- frame->ip_src = tun_ips->src;
- frame->ip_dst = tun_ips->dst;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
+ struct flow_match_ipv4_addrs match;
+
+ flow_rule_match_enc_ipv4_addrs(rule, &match);
+ ext->ip_src = match.key->src;
+ ext->ip_dst = match.key->dst;
+ msk->ip_src = match.mask->src;
+ msk->ip_dst = match.mask->dst;
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ENC_IP)) {
- ip = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_IP,
- target);
- frame->tos = ip->tos;
- frame->ttl = ip->ttl;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IP)) {
+ struct flow_match_ip match;
+
+ flow_rule_match_enc_ip(rule, &match);
+ ext->tos = match.key->tos;
+ ext->ttl = match.key->ttl;
+ msk->tos = match.mask->tos;
+ msk->ttl = match.mask->ttl;
}
}
@@ -313,12 +336,9 @@ int nfp_flower_compile_flow_match(struct nfp_app *app,
ext = nfp_flow->unmasked_data;
msk = nfp_flow->mask_data;
- /* Populate Exact Metadata. */
nfp_flower_compile_meta_tci((struct nfp_flower_meta_tci *)ext,
- flow, key_ls->key_layer, false);
- /* Populate Mask Metadata. */
- nfp_flower_compile_meta_tci((struct nfp_flower_meta_tci *)msk,
- flow, key_ls->key_layer, true);
+ (struct nfp_flower_meta_tci *)msk,
+ flow, key_ls->key_layer);
ext += sizeof(struct nfp_flower_meta_tci);
msk += sizeof(struct nfp_flower_meta_tci);
@@ -348,45 +368,33 @@ int nfp_flower_compile_flow_match(struct nfp_app *app,
msk += sizeof(struct nfp_flower_in_port);
if (NFP_FLOWER_LAYER_MAC & key_ls->key_layer) {
- /* Populate Exact MAC Data. */
nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)ext,
- flow, false);
- /* Populate Mask MAC Data. */
- nfp_flower_compile_mac((struct nfp_flower_mac_mpls *)msk,
- flow, true);
+ (struct nfp_flower_mac_mpls *)msk,
+ flow);
ext += sizeof(struct nfp_flower_mac_mpls);
msk += sizeof(struct nfp_flower_mac_mpls);
}
if (NFP_FLOWER_LAYER_TP & key_ls->key_layer) {
- /* Populate Exact TP Data. */
nfp_flower_compile_tport((struct nfp_flower_tp_ports *)ext,
- flow, false);
- /* Populate Mask TP Data. */
- nfp_flower_compile_tport((struct nfp_flower_tp_ports *)msk,
- flow, true);
+ (struct nfp_flower_tp_ports *)msk,
+ flow);
ext += sizeof(struct nfp_flower_tp_ports);
msk += sizeof(struct nfp_flower_tp_ports);
}
if (NFP_FLOWER_LAYER_IPV4 & key_ls->key_layer) {
- /* Populate Exact IPv4 Data. */
nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)ext,
- flow, false);
- /* Populate Mask IPv4 Data. */
- nfp_flower_compile_ipv4((struct nfp_flower_ipv4 *)msk,
- flow, true);
+ (struct nfp_flower_ipv4 *)msk,
+ flow);
ext += sizeof(struct nfp_flower_ipv4);
msk += sizeof(struct nfp_flower_ipv4);
}
if (NFP_FLOWER_LAYER_IPV6 & key_ls->key_layer) {
- /* Populate Exact IPv4 Data. */
nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)ext,
- flow, false);
- /* Populate Mask IPv4 Data. */
- nfp_flower_compile_ipv6((struct nfp_flower_ipv6 *)msk,
- flow, true);
+ (struct nfp_flower_ipv6 *)msk,
+ flow);
ext += sizeof(struct nfp_flower_ipv6);
msk += sizeof(struct nfp_flower_ipv6);
}
@@ -395,10 +403,7 @@ int nfp_flower_compile_flow_match(struct nfp_app *app,
key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE) {
__be32 tun_dst;
- /* Populate Exact VXLAN Data. */
- nfp_flower_compile_ipv4_udp_tun((void *)ext, flow, false);
- /* Populate Mask VXLAN Data. */
- nfp_flower_compile_ipv4_udp_tun((void *)msk, flow, true);
+ nfp_flower_compile_ipv4_udp_tun((void *)ext, (void *)msk, flow);
tun_dst = ((struct nfp_flower_ipv4_udp_tun *)ext)->ip_dst;
ext += sizeof(struct nfp_flower_ipv4_udp_tun);
msk += sizeof(struct nfp_flower_ipv4_udp_tun);
@@ -410,11 +415,7 @@ int nfp_flower_compile_flow_match(struct nfp_app *app,
nfp_tunnel_add_ipv4_off(app, tun_dst);
if (key_ls->key_layer_two & NFP_FLOWER_LAYER2_GENEVE_OP) {
- err = nfp_flower_compile_geneve_opt(ext, flow, false);
- if (err)
- return err;
-
- err = nfp_flower_compile_geneve_opt(msk, flow, true);
+ err = nfp_flower_compile_geneve_opt(ext, msk, flow);
if (err)
return err;
}
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index 2cdbf29ecbe7..74f7ff292052 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -102,23 +102,22 @@ nfp_flower_xmit_flow(struct nfp_app *app, struct nfp_fl_payload *nfp_flow,
static bool nfp_flower_check_higher_than_mac(struct tc_cls_flower_offload *f)
{
- return dissector_uses_key(f->dissector,
- FLOW_DISSECTOR_KEY_IPV4_ADDRS) ||
- dissector_uses_key(f->dissector,
- FLOW_DISSECTOR_KEY_IPV6_ADDRS) ||
- dissector_uses_key(f->dissector,
- FLOW_DISSECTOR_KEY_PORTS) ||
- dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ICMP);
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(f);
+
+ return flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS) ||
+ flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS) ||
+ flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS) ||
+ flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ICMP);
}
static int
-nfp_flower_calc_opt_layer(struct flow_dissector_key_enc_opts *enc_opts,
+nfp_flower_calc_opt_layer(struct flow_match_enc_opts *enc_opts,
u32 *key_layer_two, int *key_size)
{
- if (enc_opts->len > NFP_FL_MAX_GENEVE_OPT_KEY)
+ if (enc_opts->key->len > NFP_FL_MAX_GENEVE_OPT_KEY)
return -EOPNOTSUPP;
- if (enc_opts->len > 0) {
+ if (enc_opts->key->len > 0) {
*key_layer_two |= NFP_FLOWER_LAYER2_GENEVE_OP;
*key_size += sizeof(struct nfp_flower_geneve_options);
}
@@ -133,20 +132,21 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
struct tc_cls_flower_offload *flow,
enum nfp_flower_tun_type *tun_type)
{
- struct flow_dissector_key_basic *mask_basic = NULL;
- struct flow_dissector_key_basic *key_basic = NULL;
+ struct flow_rule *rule = tc_cls_flower_offload_flow_rule(flow);
+ struct flow_dissector *dissector = rule->match.dissector;
+ struct flow_match_basic basic = { NULL, NULL};
struct nfp_flower_priv *priv = app->priv;
u32 key_layer_two;
u8 key_layer;
int key_size;
int err;
- if (flow->dissector->used_keys & ~NFP_FLOWER_WHITELIST_DISSECTOR)
+ if (dissector->used_keys & ~NFP_FLOWER_WHITELIST_DISSECTOR)
return -EOPNOTSUPP;
/* If any tun dissector is used then the required set must be used. */
- if (flow->dissector->used_keys & NFP_FLOWER_WHITELIST_TUN_DISSECTOR &&
- (flow->dissector->used_keys & NFP_FLOWER_WHITELIST_TUN_DISSECTOR_R)
+ if (dissector->used_keys & NFP_FLOWER_WHITELIST_TUN_DISSECTOR &&
+ (dissector->used_keys & NFP_FLOWER_WHITELIST_TUN_DISSECTOR_R)
!= NFP_FLOWER_WHITELIST_TUN_DISSECTOR_R)
return -EOPNOTSUPP;
@@ -155,76 +155,53 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
key_size = sizeof(struct nfp_flower_meta_tci) +
sizeof(struct nfp_flower_in_port);
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_ETH_ADDRS) ||
- dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_MPLS)) {
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS) ||
+ flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS)) {
key_layer |= NFP_FLOWER_LAYER_MAC;
key_size += sizeof(struct nfp_flower_mac_mpls);
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
- struct flow_dissector_key_vlan *flow_vlan;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
+ struct flow_match_vlan vlan;
- flow_vlan = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_VLAN,
- flow->mask);
+ flow_rule_match_vlan(rule, &vlan);
if (!(priv->flower_ext_feats & NFP_FL_FEATS_VLAN_PCP) &&
- flow_vlan->vlan_priority)
+ vlan.key->vlan_priority)
return -EOPNOTSUPP;
}
- if (dissector_uses_key(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
- struct flow_dissector_key_ipv4_addrs *mask_ipv4 = NULL;
- struct flow_dissector_key_ports *mask_enc_ports = NULL;
- struct flow_dissector_key_enc_opts *enc_op = NULL;
- struct flow_dissector_key_ports *enc_ports = NULL;
- struct flow_dissector_key_control *mask_enc_ctl =
- skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_CONTROL,
- flow->mask);
- struct flow_dissector_key_control *enc_ctl =
- skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_CONTROL,
- flow->key);
-
- if (mask_enc_ctl->addr_type != 0xffff ||
- enc_ctl->addr_type != FLOW_DISSECTOR_KEY_IPV4_ADDRS)
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_CONTROL)) {
+ struct flow_match_enc_opts enc_op = { NULL, NULL };
+ struct flow_match_ipv4_addrs ipv4_addrs;
+ struct flow_match_control enc_ctl;
+ struct flow_match_ports enc_ports;
+
+ flow_rule_match_enc_control(rule, &enc_ctl);
+
+ if (enc_ctl.mask->addr_type != 0xffff ||
+ enc_ctl.key->addr_type != FLOW_DISSECTOR_KEY_IPV4_ADDRS)
return -EOPNOTSUPP;
/* These fields are already verified as used. */
- mask_ipv4 =
- skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
- flow->mask);
- if (mask_ipv4->dst != cpu_to_be32(~0))
+ flow_rule_match_enc_ipv4_addrs(rule, &ipv4_addrs);
+ if (ipv4_addrs.mask->dst != cpu_to_be32(~0))
return -EOPNOTSUPP;
- mask_enc_ports =
- skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_PORTS,
- flow->mask);
- enc_ports =
- skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_PORTS,
- flow->key);
- if (mask_enc_ports->dst != cpu_to_be16(~0))
+ flow_rule_match_enc_ports(rule, &enc_ports);
+ if (enc_ports.mask->dst != cpu_to_be16(~0))
return -EOPNOTSUPP;
- if (dissector_uses_key(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_OPTS)) {
- enc_op = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_ENC_OPTS,
- flow->key);
- }
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_OPTS))
+ flow_rule_match_enc_opts(rule, &enc_op);
- switch (enc_ports->dst) {
+ switch (enc_ports.key->dst) {
case htons(NFP_FL_VXLAN_PORT):
*tun_type = NFP_FL_TUNNEL_VXLAN;
key_layer |= NFP_FLOWER_LAYER_VXLAN;
key_size += sizeof(struct nfp_flower_ipv4_udp_tun);
- if (enc_op)
+ if (enc_op.key)
return -EOPNOTSUPP;
break;
case htons(NFP_FL_GENEVE_PORT):
@@ -236,11 +213,11 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
key_layer_two |= NFP_FLOWER_LAYER2_GENEVE;
key_size += sizeof(struct nfp_flower_ipv4_udp_tun);
- if (!enc_op)
+ if (!enc_op.key)
break;
if (!(priv->flower_ext_feats & NFP_FL_FEATS_GENEVE_OPT))
return -EOPNOTSUPP;
- err = nfp_flower_calc_opt_layer(enc_op, &key_layer_two,
+ err = nfp_flower_calc_opt_layer(&enc_op, &key_layer_two,
&key_size);
if (err)
return err;
@@ -254,19 +231,12 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
return -EOPNOTSUPP;
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_BASIC)) {
- mask_basic = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC,
- flow->mask);
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC))
+ flow_rule_match_basic(rule, &basic);
- key_basic = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_BASIC,
- flow->key);
- }
-
- if (mask_basic && mask_basic->n_proto) {
+ if (basic.mask && basic.mask->n_proto) {
/* Ethernet type is present in the key. */
- switch (key_basic->n_proto) {
+ switch (basic.key->n_proto) {
case cpu_to_be16(ETH_P_IP):
key_layer |= NFP_FLOWER_LAYER_IPV4;
key_size += sizeof(struct nfp_flower_ipv4);
@@ -305,9 +275,9 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
}
}
- if (mask_basic && mask_basic->ip_proto) {
+ if (basic.mask && basic.mask->ip_proto) {
/* Ethernet type is present in the key. */
- switch (key_basic->ip_proto) {
+ switch (basic.key->ip_proto) {
case IPPROTO_TCP:
case IPPROTO_UDP:
case IPPROTO_SCTP:
@@ -324,14 +294,12 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
}
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_TCP)) {
- struct flow_dissector_key_tcp *tcp;
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_TCP)) {
+ struct flow_match_tcp tcp;
u32 tcp_flags;
- tcp = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_TCP,
- flow->key);
- tcp_flags = be16_to_cpu(tcp->flags);
+ flow_rule_match_tcp(rule, &tcp);
+ tcp_flags = be16_to_cpu(tcp.key->flags);
if (tcp_flags & ~NFP_FLOWER_SUPPORTED_TCPFLAGS)
return -EOPNOTSUPP;
@@ -347,12 +315,12 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
* space, thus we need to ensure we include a IPv4/IPv6 key
* layer if we have not done so already.
*/
- if (!key_basic)
+ if (!basic.key)
return -EOPNOTSUPP;
if (!(key_layer & NFP_FLOWER_LAYER_IPV4) &&
!(key_layer & NFP_FLOWER_LAYER_IPV6)) {
- switch (key_basic->n_proto) {
+ switch (basic.key->n_proto) {
case cpu_to_be16(ETH_P_IP):
key_layer |= NFP_FLOWER_LAYER_IPV4;
key_size += sizeof(struct nfp_flower_ipv4);
@@ -369,14 +337,11 @@ nfp_flower_calculate_key_layers(struct nfp_app *app,
}
}
- if (dissector_uses_key(flow->dissector, FLOW_DISSECTOR_KEY_CONTROL)) {
- struct flow_dissector_key_control *key_ctl;
-
- key_ctl = skb_flow_dissector_target(flow->dissector,
- FLOW_DISSECTOR_KEY_CONTROL,
- flow->key);
+ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
+ struct flow_match_control ctl;
- if (key_ctl->flags & ~NFP_FLOWER_SUPPORTED_CTLFLAGS)
+ flow_rule_match_control(rule, &ctl);
+ if (ctl.key->flags & ~NFP_FLOWER_SUPPORTED_CTLFLAGS)
return -EOPNOTSUPP;
}