All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-wired-lan] [PATCH net-next 0/4] support for tunnel in ice eswitch
@ 2021-10-11  9:48 Michal Swiatkowski
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 1/4] ice: support for indirect notification Michal Swiatkowski
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Michal Swiatkowski @ 2021-10-11  9:48 UTC (permalink / raw)
  To: intel-wired-lan

This series adds the support for ice vxlan, geneve and gre offload.

Support adding drop and redirect filter from and to this tunnel deivces.
From means from uplink to VF and to means from VF to uplink. There is no
support for decapsulation and encapsulation offload.

example:
- vxlan from uplink to VF:
tc filter add dev $VXLAN_DEV protocol ip parent ffff: flower enc_dst_ip  \
$VF1_IP enc_key_id $VXLAN_VNI action mirred egress redirect dev $VF1_PR
- vxlan from VF to uplink:
tc filter add dev $VF1_PR protocol ip parent ffff: flower enc_dst_ip \
$LP_IP enc_key_id $VXLAN_VNI action mirred egress redirect dev $VXLAN_DEV

Michal Swiatkowski (4):
  ice: support for indirect notification
  ice: vxlan and geneve tc support
  ice: low level support for tunnels
  ice: support for gre in eswitch

 drivers/net/ethernet/intel/ice/ice.h          |   8 +
 .../net/ethernet/intel/ice/ice_flex_pipe.c    |  26 +-
 .../net/ethernet/intel/ice/ice_flex_type.h    |   4 +
 drivers/net/ethernet/intel/ice/ice_main.c     | 196 ++++++++-
 .../ethernet/intel/ice/ice_protocol_type.h    |  35 ++
 drivers/net/ethernet/intel/ice/ice_switch.c   | 374 ++++++++++++++++-
 drivers/net/ethernet/intel/ice/ice_switch.h   |   3 +
 drivers/net/ethernet/intel/ice/ice_tc_lib.c   | 393 ++++++++++++++++--
 drivers/net/ethernet/intel/ice/ice_tc_lib.h   |  10 +
 9 files changed, 1000 insertions(+), 49 deletions(-)

-- 
2.31.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Intel-wired-lan] [PATCH net-next 1/4] ice: support for indirect notification
  2021-10-11  9:48 [Intel-wired-lan] [PATCH net-next 0/4] support for tunnel in ice eswitch Michal Swiatkowski
@ 2021-10-11  9:48 ` Michal Swiatkowski
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 2/4] ice: vxlan and geneve tc support Michal Swiatkowski
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Michal Swiatkowski @ 2021-10-11  9:48 UTC (permalink / raw)
  To: intel-wired-lan

Implement indirect notification mechanism to support offloading tc rules
on tunnel devices.

Keep indirect block list in netdev priv. Notification will call setting
tc cls flower function.

Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
---
 drivers/net/ethernet/intel/ice/ice.h        |   8 +
 drivers/net/ethernet/intel/ice/ice_main.c   | 198 +++++++++++++++++++-
 drivers/net/ethernet/intel/ice/ice_tc_lib.h |   6 +
 3 files changed, 210 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h
index 5da21546aed7..dcb8ee1ddd43 100644
--- a/drivers/net/ethernet/intel/ice/ice.h
+++ b/drivers/net/ethernet/intel/ice/ice.h
@@ -34,6 +34,7 @@
 #include <linux/if_bridge.h>
 #include <linux/ctype.h>
 #include <linux/bpf.h>
+#include <linux/btf.h>
 #include <linux/auxiliary_bus.h>
 #include <linux/avf/virtchnl.h>
 #include <linux/cpu_rmap.h>
@@ -553,6 +554,13 @@ struct ice_pf {
 struct ice_netdev_priv {
 	struct ice_vsi *vsi;
 	struct ice_repr *repr;
+	/* indirect block callbacks on registered higher level devices
+	 * (e.g. tunnel devices)
+	 *
+	 * tc_indr_block_cb_priv_list is used to lookup indirect callback
+	 * private data
+	 */
+	struct list_head tc_indr_block_priv_list;
 };
 
 /**
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index e4cfbcfa87c9..7f5e57c0a6d6 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -55,6 +55,12 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type);
 
 static void ice_vsi_release_all(struct ice_pf *pf);
 
+static int
+ice_indr_setup_tc_cb(struct net_device *netdev, struct Qdisc *sch,
+		     void *cb_priv, enum tc_setup_type type, void *type_data,
+		     void *data,
+		     void (*cleanup)(struct flow_block_cb *block_cb));
+
 bool netif_is_ice(struct net_device *dev)
 {
 	return dev && (dev->netdev_ops == &ice_netdev_ops);
@@ -3380,6 +3386,63 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto,
 	return ret;
 }
 
+/**
+ * ice_rep_indr_tc_block_unbind
+ * @cb_priv: indirection block private data
+ */
+static void ice_rep_indr_tc_block_unbind(void *cb_priv)
+{
+	struct ice_indr_block_priv *indr_priv = cb_priv;
+
+	list_del(&indr_priv->list);
+	kfree(indr_priv);
+}
+
+/**
+ * ice_tc_indir_block_unregister - Unregister TC indirect block notifications
+ * @vsi: VSI struct which has the netdev
+ */
+static void ice_tc_indir_block_unregister(struct ice_vsi *vsi)
+{
+	struct ice_netdev_priv *np = netdev_priv(vsi->netdev);
+
+	flow_indr_dev_unregister(ice_indr_setup_tc_cb, np,
+				 ice_rep_indr_tc_block_unbind);
+}
+
+/**
+ * ice_tc_indir_block_remove - clean indirect TC block notifications
+ * @pf: PF structure
+ */
+static void ice_tc_indir_block_remove(struct ice_pf *pf)
+{
+	struct ice_vsi *pf_vsi = ice_get_main_vsi(pf);
+
+	if (!pf_vsi)
+		return;
+
+	ice_tc_indir_block_unregister(pf_vsi);
+}
+
+/**
+ * ice_tc_indir_block_register - Register TC indirect block notifications
+ * @vsi: VSI struct which has the netdev
+ *
+ * Returns 0 on success, negative value on failure
+ */
+static int ice_tc_indir_block_register(struct ice_vsi *vsi)
+{
+	struct ice_netdev_priv *np;
+
+	if (!vsi || !vsi->netdev)
+		return -EINVAL;
+
+	np = netdev_priv(vsi->netdev);
+
+	INIT_LIST_HEAD(&np->tc_indr_block_priv_list);
+	return flow_indr_dev_register(ice_indr_setup_tc_cb, np);
+}
+
 /**
  * ice_setup_pf_sw - Setup the HW switch on startup or after reset
  * @pf: board private structure
@@ -3388,6 +3451,7 @@ ice_vlan_rx_kill_vid(struct net_device *netdev, __always_unused __be16 proto,
  */
 static int ice_setup_pf_sw(struct ice_pf *pf)
 {
+	struct device *dev = ice_pf_to_dev(pf);
 	struct ice_vsi *vsi;
 	int status;
 
@@ -3404,6 +3468,13 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
 	/* netdev has to be configured before setting frame size */
 	ice_vsi_cfg_frame_size(vsi);
 
+	/* init indirect block notifications */
+	status = ice_tc_indir_block_register(vsi);
+	if (status) {
+		dev_err(dev, "Failed to register netdev notifier\n");
+		goto unroll_cfg_netdev;
+	}
+
 	/* Setup DCB netlink interface */
 	ice_dcbnl_setup(vsi);
 
@@ -3415,7 +3486,7 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
 
 	status = ice_set_cpu_rx_rmap(vsi);
 	if (status) {
-		dev_err(ice_pf_to_dev(pf), "Failed to set CPU Rx map VSI %d error %d\n",
+		dev_err(dev, "Failed to set CPU Rx map VSI %d error %d\n",
 			vsi->vsi_num, status);
 		goto unroll_napi_add;
 	}
@@ -3427,8 +3498,9 @@ static int ice_setup_pf_sw(struct ice_pf *pf)
 
 free_cpu_rx_map:
 	ice_free_cpu_rx_rmap(vsi);
-
 unroll_napi_add:
+	ice_tc_indir_block_unregister(vsi);
+unroll_cfg_netdev:
 	if (vsi) {
 		ice_napi_del(vsi);
 		if (vsi->netdev) {
@@ -4676,6 +4748,8 @@ static void ice_remove(struct pci_dev *pdev)
 		msleep(100);
 	}
 
+	ice_tc_indir_block_remove(pf);
+
 	if (test_bit(ICE_FLAG_SRIOV_ENA, pf->flags)) {
 		set_bit(ICE_VF_RESETS_DISABLED, pf->state);
 		ice_free_vfs(pf);
@@ -7126,6 +7200,126 @@ ice_setup_tc(struct net_device *netdev, enum tc_setup_type type,
 	return -EOPNOTSUPP;
 }
 
+static struct ice_indr_block_priv *
+ice_indr_block_priv_lookup(struct ice_netdev_priv *np,
+			   struct net_device *netdev)
+{
+	struct ice_indr_block_priv *cb_priv;
+
+	/* All callback list access should be protected by RTNL. */
+	ASSERT_RTNL();
+
+	list_for_each_entry(cb_priv, &np->tc_indr_block_priv_list, list) {
+		if (!cb_priv->netdev)
+			return NULL;
+		if (cb_priv->netdev == netdev)
+			return cb_priv;
+	}
+	return NULL;
+}
+
+static int
+ice_indr_setup_block_cb(enum tc_setup_type type, void *type_data,
+			void *indr_priv)
+{
+	struct ice_indr_block_priv *priv = indr_priv;
+	struct ice_netdev_priv *np = priv->np;
+
+	switch (type) {
+	case TC_SETUP_CLSFLOWER:
+		return ice_setup_tc_cls_flower(np, priv->netdev,
+					       (struct flow_cls_offload *)
+					       type_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int
+ice_indr_setup_tc_block(struct net_device *netdev, struct Qdisc *sch,
+			struct ice_netdev_priv *np,
+			struct flow_block_offload *f, void *data,
+			void (*cleanup)(struct flow_block_cb *block_cb))
+{
+	struct ice_indr_block_priv *indr_priv;
+	struct flow_block_cb *block_cb;
+
+	int tunnel_type = 0;
+
+	if (tunnel_type != TNL_VXLAN && tunnel_type != TNL_GENEVE &&
+	    !(is_vlan_dev(netdev) &&
+	    vlan_dev_real_dev(netdev) == np->vsi->netdev))
+		return -EOPNOTSUPP;
+
+	if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
+		return -EOPNOTSUPP;
+
+	switch (f->command) {
+	case FLOW_BLOCK_BIND:
+		indr_priv = ice_indr_block_priv_lookup(np, netdev);
+		if (indr_priv)
+			return -EEXIST;
+
+		indr_priv = kzalloc(sizeof(*indr_priv), GFP_KERNEL);
+		if (!indr_priv)
+			return -ENOMEM;
+
+		indr_priv->netdev = netdev;
+		indr_priv->np = np;
+		list_add(&indr_priv->list, &np->tc_indr_block_priv_list);
+
+		block_cb =
+			flow_indr_block_cb_alloc(ice_indr_setup_block_cb,
+						 indr_priv, indr_priv,
+						 ice_rep_indr_tc_block_unbind,
+						 f, netdev, sch, data, np,
+						 cleanup);
+
+		if (IS_ERR(block_cb)) {
+			list_del(&indr_priv->list);
+			kfree(indr_priv);
+			return PTR_ERR(block_cb);
+		}
+		flow_block_cb_add(block_cb, f);
+		list_add_tail(&block_cb->driver_list, &ice_block_cb_list);
+		return 0;
+	case FLOW_BLOCK_UNBIND:
+		indr_priv = ice_indr_block_priv_lookup(np, netdev);
+		if (!indr_priv)
+			return -ENOENT;
+
+		block_cb = flow_block_cb_lookup(f->block,
+						ice_indr_setup_block_cb,
+						indr_priv);
+		if (!block_cb)
+			return -ENOENT;
+
+		flow_indr_block_cb_remove(block_cb, f);
+
+		list_del(&block_cb->driver_list);
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
+static int
+ice_indr_setup_tc_cb(struct net_device *netdev, struct Qdisc *sch,
+		     void *cb_priv, enum tc_setup_type type, void *type_data,
+		     void *data,
+		     void (*cleanup)(struct flow_block_cb *block_cb))
+{
+	switch (type) {
+	case TC_SETUP_BLOCK:
+		return ice_indr_setup_tc_block(netdev, sch, cb_priv, type_data,
+					       data, cleanup);
+
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 /**
  * ice_open - Called when a network interface becomes active
  * @netdev: network interface device structure
diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.h b/drivers/net/ethernet/intel/ice/ice_tc_lib.h
index d90e9e37ae25..332c70342f1f 100644
--- a/drivers/net/ethernet/intel/ice/ice_tc_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.h
@@ -23,6 +23,12 @@
 #define ICE_TC_FLWR_FIELD_ENC_DST_MAC		BIT(16)
 #define ICE_TC_FLWR_FIELD_ETH_TYPE_ID		BIT(17)
 
+struct ice_indr_block_priv {
+	struct net_device *netdev;
+	struct ice_netdev_priv *np;
+	struct list_head list;
+};
+
 struct ice_tc_flower_action {
 	u32 tc_class;
 	enum ice_sw_fwd_act_type fltr_act;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Intel-wired-lan] [PATCH net-next 2/4] ice: vxlan and geneve tc support
  2021-10-11  9:48 [Intel-wired-lan] [PATCH net-next 0/4] support for tunnel in ice eswitch Michal Swiatkowski
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 1/4] ice: support for indirect notification Michal Swiatkowski
@ 2021-10-11  9:48 ` Michal Swiatkowski
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 3/4] ice: low level support for tunnels Michal Swiatkowski
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 4/4] ice: support for gre in eswitch Michal Swiatkowski
  3 siblings, 0 replies; 8+ messages in thread
