From a4ab862e99c49b7b9e57c5844a1843b0e3d93ebc Mon Sep 17 00:00:00 2001 From: Hyong Youb Kim Date: Wed, 9 Sep 2020 07:00:06 -0700 Subject: [PATCH] net/enic: support VXLAN decap action combined with VLAN pop 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 Reviewed-by: John Daley --- 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 3faafa4107..c6642f5f94 100644 --- a/doc/guides/rel_notes/release_20_11.rst +++ b/doc/guides/rel_notes/release_20_11.rst @@ -60,6 +60,7 @@ New Features * 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 * **Extended flow-perf application.** diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c index 8e5eb4d743..34c9005ee2 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; @@ -1472,6 +1487,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.20.1