DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation
@ 2020-09-09 14:00 Hyong Youb Kim
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 1/6] net/enic: remove obsolete code Hyong Youb Kim
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Hyong Youb Kim @ 2020-09-09 14:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Hyong Youb Kim

This series enables several flow features such as priorities and
egress PORT_ID action. It depends on the ealier patch series that adds
VF representors.

The 1st patch (remove obsolete code) does not technically belong in
the series, but is piggybacked here as it is a trivial cleanup.

Thanks..
-Hyong


Hyong Youb Kim (6):
  net/enic: remove obsolete code
  net/enic: support egress PORT_ID action
  net/enic: support priorities for TCAM flows
  net/enic: ignore vlan inner type when it is zero
  net/enic: generate VXLAN source port if it is zero in template
  net/enic: support VXLAN decap action combined with VLAN pop

 doc/guides/rel_notes/release_20_11.rst |   3 +
 drivers/net/enic/enic.h                |   5 -
 drivers/net/enic/enic_fm_flow.c        | 228 ++++++++++++++++++++++++-
 3 files changed, 222 insertions(+), 14 deletions(-)

-- 
2.26.2


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

* [dpdk-dev] [PATCH 1/6] net/enic: remove obsolete code
  2020-09-09 14:00 [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Hyong Youb Kim
@ 2020-09-09 14:00 ` Hyong Youb Kim
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 2/6] net/enic: support egress PORT_ID action Hyong Youb Kim
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Hyong Youb Kim @ 2020-09-09 14:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Hyong Youb Kim, John Daley

The 'next' field in struct enic is unused. The comment in enic_cq_rq()
is out-of-date. Remove them.

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
---
 drivers/net/enic/enic.h | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index baf6b8790..26535c9aa 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -106,7 +106,6 @@ struct rte_flow {
 
 /* Per-instance private data structure */
 struct enic {
-	struct enic *next;
 	struct rte_pci_device *pdev;
 	struct vnic_enet_config config;
 	struct vnic_dev_bar bar0;
@@ -297,10 +296,6 @@ static inline unsigned int enic_vnic_rq_count(struct enic *enic)
 
 static inline unsigned int enic_cq_rq(__rte_unused struct enic *enic, unsigned int rq)
 {
-	/* Scatter rx uses two receive queues together with one
-	 * completion queue, so the completion queue number is no
-	 * longer the same as the rq number.
-	 */
 	return rq;
 }
 
-- 
2.26.2


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

* [dpdk-dev] [PATCH 2/6] net/enic: support egress PORT_ID action
  2020-09-09 14:00 [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Hyong Youb Kim
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 1/6] net/enic: remove obsolete code Hyong Youb Kim
@ 2020-09-09 14:00 ` Hyong Youb Kim
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 3/6] net/enic: support priorities for TCAM flows Hyong Youb Kim
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Hyong Youb Kim @ 2020-09-09 14:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Hyong Youb Kim, John Daley

Use Flow Manager (flowman) to support egress PORT_ID action. It can
steer egress packets from PFs and VFs to any uplink port as long as
they are all on the same VIC adapter. It can also steer packets
between ports on the same VIC adapter (i.e. loopback).

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
---
 doc/guides/rel_notes/release_20_11.rst |   1 +
 drivers/net/enic/enic_fm_flow.c        | 154 +++++++++++++++++++++++++
 2 files changed, 155 insertions(+)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 180ab8fa0..afe81711a 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -138,3 +138,4 @@ Tested Platforms
 * **Updated Cisco enic driver.**
 
   * Added support for VF representors with single-queue Tx/Rx and flow API