From: Michal Swiatkowski @ 2021-10-11  9:48 UTC (permalink / raw)
  To: intel-wired-lan

Add definition for vxlan and geneve dummy packet. Define vxlan and
geneve type of fields to match on correct UDP tunnel header.

Parse tunnel specific fields from tc tool like outer macs, outer ips,
outer destination port and VNI. Save values and masks in outer header
struct and move header pointer to inner to simplify parsing inner
values.

There are two cases for redirect action:
- from uplink to VF - tc filter is added on tunnel device
- from VF to uplink - tc filter is added on PR, for this case check if
  redirect device is tunnel device

vxlan example:
- create tunnel device
ip l add $VXLAN_DEV type vxlan id $VXLAN_VNI dstport $VXLAN_PORT \
dev $PF
- add tc filter (in switchdev mode)
tc filter add dev $VXLAN_DEV protocol ip parent ffff: flower \
enc_dst_ip $VF1_IP enc_key_id $VXLAN_VNI action mirred egress \
redirect dev $VF1_PR

geneve example:
- create tunnel device
ip l add $GENEVE_DEV type geneve id $GENEVE_VNI dstport $GENEVE_PORT \
remote $GENEVE_IP
- add tc filter (in switchdev mode)
tc filter add dev $GENEVE_DEV protocol ip parent ffff: flower \
enc_key_id $GENEVE_VNI dst_ip $GENEVE1_IP action mirred egress \
redirect dev $VF1_PR

Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
---
 drivers/net/ethernet/intel/ice/ice_main.c     |   6 +-
 .../ethernet/intel/ice/ice_protocol_type.h    |  16 +
 drivers/net/ethernet/intel/ice/ice_switch.h   |   1 +
 drivers/net/ethernet/intel/ice/ice_tc_lib.c   | 385 ++++++++++++++++--
 drivers/net/ethernet/intel/ice/ice_tc_lib.h   |   4 +
 5 files changed, 364 insertions(+), 48 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index 7f5e57c0a6d6..848f4acc71bc 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -7244,11 +7244,9 @@ ice_indr_setup_tc_block(struct net_device *netdev, struct Qdisc *sch,
 	struct ice_indr_block_priv *indr_priv;
 	struct flow_block_cb *block_cb;
 
-	int tunnel_type = 0;
-
-	if (tunnel_type != TNL_VXLAN && tunnel_type != TNL_GENEVE &&
+	if (!ice_is_tunnel_supported(netdev) &&
 	    !(is_vlan_dev(netdev) &&
-	    vlan_dev_real_dev(netdev) == np->vsi->netdev))
+	      vlan_dev_real_dev(netdev) == np->vsi->netdev))
 		return -EOPNOTSUPP;
 
 	if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
diff --git a/drivers/net/ethernet/intel/ice/ice_protocol_type.h b/drivers/net/ethernet/intel/ice/ice_protocol_type.h
index 0b220dfa7457..d717d1158545 100644
--- a/drivers/net/ethernet/intel/ice/ice_protocol_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_protocol_type.h
@@ -37,10 +37,19 @@ enum ice_protocol_type {
 	ICE_TCP_IL,
 	ICE_UDP_OF,
 	ICE_UDP_ILOS,
+	ICE_VXLAN,
+	ICE_GENEVE,
+	ICE_VXLAN_GPE,
 	ICE_SCTP_IL,
 	ICE_PROTOCOL_LAST
 };
 
+enum ice_sw_tunnel_type {
+	ICE_NON_TUN = 0,
+	ICE_SW_TUN_VXLAN,
+	ICE_SW_TUN_GENEVE,
+};
+
 /* Decoders for ice_prot_id:
  * - F: First
  * - I: Inner
@@ -152,6 +161,12 @@ struct ice_l4_hdr {
 	__be16 check;
 };
 
+struct ice_udp_tnl_hdr {
+	__be16 field;
+	__be16 proto_type;
+	__be32 vni;     /* only use lower 24-bits */
+};
+
 union ice_prot_hdr {
 	struct ice_ether_hdr eth_hdr;
 	struct ice_ethtype_hdr ethertype;
@@ -160,6 +175,7 @@ union ice_prot_hdr {
 	struct ice_ipv6_hdr ipv6_hdr;
 	struct ice_l4_hdr l4_hdr;
 	struct ice_sctp_hdr sctp_hdr;
+	struct ice_udp_tnl_hdr tnl_hdr;
 };
 
 /* This is mapping table entry that maps every word within a given protocol
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.h b/drivers/net/ethernet/intel/ice/ice_switch.h
index 4a471cccb3d5..661cecf8fd99 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.h
+++ b/drivers/net/ethernet/intel/ice/ice_switch.h
@@ -180,6 +180,7 @@ struct ice_adv_rule_flags_info {
 };
 
 struct ice_adv_rule_info {
+	enum ice_sw_tunnel_type tun_type;
 	struct ice_sw_act_ctrl sw_act;
 	u32 priority;
 	u8 rx; /* true means LOOKUP_RX otherwise LOOKUP_TX */
diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.c b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
index dc6672bd4613..e3e02027f71d 100644
--- a/drivers/net/ethernet/intel/ice/ice_tc_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
@@ -3,8 +3,9 @@
 
 #include "ice.h"
 #include "ice_tc_lib.h"
-#include "ice_lib.h"
 #include "ice_fltr.h"
+#include "ice_lib.h"
+#include "ice_protocol_type.h"
 
 /**
  * ice_tc_count_lkups - determine lookup count for switch filter
@@ -20,7 +21,21 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
 {
 	int lkups_cnt = 0;
 
-	if (flags & ICE_TC_FLWR_FIELD_ETH_TYPE_ID)
+	if (flags & ICE_TC_FLWR_FIELD_TENANT_ID)
+		lkups_cnt++;
+
+	if (flags & (ICE_TC_FLWR_FIELD_ENC_SRC_IPV4 |
+		     ICE_TC_FLWR_FIELD_ENC_DEST_IPV4 |
+		     ICE_TC_FLWR_FIELD_ENC_SRC_IPV6 |
+		     ICE_TC_FLWR_FIELD_ENC_DEST_IPV6))
+		lkups_cnt++;
+
+	if (flags & ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT)
+		lkups_cnt++;
+
+	/* currently inner etype filter isn't supported */
+	if ((flags & ICE_TC_FLWR_FIELD_ETH_TYPE_ID) &&
+	    fltr->tunnel_type == TNL_LAST)
 		lkups_cnt++;
 
 	/* is MAC fields specified? */
@@ -32,10 +47,8 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
 		lkups_cnt++;
 
 	/* are IPv[4|6] fields specified? */
-	if (flags & (ICE_TC_FLWR_FIELD_DEST_IPV4 | ICE_TC_FLWR_FIELD_SRC_IPV4))
-		lkups_cnt++;
-	else if (flags & (ICE_TC_FLWR_FIELD_DEST_IPV6 |
-			  ICE_TC_FLWR_FIELD_SRC_IPV6))
+	if (flags & (ICE_TC_FLWR_FIELD_DEST_IPV4 | ICE_TC_FLWR_FIELD_SRC_IPV4 |
+		     ICE_TC_FLWR_FIELD_DEST_IPV6 | ICE_TC_FLWR_FIELD_SRC_IPV6))
 		lkups_cnt++;
 
 	/* is L4 (TCP/UDP/any other L4 protocol fields) specified? */
@@ -46,6 +59,135 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
 	return lkups_cnt;
 }
 
