Support for setting nsi using an action namely set_nsi.
It works similar to set_tunnel in vxlan/gre tunnel and
can be used to set the outgoing nsh service index (nsi).
Also NXM_NX_NSI is defined here which enables matching
NSIs.

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

diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
index e716fd7..c28f06a 100644
--- a/include/openflow/nicira-ext.h
+++ b/include/openflow/nicira-ext.h
@@ -315,6 +315,7 @@ enum nx_action_subtype {
     NXAST_SET_MPLS_LABEL,       /* struct nx_action_ttl */
     NXAST_SET_MPLS_TC,          /* struct nx_action_ttl */
     NXAST_SET_NSP,              /* struct nx_action_set_nsp */
+    NXAST_SET_NSI,              /* struct nx_action_set_nsi */
 };
 
 /* Header for Nicira-defined actions. */
@@ -1820,6 +1821,20 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
 #define NXM_NX_NSP_W   NXM_HEADER_W(0x0001, 35, 4)
 
 
+/* NSH Service Index.
+ *
+ * For a packet received via a VXLAN tunnel, it includes a (8-bit)
+ * network service header service index (nsi).
+ *
+ * Prereqs: None.
+ *
+ * Format: 8-bit integer.
+ *
+ * Masking: Arbitrary masks. */
+#define NXM_NX_NSI     NXM_HEADER  (0x0001, 35, 1)
+#define NXM_NX_NSI_W   NXM_HEADER_W(0x0001, 35, 1)
+
+
 /* ## --------------------- ## */
 /* ## Requests and replies. ## */
 /* ## --------------------- ## */
@@ -2368,4 +2383,17 @@ struct nx_action_set_nsp {
 };
 OFP_ASSERT(sizeof(struct nx_action_set_nsp) == 16);
 
+/* Action structure for NXAST_SET_NSI.
+ *
+ * Sets the encapsulating NSH service index to a 8-bit value. */
+struct nx_action_set_nsi {
+    ovs_be16 type;                  /* OFPAT_VENDOR. */
+    ovs_be16 len;                   /* Length is 16. */
+    ovs_be32 vendor;                /* NX_VENDOR_ID. */
+    ovs_be16 subtype;               /* NXAST_SET_NSI. */
+    uint8_t nsi;                    /* NSH service index. */
+    uint8_t pad[5];
+};
+OFP_ASSERT(sizeof(struct nx_action_set_nsi) == 16);
+
 #endif /* openflow/nicira-ext.h */
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index d9473ad..e0b3c72 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -787,11 +787,11 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFM_NONE,
         MFS_DECIMAL,
         MFP_NONE,
-        false,
-        0, NULL,
+        true,
+        NXM_NX_NSI, "NXM_NX_NSI",
         0, NULL,
-        OFPUTIL_P_NONE,
-        OFPUTIL_P_NONE,
+        OFPUTIL_P_NXM_OXM_ANY,
+        OFPUTIL_P_NXM_OXM_ANY,
         -1,
     },
 };
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 9092fba..ad0799158 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -689,6 +689,8 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match 
*match,
                 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);