+  * Added support for egress PORT_ID action
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 9255f2592..296e7e30d 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -97,6 +97,8 @@ struct enic_fm_flow {
 	uint64_t action_handle;
 	struct enic_fm_counter *counter;
 	struct enic_fm_fet *fet;
+	/* Auto-added steer action for hairpin flows (e.g. vnic->vnic) */
+	struct enic_fm_flow *hairpin_steer_flow;
 };
 
 struct enic_fm_jump_flow {
@@ -166,6 +168,9 @@ struct enic_flowman {
 	int action_op_count;
 	/* Tags used for representor flows */
 	uint8_t vf_rep_tag;
+	/* For auto-added steer action for hairpin */
+	int need_hairpin_steer;
+	uint64_t hairpin_steer_vnic_h;
 };
 
 static int enic_fm_tbl_free(struct enic_flowman *fm, uint64_t handle);
@@ -244,6 +249,7 @@ static const enum rte_flow_action_type enic_fm_supported_eg_actions[] = {
 	RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN,
 	RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP,
 	RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID,
+	RTE_FLOW_ACTION_TYPE_PORT_ID,
 	RTE_FLOW_ACTION_TYPE_PASSTHRU,
 	RTE_FLOW_ACTION_TYPE_VOID,
 	RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP,
@@ -1120,6 +1126,68 @@ enic_fm_find_vnic(struct enic *enic, const struct rte_pci_addr *addr,
 	return 0;
 }
 
+/*
+ * Egress: target port should be either PF uplink or VF.
+ * Supported cases
+ * 1. VF egress -> PF uplink
+ *   PF may be this VF's PF, or another PF, as long as they are on the same VIC.
+ * 2. VF egress -> VF
+ *
+ * Unsupported cases
+ * 1. PF egress -> VF
+ *   App should be using representor to pass packets to VF
+ */
+static int
+vf_egress_port_id_action(struct enic_flowman *fm,
+			 struct rte_eth_dev *dst_dev,
+			 uint64_t dst_vnic_h,
+			 struct fm_action_op *fm_op,
+			 struct rte_flow_error *error)
+{
+	struct enic *src_enic, *dst_enic;
+	struct enic_vf_representor *vf;
+	uint8_t uif;
+	int ret;
+
+	ENICPMD_FUNC_TRACE();
+	src_enic = fm->user_enic;
+	dst_enic = pmd_priv(dst_dev);
+	if (!(src_enic->rte_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)) {
+		return rte_flow_error_set(error, EINVAL,
+			RTE_FLOW_ERROR_TYPE_ACTION,
+			NULL, "source port is not VF representor");
+	}
+
+	/* VF -> PF uplink. dst is not VF representor */
+	if (!(dst_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR)) {
+		/* PF is the VF's PF? Then nothing to do */
+		vf = VF_ENIC_TO_VF_REP(src_enic);
+		if (vf->pf == dst_enic) {
+			ENICPMD_LOG(DEBUG, "destination port is VF's PF");
+			return 0;
+		}
+		/* If not, steer to the remote PF's uplink */
+		uif = dst_enic->fm_vnic_uif;
+		ENICPMD_LOG(DEBUG, "steer to uplink %u", uif);
+		memset(fm_op, 0, sizeof(*fm_op));
+		fm_op->fa_op = FMOP_SET_EGPORT;
+		fm_op->set_egport.egport = uif;
+		ret = enic_fm_append_action_op(fm, fm_op, error);
+		return ret;
+	}
+
+	/* VF -> VF loopback. Hairpin and steer to vnic */
+	memset(fm_op, 0, sizeof(*fm_op));
+	fm_op->fa_op = FMOP_EG_HAIRPIN;
+	ret = enic_fm_append_action_op(fm, fm_op, error);
+	if (ret)
+		return ret;
+	ENICPMD_LOG(DEBUG, "egress hairpin");
+	fm->hairpin_steer_vnic_h = dst_vnic_h;
+	fm->need_hairpin_steer = 1;
+	return 0;
+}
+
 /* Translate flow actions to flowman TCAM entry actions */
 static int
 enic_fm_copy_action(struct enic_flowman *fm,
@@ -1310,6 +1378,10 @@ enic_fm_copy_action(struct enic_flowman *fm,
 			const struct rte_flow_action_port_id *port;
 			struct rte_eth_dev *dev;
 
+			if (!ingress && (overlap & PORT_ID)) {
+				ENICPMD_LOG(DEBUG, "cannot have multiple egress PORT_ID actions");
+				goto unsupported;
+			}
 			port = actions->conf;
 			if (port->original) {
 				vnic_h = enic->fm_vnic_handle; /* This port */
@@ -1339,6 +1411,13 @@ enic_fm_copy_action(struct enic_flowman *fm,
 			 * Ingress. Nothing more to do. We add an implicit
 			 * steer at the end if needed.
 			 */
+			if (ingress)
+				break;
+			/* Egress */
+			ret = vf_egress_port_id_action(fm, dev, vnic_h, &fm_op,
+				error);
+			if (ret)
+				return ret;
 			break;
 		}
 		case RTE_FLOW_ACTION_TYPE_VXLAN_DECAP: {
@@ -1920,9 +1999,15 @@ __enic_fm_flow_free(struct enic_flowman *fm, struct enic_fm_flow *fm_flow)
 static void
 enic_fm_flow_free(struct enic_flowman *fm, struct rte_flow *flow)
 {
+	struct enic_fm_flow *steer = flow->fm->hairpin_steer_flow;
+
 	if (flow->fm->fet && flow->fm->fet->default_key)
 		remove_jump_flow(fm, flow);
 	__enic_fm_flow_free(fm, flow->fm);
+	if (steer) {
+		__enic_fm_flow_free(fm, steer);
+		free(steer);
+	}
 	free(flow->fm);
 	free(flow);
 }
@@ -2173,11 +2258,71 @@ convert_jump_flows(struct enic_flowman *fm, struct enic_fm_fet *fet,
 	}
 }
 
+static int
+add_hairpin_steer(struct enic_flowman *fm, struct rte_flow *flow,
+		  struct rte_flow_error *error)
+{
+	struct fm_tcam_match_entry *fm_tcam_entry;
+	struct enic_fm_flow *fm_flow;
+	struct fm_action *fm_action;
+	struct fm_action_op fm_op;
+	int ret;
+
+	ENICPMD_FUNC_TRACE();
+	fm_flow = calloc(1, sizeof(*fm_flow));
+	if (fm_flow == NULL) {
+		rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE,
+			NULL, "enic: cannot allocate rte_flow");
+		return -ENOMEM;
+	}
+	/* Original egress hairpin flow */
+	fm_tcam_entry = &fm->tcam_entry;
+	fm_action = &fm->action;
+	/* Use the match pattern of the egress flow as is, without counters */
+	fm_tcam_entry->ftm_flags &= ~FMEF_COUNTER;
+	/* The only action is steer to vnic */
+	fm->action_op_count = 0;
+	memset(fm_action, 0, sizeof(*fm_action));
+	memset(&fm_op, 0, sizeof(fm_op));
+	/* Always to queue 0 for now */
+	fm_op.fa_op = FMOP_RQ_STEER;
+	fm_op.rq_steer.rq_index = 0;
+	fm_op.rq_steer.vnic_handle = fm->hairpin_steer_vnic_h;
+	ret = enic_fm_append_action_op(fm, &fm_op, error);
+	if (ret)
+		goto error_with_flow;
+	ENICPMD_LOG(DEBUG, "add steer op");
+	/* Add required END */
+	memset(&fm_op, 0, sizeof(fm_op));
+	fm_op.fa_op = FMOP_END;
+	ret = enic_fm_append_action_op(fm, &fm_op, error);
+	if (ret)
+		goto error_with_flow;
+	/* Add the ingress flow */
+	fm_flow->action_handle = FM_INVALID_HANDLE;
+	fm_flow->entry_handle = FM_INVALID_HANDLE;
+	ret = __enic_fm_flow_add_entry(fm, fm_flow, fm_tcam_entry, fm_action,
+				       FM_TCAM_RTE_GROUP, 1 /* ingress */, error);
+	if (ret) {
+		ENICPMD_LOG(ERR, "cannot add hairpin-steer flow");
+		goto error_with_flow;
+	}
+	/* The new flow is now the egress flow's paired flow */
+	flow->fm->hairpin_steer_flow = fm_flow;
+	return 0;
+
+error_with_flow:
+	free(fm_flow);
+	return ret;
+}
+
 static void
 enic_fm_open_scratch(struct enic_flowman *fm)
 {
 	fm->action_op_count = 0;
 	fm->fet = NULL;
+	fm->need_hairpin_steer = 0;
+	fm->hairpin_steer_vnic_h = 0;
 	memset(&fm->tcam_entry, 0, sizeof(fm->tcam_entry));
 	memset(&fm->action, 0, sizeof(fm->action));
 }
@@ -2325,6 +2470,15 @@ enic_fm_flow_create(struct rte_eth_dev *dev,
 	flow = enic_fm_flow_add_entry(fm, fm_tcam_entry, fm_action,
 				      attrs, error);
 	if (flow) {
+		/* Add ingress rule that pairs with hairpin rule */
+		if (fm->need_hairpin_steer) {
+			ret = add_hairpin_steer(fm, flow, error);
+			if (ret) {
+				enic_fm_flow_free(fm, flow);
+				flow = NULL;
+				goto error_with_scratch;
+			}
+		}
 		LIST_INSERT_HEAD(&enic->flows, flow, next);
 		fet = flow->fm->fet;
 		if (fet && fet->default_key) {
-- 
2.26.2


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

* [dpdk-dev] [PATCH 3/6] net/enic: support priorities for TCAM flows
  2020-09-09 14:00 [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Hyong Youb Kim
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 1/6] net/enic: remove obsolete code Hyong Youb Kim
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 2/6] net/enic: support egress PORT_ID action Hyong Youb Kim
@ 2020-09-09 14:00 ` Hyong Youb Kim
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 4/6] net/enic: ignore vlan inner type when it is zero Hyong Youb Kim
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Hyong Youb Kim @ 2020-09-09 14:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Hyong Youb Kim, John Daley

Group 0 corresponds to TCAM which supports priorities. Accept non-zero
priorities for group 0 flows.

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
---
 doc/guides/rel_notes/release_20_11.rst |  1 +
 drivers/net/enic/enic_fm_flow.c        | 10 ++++++----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index afe81711a..6a7e7d666 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -139,3 +139,4 @@ Tested Platforms
 
   * Added support for VF representors with single-queue Tx/Rx and flow API
   * Added support for egress PORT_ID action
+  * Added support for non-zero priorities for group 0 flows
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 296e7e30d..5f22f2a32 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -1711,9 +1711,10 @@ enic_fm_dump_tcam_match(const struct fm_tcam_match_entry *match,
 	memset(buf, 0, sizeof(buf));
 	__enic_fm_dump_tcam_match(&match->ftm_mask.fk_hdrset[0],
 				  buf, sizeof(buf));
-	ENICPMD_LOG(DEBUG, " TCAM %s Outer: %s %scounter",
+	ENICPMD_LOG(DEBUG, " TCAM %s Outer: %s %scounter position %u",
 		    (ingress) ? "IG" : "EG", buf,
-		    (match->ftm_flags & FMEF_COUNTER) ? "" : "no ");
+		    (match->ftm_flags & FMEF_COUNTER) ? "" : "no ",
+		    match->ftm_position);
 	memset(buf, 0, sizeof(buf));
 	__enic_fm_dump_tcam_match(&match->ftm_mask.fk_hdrset[1],
 				  buf, sizeof(buf));
@@ -1760,11 +1761,11 @@ enic_fm_flow_parse(struct enic_flowman *fm,
 	}
 
 	if (attrs) {
-		if (attrs->priority) {
+		if (attrs->group != FM_TCAM_RTE_GROUP && attrs->priority) {
 			rte_flow_error_set(error, ENOTSUP,
 					   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
 					   NULL,
-					   "priorities are not supported");
+					   "priorities are not supported for non-default (0) groups");
 			return -rte_errno;
 		} else if (!fm->owner_enic->switchdev_mode && attrs->transfer) {
 			rte_flow_error_set(error, ENOTSUP,
@@ -2192,6 +2193,7 @@ enic_fm_flow_add_entry(struct enic_flowman *fm,
 	struct rte_flow *flow;
 
 	ENICPMD_FUNC_TRACE();
+	match_in->ftm_position = attrs->priority;
 	enic_fm_dump_tcam_entry(match_in, action_in, attrs->ingress);
 	flow = calloc(1, sizeof(*flow));
 	fm_flow = calloc(1, sizeof(*fm_flow));
-- 
2.26.2


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

* [dpdk-dev] [PATCH 4/6] net/enic: ignore vlan inner type when it is zero
  2020-09-09 14:00 [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Hyong Youb Kim
                   ` (2 preceding siblings ...)
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 3/6] net/enic: support priorities for TCAM flows Hyong Youb Kim
@ 2020-09-09 14:00 ` Hyong Youb Kim
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 5/6] net/enic: generate VXLAN source port if it is zero in template Hyong Youb Kim
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Hyong Youb Kim @ 2020-09-09 14:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Hyong Youb Kim, stable, John Daley

When a VLAN pattern is present, the flow handler always copies its
inner_type to the match buffer regardless of its value (i.e. HW
matches inner_type against packet's inner ethertype). When inner_type
spec and mask are both 0, adding it to the match buffer is usually
harmless but breaks the following pattern used in some applications
like OVS-DPDK.

flow create 0 ingress ... pattern eth ... type is 0x0800 / vlan tci spec 0x2 \
tci mask 0xefff / ipv4 / end actions count / of_pop_vlan / ...

The VLAN pattern's inner_type is 0. And the outer eth pattern's type
actually specifies the inner ethertype. The outer ethertype (0x0800)
is first copied to the match buffer. Then, the driver copies
inner_type (0) to the match buffer, which overwrites the existing
0x0800 with 0 and breaks the app usage above.

Simply ignore inner_type when it is 0, which is the correct
behavior. As a byproduct, the driver can support the usage like the
above.

Fixes: ea7768b5bba8 ("net/enic: add flow implementation based on Flow Manager API")
Cc: stable@dpdk.org

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
---
 drivers/net/enic/enic_fm_flow.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 5f22f2a32..a350b29a3 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -392,8 +392,11 @@ enic_fm_copy_item_vlan(struct copy_item_args *arg)
 	eth_mask = (void *)&fm_mask->l2.eth;
 	eth_val = (void *)&fm_data->l2.eth;
 
-	/* Outer TPID cannot be matched */
-	if (eth_mask->ether_type)
+	/*
+	 * Outer TPID cannot be matched. If inner_type is 0, use what is
+	 * in the eth header.
+	 */
+	if (eth_mask->ether_type && mask->inner_type)
 		return -ENOTSUP;
 
 	/*
@@ -401,8 +404,10 @@ enic_fm_copy_item_vlan(struct copy_item_args *arg)
 	 * L2, regardless of vlan stripping settings. So, the inner type
 	 * from vlan becomes the ether type of the eth header.
 	 */
-	eth_mask->ether_type = mask->inner_type;
-	eth_val->ether_type = spec->inner_type;
+	if (mask->inner_type) {
+		eth_mask->ether_type = mask->inner_type;
+		eth_val->ether_type = spec->inner_type;
+	}
 	fm_data->fk_header_select |= FKH_ETHER | FKH_QTAG;
 	fm_mask->fk_header_select |= FKH_ETHER | FKH_QTAG;
 	fm_data->fk_vlan = rte_be_to_cpu_16(spec->tci);
-- 
2.26.2


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

* [dpdk-dev] [PATCH 5/6] net/enic: generate VXLAN source port if it is zero in template
  2020-09-09 14:00 [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Hyong Youb Kim
                   ` (3 preceding siblings ...)
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 4/6] net/enic: ignore vlan inner type when it is zero Hyong Youb Kim
@ 2020-09-09 14:00 ` Hyong Youb Kim
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 6/6] net/enic: support VXLAN decap action combined with VLAN pop Hyong Youb Kim
  2020-09-21 16:12 ` [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Ferruh Yigit
  6 siblings, 0 replies; 8+ messages in thread
From: Hyong Youb Kim @ 2020-09-09 14:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Hyong Youb Kim, stable, John Daley

When VXLAN source port in the template is zero, the adapter is
expected to generate a value based on the inner packet flow, when it
performs encapsulation. Flow Manager in the VIC adapter currently
lacks such ability. So, generate a random port when creating a flow if
the port is zero, to avoid transmitting packets with source port 0.

Fixes: ea7768b5bba8 ("net/enic: add flow implementation based on Flow Manager API")
Cc: stable@dpdk.org

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
---
 drivers/net/enic/enic_fm_flow.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index a350b29a3..7eec8e6eb 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -978,6 +978,17 @@ enic_fm_copy_vxlan_decap(struct enic_flowman *fm,
 	return enic_fm_append_action_op(fm, &fm_op, error);
 }
 
+/* Generate a reasonable source port number */
+static uint16_t
+gen_src_port(void)
+{
+	/* Min/max below are the default values in OVS-DPDK and Linux */
+	uint16_t p = rte_rand();
+	p = RTE_MAX(p, 32768);
+	p = RTE_MIN(p, 61000);
+	return rte_cpu_to_be_16(p);
+}
+
 /* VXLAN encap is done via flowman compound action */
 static int
 enic_fm_copy_vxlan_encap(struct enic_flowman *fm,
@@ -986,6 +997,7 @@ enic_fm_copy_vxlan_encap(struct enic_flowman *fm,
 {
 	struct fm_action_op fm_op;
 	struct rte_ether_hdr *eth;
+	struct rte_udp_hdr *udp;
 	uint16_t *ethertype;
 	void *template;
 	uint8_t off;
@@ -1084,8 +1096,17 @@ enic_fm_copy_vxlan_encap(struct enic_flowman *fm,
 		off + offsetof(struct rte_udp_hdr, dgram_len);
 	fm_op.encap.len2_delta =
 		sizeof(struct rte_udp_hdr) + sizeof(struct rte_vxlan_hdr);
+	udp = (struct rte_udp_hdr *)template;
 	append_template(&template, &off, item->spec,
 			sizeof(struct rte_udp_hdr));
+	/*
+	 * Firmware does not hash/fill source port yet. Generate a
+	 * random port, as there is *usually* one rte_flow for the
+	 * given inner packet stream (i.e. a single stream has one
+	 * random port).
+	 */
+	if (udp->src_port == 0)
+		udp->src_port = gen_src_port();
 	item++;
 	flow_item_skip_void(&item);
 
-- 
2.26.2


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

* [dpdk-dev] [PATCH 6/6] net/enic: support VXLAN decap action combined with VLAN pop
  2020-09-09 14:00 [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Hyong Youb Kim
                   ` (4 preceding siblings ...)
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 5/6] net/enic: generate VXLAN source port if it is zero in template Hyong Youb Kim
@ 2020-09-09 14:00 ` Hyong Youb Kim
  2020-09-21 16:12 ` [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Ferruh Yigit
  6 siblings, 0 replies; 8+ messages in thread
From: Hyong Youb Kim @ 2020-09-09 14:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Hyong Youb Kim, John Daley

Flow Manager (flowman) provides DECAP_STRIP operation which
decapsulates VXLAN header and then removes VLAN header from the inner
packet. Use this operation to support vxlan_decap followed by
of_pop_vlan.

Signed-off-by: Hyong Youb Kim <hyonkim@cisco.com>
Reviewed-by: John Daley <johndale@cisco.com>
---
 doc/guides/rel_notes/release_20_11.rst |  1 +
 drivers/net/enic/enic_fm_flow.c        | 30 +++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_20_11.rst b/doc/guides/rel_notes/release_20_11.rst
index 6a7e7d666..4767348d3 100644
--- a/doc/guides/rel_notes/release_20_11.rst
+++ b/doc/guides/rel_notes/release_20_11.rst
@@ -140,3 +140,4 @@ Tested Platforms
   * Added support for VF representors with single-queue Tx/Rx and flow API
   * Added support for egress PORT_ID action
   * Added support for non-zero priorities for group 0 flows
+  * Added support for VXLAN decap combined with VLAN pop
diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 7eec8e6eb..ef4705d47 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -923,6 +923,20 @@ enic_fm_append_action_op(struct enic_flowman *fm,
 	return 0;
 }
 
+static struct fm_action_op *
+find_prev_action_op(struct enic_flowman *fm, uint32_t opcode)
+{
+	struct fm_action_op *op;
+	int i;
+
+	for (i = 0; i < fm->action_op_count; i++) {
+		op = &fm->action.fma_action_ops[i];
+		if (op->fa_op == opcode)
+			return op;
+	}
+	return NULL;
+}
+
 /* NIC requires that 1st steer appear before decap.
  * Correct example: steer, decap, steer, steer, ...
  */
@@ -938,7 +952,8 @@ enic_fm_reorder_action_op(struct enic_flowman *fm)
 	steer = NULL;
 	decap = NULL;
 	while (op->fa_op != FMOP_END) {
-		if (!decap && op->fa_op == FMOP_DECAP_NOSTRIP)
+		if (!decap && (op->fa_op == FMOP_DECAP_NOSTRIP ||
+			       op->fa_op == FMOP_DECAP_STRIP))
 			decap = op;
 		else if (!steer && op->fa_op == FMOP_RQ_STEER)
 			steer = op;
@@ -1471,6 +1486,19 @@ enic_fm_copy_action(struct enic_flowman *fm,
 			break;
 		}
 		case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: {
+			struct fm_action_op *decap;
+
+			/*
+			 * If decap-nostrip appears before pop vlan, this pop
+			 * applies to the inner packet vlan. Turn it into
+			 * decap-strip.
+			 */
+			decap = find_prev_action_op(fm, FMOP_DECAP_NOSTRIP);
+			if (decap) {
+				ENICPMD_LOG(DEBUG, "pop-vlan inner: decap-nostrip => decap-strip");
+				decap->fa_op = FMOP_DECAP_STRIP;
+				break;
+			}
 			memset(&fm_op, 0, sizeof(fm_op));
 			fm_op.fa_op = FMOP_POP_VLAN;
 			ret = enic_fm_append_action_op(fm, &fm_op, error);
-- 
2.26.2


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

* Re: [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation
  2020-09-09 14:00 [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Hyong Youb Kim
                   ` (5 preceding siblings ...)
  2020-09-09 14:00 ` [dpdk-dev] [PATCH 6/6] net/enic: support VXLAN decap action combined with VLAN pop Hyong Youb Kim
@ 2020-09-21 16:12 ` Ferruh Yigit
  6 siblings, 0 replies; 8+ messages in thread
From: Ferruh Yigit @ 2020-09-21 16:12 UTC (permalink / raw)
  To: Hyong Youb Kim; +Cc: dev

On 9/9/2020 3:00 PM, Hyong Youb Kim wrote:
> This series enables several flow features such as priorities and
> egress PORT_ID action. It depends on the ealier patch series that adds
> VF representors.
> 
> The 1st patch (remove obsolete code) does not technically belong in
> the series, but is piggybacked here as it is a trivial cleanup.
> 
> Thanks..
> -Hyong
> 
> 
> Hyong Youb Kim (6):
>    net/enic: remove obsolete code
>    net/enic: support egress PORT_ID action
>    net/enic: support priorities for TCAM flows
>    net/enic: ignore vlan inner type when it is zero
>    net/enic: generate VXLAN source port if it is zero in template
>    net/enic: support VXLAN decap action combined with VLAN pop
> 

Series applied to dpdk-next-net/main, thanks.

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

end of thread, other threads:[~2020-09-21 16:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-09 14:00 [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Hyong Youb Kim
2020-09-09 14:00 ` [dpdk-dev] [PATCH 1/6] net/enic: remove obsolete code Hyong Youb Kim
2020-09-09 14:00 ` [dpdk-dev] [PATCH 2/6] net/enic: support egress PORT_ID action Hyong Youb Kim
2020-09-09 14:00 ` [dpdk-dev] [PATCH 3/6] net/enic: support priorities for TCAM flows Hyong Youb Kim
2020-09-09 14:00 ` [dpdk-dev] [PATCH 4/6] net/enic: ignore vlan inner type when it is zero Hyong Youb Kim
2020-09-09 14:00 ` [dpdk-dev] [PATCH 5/6] net/enic: generate VXLAN source port if it is zero in template Hyong Youb Kim
2020-09-09 14:00 ` [dpdk-dev] [PATCH 6/6] net/enic: support VXLAN decap action combined with VLAN pop Hyong Youb Kim
2020-09-21 16:12 ` [dpdk-dev] [PATCH 0/6] net/enic: minor updates to flow implementation Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).