Support for setting nsp using an action namely set_nsp. It works similar to
set_tunnel in vxlan/gre tunnel and can be used to set the outgoing nsh
service path id.

Signed-off-by: pritesh <pritesh.koth...@cisco.com>

diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
index de5ff6a..748ceee 100644
--- a/include/openflow/nicira-ext.h
+++ b/include/openflow/nicira-ext.h
@@ -312,6 +312,7 @@ enum nx_action_subtype {
     NXAST_STACK_PUSH,           /* struct nx_action_stack */
     NXAST_STACK_POP,            /* struct nx_action_stack */
     NXAST_SAMPLE,               /* struct nx_action_sample */
+    NXAST_SET_NSP,              /* struct nx_action_set_nsp */
 };
 
 /* Header for Nicira-defined actions. */
@@ -1783,6 +1784,21 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
 #define NXM_NX_PKT_MARK   NXM_HEADER  (0x0001, 33, 4)
 #define NXM_NX_PKT_MARK_W NXM_HEADER_W(0x0001, 33, 4)
 
+/* NSH Service Path.
+ *
+ * For a packet received via a VXLAN tunnel including a (32-bit)
+ * network service header service path (nsp), the nsp is stored
+ * in the low 24-bits and the high bits are zeroed.  For
+ * other packets, the value is 0.
+ *
+ * Prereqs: None.
+ *
+ * Format: 32-bit integer in network byte order.
+ *
+ * Masking: Arbitrary masks. */
+#define NXM_NX_NSP     NXM_HEADER  (0x0001, 34, 4)
+#define NXM_NX_NSP_W   NXM_HEADER_W(0x0001, 34, 4)
+
 /* ## --------------------- ## */
 /* ## Requests and replies. ## */
 /* ## --------------------- ## */
@@ -2296,4 +2312,17 @@ struct nx_action_sample {
 };
 OFP_ASSERT(sizeof(struct nx_action_sample) == 24);
 
+/* Action structure for NXAST_SET_NSP.
+ *
+ * Sets the encapsulating NSH service path ID to a 32-bit value. */
+struct nx_action_set_nsp {
+    ovs_be16 type;                  /* OFPAT_VENDOR. */
+    ovs_be16 len;                   /* Length is 16. */
+    ovs_be32 vendor;                /* NX_VENDOR_ID. */
+    ovs_be16 subtype;               /* NXAST_SET_NSP. */
+    uint8_t pad[2];
+    ovs_be32 nsp;                   /* NSH service path ID. */
+};
+OFP_ASSERT(sizeof(struct nx_action_set_nsp) == 16);
+
 #endif /* openflow/nicira-ext.h */
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 1d175d5..67ddd3e 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -707,7 +707,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = {
         MFS_HEXADECIMAL,
         MFP_NONE,
         false,
-        0, NULL,
+        NXM_NX_NSP, "NXM_NX_NSP",
         0, NULL,
         OFPUTIL_P_OF10_NXM_ANY,
         OFPUTIL_P_OF10_NXM_ANY,
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 2d7ee34..f8e6223 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -686,6 +686,7 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match 
*match,
     nxm_put_64m(b, oxm ? OXM_OF_TUNNEL_ID : NXM_NX_TUN_ID,
                 flow->tunnel.tun_id, match->wc.masks.tunnel.tun_id);
 
+    nxm_put_32m(b, NXM_NX_NSP, flow->tunnel.nsp, match->wc.masks.tunnel.nsp);
     /* Other tunnel metadata. */
     nxm_put_32m(b, NXM_NX_TUN_IPV4_SRC,
                 flow->tunnel.ip_src, match->wc.masks.tunnel.ip_src);
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
index dcc82db..b9c3f57 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -314,7 +314,9 @@ ofpact_from_nxast(const union ofp_action *a, enum 
ofputil_action_code code,
     const struct nx_action_note *nan;
     const struct nx_action_set_tunnel64 *nast64;
     const struct nx_action_write_metadata *nawm;
+    const struct nx_action_set_nsp *nasnsp;
     struct ofpact_tunnel *tunnel;
+    struct ofpact_nsp *nsp;
     enum ofperr error = 0;
 
     switch (code) {
@@ -460,6 +462,13 @@ ofpact_from_nxast(const union ofp_action *a, enum 
ofputil_action_code code,
         error = sample_from_openflow(
             (const struct nx_action_sample *) a, out);
         break;
+
+    case OFPUTIL_NXAST_SET_NSP:
+        nasnsp = (const struct nx_action_set_nsp *) a;
+        nsp = ofpact_put_SET_NSP(out);
+        nsp->ofpact.compat = code;
+        nsp->nsp = ntohl(nasnsp->nsp);
+        break;
     }
 
     return error;
@@ -986,6 +995,7 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type type)
     case OFPACT_NOTE:
     case OFPACT_EXIT:
     case OFPACT_SAMPLE:
+    case OFPACT_SET_NSP:
     default:
         return OVSINST_OFPIT11_APPLY_ACTIONS;
     }
@@ -1268,6 +1278,7 @@ ofpact_check__(const struct ofpact *a, struct flow *flow, 
ofp_port_t max_ports,
     case OFPACT_POP_QUEUE:
     case OFPACT_FIN_TIMEOUT:
     case OFPACT_RESUBMIT:
+    case OFPACT_SET_NSP:
         return 0;
 
     case OFPACT_LEARN:
@@ -1608,6 +1619,11 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf 
*out)
         ofpact_sample_to_nxast(ofpact_get_SAMPLE(a), out);
         break;
 
+    case OFPACT_SET_NSP:
+        ofputil_put_NXAST_SET_NSP(out)->nsp
+            = htonl(ofpact_get_SET_NSP(a)->nsp);
+        break;
+
     case OFPACT_GROUP:
     case OFPACT_OUTPUT:
     case OFPACT_ENQUEUE:
@@ -1747,6 +1763,7 @@ ofpact_to_openflow10(const struct ofpact *a, struct 
ofpbuf *out)
     case OFPACT_PUSH_MPLS:
     case OFPACT_POP_MPLS:
     case OFPACT_SAMPLE:
+    case OFPACT_SET_NSP:
         ofpact_to_nxast(a, out);
         break;
     }