+static enum ice_protocol_type
+ice_proto_type_from_mac(bool inner)
+{
+	return inner ? ICE_MAC_IL : ICE_MAC_OFOS;
+}
+
+static enum ice_protocol_type
+ice_proto_type_from_ipv4(bool inner)
+{
+	return inner ? ICE_IPV4_IL : ICE_IPV4_OFOS;
+}
+
+static enum ice_protocol_type
+ice_proto_type_from_ipv6(bool inner)
+{
+	return inner ? ICE_IPV6_IL : ICE_IPV6_OFOS;
+}
+
+static enum ice_protocol_type
+ice_proto_type_from_l4_port(bool inner, u16 ip_proto)
+{
+	if (inner) {
+		switch (ip_proto) {
+		case IPPROTO_UDP:
+			return ICE_UDP_ILOS;
+		}
+	} else {
+		switch (ip_proto) {
+		case IPPROTO_TCP:
+			return ICE_TCP_IL;
+		case IPPROTO_UDP:
+			return ICE_UDP_OF;
+		}
+	}
+
+	return 0;
+}
+
+static enum ice_protocol_type
+ice_proto_type_from_tunnel(enum ice_tunnel_type type)
+{
+	switch (type) {
+	case TNL_VXLAN:
+		return ICE_VXLAN;
+	case TNL_GENEVE:
+		return ICE_GENEVE;
+	default:
+		return 0;
+	}
+}
+
+static enum ice_sw_tunnel_type
+ice_sw_type_from_tunnel(enum ice_tunnel_type type)
+{
+	switch (type) {
+	case TNL_VXLAN:
+		return ICE_SW_TUN_VXLAN;
+	case TNL_GENEVE:
+		return ICE_SW_TUN_GENEVE;
+	default:
+		return ICE_NON_TUN;
+	}
+}
+
+static int
+ice_tc_fill_tunnel_outer(u32 flags, struct ice_tc_flower_fltr *fltr,
+			 struct ice_adv_lkup_elem *list)
+{
+	struct ice_tc_flower_lyr_2_4_hdrs *hdr = &fltr->outer_headers;
+	int i = 0;
+
+	if (flags & ICE_TC_FLWR_FIELD_TENANT_ID) {
+		u32 tenant_id = fltr->tenant_id;
+
+		list[i].type = ice_proto_type_from_tunnel(fltr->tunnel_type);
+		tenant_id = be32_to_cpu(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++;
+	}
+
+	if (flags & (ICE_TC_FLWR_FIELD_ENC_SRC_IPV4 |
+		     ICE_TC_FLWR_FIELD_ENC_DEST_IPV4)) {
+		list[i].type = ice_proto_type_from_ipv4(false);
+
+		if (flags & ICE_TC_FLWR_FIELD_ENC_SRC_IPV4) {
+			list[i].h_u.ipv4_hdr.src_addr = hdr->l3_key.src_ipv4;
+			list[i].m_u.ipv4_hdr.src_addr = hdr->l3_mask.src_ipv4;
+		}
+		if (flags & ICE_TC_FLWR_FIELD_ENC_DEST_IPV4) {
+			list[i].h_u.ipv4_hdr.dst_addr = hdr->l3_key.dst_ipv4;
+			list[i].m_u.ipv4_hdr.dst_addr = hdr->l3_mask.dst_ipv4;
+		}
+		i++;
+	}
+
+	if (flags & (ICE_TC_FLWR_FIELD_ENC_SRC_IPV6 |
+		     ICE_TC_FLWR_FIELD_ENC_DEST_IPV6)) {
+		list[i].type = ice_proto_type_from_ipv6(false);
+
+		if (flags & ICE_TC_FLWR_FIELD_ENC_SRC_IPV6) {
+			memcpy(&list[i].h_u.ipv6_hdr.src_addr,
+			       &hdr->l3_key.src_ipv6_addr,
+			       sizeof(hdr->l3_key.src_ipv6_addr));
+			memcpy(&list[i].m_u.ipv6_hdr.src_addr,
+			       &hdr->l3_mask.src_ipv6_addr,
+			       sizeof(hdr->l3_mask.src_ipv6_addr));
+		}
+		if (flags & ICE_TC_FLWR_FIELD_ENC_DEST_IPV6) {
+			memcpy(&list[i].h_u.ipv6_hdr.dst_addr,
+			       &hdr->l3_key.dst_ipv6_addr,
+			       sizeof(hdr->l3_key.dst_ipv6_addr));
+			memcpy(&list[i].m_u.ipv6_hdr.dst_addr,
+			       &hdr->l3_mask.dst_ipv6_addr,
+			       sizeof(hdr->l3_mask.dst_ipv6_addr));
+		}
+		i++;
+	}
+
+	if (flags & ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT) {
+		list[i].type = ice_proto_type_from_l4_port(false, hdr->l3_key.ip_proto);
+		list[i].h_u.l4_hdr.dst_port = hdr->l4_key.dst_port;
+		list[i].m_u.l4_hdr.dst_port = hdr->l4_mask.dst_port;
+		i++;
+	}
+
+	return i;
+}
+
 /**
  * ice_tc_fill_rules - fill filter rules based on TC fltr
  * @hw: pointer to HW structure
@@ -67,9 +209,16 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
 		  u16 *l4_proto)
 {
 	struct ice_tc_flower_lyr_2_4_hdrs *headers = &tc_fltr->outer_headers;
+	bool inner = false;
 	int i = 0;
 
-	if (flags & ICE_TC_FLWR_FIELD_ETH_TYPE_ID) {
+	rule_info->tun_type = ice_sw_type_from_tunnel(tc_fltr->tunnel_type);
+	if (tc_fltr->tunnel_type != TNL_LAST) {
+		i = ice_tc_fill_tunnel_outer(flags, tc_fltr, list);
+
+		headers = &tc_fltr->inner_headers;
+		inner = true;
+	} else if (flags & ICE_TC_FLWR_FIELD_ETH_TYPE_ID) {
 		list[i].type = ICE_ETYPE_OL;
 		list[i].h_u.ethertype.ethtype_id = headers->l2_key.n_proto;
 		list[i].m_u.ethertype.ethtype_id = headers->l2_mask.n_proto;
@@ -83,7 +232,7 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
 		l2_key = &headers->l2_key;
 		l2_mask = &headers->l2_mask;
 
-		list[i].type = ICE_MAC_OFOS;
+		list[i].type = ice_proto_type_from_mac(inner);
 		if (flags & ICE_TC_FLWR_FIELD_DST_MAC) {
 			ether_addr_copy(list[i].h_u.eth_hdr.dst_addr,
 					l2_key->dst_mac);
@@ -112,7 +261,7 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
 		     ICE_TC_FLWR_FIELD_SRC_IPV4)) {
 		struct ice_tc_l3_hdr *l3_key, *l3_mask;
 
-		list[i].type = ICE_IPV4_OFOS;
+		list[i].type = ice_proto_type_from_ipv4(inner);
 		l3_key = &headers->l3_key;
 		l3_mask = &headers->l3_mask;
 		if (flags & ICE_TC_FLWR_FIELD_DEST_IPV4) {
@@ -129,7 +278,7 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
 		struct ice_ipv6_hdr *ipv6_hdr, *ipv6_mask;
 		struct ice_tc_l3_hdr *l3_key, *l3_mask;
 
-		list[i].type = ICE_IPV6_OFOS;
+		list[i].type = ice_proto_type_from_ipv6(inner);
 		ipv6_hdr = &list[i].h_u.ipv6_hdr;
 		ipv6_mask = &list[i].m_u.ipv6_hdr;
 		l3_key = &headers->l3_key;
@@ -155,19 +304,10 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
 		     ICE_TC_FLWR_FIELD_SRC_L4_PORT)) {
 		struct ice_tc_l4_hdr *l4_key, *l4_mask;
 
+		list[i].type = ice_proto_type_from_l4_port(inner, headers->l3_key.ip_proto);
 		l4_key = &headers->l4_key;
 		l4_mask = &headers->l4_mask;
-		if (headers->l3_key.ip_proto == IPPROTO_TCP) {
-			list[i].type = ICE_TCP_IL;
-			/* detected L4 proto is TCP */
-			if (l4_proto)
-				*l4_proto = IPPROTO_TCP;
-		} else if (headers->l3_key.ip_proto == IPPROTO_UDP) {
-			list[i].type = ICE_UDP_ILOS;
-			/* detected L4 proto is UDP */
-			if (l4_proto)
-				*l4_proto = IPPROTO_UDP;
-		}
+
 		if (flags & ICE_TC_FLWR_FIELD_DEST_L4_PORT) {
 			list[i].h_u.l4_hdr.dst_port = l4_key->dst_port;
 			list[i].m_u.l4_hdr.dst_port = l4_mask->dst_port;
@@ -182,6 +322,28 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
 	return i;
 }
 
+/**
+ * ice_tc_tun_get_type - get the tunnel type
+ * @tunnel_dev: ptr to tunnel device
+ * @rule: ptr to flow_rule
+ *
+ * This function detects appropriate tunnel_type if specified device is
+ * tunnel device such as vxlan/geneve
+ */
+static int ice_tc_tun_get_type(struct net_device *tunnel_dev)
+{
+	if (netif_is_vxlan(tunnel_dev))
+		return TNL_VXLAN;
+	if (netif_is_geneve(tunnel_dev))
+		return TNL_GENEVE;
+	return TNL_LAST;
+}
+
+bool ice_is_tunnel_supported(struct net_device *dev)
+{
+	return ice_tc_tun_get_type(dev) != TNL_LAST;
+}
+
 static int
 ice_eswitch_tc_parse_action(struct ice_tc_flower_fltr *fltr,
 			    struct flow_action_entry *act)
