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