+    nxm_put_8m(b, NXM_NX_NSI, flow->tunnel.nsi, match->wc.masks.tunnel.nsi);
+
     /* 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 f88297e..4d68b7e 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -82,6 +82,7 @@ union ofp_action {
     struct nx_action_mpls_label mpls_label;
     struct nx_action_mpls_tc mpls_tc;
     struct nx_action_set_nsp set_nsp;
+    struct nx_action_set_nsi set_nsi;
 };
 
 static enum ofperr
@@ -373,6 +374,7 @@ ofpact_from_nxast(const union ofp_action *a, enum 
ofputil_action_code code,
 {
     struct ofpact_tunnel *tunnel;
     struct ofpact_nsp *nsp;
+    struct ofpact_nsi *nsi;
     enum ofperr error = 0;
 
     switch (code) {
@@ -508,6 +510,12 @@ ofpact_from_nxast(const union ofp_action *a, enum 
ofputil_action_code code,
         nsp->ofpact.compat = code;
         nsp->nsp = ntohl(a->set_nsp.nsp);
         break;
+
+    case OFPUTIL_NXAST_SET_NSI:
+        nsi = ofpact_put_SET_NSI(out);
+        nsi->ofpact.compat = code;
+        nsi->nsi = a->set_nsi.nsi;
+        break;
     }
 
     return error;
@@ -1308,6 +1316,7 @@ ofpact_is_set_action(const struct ofpact *a)
     case OFPACT_SET_VLAN_PCP:
     case OFPACT_SET_VLAN_VID:
     case OFPACT_SET_NSP:
+    case OFPACT_SET_NSI:
         return true;
     case OFPACT_BUNDLE:
     case OFPACT_CLEAR_ACTIONS:
@@ -1376,6 +1385,7 @@ ofpact_is_allowed_in_actions_set(const struct ofpact *a)
     case OFPACT_SET_VLAN_VID:
     case OFPACT_STRIP_VLAN:
     case OFPACT_SET_NSP:
+    case OFPACT_SET_NSI:
         return true;
 
     /* In general these actions are excluded because they are not part of
@@ -1636,6 +1646,7 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type 
type)
     case OFPACT_EXIT:
     case OFPACT_SAMPLE:
     case OFPACT_SET_NSP:
+    case OFPACT_SET_NSI:
     default:
         return OVSINST_OFPIT11_APPLY_ACTIONS;
     }
@@ -2052,6 +2063,7 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, 
struct ofpact *a,
     case OFPACT_POP_QUEUE:
     case OFPACT_RESUBMIT:
     case OFPACT_SET_NSP:
+    case OFPACT_SET_NSI:
         return 0;
 
     case OFPACT_FIN_TIMEOUT:
@@ -2470,6 +2482,11 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf 
*out)
             = htonl(ofpact_get_SET_NSP(a)->nsp);
         break;
 
+    case OFPACT_SET_NSI:
+        ofputil_put_NXAST_SET_NSI(out)->nsi
+            = ofpact_get_SET_NSI(a)->nsi;
+        break;
+
     case OFPACT_GROUP:
     case OFPACT_OUTPUT:
     case OFPACT_ENQUEUE:
@@ -2627,6 +2644,7 @@ ofpact_to_openflow10(const struct ofpact *a, struct 
ofpbuf *out)
     case OFPACT_POP_MPLS:
     case OFPACT_SAMPLE:
     case OFPACT_SET_NSP:
+    case OFPACT_SET_NSI:
         ofpact_to_nxast(a, out);
         break;
     }
@@ -2821,6 +2839,7 @@ ofpact_to_openflow11(const struct ofpact *a, struct 
ofpbuf *out)
     case OFPACT_EXIT:
     case OFPACT_SAMPLE:
     case OFPACT_SET_NSP:
+    case OFPACT_SET_NSI:
         ofpact_to_nxast(a, out);
         break;
     }
@@ -3150,6 +3169,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, 
ofp_port_t port)
     case OFPACT_METER:
     case OFPACT_GROUP:
     case OFPACT_SET_NSP:
+    case OFPACT_SET_NSI:
     default:
         return false;
     }
@@ -3578,6 +3598,10 @@ ofpact_format(const struct ofpact *a, struct ds *s)
     case OFPACT_SET_NSP:
         ds_put_format(s, "set_nsp:%#"PRIx32, ofpact_get_SET_NSP(a)->nsp);
         break;
+
+    case OFPACT_SET_NSI:
+        ds_put_format(s, "set_nsi:%"PRIu8, ofpact_get_SET_NSI(a)->nsi);
+        break;
     }
 }
 
diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h
index 70125ba..f2e0eb0 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -91,6 +91,7 @@
     DEFINE_OFPACT(POP_QUEUE,       ofpact_null,          ofpact)    \
     DEFINE_OFPACT(FIN_TIMEOUT,     ofpact_fin_timeout,   ofpact)    \
     DEFINE_OFPACT(SET_NSP,         ofpact_nsp,           ofpact)    \
+    DEFINE_OFPACT(SET_NSI,         ofpact_nsi,           ofpact)    \
                                                                     \
     /* Flow table interaction. */                                   \
     DEFINE_OFPACT(RESUBMIT,        ofpact_resubmit,      ofpact)    \
@@ -423,6 +424,14 @@ struct ofpact_nsp {
     uint32_t nsp;
 };
 
+/* OFPACT_SET_NSI.
+ *
+ * Used for NXAST_SET_NSI. */
+struct ofpact_nsi {
+    struct ofpact ofpact;
+    uint8_t nsi;
+};
+
 /* OFPACT_WRITE_METADATA.
  *
  * Used for NXAST_WRITE_METADATA. */
diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c
index d216e44..15469a2 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -637,6 +637,7 @@ parse_named_action(enum ofputil_action_code code,
     struct ofpact_vlan_vid *vlan_vid;
     struct ofpact_vlan_pcp *vlan_pcp;
     struct ofpact_nsp *nsp;
+    struct ofpact_nsi *nsi;
     char *error = NULL;
     uint16_t ethertype = 0;
     uint16_t vid = 0;
@@ -915,6 +916,11 @@ parse_named_action(enum ofputil_action_code code,
         error = str_to_u32(arg, &nsp->nsp);
         break;
 
+    case OFPUTIL_NXAST_SET_NSI:
+        nsi = ofpact_put_SET_NSI(ofpacts);
+        nsi->ofpact.compat = code;
+        error = str_to_u8(arg, "nsi", &nsi->nsi);
+        break;
     }
 
     if (error) {
diff --git a/lib/ofp-util.def b/lib/ofp-util.def
index bf8c0de..4733d33 100644
--- a/lib/ofp-util.def
+++ b/lib/ofp-util.def
@@ -78,6 +78,7 @@ 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")
+NXAST_ACTION(NXAST_SET_NSI,         nx_action_set_nsi,      0, "set_nsi")
 
 #undef OFPAT10_ACTION
 #undef OFPAT11_ACTION
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 551f104..0d7919a 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2793,6 +2793,10 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t 
ofpacts_len,
         case OFPACT_SET_NSP:
             flow->tunnel.nsp = htonl(ofpact_get_SET_NSP(a)->nsp);
             break;
+
+        case OFPACT_SET_NSI:
+            flow->tunnel.nsi = ofpact_get_SET_NSI(a)->nsi;
+            break;
         }
     }
 }
-- 
1.7.9.5

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

Reply via email to