@@ -201,10 +363,7 @@ ice_eswitch_tc_parse_action(struct ice_tc_flower_fltr *fltr,
 
 			fltr->dest_vsi = repr->src_vsi;
 			fltr->direction = ICE_ESWITCH_FLTR_INGRESS;
-		} else if (netif_is_ice(act->dev)) {
-			struct ice_netdev_priv *np = netdev_priv(act->dev);
-
-			fltr->dest_vsi = np->vsi;
+		} else if (netif_is_ice(act->dev) || ice_is_tunnel_supported(act->dev)) {
 			fltr->direction = ICE_ESWITCH_FLTR_EGRESS;
 		} else {
 			NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported netdevice in switchdev mode");
@@ -234,11 +393,7 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
 	int ret;
 	int i;
 
-	if (!flags || (flags & (ICE_TC_FLWR_FIELD_ENC_DEST_IPV4 |
-				ICE_TC_FLWR_FIELD_ENC_SRC_IPV4 |
-				ICE_TC_FLWR_FIELD_ENC_DEST_IPV6 |
-				ICE_TC_FLWR_FIELD_ENC_SRC_IPV6 |
-				ICE_TC_FLWR_FIELD_ENC_SRC_L4_PORT))) {
+	if (!flags || (flags & ICE_TC_FLWR_FIELD_ENC_SRC_L4_PORT)) {
 		NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported encap field(s)");
 		return -EOPNOTSUPP;
 	}
@@ -254,6 +409,10 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
 		goto exit;
 	}
 
+	/* egress traffic is always redirect to uplink */
+	if (fltr->direction == ICE_ESWITCH_FLTR_EGRESS)
+		fltr->dest_vsi = vsi->back->switchdev.uplink_vsi;
+
 	rule_info.sw_act.fltr_act = fltr->action.fltr_act;
 	if (fltr->action.fltr_act != ICE_DROP_PACKET)
 		rule_info.sw_act.vsi_handle = fltr->dest_vsi->idx;
@@ -306,19 +465,26 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr)
  * @match: Pointer to flow match structure
  * @fltr: Pointer to filter structure
  * @headers: inner or outer header fields
+ * @is_encap: set true for tunnel IPv4 address
  */
 static int
 ice_tc_set_ipv4(struct flow_match_ipv4_addrs *match,
 		struct ice_tc_flower_fltr *fltr,
-		struct ice_tc_flower_lyr_2_4_hdrs *headers)
+		struct ice_tc_flower_lyr_2_4_hdrs *headers, bool is_encap)
 {
 	if (match->key->dst) {
-		fltr->flags |= ICE_TC_FLWR_FIELD_DEST_IPV4;
+		if (is_encap)
+			fltr->flags |= ICE_TC_FLWR_FIELD_ENC_DEST_IPV4;
+		else
+			fltr->flags |= ICE_TC_FLWR_FIELD_DEST_IPV4;
 		headers->l3_key.dst_ipv4 = match->key->dst;
 		headers->l3_mask.dst_ipv4 = match->mask->dst;
 	}
 	if (match->key->src) {
-		fltr->flags |= ICE_TC_FLWR_FIELD_SRC_IPV4;
+		if (is_encap)
+			fltr->flags |= ICE_TC_FLWR_FIELD_ENC_SRC_IPV4;
+		else
+			fltr->flags |= ICE_TC_FLWR_FIELD_SRC_IPV4;
 		headers->l3_key.src_ipv4 = match->key->src;
 		headers->l3_mask.src_ipv4 = match->mask->src;
 	}
@@ -330,11 +496,12 @@ ice_tc_set_ipv4(struct flow_match_ipv4_addrs *match,
  * @match: Pointer to flow match structure
  * @fltr: Pointer to filter structure
  * @headers: inner or outer header fields
+ * @is_encap: set true for tunnel IPv6 address
  */
 static int
 ice_tc_set_ipv6(struct flow_match_ipv6_addrs *match,
 		struct ice_tc_flower_fltr *fltr,
-		struct ice_tc_flower_lyr_2_4_hdrs *headers)
+		struct ice_tc_flower_lyr_2_4_hdrs *headers, bool is_encap)
 {
 	struct ice_tc_l3_hdr *l3_key, *l3_mask;
 
@@ -352,21 +519,31 @@ ice_tc_set_ipv6(struct flow_match_ipv6_addrs *match,
 		NL_SET_ERR_MSG_MOD(fltr->extack, "Bad src/dest IPv6, addr is any");
 		return -EINVAL;
 	}
-	if (!ipv6_addr_any(&match->mask->dst))
-		fltr->flags |= ICE_TC_FLWR_FIELD_DEST_IPV6;
-	if (!ipv6_addr_any(&match->mask->src))
-		fltr->flags |= ICE_TC_FLWR_FIELD_SRC_IPV6;
+	if (!ipv6_addr_any(&match->mask->dst)) {
+		if (is_encap)
+			fltr->flags |= ICE_TC_FLWR_FIELD_ENC_DEST_IPV6;
+		else
+			fltr->flags |= ICE_TC_FLWR_FIELD_DEST_IPV6;
+	}
+	if (!ipv6_addr_any(&match->mask->src)) {
+		if (is_encap)
+			fltr->flags |= ICE_TC_FLWR_FIELD_ENC_SRC_IPV6;
+		else
+			fltr->flags |= ICE_TC_FLWR_FIELD_SRC_IPV6;
+	}
 
 	l3_key = &headers->l3_key;
 	l3_mask = &headers->l3_mask;
 
-	if (fltr->flags & ICE_TC_FLWR_FIELD_SRC_IPV6) {
+	if (fltr->flags & (ICE_TC_FLWR_FIELD_ENC_SRC_IPV6 |
+			   ICE_TC_FLWR_FIELD_SRC_IPV6)) {
 		memcpy(&l3_key->src_ipv6_addr, &match->key->src.s6_addr,
 		       sizeof(match->key->src.s6_addr));
 		memcpy(&l3_mask->src_ipv6_addr, &match->mask->src.s6_addr,
 		       sizeof(match->mask->src.s6_addr));
 	}
-	if (fltr->flags & ICE_TC_FLWR_FIELD_DEST_IPV6) {
+	if (fltr->flags & (ICE_TC_FLWR_FIELD_ENC_DEST_IPV6 |
+			   ICE_TC_FLWR_FIELD_DEST_IPV6)) {
 		memcpy(&l3_key->dst_ipv6_addr, &match->key->dst.s6_addr,
 		       sizeof(match->key->dst.s6_addr));
 		memcpy(&l3_mask->dst_ipv6_addr, &match->mask->dst.s6_addr,
@@ -381,18 +558,27 @@ ice_tc_set_ipv6(struct flow_match_ipv6_addrs *match,
  * @match: Flow match structure
  * @fltr: Pointer to filter structure
  * @headers: inner or outer header fields
+ * @is_encap: set true for tunnel port
  */
 static int
 ice_tc_set_port(struct flow_match_ports match,
 		struct ice_tc_flower_fltr *fltr,
-		struct ice_tc_flower_lyr_2_4_hdrs *headers)
+		struct ice_tc_flower_lyr_2_4_hdrs *headers, bool is_encap)
 {
 	if (match.key->dst) {
+		if (is_encap)
+			fltr->flags |= ICE_TC_FLWR_FIELD_ENC_DEST_L4_PORT;
+		else
+			fltr->flags |= ICE_TC_FLWR_FIELD_DEST_L4_PORT;
 		fltr->flags |= ICE_TC_FLWR_FIELD_DEST_L4_PORT;
 		headers->l4_key.dst_port = match.key->dst;
 		headers->l4_mask.dst_port = match.mask->dst;
 	}
 	if (match.key->src) {
+		if (is_encap)
+			fltr->flags |= ICE_TC_FLWR_FIELD_ENC_SRC_L4_PORT;
+		else
+			fltr->flags |= ICE_TC_FLWR_FIELD_SRC_L4_PORT;
 		fltr->flags |= ICE_TC_FLWR_FIELD_SRC_L4_PORT;
 		headers->l4_key.src_port = match.key->src;
 		headers->l4_mask.src_port = match.mask->src;
@@ -400,6 +586,85 @@ ice_tc_set_port(struct flow_match_ports match,
 	return 0;
 }
 
+static struct net_device *
+ice_get_tunnel_device(struct net_device *dev, struct flow_rule *rule)
+{
+	struct flow_action_entry *act;
+	int i;
+
+	if (ice_is_tunnel_supported(dev))
+		return dev;
+
+	flow_action_for_each(i, act, &rule->action) {
+		if (act->id == FLOW_ACTION_REDIRECT &&
+		    ice_is_tunnel_supported(act->dev))
+			return act->dev;
+	}
+
+	return NULL;
+}
+
+static int
+ice_parse_tunnel_attr(struct net_device *dev, struct flow_rule *rule,
+		      struct ice_tc_flower_fltr *fltr)
+{
+	struct ice_tc_flower_lyr_2_4_hdrs *headers = &fltr->outer_headers;
+	struct flow_match_control enc_control;
+
+	fltr->tunnel_type = ice_tc_tun_get_type(dev);
+	headers->l3_key.ip_proto = IPPROTO_UDP;
+
+	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
+		struct flow_match_enc_keyid enc_keyid;
+
+		flow_rule_match_enc_keyid(rule, &enc_keyid);
+
+		if (!enc_keyid.mask->keyid ||
+		    enc_keyid.mask->keyid != cpu_to_be32(ICE_TC_FLOWER_MASK_32))
+			return -EINVAL;
+
+		fltr->flags |= ICE_TC_FLWR_FIELD_TENANT_ID;
+		fltr->tenant_id = enc_keyid.key->keyid;
+	}
+
+	flow_rule_match_enc_control(rule, &enc_control);
+
+	if (enc_control.key->addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
+		struct flow_match_ipv4_addrs match;
+
+		flow_rule_match_enc_ipv4_addrs(rule, &match);
+		if (ice_tc_set_ipv4(&match, fltr, headers, true))
+			return -EINVAL;
+	} else if (enc_control.key->addr_type ==
+					FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
+		struct flow_match_ipv6_addrs match;
+
+		flow_rule_match_enc_ipv6_addrs(rule, &match);
+		if (ice_tc_set_ipv6(&match, fltr, headers, true))
+			return -EINVAL;
+	}
+
+	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IP)) {
+		struct flow_match_ip match;
+
+		flow_rule_match_enc_ip(rule, &match);
+		headers->l3_key.tos = match.key->tos;
+		headers->l3_key.ttl = match.key->ttl;
+		headers->l3_mask.tos = match.mask->tos;
+		headers->l3_mask.ttl = match.mask->ttl;
+	}
+
+	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS)) {
+		struct flow_match_ports match;
+
+		flow_rule_match_enc_ports(rule, &match);
+		if (ice_tc_set_port(match, fltr, headers, true))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 /**
  * ice_parse_cls_flower - Parse TC flower filters provided by kernel
  * @vsi: Pointer to the VSI
@@ -427,12 +692,44 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
 	      BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
 	      BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
 	      BIT(FLOW_DISSECTOR_KEY_ENC_CONTROL) |
+	      BIT(FLOW_DISSECTOR_KEY_ENC_KEYID) |
+	      BIT(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) |
+	      BIT(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) |
+	      BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) |
 	      BIT(FLOW_DISSECTOR_KEY_ENC_IP) |
 	      BIT(FLOW_DISSECTOR_KEY_PORTS))) {
 		NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported key used");
 		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))) {
+		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;
+		}
+
+		err = ice_parse_tunnel_attr(filter_dev, rule, fltr);
+		if (err) {
+			NL_SET_ERR_MSG_MOD(fltr->extack,
+					   "Failed to parse TC flower tunnel attributes");
+			return err;
+		}
+
+		/* header pointers should point to the inner headers, outer
+		 * header were already set by ice_parse_tunnel_attr
+		 */
+		headers = &fltr->inner_headers;
+	} else {
+		fltr->tunnel_type = TNL_LAST;
+	}
+
 	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
 		struct flow_match_basic match;
 
@@ -519,7 +816,7 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
 		struct flow_match_ipv4_addrs match;
 
 		flow_rule_match_ipv4_addrs(rule, &match);
-		if (ice_tc_set_ipv4(&match, fltr, headers))
+		if (ice_tc_set_ipv4(&match, fltr, headers, false))
 			return -EINVAL;
 	}
 
@@ -527,7 +824,7 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
 		struct flow_match_ipv6_addrs match;
 
 		flow_rule_match_ipv6_addrs(rule, &match);
-		if (ice_tc_set_ipv6(&match, fltr, headers))
+		if (ice_tc_set_ipv6(&match, fltr, headers, false))
 			return -EINVAL;
 	}
 
@@ -535,7 +832,7 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
 		struct flow_match_ports match;
 
 		flow_rule_match_ports(rule, &match);
-		if (ice_tc_set_port(match, fltr, headers))
+		if (ice_tc_set_port(match, fltr, headers, false))
 			return -EINVAL;
 		switch (headers->l3_key.ip_proto) {
 		case IPPROTO_TCP:
diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.h b/drivers/net/ethernet/intel/ice/ice_tc_lib.h
index 332c70342f1f..28c33b850ffb 100644
--- a/drivers/net/ethernet/intel/ice/ice_tc_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.h
@@ -23,6 +23,8 @@
 #define ICE_TC_FLWR_FIELD_ENC_DST_MAC		BIT(16)
 #define ICE_TC_FLWR_FIELD_ETH_TYPE_ID		BIT(17)
 
+#define ICE_TC_FLOWER_MASK_32   0xFFFFFFFF
+
 struct ice_indr_block_priv {
 	struct net_device *netdev;
 	struct ice_netdev_priv *np;
@@ -118,6 +120,7 @@ struct ice_tc_flower_fltr {
 	struct ice_vsi *src_vsi;
 	__be32 tenant_id;
 	u32 flags;
+	u8 tunnel_type;
 	struct ice_tc_flower_action	action;
 
 	/* cache ptr which is used wherever needed to communicate netlink
@@ -132,5 +135,6 @@ ice_add_cls_flower(struct net_device *netdev, struct ice_vsi *vsi,
 int
 ice_del_cls_flower(struct ice_vsi *vsi, struct flow_cls_offload *cls_flower);
 void ice_replay_tc_fltrs(struct ice_pf *pf);
+bool ice_is_tunnel_supported(struct net_device *dev);
 
 #endif /* _ICE_TC_LIB_H_ */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Intel-wired-lan] [PATCH net-next 3/4] ice: low level support for tunnels
  2021-10-11  9:48 [Intel-wired-lan] [PATCH net-next 0/4] support for tunnel in ice eswitch Michal Swiatkowski
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 1/4] ice: support for indirect notification Michal Swiatkowski
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 2/4] ice: vxlan and geneve tc support Michal Swiatkowski
@ 2021-10-11  9:48 ` Michal Swiatkowski
  2021-10-11 23:15     ` kernel test robot
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 4/4] ice: support for gre in eswitch Michal Swiatkowski
  3 siblings, 1 reply; 8+ messages in thread
From: Michal Swiatkowski @ 2021-10-11  9:48 UTC (permalink / raw)
  To: intel-wired-lan

Add definition of UDP tunnel dummy packets. Fill destination port value
in filter based on UDP tunnel port. Append tunnel flags to switch filter
definition in case of matching the tunnel.

Both vxlan and geneve are UDP tunnels, so only one new header is needed.

Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
---
 .../net/ethernet/intel/ice/ice_flex_pipe.c    |  22 +-
 .../net/ethernet/intel/ice/ice_flex_type.h    |   2 +
 .../ethernet/intel/ice/ice_protocol_type.h    |   9 +
 drivers/net/ethernet/intel/ice/ice_switch.c   | 264 +++++++++++++++++-
 drivers/net/ethernet/intel/ice/ice_switch.h   |   2 +
 5 files changed, 296 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
index a9efd8985a42..c24c64e3bc65 100644
--- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
+++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
@@ -1706,6 +1706,26 @@ static struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw)
 	return bld;
 }
 
