[ovs-dev] [PATCH v2 3/7] nsh: support for setting nsp, action set_nsp=<value>

Pritesh Kothari pritesh.kothari at cisco.com
Tue Feb 25 23:44:16 UTC 2014


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.
Also NXM_NX_NSP is defined which enables matching NSPs.

Signed-off-by: Pritesh Kothari <pritesh.kothari at cisco.com>

diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h
index 22939f4..e716fd7 100644
--- a/include/openflow/nicira-ext.h
+++ b/include/openflow/nicira-ext.h
@@ -314,6 +314,7 @@ enum nx_action_subtype {
     NXAST_SAMPLE,               /* struct nx_action_sample */
     NXAST_SET_MPLS_LABEL,       /* struct nx_action_ttl */
     NXAST_SET_MPLS_TC,          /* struct nx_action_ttl */
+    NXAST_SET_NSP,              /* struct nx_action_set_nsp */
 };
 
 /* Header for Nicira-defined actions. */
@@ -1803,6 +1804,22 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24);
 #define NXM_NX_TCP_FLAGS   NXM_HEADER  (0x0001, 34, 2)
 #define NXM_NX_TCP_FLAGS_W NXM_HEADER_W(0x0001, 34, 2)
 
+/* 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, 35, 4)
+#define NXM_NX_NSP_W   NXM_HEADER_W(0x0001, 35, 4)
+
+
 /* ## --------------------- ## */
 /* ## Requests and replies. ## */
 /* ## --------------------- ## */
@@ -2338,4 +2355,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 5a620a1..8b64de2 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -775,11 +775,11 @@ const struct mf_field mf_fields[MFF_N_IDS] = {
         MFM_FULLY,
         MFS_HEXADECIMAL,
         MFP_NONE,
-        false,
-        0, NULL,
+        true,
+        NXM_NX_NSP, "NXM_NX_NSP",
         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 437e85b..9092fba 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -688,6 +688,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 3cd1e8b..f88297e 100644
--- a/lib/ofp-actions.c
+++ b/lib/ofp-actions.c
@@ -81,6 +81,7 @@ union ofp_action {
     struct nx_action_learn learn;
     struct nx_action_mpls_label mpls_label;
     struct nx_action_mpls_tc mpls_tc;
+    struct nx_action_set_nsp set_nsp;
 };
 
 static enum ofperr
@@ -371,6 +372,7 @@ ofpact_from_nxast(const union ofp_action *a, enum ofputil_action_code code,
                   struct ofpbuf *out)
 {
     struct ofpact_tunnel *tunnel;
+    struct ofpact_nsp *nsp;
     enum ofperr error = 0;
 
     switch (code) {
@@ -500,6 +502,12 @@ ofpact_from_nxast(const union ofp_action *a, enum ofputil_action_code code,
     case OFPUTIL_NXAST_SAMPLE:
         error = sample_from_openflow(&a->sample, out);
         break;
+
+    case OFPUTIL_NXAST_SET_NSP:
+        nsp = ofpact_put_SET_NSP(out);
+        nsp->ofpact.compat = code;
+        nsp->nsp = ntohl(a->set_nsp.nsp);
+        break;
     }
 
     return error;
@@ -1299,6 +1307,7 @@ ofpact_is_set_action(const struct ofpact *a)
     case OFPACT_SET_TUNNEL:
     case OFPACT_SET_VLAN_PCP:
     case OFPACT_SET_VLAN_VID:
+    case OFPACT_SET_NSP:
         return true;
     case OFPACT_BUNDLE:
     case OFPACT_CLEAR_ACTIONS:
@@ -1366,6 +1375,7 @@ ofpact_is_allowed_in_actions_set(const struct ofpact *a)
     case OFPACT_SET_VLAN_PCP:
     case OFPACT_SET_VLAN_VID:
     case OFPACT_STRIP_VLAN:
+    case OFPACT_SET_NSP:
         return true;
 
     /* In general these actions are excluded because they are not part of
@@ -1625,6 +1635,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;
     }
@@ -2040,6 +2051,7 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a,
     case OFPACT_SET_QUEUE:
     case OFPACT_POP_QUEUE:
     case OFPACT_RESUBMIT:
+    case OFPACT_SET_NSP:
         return 0;
 
     case OFPACT_FIN_TIMEOUT:
@@ -2453,6 +2465,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:
@@ -2609,6 +2626,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;
     }
@@ -2802,6 +2820,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;
     }
@@ -3130,6 +3149,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;
     }
@@ -3554,6 +3574,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 0f6bf70..70125ba 100644
--- a/lib/ofp-actions.h
+++ b/lib/ofp-actions.h
@@ -90,6 +90,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)    \
@@ -414,6 +415,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 b254ac6..d216e44 100644
--- a/lib/ofp-parse.c
+++ b/lib/ofp-parse.c
@@ -636,6 +636,7 @@ parse_named_action(enum ofputil_action_code code,
     struct ofpact_tunnel *tunnel;
     struct ofpact_vlan_vid *vlan_vid;
     struct ofpact_vlan_pcp *vlan_pcp;
+    struct ofpact_nsp *nsp;
     char *error = NULL;
     uint16_t ethertype = 0;
     uint16_t vid = 0;
@@ -907,6 +908,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 fae2bf2..bf8c0de 100644
--- a/lib/ofp-util.def
+++ b/lib/ofp-util.def
@@ -77,6 +77,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 89d92af..551f104 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2789,6 +2789,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




More information about the dev mailing list