@@ -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") \
@@ -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;
}
@@ -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
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>