+/**
+ * ice_get_sw_prof_type - determine switch profile type
+ * @hw: pointer to the HW structure
+ * @fv: pointer to the switch field vector
+ */
+static enum ice_prof_type
+ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv)
+{
+	u16 i;
+
+	for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) {
+		/* UDP tunnel will have UDP_OF protocol ID and VNI offset */
+		if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&
+		    fv->ew[i].off == ICE_VNI_OFFSET)
+			return ICE_PROF_TUN_UDP;
+	}
+
+	return ICE_PROF_NON_TUN;
+}
+
 /**
  * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type
  * @hw: pointer to hardware structure
@@ -1737,7 +1757,7 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs,
 		ice_seg = NULL;
 
 		if (fv) {
-			prof_type = ICE_PROF_NON_TUN;
+			prof_type = ice_get_sw_prof_type(hw, fv);
 
 			if (req_profs & prof_type)
 				set_bit((u16)offset, bm);
diff --git a/drivers/net/ethernet/intel/ice/ice_flex_type.h b/drivers/net/ethernet/intel/ice/ice_flex_type.h
index c73fde45b266..fce1bd929467 100644
--- a/drivers/net/ethernet/intel/ice/ice_flex_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_flex_type.h
@@ -656,6 +656,8 @@ struct ice_chs_chg {
 
 enum ice_prof_type {
 	ICE_PROF_NON_TUN = 0x1,
+	ICE_PROF_TUN_UDP = 0x2,
+	ICE_PROF_TUN_ALL = 0x6,
 	ICE_PROF_ALL = 0xFF,
 };
 #endif /* _ICE_FLEX_TYPE_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_protocol_type.h b/drivers/net/ethernet/intel/ice/ice_protocol_type.h
index d717d1158545..e4a8024de3f7 100644
--- a/drivers/net/ethernet/intel/ice/ice_protocol_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_protocol_type.h
@@ -48,6 +48,7 @@ enum ice_sw_tunnel_type {
 	ICE_NON_TUN = 0,
 	ICE_SW_TUN_VXLAN,
 	ICE_SW_TUN_GENEVE,
+	ICE_ALL_TUNNELS /* All tunnel types including NVGRE */
 };
 
 /* Decoders for ice_prot_id:
@@ -83,6 +84,8 @@ enum ice_prot_id {
 	ICE_PROT_INVALID	= 255  /* when offset == ICE_FV_OFFSET_INVAL */
 };
 
+#define ICE_VNI_OFFSET		12 /* offset of VNI from ICE_PROT_UDP_OF */
+
 #define ICE_MAC_OFOS_HW		1
 #define ICE_MAC_IL_HW		4
 #define ICE_ETYPE_OL_HW		9
