net/enic: support VXLAN decap action combined with VLAN pop
authorHyong Youb Kim <hyonkim@cisco.com>
Wed, 9 Sep 2020 14:00:06 +0000 (07:00 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 21 Sep 2020 16:10:38 +0000 (18:10 +0200)
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
drivers/net/enic/enic_fm_flow.c

index 3faafa4..c6642f5 100644 (file)
@@ -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.**
 
index 8e5eb4d..34c9005 100644 (file)
@@ -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);