diff mbox

[ovs-dev,RFC,v2,11/13] Add control plane command push_eth and pop_eth

Message ID 1468344571-11567-1-git-send-email-johnson.li@intel.com
State Changes Requested
Headers show

Commit Message

Johnson.Li July 12, 2016, 5:29 p.m. UTC
User can use the flow command push_eth/pop_eth command to push/
strip Ethernet header. Action formats are:
    actions=push_eth
or
    actions=pop_eth.
For pushing an Ethernet header with specified MAC address,
"set_field" actions are required before the "push_eth" action.

Signed-off-by: Johnson Li <johnson.li@intel.com>
diff mbox

Patch

diff --git a/include/openvswitch/ofp-actions.h b/include/openvswitch/ofp-actions.h
index 46a3d4e..a2a234a 100644
--- a/include/openvswitch/ofp-actions.h
+++ b/include/openvswitch/ofp-actions.h
@@ -97,6 +97,9 @@ 
     OFPACT(PUSH_NSH,        ofpact_null,        ofpact, "push_nsh")     \
     OFPACT(POP_NSH,         ofpact_null,        ofpact, "pop_nsh")      \
                                                                         \
+    OFPACT(PUSH_ETH,        ofpact_null,        ofpact, "push_eth")     \
+    OFPACT(POP_ETH,         ofpact_null,        ofpact, "pop_eth")      \
+                                                                        \
     /* Flow table interaction. */                                       \
     OFPACT(RESUBMIT,        ofpact_resubmit,    ofpact, "resubmit")     \
     OFPACT(LEARN,           ofpact_learn,       specs, "learn")         \
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index 8568dda..ab964e9 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -310,6 +310,12 @@  enum ofp_raw_action_type {
     /* NX1.0+(41): void */
     NXAST_RAW_POP_NSH,
 
+    /* NX1.0+(42): void */
+    NXAST_RAW_PUSH_ETH,
+
+    /* NX1.0+(43): void */
+    NXAST_RAW_POP_ETH,
+
 /* ## ------------------ ## */
 /* ## Debugging actions. ## */
 /* ## ------------------ ## */
@@ -435,6 +441,8 @@  ofpact_next_flattened(const struct ofpact *ofpact)
     case OFPACT_GOTO_TABLE:
     case OFPACT_PUSH_NSH:
     case OFPACT_POP_NSH:
+    case OFPACT_PUSH_ETH:
+    case OFPACT_POP_ETH:
     case OFPACT_NAT:
         return ofpact_next(ofpact);
 
@@ -1738,6 +1746,63 @@  format_POP_NSH(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
 }
 
 
+static enum ofperr
+decode_NXAST_RAW_PUSH_ETH(struct ofpbuf * out)
+{
+    ofpact_put_PUSH_ETH(out)->ofpact.raw = NXAST_RAW_PUSH_ETH;
+    return 0;
+}
+
+static void
+encode_PUSH_ETH(const struct ofpact_null *null OVS_UNUSED,
+               enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
+{
+    put_NXAST_PUSH_ETH(out);
+}
+
+static char * OVS_WARN_UNUSED_RESULT
+parse_PUSH_ETH(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
+              enum ofputil_protocol *usable_protocols OVS_UNUSED)
+{
+    ofpact_put_PUSH_ETH(ofpacts)->ofpact.raw = NXAST_RAW_PUSH_ETH;
+    return NULL;
+}
+
+static void
+format_PUSH_ETH(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
+{
+    ds_put_format(s, "push_eth");
+}
+
+static enum ofperr
+decode_NXAST_RAW_POP_ETH(struct ofpbuf * out)
+{
+    ofpact_put_POP_ETH(out)->ofpact.raw = NXAST_RAW_POP_ETH;
+    return 0;
+}
+
+static void
+encode_POP_ETH(const struct ofpact_null *null OVS_UNUSED,
+               enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
+{
+    put_NXAST_POP_ETH(out);
+}
+
+static char * OVS_WARN_UNUSED_RESULT
+parse_POP_ETH(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
+              enum ofputil_protocol *usable_protocols OVS_UNUSED)
+{
+    ofpact_put_POP_ETH(ofpacts)->ofpact.raw = NXAST_RAW_POP_ETH;
+    return NULL;
+}
+
+static void
+format_POP_ETH(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
+{
+    ds_put_format(s, "pop_eth");
+}
+
+
 /* Action structure for OFPAT10_SET_DL_SRC/DST and OFPAT11_SET_DL_SRC/DST. */
 struct ofp_action_dl_addr {
     ovs_be16 type;                  /* Type. */
@@ -6178,6 +6243,8 @@  ofpact_is_set_or_move_action(const struct ofpact *a)
     case OFPACT_DEBUG_RECIRC:
     case OFPACT_PUSH_NSH:
     case OFPACT_POP_NSH:
+    case OFPACT_PUSH_ETH:
+    case OFPACT_POP_ETH:
         return false;
     default:
         OVS_NOT_REACHED();
@@ -6252,6 +6319,8 @@  ofpact_is_allowed_in_actions_set(const struct ofpact *a)
     case OFPACT_WRITE_METADATA:
     case OFPACT_PUSH_NSH:
     case OFPACT_POP_NSH:
+    case OFPACT_PUSH_ETH:
+    case OFPACT_POP_ETH:
         return false;
     default:
         OVS_NOT_REACHED();
@@ -6464,6 +6533,8 @@  ovs_instruction_type_from_ofpact_type(enum ofpact_type type)
     case OFPACT_NAT:
     case OFPACT_PUSH_NSH:
     case OFPACT_POP_NSH:
+    case OFPACT_PUSH_ETH:
+    case OFPACT_POP_ETH:
     default:
         return OVSINST_OFPIT11_APPLY_ACTIONS;
     }
@@ -7096,6 +7167,8 @@  ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
 
     case OFPACT_PUSH_NSH:
     case OFPACT_POP_NSH:
+    case OFPACT_PUSH_ETH:
+    case OFPACT_POP_ETH:
         return 0;
 
     default:
@@ -7586,6 +7659,8 @@  ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
     case OFPACT_NAT:
     case OFPACT_PUSH_NSH:
     case OFPACT_POP_NSH:
+    case OFPACT_PUSH_ETH:
+    case OFPACT_POP_ETH:
     default:
         return false;
     }
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 1a63175..f5c1888 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4445,6 +4445,8 @@  freeze_unroll_actions(const struct ofpact *a, const struct ofpact *end,
         case OFPACT_NAT:
         case OFPACT_PUSH_NSH:
         case OFPACT_POP_NSH:
+        case OFPACT_PUSH_ETH:
+        case OFPACT_POP_ETH:
             /* These may not generate PACKET INs. */
             break;
 
@@ -4701,6 +4703,8 @@  recirc_for_mpls(const struct ofpact *a, struct xlate_ctx *ctx)
     case OFPACT_GOTO_TABLE:
     case OFPACT_PUSH_NSH:
     case OFPACT_POP_NSH:
+    case OFPACT_PUSH_ETH:
+    case OFPACT_POP_ETH:
     default:
         break;
     }
@@ -5125,6 +5129,9 @@  do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
             memset(&flow->nsh, 0x0, sizeof flow->nsh);
             nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_POP_NSH);
             break;
+        case OFPACT_PUSH_ETH:
+        case OFPACT_POP_ETH:
+            break;
         }
 
         /* Check if need to store this and the remaining actions for later