@@ -96,6 +99,12 @@ enum ice_prot_id {
 #define ICE_UDP_ILOS_HW		53
 
 #define ICE_UDP_OF_HW	52 /* UDP Tunnels */
+#define ICE_META_DATA_ID_HW 255 /* this is used for tunnel type */
+
+#define ICE_MDID_SIZE 2
+#define ICE_TUN_FLAG_MDID 21
+#define ICE_TUN_FLAG_MDID_OFF (ICE_MDID_SIZE * ICE_TUN_FLAG_MDID)
+#define ICE_TUN_FLAG_MASK 0xFF
 
 #define ICE_TUN_FLAG_FV_IND 2
 
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
index 61178f9aa31f..1d26db24e376 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
@@ -35,6 +35,105 @@ struct ice_dummy_pkt_offsets {
 	u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
 };
 
+static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = {
+	{ ICE_MAC_OFOS,		0 },
+	{ ICE_ETYPE_OL,		12 },
+	{ ICE_IPV4_OFOS,	14 },
+	{ ICE_UDP_OF,		34 },
+	{ ICE_VXLAN,		42 },
+	{ ICE_GENEVE,		42 },
+	{ ICE_VXLAN_GPE,	42 },
+	{ ICE_MAC_IL,		50 },
+	{ ICE_IPV4_IL,		64 },
+	{ ICE_TCP_IL,		84 },
+	{ ICE_PROTOCOL_LAST,	0 },
+};
+
+static const u8 dummy_udp_tun_tcp_packet[] = {
+	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
+
+	0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
+	0x00, 0x01, 0x00, 0x00,
+	0x40, 0x11, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
+	0x00, 0x46, 0x00, 0x00,
+
+	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00,
+
+	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
+	0x00, 0x01, 0x00, 0x00,
+	0x40, 0x06, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x50, 0x02, 0x20, 0x00,
+	0x00, 0x00, 0x00, 0x00
+};
+
+static const struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = {
+	{ ICE_MAC_OFOS,		0 },
+	{ ICE_ETYPE_OL,		12 },
+	{ ICE_IPV4_OFOS,	14 },
+	{ ICE_UDP_OF,		34 },
+	{ ICE_VXLAN,		42 },
+	{ ICE_GENEVE,		42 },
+	{ ICE_VXLAN_GPE,	42 },
+	{ ICE_MAC_IL,		50 },
+	{ ICE_IPV4_IL,		64 },
+	{ ICE_UDP_ILOS,		84 },
+	{ ICE_PROTOCOL_LAST,	0 },
+};
+
+static const u8 dummy_udp_tun_udp_packet[] = {
+	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
+
+	0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
+	0x00, 0x01, 0x00, 0x00,
+	0x00, 0x11, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
+	0x00, 0x3a, 0x00, 0x00,
+
+	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00,
+
+	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
+	0x00, 0x01, 0x00, 0x00,
+	0x00, 0x11, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
+	0x00, 0x08, 0x00, 0x00,
+};
+
 /* offset info for MAC + IPv4 + UDP dummy packet */
 static const struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = {
 	{ ICE_MAC_OFOS,		0 },
@@ -3517,6 +3616,8 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
 	{ ICE_TCP_IL,		{ 0, 2 } },
 	{ ICE_UDP_OF,		{ 0, 2 } },
 	{ ICE_UDP_ILOS,		{ 0, 2 } },
+	{ ICE_VXLAN,		{ 8, 10, 12, 14 } },
+	{ ICE_GENEVE,		{ 8, 10, 12, 14 } },
 };
 
 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
@@ -3531,6 +3632,8 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
 	{ ICE_TCP_IL,		ICE_TCP_IL_HW },
 	{ ICE_UDP_OF,		ICE_UDP_OF_HW },
 	{ ICE_UDP_ILOS,		ICE_UDP_ILOS_HW },
+	{ ICE_VXLAN,		ICE_UDP_OF_HW },
+	{ ICE_GENEVE,		ICE_UDP_OF_HW },
 };
 
 /**
@@ -4134,6 +4237,7 @@ ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
 		recp->chain_idx = entry->chain_idx;
 		recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
 		recp->n_grp_count = rm->n_grp_count;
+		recp->tun_type = rm->tun_type;
 		recp->recp_created = true;
 	}
 	rm->root_buf = buf;
@@ -4214,6 +4318,54 @@ ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
 	return status;
 }
 
+/**
+ * ice_tun_type_match_word - determine if tun type needs a match mask
+ * @tun_type: tunnel type
+ * @mask: mask to be used for the tunnel
+ */
+static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
+{
+	switch (tun_type) {
+	case ICE_SW_TUN_GENEVE:
+	case ICE_SW_TUN_VXLAN:
+		*mask = ICE_TUN_FLAG_MASK;
+		return true;
+
+	default:
+		*mask = 0;
+		return false;
+	}
+}
+
+/**
+ * ice_add_special_words - Add words that are not protocols, such as metadata
+ * @rinfo: other information regarding the rule e.g. priority and action info
+ * @lkup_exts: lookup word structure
+ */
+static enum ice_status
+ice_add_special_words(struct ice_adv_rule_info *rinfo,
+		      struct ice_prot_lkup_ext *lkup_exts)
+{
+	u16 mask;
+
+	/* If this is a tunneled packet, then add recipe index to match the
+	 * tunnel bit in the packet metadata flags.
+	 */
+	if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
+		if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
+			u8 word = lkup_exts->n_val_words++;
+
+			lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
+			lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
+			lkup_exts->field_mask[word] = mask;
+		} else {
+			return ICE_ERR_MAX_LIMIT;
+		}
+	}
+
+	return ICE_SUCCESS;
+}
+
 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
  * @hw: pointer to hardware structure
  * @rinfo: other information regarding the rule e.g. priority and action info
@@ -4223,9 +4375,27 @@ static void
 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
 			 unsigned long *bm)
 {
+	enum ice_prof_type prof_type;
+
 	bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
 
-	ice_get_sw_fv_bitmap(hw, ICE_PROF_NON_TUN, bm);
+	switch (rinfo->tun_type) {
+	case ICE_NON_TUN:
+		prof_type = ICE_PROF_NON_TUN;
+		break;
+	case ICE_ALL_TUNNELS:
+		prof_type = ICE_PROF_TUN_ALL;
+		break;
+	case ICE_SW_TUN_GENEVE:
+	case ICE_SW_TUN_VXLAN:
+		prof_type = ICE_PROF_TUN_UDP;
+		break;
+	default:
+		prof_type = ICE_PROF_ALL;
+		break;
+	}
+
+	ice_get_sw_fv_bitmap(hw, prof_type, bm);
 }
 
 /**
@@ -4251,6 +4421,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
 	struct ice_sw_recipe *rm;
 	u16 match_tun_mask = 0;
 	int status = 0;
+	u16 mask;
 	u8 i;
 
 	if (!lkups_cnt)
@@ -4307,6 +4478,10 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
 	if (status)
 		goto err_unroll;
 
+	if (ice_tun_type_match_word(rinfo->tun_type, &mask) &&
+	    rm->n_grp_count > 1)
+		match_tun_mask = mask;
+
 	/* set the recipe priority if specified */
 	rm->priority = (u8)rinfo->priority;
 
@@ -4324,6 +4499,13 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
 		set_bit((u16)fvit->profile_id, profiles);
 	}
 
+	/* Create any special protocol/offset pairs, such as looking at tunnel
+	 * bits by extracting metadata
+	 */
+	status = ice_add_special_words(rinfo, lkup_exts);
+	if (status)
+		goto err_free_lkup_exts;
+
 	/* Look for a recipe which matches our requested fv / mask list */
 	*rid = ice_find_recp(hw, lkup_exts);
 	if (*rid < ICE_MAX_NUM_RECIPES)
@@ -4407,6 +4589,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
  */
 static void
 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
+		      enum ice_sw_tunnel_type tun_type,
 		      const u8 **pkt, u16 *pkt_len,
 		      const struct ice_dummy_pkt_offsets **offsets)
 {
@@ -4430,6 +4613,21 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
 			ipv6 = true;
 	}
 
+	if (tun_type == ICE_SW_TUN_VXLAN ||
+	    tun_type == ICE_SW_TUN_GENEVE) {
+		if (tcp) {
+			*pkt = dummy_udp_tun_tcp_packet;
+			*pkt_len = sizeof(dummy_udp_tun_tcp_packet);
+			*offsets = dummy_udp_tun_tcp_packet_offsets;
+			return;
+		}
+
+		*pkt = dummy_udp_tun_udp_packet;
+		*pkt_len = sizeof(dummy_udp_tun_udp_packet);
+		*offsets = dummy_udp_tun_udp_packet_offsets;
+		return;
+	}
+
 	if (udp && !ipv6) {
 		if (vlan) {
 			*pkt = dummy_vlan_udp_packet;
@@ -4550,6 +4748,10 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
 		case ICE_SCTP_IL:
 			len = sizeof(struct ice_sctp_hdr);
 			break;
+		case ICE_VXLAN:
+		case ICE_GENEVE:
+			len = sizeof(struct ice_udp_tnl_hdr);
+			break;
 		default:
 			return -EINVAL;
 		}
@@ -4579,6 +4781,48 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
 	return 0;
 }
 
+/**
+ * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
+ * @hw: pointer to the hardware structure
+ * @tun_type: tunnel type
+ * @pkt: dummy packet to fill in
+ * @offsets: offset info for the dummy packet
+ */
+static enum ice_status
+ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
+			u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
+{
+	u16 open_port, i;
+
+	switch (tun_type) {
+	case ICE_SW_TUN_VXLAN:
+	case ICE_SW_TUN_GENEVE:
+		if (!ice_get_open_tunnel_port(hw, &open_port))
+			return ICE_ERR_CFG;
+		break;
+
+	default:
+		/* Nothing needs to be done for this tunnel type */
+		return ICE_SUCCESS;
+	}
+
+	/* Find the outer UDP protocol header and insert the port number */
+	for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
+		if (offsets[i].type == ICE_UDP_OF) {
+			struct ice_l4_hdr *hdr;
+			u16 offset;
+
+			offset = offsets[i].offset;
+			hdr = (struct ice_l4_hdr *)&pkt[offset];
+			hdr->dst_port = cpu_to_be16(open_port);
+
+			return ICE_SUCCESS;
+		}
+	}
+
+	return ICE_ERR_CFG;
+}
+
 /**
  * ice_find_adv_rule_entry - Search a rule entry
  * @hw: pointer to the hardware structure
@@ -4613,6 +4857,7 @@ ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
 				break;
 			}
 		if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
+		    rinfo->tun_type == list_itr->rule_info.tun_type &&
 		    lkups_matched)
 			return list_itr;
 	}
@@ -4787,7 +5032,7 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
 		return -EINVAL;
 
 	/* make sure that we can locate a dummy packet */
-	ice_find_dummy_packet(lkups, lkups_cnt, &pkt, &pkt_len,
+	ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len,
 			      &pkt_offsets);
 	if (!pkt) {
 		status = -EINVAL;
@@ -4898,6 +5143,14 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
 	if (status)
 		goto err_ice_add_adv_rule;
 
+	if (rinfo->tun_type != ICE_NON_TUN) {
+		status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
+						 s_rule->pdata.lkup_tx_rx.hdr,
+						 pkt_offsets);
+		if (status)
+			goto err_ice_add_adv_rule;
+	}
+
 	status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
 				 rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
 				 NULL);
@@ -5133,6 +5386,13 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
 			return -EIO;
 	}
 
+	/* Create any special protocol/offset pairs, such as looking at tunnel
+	 * bits by extracting metadata
+	 */
+	status = ice_add_special_words(rinfo, &lkup_exts);
+	if (status)
+		return status;
+
 	rid = ice_find_recp(hw, &lkup_exts);
 	/* If did not find a recipe that match the existing criteria */
 	if (rid == ICE_MAX_NUM_RECIPES)
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.h b/drivers/net/ethernet/intel/ice/ice_switch.h
index 661cecf8fd99..b1496c330a1b 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.h
+++ b/drivers/net/ethernet/intel/ice/ice_switch.h
@@ -221,6 +221,8 @@ struct ice_sw_recipe {
 	/* Bit map specifying the IDs associated with this group of recipe */
 	DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
 
+	enum ice_sw_tunnel_type tun_type;
+
 	/* List of type ice_fltr_mgmt_list_entry or adv_rule */
 	u8 adv_rule;
 	struct list_head filt_rules;
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Intel-wired-lan] [PATCH net-next 4/4] ice: support for gre in eswitch
  2021-10-11  9:48 [Intel-wired-lan] [PATCH net-next 0/4] support for tunnel in ice eswitch Michal Swiatkowski
                   ` (2 preceding siblings ...)
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 3/4] ice: low level support for tunnels Michal Swiatkowski
@ 2021-10-11  9:48 ` Michal Swiatkowski
  3 siblings, 0 replies; 8+ messages in thread
From: Michal Swiatkowski @ 2021-10-11  9:48 UTC (permalink / raw)
  To: intel-wired-lan

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>
---
 .../net/ethernet/intel/ice/ice_flex_pipe.c    |   4 +
 .../net/ethernet/intel/ice/ice_flex_type.h    |   2 +
 .../ethernet/intel/ice/ice_protocol_type.h    |  10 ++
 drivers/net/ethernet/intel/ice/ice_switch.c   | 110 ++++++++++++++++++
 drivers/net/ethernet/intel/ice/ice_tc_lib.c   |  28 +++--
 5 files changed, 144 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
