summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/ice/ice_tc_lib.c
diff options
context:
space:
mode:
authorMichal Swiatkowski <michal.swiatkowski@linux.intel.com>2021-10-12 11:31:06 -0700
committerTony Nguyen <anthony.l.nguyen@intel.com>2021-10-28 11:00:20 -0700
commitf0a35040adbe72f6b2e9ddc9fefdbcdbe0b92c55 (patch)
tree813ef825fe4ca86e818673573b00ef7a1be67ade /drivers/net/ethernet/intel/ice/ice_tc_lib.c
parent8b032a55c1bd5d47527263445aba9dc45144b00d (diff)
downloadlwn-f0a35040adbe72f6b2e9ddc9fefdbcdbe0b92c55.tar.gz
lwn-f0a35040adbe72f6b2e9ddc9fefdbcdbe0b92c55.zip
ice: support for GRE in eswitch
Mostly reuse code from Geneve and VXLAN in TC parsing code. Add new GRE header to match on correct fields. Create new dummy packets with GRE fields. Instead of checking if any encap values are presented in TC flower, check if device is tunnel type or redirect is to tunnel device. This will allow adding all combination of rules. For example filters only with inner fields. Return error in case device isn't tunnel but encap values are presented. gre example: - create tunnel device ip l add $NVGRE_DEV type gretap remote $NVGRE_REM_IP local $VF1_IP \ dev $PF - add tc filter (in switchdev mode) tc filter add dev $NVGRE_DEV protocol ip parent ffff: flower dst_ip \ $NVGRE1_IP action mirred egress redirect dev $VF1_PR Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> Tested-by: Sandeep Penigalapati <sandeep.penigalapati@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_tc_lib.c')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_tc_lib.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.c b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
index 920d9024a6c1..e5d23feb6701 100644
--- a/drivers/net/ethernet/intel/ice/ice_tc_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
@@ -102,6 +102,8 @@ ice_proto_type_from_tunnel(enum ice_tunnel_type type)
return ICE_VXLAN;
case TNL_GENEVE:
return ICE_GENEVE;
+ case TNL_GRETAP:
+ return ICE_NVGRE;
default:
return 0;
}
@@ -115,6 +117,8 @@ ice_sw_type_from_tunnel(enum ice_tunnel_type type)
return ICE_SW_TUN_VXLAN;
case TNL_GENEVE:
return ICE_SW_TUN_GENEVE;
+ case TNL_GRETAP:
+ return ICE_SW_TUN_NVGRE;
default:
return ICE_NON_TUN;
}
@@ -131,10 +135,22 @@ ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr,
u32 tenant_id;
list[i].type = ice_proto_type_from_tunnel(fltr->tunnel_type);
- tenant_id = be32_to_cpu(fltr->tenant_id) << 8;
- list[i].h_u.tnl_hdr.vni = cpu_to_be32(tenant_id);
- memcpy(&list[i].m_u.tnl_hdr.vni, "\xff\xff\xff\x00", 4);
- i++;
+ switch (fltr->tunnel_type) {
+ case TNL_VXLAN:
+ case TNL_GENEVE:
+ tenant_id = be32_to_cpu(fltr->tenant_id) << 8;
+ list[i].h_u.tnl_hdr.vni = cpu_to_be32(tenant_id);
+ memcpy(&list[i].m_u.tnl_hdr.vni, "\xff\xff\xff\x00", 4);
+ i++;
+ break;
+ case TNL_GRETAP:
+ list[i].h_u.nvgre_hdr.tni_flow = fltr->tenant_id;
+ memcpy(&list[i].m_u.nvgre_hdr.tni_flow, "\xff\xff\xff\xff", 4);
+ i++;
+ break;
+ default:
+ break;
+ }
}
if (flags & (ICE_TC_FLWR_FIELD_ENC_SRC_IPV4 |
@@ -332,6 +348,9 @@ static int ice_tc_tun_get_type(struct net_device *tunnel_dev)
return TNL_VXLAN;
if (netif_is_geneve(tunnel_dev))
return TNL_GENEVE;
+ if (netif_is_gretap(tunnel_dev) ||
+ netif_is_ip6gretap(tunnel_dev))
+ return TNL_GRETAP;
return TNL_LAST;
}
@@ -810,6 +829,7 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
u16 n_proto_mask = 0, n_proto_key = 0, addr_type = 0;
struct flow_dissector *dissector;
+ struct net_device *tunnel_dev;
dissector = rule->match.dissector;
@@ -831,17 +851,11 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
return -EOPNOTSUPP;
}
- if ((flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) ||
- flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) ||
- flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID) ||
- flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS))) {
+ tunnel_dev = ice_get_tunnel_device(filter_dev, rule);
+ if (tunnel_dev) {
int err;
- filter_dev = ice_get_tunnel_device(filter_dev, rule);
- if (!filter_dev) {
- NL_SET_ERR_MSG_MOD(fltr->extack, "Tunnel device not found");
- return -EOPNOTSUPP;
- }
+ filter_dev = tunnel_dev;
err = ice_parse_tunnel_attr(filter_dev, rule, fltr);
if (err) {
@@ -853,6 +867,13 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
* header were already set by ice_parse_tunnel_attr
*/
headers = &fltr->inner_headers;
+ } else if (dissector->used_keys &
+ (BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) |
+ BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) |
+ BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) |
+ BIT(FLOW_DISSECTOR_KEY_ENC_PORTS))) {
+ NL_SET_ERR_MSG_MOD(fltr->extack, "Tunnel key used, but device isn't a tunnel");
+ return -EOPNOTSUPP;
} else {
fltr->tunnel_type = TNL_LAST;
}