@@ -1917,6 +1934,7 @@ ofpact_to_openflow11(const struct ofpact *a, struct 
ofpbuf *out)
     case OFPACT_NOTE:
     case OFPACT_EXIT:
     case OFPACT_SAMPLE:
+    case OFPACT_SET_NSP:
         ofpact_to_nxast(a, out);
         break;
     }
@@ -2071,6 +2089,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, 
ofp_port_t port)
     case OFPACT_GOTO_TABLE:
     case OFPACT_METER:
     case OFPACT_GROUP:
+    case OFPACT_SET_NSP:
     default:
         return false;
     }
@@ -2450,6 +2469,10 @@ ofpact_format(const struct ofpact *a, struct ds *s)
         ds_put_format(s, "group:%"PRIu32,
                       ofpact_get_GROUP(a)->group_id);
         break;
+
+    case OFPACT_SET_NSP:
+        ds_put_format(s, "set_nsp:%#"PRIx32, ofpact_get_SET_NSP(a)->nsp);
+        break;
     }
 }
 
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index 0876ed7..443d8c3 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -84,6 +84,7 @@
     DEFINE_OFPACT(SET_QUEUE,       ofpact_queue,         ofpact)    \
     DEFINE_OFPACT(POP_QUEUE,       ofpact_null,          ofpact)    \
     DEFINE_OFPACT(FIN_TIMEOUT,     ofpact_fin_timeout,   ofpact)    \
+    DEFINE_OFPACT(SET_NSP,         ofpact_nsp,           ofpact)    \
                                                                     \
     /* Flow table interaction. */                                   \
     DEFINE_OFPACT(RESUBMIT,        ofpact_resubmit,      ofpact)    \
@@ -367,6 +368,14 @@ struct ofpact_fin_timeout {
     uint16_t fin_hard_timeout;
 };
 
+/* OFPACT_SET_NSP.
+ *
+ * Used for NXAST_SET_NSP. */
+struct ofpact_nsp {
+    struct ofpact ofpact;
+    uint32_t nsp;
+};
+
 /* OFPACT_WRITE_METADATA.
  *
  * Used for NXAST_WRITE_METADATA. */
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index 522bd95..d17622c 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -601,6 +601,7 @@ parse_named_action(enum ofputil_action_code code,
 {
     size_t orig_size = ofpacts->size;
     struct ofpact_tunnel *tunnel;
+    struct ofpact_nsp *nsp;
     char *error = NULL;
     uint16_t ethertype = 0;
     uint16_t vid = 0;
@@ -833,6 +834,13 @@ parse_named_action(enum ofputil_action_code code,
     case OFPUTIL_NXAST_SAMPLE:
         error = parse_sample(ofpacts, arg);
         break;
+
+    case OFPUTIL_NXAST_SET_NSP:
+        nsp = ofpact_put_SET_NSP(ofpacts);
+        nsp->ofpact.compat = code;
+        error = str_to_u32(arg, &nsp->nsp);
+        break;
+
     }
 
     if (error) {
diff --git a/lib/ofp-util.def b/lib/ofp-util.def
index f5eec73..dfa9f4d 100644
--- a/lib/ofp-util.def
+++ b/lib/ofp-util.def
@@ -73,6 +73,7 @@ NXAST_ACTION(NXAST_DEC_MPLS_TTL,    nx_action_header,       
0, "dec_mpls_ttl")
 NXAST_ACTION(NXAST_PUSH_MPLS,       nx_action_push_mpls,    0, "push_mpls")
 NXAST_ACTION(NXAST_POP_MPLS,        nx_action_pop_mpls,     0, "pop_mpls")
 NXAST_ACTION(NXAST_SAMPLE,          nx_action_sample,       0, "sample")
+NXAST_ACTION(NXAST_SET_NSP,         nx_action_set_nsp,      0, "set_nsp")
 
 #undef OFPAT10_ACTION
 #undef OFPAT11_ACTION
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index a5b6814..c184f72 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2397,6 +2397,10 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t 
ofpacts_len,
         case OFPACT_SAMPLE:
             xlate_sample_action(ctx, ofpact_get_SAMPLE(a));
             break;
+
+        case OFPACT_SET_NSP:
+            flow->tunnel.nsp = htonl(ofpact_get_SET_NSP(a)->nsp);
+            break;
         }
     }
 }
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to