index c24c64e3bc65..c172ff91700f 100644
--- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
+++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c
@@ -1721,6 +1721,10 @@ ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv)
 		if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&
 		    fv->ew[i].off == ICE_VNI_OFFSET)
 			return ICE_PROF_TUN_UDP;
+
+		/* GRE tunnel will have GRE protocol */
+		if (fv->ew[i].prot_id == (u8)ICE_PROT_GRE_OF)
+			return ICE_PROF_TUN_GRE;
 	}
 
 	return ICE_PROF_NON_TUN;
diff --git a/drivers/net/ethernet/intel/ice/ice_flex_type.h b/drivers/net/ethernet/intel/ice/ice_flex_type.h
index fce1bd929467..fc087e0b5292 100644
--- a/drivers/net/ethernet/intel/ice/ice_flex_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_flex_type.h
@@ -415,6 +415,7 @@ struct ice_pkg_enum {
 enum ice_tunnel_type {
 	TNL_VXLAN = 0,
 	TNL_GENEVE,
+	TNL_GRETAP,
 	__TNL_TYPE_CNT,
 	TNL_LAST = 0xFF,
 	TNL_ALL = 0xFF,
@@ -657,6 +658,7 @@ struct ice_chs_chg {
 enum ice_prof_type {
 	ICE_PROF_NON_TUN = 0x1,
 	ICE_PROF_TUN_UDP = 0x2,
+	ICE_PROF_TUN_GRE = 0x4,
 	ICE_PROF_TUN_ALL = 0x6,
 	ICE_PROF_ALL = 0xFF,
 };
diff --git a/drivers/net/ethernet/intel/ice/ice_protocol_type.h b/drivers/net/ethernet/intel/ice/ice_protocol_type.h
index e4a8024de3f7..dc1b0e9e6df5 100644
--- a/drivers/net/ethernet/intel/ice/ice_protocol_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_protocol_type.h
@@ -39,6 +39,7 @@ enum ice_protocol_type {
 	ICE_UDP_ILOS,
 	ICE_VXLAN,
 	ICE_GENEVE,
+	ICE_NVGRE,
 	ICE_VXLAN_GPE,
 	ICE_SCTP_IL,
 	ICE_PROTOCOL_LAST
@@ -48,6 +49,7 @@ enum ice_sw_tunnel_type {
 	ICE_NON_TUN = 0,
 	ICE_SW_TUN_VXLAN,
 	ICE_SW_TUN_GENEVE,
+	ICE_SW_TUN_NVGRE,
 	ICE_ALL_TUNNELS /* All tunnel types including NVGRE */
 };
 
@@ -97,6 +99,7 @@ enum ice_prot_id {
 #define ICE_IPV6_IL_HW		41
 #define ICE_TCP_IL_HW		49
 #define ICE_UDP_ILOS_HW		53
+#define ICE_GRE_OF_HW		64
 
 #define ICE_UDP_OF_HW	52 /* UDP Tunnels */
 #define ICE_META_DATA_ID_HW 255 /* this is used for tunnel type */
@@ -176,6 +179,12 @@ struct ice_udp_tnl_hdr {
 	__be32 vni;     /* only use lower 24-bits */
 };
 
+struct ice_nvgre_hdr {
+	__be16 flags;
+	__be16 protocol;
+	__be32 tni_flow;
+};
+
 union ice_prot_hdr {
 	struct ice_ether_hdr eth_hdr;
 	struct ice_ethtype_hdr ethertype;
@@ -185,6 +194,7 @@ union ice_prot_hdr {
 	struct ice_l4_hdr l4_hdr;
 	struct ice_sctp_hdr sctp_hdr;
 	struct ice_udp_tnl_hdr tnl_hdr;
+	struct ice_nvgre_hdr nvgre_hdr;
 };
 
 /* This is mapping table entry that maps every word within a given protocol
diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c
index 1d26db24e376..5d8d7f370d7b 100644
--- a/drivers/net/ethernet/intel/ice/ice_switch.c
+++ b/drivers/net/ethernet/intel/ice/ice_switch.c
@@ -35,6 +35,93 @@ struct ice_dummy_pkt_offsets {
 	u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
 };
 
+static const struct ice_dummy_pkt_offsets dummy_gre_tcp_packet_offsets[] = {
+	{ ICE_MAC_OFOS,		0 },
+	{ ICE_ETYPE_OL,		12 },
+	{ ICE_IPV4_OFOS,	14 },
+	{ ICE_NVGRE,		34 },
+	{ ICE_MAC_IL,		42 },
+	{ ICE_IPV4_IL,		56 },
+	{ ICE_TCP_IL,		76 },
+	{ ICE_PROTOCOL_LAST,	0 },
+};
+
+static const u8 dummy_gre_tcp_packet[] = {
+	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_OFOS 0 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
+
+	0x45, 0x00, 0x00, 0x3E,	/* ICE_IPV4_OFOS 14 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x2F, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x80, 0x00, 0x65, 0x58,	/* ICE_NVGRE 34 */
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_IL 42 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00,
+
+	0x45, 0x00, 0x00, 0x14,	/* ICE_IPV4_IL 56 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x06, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x00, 0x00,	/* ICE_TCP_IL 76 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x50, 0x02, 0x20, 0x00,
+	0x00, 0x00, 0x00, 0x00
+};
+
+static const struct ice_dummy_pkt_offsets dummy_gre_udp_packet_offsets[] = {
+	{ ICE_MAC_OFOS,		0 },
+	{ ICE_ETYPE_OL,		12 },
+	{ ICE_IPV4_OFOS,	14 },
+	{ ICE_NVGRE,		34 },
+	{ ICE_MAC_IL,		42 },
+	{ ICE_IPV4_IL,		56 },
+	{ ICE_UDP_ILOS,		76 },
+	{ ICE_PROTOCOL_LAST,	0 },
+};
+
+static const u8 dummy_gre_udp_packet[] = {
+	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_OFOS 0 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
+
+	0x45, 0x00, 0x00, 0x3E,	/* ICE_IPV4_OFOS 14 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x2F, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x80, 0x00, 0x65, 0x58,	/* ICE_NVGRE 34 */
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_IL 42 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00,
+
+	0x45, 0x00, 0x00, 0x14,	/* ICE_IPV4_IL 56 */
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x11, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+
+	0x00, 0x00, 0x00, 0x00,	/* ICE_UDP_ILOS 76 */
+	0x00, 0x08, 0x00, 0x00,
+};
+
 static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = {
 	{ ICE_MAC_OFOS,		0 },
 	{ ICE_ETYPE_OL,		12 },
@@ -3618,6 +3705,7 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
 	{ ICE_UDP_ILOS,		{ 0, 2 } },
 	{ ICE_VXLAN,		{ 8, 10, 12, 14 } },
 	{ ICE_GENEVE,		{ 8, 10, 12, 14 } },
+	{ ICE_NVGRE,            { 0, 2, 4, 6 } },
 };
 
 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
@@ -3634,6 +3722,7 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
 	{ ICE_UDP_ILOS,		ICE_UDP_ILOS_HW },
 	{ ICE_VXLAN,		ICE_UDP_OF_HW },
 	{ ICE_GENEVE,		ICE_UDP_OF_HW },
+	{ ICE_NVGRE,            ICE_GRE_OF_HW },
 };
 
 /**
@@ -4328,6 +4417,7 @@ static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
 	switch (tun_type) {
 	case ICE_SW_TUN_GENEVE:
 	case ICE_SW_TUN_VXLAN:
+	case ICE_SW_TUN_NVGRE:
 		*mask = ICE_TUN_FLAG_MASK;
 		return true;
 
@@ -4390,6 +4480,9 @@ ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
 	case ICE_SW_TUN_VXLAN:
 		prof_type = ICE_PROF_TUN_UDP;
 		break;
+	case ICE_SW_TUN_NVGRE:
+		prof_type = ICE_PROF_TUN_GRE;
+		break;
 	default:
 		prof_type = ICE_PROF_ALL;
 		break;
@@ -4613,6 +4706,20 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
 			ipv6 = true;
 	}
 
+	if (tun_type == ICE_SW_TUN_NVGRE) {
+		if (tcp) {
+			*pkt = dummy_gre_tcp_packet;
+			*pkt_len = sizeof(dummy_gre_tcp_packet);
+			*offsets = dummy_gre_tcp_packet_offsets;
+			return;
+		}
+
+		*pkt = dummy_gre_udp_packet;
+		*pkt_len = sizeof(dummy_gre_udp_packet);
+		*offsets = dummy_gre_udp_packet_offsets;
+		return;
+	}
+
 	if (tun_type == ICE_SW_TUN_VXLAN ||
 	    tun_type == ICE_SW_TUN_GENEVE) {
 		if (tcp) {
@@ -4748,6 +4855,9 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
 		case ICE_SCTP_IL:
 			len = sizeof(struct ice_sctp_hdr);
 			break;
+		case ICE_NVGRE:
+			len = sizeof(struct ice_nvgre_hdr);
+			break;
 		case ICE_VXLAN:
 		case ICE_GENEVE:
 			len = sizeof(struct ice_udp_tnl_hdr);
diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.c b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
index e3e02027f71d..a7f98437e0c1 100644
--- a/drivers/net/ethernet/intel/ice/ice_tc_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.c
@@ -105,6 +105,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;
 	}
@@ -118,6 +120,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;
 	}
@@ -336,6 +340,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;
 }
 
@@ -681,6 +688,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;
 
@@ -702,18 +710,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) {
@@ -726,6 +727,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;
 	}
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Intel-wired-lan] [PATCH net-next 3/4] ice: low level support for tunnels
  2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 3/4] ice: low level support for tunnels Michal Swiatkowski
  2021-10-11 23:15     ` kernel test robot
@ 2021-10-11 23:15     ` kernel test robot
  0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2021-10-11 23:15 UTC (permalink / raw)
  To: Michal Swiatkowski, intel-wired-lan; +Cc: llvm, kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4584 bytes --]

Hi Michal,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on tnguy-next-queue/dev-queue]
[cannot apply to net-next/master v5.15-rc5 next-20211011]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Michal-Swiatkowski/support-for-tunnel-in-ice-eswitch/20211011-175106
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue.git dev-queue
config: x86_64-randconfig-a001-20211011 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project f95d9c95bbf4cf662b9a181245fc6dcede39f590)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/f4c17653182af5b6d1de81aad68469380b734f1e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Michal-Swiatkowski/support-for-tunnel-in-ice-eswitch/20211011-175106
        git checkout f4c17653182af5b6d1de81aad68469380b734f1e
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/net/ethernet/intel/ice/ice_switch.c:4346:1: error: incomplete result type 'enum ice_status' in function definition
   ice_add_special_words(struct ice_adv_rule_info *rinfo,
   ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4345:13: note: forward declaration of 'enum ice_status'
   static enum ice_status
               ^
>> drivers/net/ethernet/intel/ice/ice_switch.c:4362:11: error: use of undeclared identifier 'ICE_ERR_MAX_LIMIT'
                           return ICE_ERR_MAX_LIMIT;
                                  ^
>> drivers/net/ethernet/intel/ice/ice_switch.c:4366:9: error: use of undeclared identifier 'ICE_SUCCESS'
           return ICE_SUCCESS;
                  ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4792:1: error: incomplete result type 'enum ice_status' in function definition
   ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
   ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4345:13: note: forward declaration of 'enum ice_status'
   static enum ice_status
               ^
>> drivers/net/ethernet/intel/ice/ice_switch.c:4801:11: error: use of undeclared identifier 'ICE_ERR_CFG'
                           return ICE_ERR_CFG;
                                  ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4806:10: error: use of undeclared identifier 'ICE_SUCCESS'
                   return ICE_SUCCESS;
                          ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4819:11: error: use of undeclared identifier 'ICE_SUCCESS'
                           return ICE_SUCCESS;
                                  ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4823:9: error: use of undeclared identifier 'ICE_ERR_CFG'
           return ICE_ERR_CFG;
                  ^
   8 errors generated.


vim +4346 drivers/net/ethernet/intel/ice/ice_switch.c

  4339	
  4340	/**
  4341	 * ice_add_special_words - Add words that are not protocols, such as metadata
  4342	 * @rinfo: other information regarding the rule e.g. priority and action info
  4343	 * @lkup_exts: lookup word structure
  4344	 */
  4345	static enum ice_status
> 4346	ice_add_special_words(struct ice_adv_rule_info *rinfo,
  4347			      struct ice_prot_lkup_ext *lkup_exts)
  4348	{
  4349		u16 mask;
  4350	
  4351		/* If this is a tunneled packet, then add recipe index to match the
  4352		 * tunnel bit in the packet metadata flags.
  4353		 */
  4354		if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
  4355			if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
  4356				u8 word = lkup_exts->n_val_words++;
  4357	
  4358				lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
  4359				lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
  4360				lkup_exts->field_mask[word] = mask;
  4361			} else {
> 4362				return ICE_ERR_MAX_LIMIT;
  4363			}
  4364		}
  4365	
> 4366		return ICE_SUCCESS;
  4367	}
  4368	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 44255 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Intel-wired-lan] [PATCH net-next 3/4] ice: low level support for tunnels
@ 2021-10-11 23:15     ` kernel test robot
  0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2021-10-11 23:15 UTC (permalink / raw)
  To: intel-wired-lan

Hi Michal,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on tnguy-next-queue/dev-queue]
[cannot apply to net-next/master v5.15-rc5 next-20211011]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Michal-Swiatkowski/support-for-tunnel-in-ice-eswitch/20211011-175106
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue.git dev-queue
config: x86_64-randconfig-a001-20211011 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project f95d9c95bbf4cf662b9a181245fc6dcede39f590)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/f4c17653182af5b6d1de81aad68469380b734f1e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Michal-Swiatkowski/support-for-tunnel-in-ice-eswitch/20211011-175106
        git checkout f4c17653182af5b6d1de81aad68469380b734f1e
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/net/ethernet/intel/ice/ice_switch.c:4346:1: error: incomplete result type 'enum ice_status' in function definition
   ice_add_special_words(struct ice_adv_rule_info *rinfo,
   ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4345:13: note: forward declaration of 'enum ice_status'
   static enum ice_status
               ^
>> drivers/net/ethernet/intel/ice/ice_switch.c:4362:11: error: use of undeclared identifier 'ICE_ERR_MAX_LIMIT'
                           return ICE_ERR_MAX_LIMIT;
                                  ^
>> drivers/net/ethernet/intel/ice/ice_switch.c:4366:9: error: use of undeclared identifier 'ICE_SUCCESS'
           return ICE_SUCCESS;
                  ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4792:1: error: incomplete result type 'enum ice_status' in function definition
   ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
   ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4345:13: note: forward declaration of 'enum ice_status'
   static enum ice_status
               ^
>> drivers/net/ethernet/intel/ice/ice_switch.c:4801:11: error: use of undeclared identifier 'ICE_ERR_CFG'
                           return ICE_ERR_CFG;
                                  ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4806:10: error: use of undeclared identifier 'ICE_SUCCESS'
                   return ICE_SUCCESS;
                          ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4819:11: error: use of undeclared identifier 'ICE_SUCCESS'
                           return ICE_SUCCESS;
                                  ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4823:9: error: use of undeclared identifier 'ICE_ERR_CFG'
           return ICE_ERR_CFG;
                  ^
   8 errors generated.


vim +4346 drivers/net/ethernet/intel/ice/ice_switch.c

  4339	
  4340	/**
  4341	 * ice_add_special_words - Add words that are not protocols, such as metadata
  4342	 * @rinfo: other information regarding the rule e.g. priority and action info
  4343	 * @lkup_exts: lookup word structure
  4344	 */
  4345	static enum ice_status
> 4346	ice_add_special_words(struct ice_adv_rule_info *rinfo,
  4347			      struct ice_prot_lkup_ext *lkup_exts)
  4348	{
  4349		u16 mask;
  4350	
  4351		/* If this is a tunneled packet, then add recipe index to match the
  4352		 * tunnel bit in the packet metadata flags.
  4353		 */
  4354		if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
  4355			if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
  4356				u8 word = lkup_exts->n_val_words++;
  4357	
  4358				lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
  4359				lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
  4360				lkup_exts->field_mask[word] = mask;
  4361			} else {
> 4362				return ICE_ERR_MAX_LIMIT;
  4363			}
  4364		}
  4365	
> 4366		return ICE_SUCCESS;
  4367	}
  4368	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 44255 bytes
Desc: not available
URL: <http://lists.osuosl.org/pipermail/intel-wired-lan/attachments/20211012/e0332ab2/attachment-0001.bin>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Intel-wired-lan] [PATCH net-next 3/4] ice: low level support for tunnels
@ 2021-10-11 23:15     ` kernel test robot
  0 siblings, 0 replies; 8+ messages in thread
From: kernel test robot @ 2021-10-11 23:15 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4685 bytes --]

