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.koth...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev