@@ -93,6 +93,10 @@
OFPACT(POP_QUEUE, ofpact_null, ofpact, "pop_queue") \
OFPACT(FIN_TIMEOUT, ofpact_fin_timeout, ofpact, "fin_timeout") \
\
+ /* Network Service Header */ \
+ OFPACT(PUSH_NSH, ofpact_null, ofpact, "push_nsh") \
+ OFPACT(POP_NSH, ofpact_null, ofpact, "pop_nsh") \
+ \
/* Flow table interaction. */ \
OFPACT(RESUBMIT, ofpact_resubmit, ofpact, "resubmit") \
OFPACT(LEARN, ofpact_learn, specs, "learn") \
@@ -304,6 +304,12 @@ enum ofp_raw_action_type {
/* NX1.0+(39): struct nx_action_output_trunc. */
NXAST_RAW_OUTPUT_TRUNC,
+ /* NX1.0+(40): void */
+ NXAST_RAW_PUSH_NSH,
+
+ /* NX1.0+(41): void */
+ NXAST_RAW_POP_NSH,
+
/* ## ------------------ ## */
/* ## Debugging actions. ## */
/* ## ------------------ ## */
@@ -427,6 +433,8 @@ ofpact_next_flattened(const struct ofpact *ofpact)
case OFPACT_CLEAR_ACTIONS:
case OFPACT_WRITE_METADATA:
case OFPACT_GOTO_TABLE:
+ case OFPACT_PUSH_NSH:
+ case OFPACT_POP_NSH:
case OFPACT_NAT:
return ofpact_next(ofpact);
@@ -1669,6 +1677,66 @@ format_PUSH_VLAN(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
ds_put_format(s, "%spush_vlan:%s%#"PRIx16,
colors.param, colors.end, ETH_TYPE_VLAN_8021Q);
}
+
+
+/* Network Service Header. */
+static enum ofperr
+decode_NXAST_RAW_PUSH_NSH(struct ofpbuf * out)
+{
+ ofpact_put_PUSH_NSH(out);
+ return 0;
+}
+
+static void
+encode_PUSH_NSH(const struct ofpact_null *null OVS_UNUSED,
+ enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
+{
+ put_NXAST_PUSH_NSH(out);
+}
+
+static char * OVS_WARN_UNUSED_RESULT
+parse_PUSH_NSH(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
+ enum ofputil_protocol *usable_protocols OVS_UNUSED)
+{
+ ofpact_put_PUSH_NSH(ofpacts)->ofpact.raw = NXAST_RAW_PUSH_NSH;
+ return NULL;
+}
+
+static void
+format_PUSH_NSH(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
+{
+ ds_put_format(s, "push_nsh");
+}
+
+/* Pop NSH header actions. */
+static enum ofperr
+decode_NXAST_RAW_POP_NSH(struct ofpbuf * out)
+{
+ ofpact_put_POP_NSH(out)->ofpact.raw = NXAST_RAW_POP_NSH;
+ return 0;
+}
+
+static void
+encode_POP_NSH(const struct ofpact_null *null OVS_UNUSED,
+ enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out)
+{
+ put_NXAST_POP_NSH(out);
+}
+
+static char * OVS_WARN_UNUSED_RESULT
+parse_POP_NSH(char *arg OVS_UNUSED, struct ofpbuf *ofpacts,
+ enum ofputil_protocol *usable_protocols OVS_UNUSED)
+{
+ ofpact_put_POP_NSH(ofpacts)->ofpact.raw = NXAST_RAW_POP_NSH;
+ return NULL;
+}
+
+static void
+format_POP_NSH(const struct ofpact_null *a OVS_UNUSED, struct ds *s)
+{
+ ds_put_format(s, "pop_nsh");
+}
+
/* Action structure for OFPAT10_SET_DL_SRC/DST and OFPAT11_SET_DL_SRC/DST. */
struct ofp_action_dl_addr {
@@ -6108,6 +6176,8 @@ ofpact_is_set_or_move_action(const struct ofpact *a)
case OFPACT_WRITE_ACTIONS:
case OFPACT_WRITE_METADATA:
case OFPACT_DEBUG_RECIRC:
+ case OFPACT_PUSH_NSH:
+ case OFPACT_POP_NSH:
return false;
default:
OVS_NOT_REACHED();
@@ -6180,6 +6250,8 @@ ofpact_is_allowed_in_actions_set(const struct ofpact *a)
case OFPACT_METER:
case OFPACT_WRITE_ACTIONS:
case OFPACT_WRITE_METADATA:
+ case OFPACT_PUSH_NSH:
+ case OFPACT_POP_NSH:
return false;
default:
OVS_NOT_REACHED();
@@ -6390,6 +6462,8 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type type)
case OFPACT_DEBUG_RECIRC:
case OFPACT_CT:
case OFPACT_NAT:
+ case OFPACT_PUSH_NSH:
+ case OFPACT_POP_NSH:
default:
return OVSINST_OFPIT11_APPLY_ACTIONS;
}
@@ -7020,6 +7094,10 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
case OFPACT_DEBUG_RECIRC:
return 0;
+ case OFPACT_PUSH_NSH:
+ case OFPACT_POP_NSH:
+ return 0;
+
default:
OVS_NOT_REACHED();
}
@@ -7506,6 +7584,8 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port)
case OFPACT_DEBUG_RECIRC:
case OFPACT_CT:
case OFPACT_NAT:
+ case OFPACT_PUSH_NSH:
+ case OFPACT_POP_NSH:
default:
return false;
}
@@ -4443,6 +4443,8 @@ freeze_unroll_actions(const struct ofpact *a, const struct ofpact *end,
case OFPACT_DEBUG_RECIRC:
case OFPACT_CT:
case OFPACT_NAT:
+ case OFPACT_PUSH_NSH:
+ case OFPACT_POP_NSH:
/* These may not generate PACKET INs. */
break;
@@ -4697,6 +4699,8 @@ recirc_for_mpls(const struct ofpact *a, struct xlate_ctx *ctx)
case OFPACT_WRITE_ACTIONS:
case OFPACT_WRITE_METADATA:
case OFPACT_GOTO_TABLE:
+ case OFPACT_PUSH_NSH:
+ case OFPACT_POP_NSH:
default:
break;
}
@@ -5068,6 +5072,9 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
ctx_trigger_freeze(ctx);
a = ofpact_next(a);
break;
+ case OFPACT_PUSH_NSH:
+ case OFPACT_POP_NSH:
+ break;
}
/* Check if need to store this and the remaining actions for later
This patch adds pop_nsh and push_nsh Openflow actions to control plane, and these actions strip or append the NSH respectively. The data plane implementation is included in other patches. How to use: 1) Flow rule for push_nsh: ovs-ofctl add-flow br-int "table=0, priority=260, \ in_port=1, ip, nw_src=192.168.0.1 \ actions=push_nsh,${Other actions}" 2) Flow rule for pop_nsh ovs-ofctl add-flow br-int "table=0, priority=260, \ in_port=xxx,actions=pop_nsh,{Other actions}" Signed-off-by: Johnson Li <johnson.li@intel.com>