Hi Michal,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on tnguy-next-queue/dev-queue]
[cannot apply to net-next/master v5.15-rc5 next-20211011]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Michal-Swiatkowski/support-for-tunnel-in-ice-eswitch/20211011-175106
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue.git dev-queue
config: x86_64-randconfig-a001-20211011 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project f95d9c95bbf4cf662b9a181245fc6dcede39f590)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/f4c17653182af5b6d1de81aad68469380b734f1e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Michal-Swiatkowski/support-for-tunnel-in-ice-eswitch/20211011-175106
        git checkout f4c17653182af5b6d1de81aad68469380b734f1e
        # save the attached .config to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> drivers/net/ethernet/intel/ice/ice_switch.c:4346:1: error: incomplete result type 'enum ice_status' in function definition
   ice_add_special_words(struct ice_adv_rule_info *rinfo,
   ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4345:13: note: forward declaration of 'enum ice_status'
   static enum ice_status
               ^
>> drivers/net/ethernet/intel/ice/ice_switch.c:4362:11: error: use of undeclared identifier 'ICE_ERR_MAX_LIMIT'
                           return ICE_ERR_MAX_LIMIT;
                                  ^
>> drivers/net/ethernet/intel/ice/ice_switch.c:4366:9: error: use of undeclared identifier 'ICE_SUCCESS'
           return ICE_SUCCESS;
                  ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4792:1: error: incomplete result type 'enum ice_status' in function definition
   ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
   ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4345:13: note: forward declaration of 'enum ice_status'
   static enum ice_status
               ^
>> drivers/net/ethernet/intel/ice/ice_switch.c:4801:11: error: use of undeclared identifier 'ICE_ERR_CFG'
                           return ICE_ERR_CFG;
                                  ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4806:10: error: use of undeclared identifier 'ICE_SUCCESS'
                   return ICE_SUCCESS;
                          ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4819:11: error: use of undeclared identifier 'ICE_SUCCESS'
                           return ICE_SUCCESS;
                                  ^
   drivers/net/ethernet/intel/ice/ice_switch.c:4823:9: error: use of undeclared identifier 'ICE_ERR_CFG'
           return ICE_ERR_CFG;
                  ^
   8 errors generated.


vim +4346 drivers/net/ethernet/intel/ice/ice_switch.c

  4339	
  4340	/**
  4341	 * ice_add_special_words - Add words that are not protocols, such as metadata
  4342	 * @rinfo: other information regarding the rule e.g. priority and action info
  4343	 * @lkup_exts: lookup word structure
  4344	 */
  4345	static enum ice_status
> 4346	ice_add_special_words(struct ice_adv_rule_info *rinfo,
  4347			      struct ice_prot_lkup_ext *lkup_exts)
  4348	{
  4349		u16 mask;
  4350	
  4351		/* If this is a tunneled packet, then add recipe index to match the
  4352		 * tunnel bit in the packet metadata flags.
  4353		 */
  4354		if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
  4355			if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
  4356				u8 word = lkup_exts->n_val_words++;
  4357	
  4358				lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
  4359				lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
  4360				lkup_exts->field_mask[word] = mask;
  4361			} else {
> 4362				return ICE_ERR_MAX_LIMIT;
  4363			}
  4364		}
  4365	
> 4366		return ICE_SUCCESS;
  4367	}
  4368	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 44255 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-10-11 23:16 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-11  9:48 [Intel-wired-lan] [PATCH net-next 0/4] support for tunnel in ice eswitch Michal Swiatkowski
2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 1/4] ice: support for indirect notification Michal Swiatkowski
2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 2/4] ice: vxlan and geneve tc support Michal Swiatkowski
2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 3/4] ice: low level support for tunnels Michal Swiatkowski
2021-10-11 23:15   ` kernel test robot
2021-10-11 23:15     ` kernel test robot
2021-10-11 23:15     ` kernel test robot
2021-10-11  9:48 ` [Intel-wired-lan] [PATCH net-next 4/4] ice: support for gre in eswitch Michal Swiatkowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.