On Thu, Oct 24, 2013 at 01:19:34PM -0700, Jarno Rajahalme wrote: > Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
This looks good to me. Reviewed-by: Simon Horman <ho...@verge.net.au> > --- > v3: Fix byte order errors. > > include/openflow/nicira-ext.h | 24 ++++++++++++ > lib/ofp-actions.c | 82 > +++++++++++++++++++++++++++++++++++++++-- > lib/ofp-actions.h | 22 ++++++++++- > lib/ofp-parse.c | 46 +++++++++++++++++++++++ > lib/ofp-util.c | 24 ++++++++---- > lib/ofp-util.def | 4 ++ > ofproto/ofproto-dpif-xlate.c | 62 +++++++++++++++++++++++++++++++ > tests/ovs-ofctl.at | 9 +++-- > 8 files changed, 256 insertions(+), 17 deletions(-) > > diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h > index 3362a49..0cd62ea 100644 > --- a/include/openflow/nicira-ext.h > +++ b/include/openflow/nicira-ext.h > @@ -312,6 +312,8 @@ 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_MPLS_LABEL, /* struct nx_action_ttl */ > + NXAST_SET_MPLS_TC, /* struct nx_action_ttl */ > }; > > /* Header for Nicira-defined actions. */ > @@ -2261,6 +2263,28 @@ struct nx_action_pop_mpls { > }; > OFP_ASSERT(sizeof(struct nx_action_pop_mpls) == 16); > > +/* Action structure for NXAST_SET_MPLS_LABEL. */ > +struct nx_action_mpls_label { > + ovs_be16 type; /* OFPAT_VENDOR. */ > + ovs_be16 len; /* Length is 8. */ > + ovs_be32 vendor; /* NX_VENDOR_ID. */ > + ovs_be16 subtype; /* NXAST_SET_MPLS_LABEL. */ > + uint8_t zeros[2]; /* Must be zero. */ > + ovs_be32 label; /* LABEL */ > +}; > +OFP_ASSERT(sizeof(struct nx_action_mpls_label) == 16); > + > +/* Action structure for NXAST_SET_MPLS_TC. */ > +struct nx_action_mpls_tc { > + ovs_be16 type; /* OFPAT_VENDOR. */ > + ovs_be16 len; /* Length is 8. */ > + ovs_be32 vendor; /* NX_VENDOR_ID. */ > + ovs_be16 subtype; /* NXAST_SET_MPLS_TC. */ > + uint8_t tc; /* TC */ > + uint8_t pad[5]; > +}; > +OFP_ASSERT(sizeof(struct nx_action_mpls_tc) == 16); > + > /* Action structure for NXAST_SET_MPLS_TTL. */ > struct nx_action_mpls_ttl { > ovs_be16 type; /* OFPAT_VENDOR. */ > diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c > index 4713371..9ef1c12 100644 > --- a/lib/ofp-actions.c > +++ b/lib/ofp-actions.c > @@ -53,6 +53,8 @@ union ofp_action { > struct ofp11_action_push push; > struct ofp11_action_pop_mpls ofp11_pop_mpls; > struct ofp11_action_set_queue ofp11_set_queue; > + struct ofp11_action_mpls_label ofp11_mpls_label; > + struct ofp11_action_mpls_tc ofp11_mpls_tc; > struct ofp11_action_mpls_ttl ofp11_mpls_ttl; > struct ofp11_action_group group; > struct ofp12_action_set_field set_field; > @@ -77,6 +79,8 @@ union ofp_action { > struct nx_action_pop_mpls pop_mpls; > struct nx_action_sample sample; > struct nx_action_learn learn; > + struct nx_action_mpls_label mpls_label; > + struct nx_action_mpls_tc mpls_tc; > }; > > static enum ofperr > @@ -473,6 +477,14 @@ ofpact_from_nxast(const union ofp_action *a, enum > ofputil_action_code code, > OFPACT_MPLS_AFTER_VLAN, out); > break; > > + case OFPUTIL_NXAST_SET_MPLS_LABEL: > + ofpact_put_SET_MPLS_LABEL(out)->label = a->mpls_label.label; > + break; > + > + case OFPUTIL_NXAST_SET_MPLS_TC: > + ofpact_put_SET_MPLS_TC(out)->tc = a->mpls_tc.tc; > + break; > + > case OFPUTIL_NXAST_SET_MPLS_TTL: > ofpact_put_SET_MPLS_TTL(out)->ttl = a->mpls_ttl.ttl; > break; > @@ -993,13 +1005,13 @@ set_field_to_openflow(const struct ofpact_set_field > *sf, > return; > > case MFF_MPLS_LABEL: > - /* ofputil_put_OFPAT11_SET_MPLS_LABEL(openflow)->label = > - sf->value.be32; */ > + ofputil_put_OFPAT11_SET_MPLS_LABEL(openflow)->mpls_label = > + sf->value.be32; > break; > > case MFF_MPLS_TC: > - /* ofputil_put_OFPAT11_SET_MPLS_TC(openflow)->tc = > - sf->value.u8; */ > + ofputil_put_OFPAT11_SET_MPLS_TC(openflow)->mpls_tc = > + sf->value.u8; > break; > > case MFF_IPV4_SRC: > @@ -1220,6 +1232,14 @@ ofpact_from_openflow11(const union ofp_action *a, enum > ofp_version version, > case OFPUTIL_OFPAT12_SET_FIELD: > return set_field_from_openflow(&a->set_field, out); > > + case OFPUTIL_OFPAT11_SET_MPLS_LABEL: > + ofpact_put_SET_MPLS_LABEL(out)->label = > a->ofp11_mpls_label.mpls_label; > + break; > + > + case OFPUTIL_OFPAT11_SET_MPLS_TC: > + ofpact_put_SET_MPLS_TC(out)->tc = a->ofp11_mpls_tc.mpls_tc; > + break; > + > case OFPUTIL_OFPAT11_SET_MPLS_TTL: > ofpact_put_SET_MPLS_TTL(out)->ttl = a->ofp11_mpls_ttl.mpls_ttl; > break; > @@ -1273,6 +1293,8 @@ ofpact_is_set_action(const struct ofpact *a) > case OFPACT_SET_IPV4_SRC: > case OFPACT_SET_L4_DST_PORT: > case OFPACT_SET_L4_SRC_PORT: > + case OFPACT_SET_MPLS_LABEL: > + case OFPACT_SET_MPLS_TC: > case OFPACT_SET_MPLS_TTL: > case OFPACT_SET_QUEUE: > case OFPACT_SET_TUNNEL: > @@ -1337,6 +1359,8 @@ ofpact_is_allowed_in_actions_set(const struct ofpact *a) > case OFPACT_SET_IPV4_SRC: > case OFPACT_SET_L4_DST_PORT: > case OFPACT_SET_L4_SRC_PORT: > + case OFPACT_SET_MPLS_LABEL: > + case OFPACT_SET_MPLS_TC: > case OFPACT_SET_MPLS_TTL: > case OFPACT_SET_QUEUE: > case OFPACT_SET_TUNNEL: > @@ -1586,6 +1610,8 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type > type) > case OFPACT_STACK_PUSH: > case OFPACT_STACK_POP: > case OFPACT_DEC_TTL: > + case OFPACT_SET_MPLS_LABEL: > + case OFPACT_SET_MPLS_TC: > case OFPACT_SET_MPLS_TTL: > case OFPACT_DEC_MPLS_TTL: > case OFPACT_PUSH_MPLS: > @@ -1961,6 +1987,8 @@ ofpact_check__(struct ofpact *a, struct flow *flow, > ofp_port_t max_ports, > case OFPACT_STACK_POP: > return nxm_stack_pop_check(ofpact_get_STACK_POP(a), flow); > > + case OFPACT_SET_MPLS_LABEL: > + case OFPACT_SET_MPLS_TC: > case OFPACT_SET_MPLS_TTL: > case OFPACT_DEC_MPLS_TTL: > if (!eth_type_mpls(flow->dl_type)) { > @@ -2280,6 +2308,16 @@ ofpact_to_nxast(const struct ofpact *a, struct ofpbuf > *out) > ofpact_dec_ttl_to_nxast(ofpact_get_DEC_TTL(a), out); > break; > > + case OFPACT_SET_MPLS_LABEL: > + ofputil_put_NXAST_SET_MPLS_LABEL(out)->label > + = ofpact_get_SET_MPLS_LABEL(a)->label; > + break; > + > + case OFPACT_SET_MPLS_TC: > + ofputil_put_NXAST_SET_MPLS_TC(out)->tc > + = ofpact_get_SET_MPLS_TC(a)->tc; > + break; > + > case OFPACT_SET_MPLS_TTL: > ofputil_put_NXAST_SET_MPLS_TTL(out)->ttl > = ofpact_get_SET_MPLS_TTL(a)->ttl; > @@ -2483,6 +2521,8 @@ ofpact_to_openflow10(const struct ofpact *a, struct > ofpbuf *out) > case OFPACT_DEC_TTL: > case OFPACT_SET_IP_ECN: > case OFPACT_SET_IP_TTL: > + case OFPACT_SET_MPLS_LABEL: > + case OFPACT_SET_MPLS_TC: > case OFPACT_SET_MPLS_TTL: > case OFPACT_DEC_MPLS_TTL: > case OFPACT_SET_TUNNEL: > @@ -2626,6 +2666,16 @@ ofpact_to_openflow11(const struct ofpact *a, struct > ofpbuf *out) > ofpact_dec_ttl_to_openflow11(ofpact_get_DEC_TTL(a), out); > break; > > + case OFPACT_SET_MPLS_LABEL: > + ofputil_put_OFPAT11_SET_MPLS_LABEL(out)->mpls_label > + = ofpact_get_SET_MPLS_LABEL(a)->label; > + break; > + > + case OFPACT_SET_MPLS_TC: > + ofputil_put_OFPAT11_SET_MPLS_TC(out)->mpls_tc > + = ofpact_get_SET_MPLS_TC(a)->tc; > + break; > + > case OFPACT_SET_MPLS_TTL: > ofputil_put_OFPAT11_SET_MPLS_TTL(out)->mpls_ttl > = ofpact_get_SET_MPLS_TTL(a)->ttl; > @@ -2710,6 +2760,8 @@ ofpact_to_openflow12(const struct ofpact *a, struct > ofpbuf *out) > case OFPACT_SET_IP_ECN: > case OFPACT_SET_L4_SRC_PORT: > case OFPACT_SET_L4_DST_PORT: > + case OFPACT_SET_MPLS_LABEL: > + case OFPACT_SET_MPLS_TC: > case OFPACT_SET_TUNNEL: /* Convert to a set_field, too. */ > > switch ((int)a->type) { > @@ -2791,6 +2843,16 @@ ofpact_to_openflow12(const struct ofpact *a, struct > ofpbuf *out) > value.be16 = htons(l4port->port); > break; > > + case OFPACT_SET_MPLS_LABEL: > + field = MFF_MPLS_LABEL; > + value.be32 = ofpact_get_SET_MPLS_LABEL(a)->label; > + break; > + > + case OFPACT_SET_MPLS_TC: > + field = MFF_MPLS_TC; > + value.u8 = ofpact_get_SET_MPLS_TC(a)->tc; > + break; > + > case OFPACT_SET_TUNNEL: > field = MFF_TUN_ID; > value.be64 = htonll(ofpact_get_SET_TUNNEL(a)->tun_id); > @@ -2975,6 +3037,8 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, > ofp_port_t port) > case OFPACT_STACK_PUSH: > case OFPACT_STACK_POP: > case OFPACT_DEC_TTL: > + case OFPACT_SET_MPLS_LABEL: > + case OFPACT_SET_MPLS_TC: > case OFPACT_SET_MPLS_TTL: > case OFPACT_DEC_MPLS_TTL: > case OFPACT_SET_TUNNEL: > @@ -3291,6 +3355,16 @@ ofpact_format(const struct ofpact *a, struct ds *s) > print_dec_ttl(ofpact_get_DEC_TTL(a), s); > break; > > + case OFPACT_SET_MPLS_LABEL: > + ds_put_format(s, "set_mpls_label(%"PRIu32")", > + ntohl(ofpact_get_SET_MPLS_LABEL(a)->label)); > + break; > + > + case OFPACT_SET_MPLS_TC: > + ds_put_format(s, "set_mpls_ttl(%"PRIu8")", > + ofpact_get_SET_MPLS_TC(a)->tc); > + break; > + > case OFPACT_SET_MPLS_TTL: > ds_put_format(s, "set_mpls_ttl(%"PRIu8")", > ofpact_get_SET_MPLS_TTL(a)->ttl); > diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h > index 41579ce..a17688f 100644 > --- a/lib/ofp-actions.h > +++ b/lib/ofp-actions.h > @@ -78,6 +78,8 @@ > DEFINE_OFPACT(STACK_PUSH, ofpact_stack, ofpact) \ > DEFINE_OFPACT(STACK_POP, ofpact_stack, ofpact) \ > DEFINE_OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids) \ > + DEFINE_OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact) \ > + DEFINE_OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact) \ > DEFINE_OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact) \ > DEFINE_OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact) \ > DEFINE_OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact) \ > @@ -552,9 +554,27 @@ struct ofpact_cnt_ids { > uint16_t cnt_ids[]; > }; > > +/* OFPACT_SET_MPLS_LABEL. > + * > + * Used for OFPAT11_SET_MPLS_LABEL and NXAST_SET_MPLS_LABEL */ > +struct ofpact_mpls_label { > + struct ofpact ofpact; > + > + ovs_be32 label; > +}; > + > +/* OFPACT_SET_MPLS_TC. > + * > + * Used for OFPAT11_SET_MPLS_TC and NXAST_SET_MPLS_TC */ > +struct ofpact_mpls_tc { > + struct ofpact ofpact; > + > + uint8_t tc; > +}; > + > /* OFPACT_SET_MPLS_TTL. > * > - * Used for NXAST_SET_MPLS_TTL */ > + * Used for OFPAT11_SET_MPLS_TTL and NXAST_SET_MPLS_TTL */ > struct ofpact_mpls_ttl { > struct ofpact ofpact; > > diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c > index 7b19dc0..5ad2255 100644 > --- a/lib/ofp-parse.c > +++ b/lib/ofp-parse.c > @@ -438,6 +438,42 @@ parse_dec_ttl(struct ofpbuf *b, char *arg) > return NULL; > } > > +/* Parses 'arg' as the argument to a "set_mpls_label" action, and appends > such > + * an action to 'b'. > + * > + * Returns NULL if successful, otherwise a malloc()'d string describing the > + * error. The caller is responsible for freeing the returned string. */ > +static char * WARN_UNUSED_RESULT > +parse_set_mpls_label(struct ofpbuf *b, const char *arg) > +{ > + struct ofpact_mpls_label *mpls_label = ofpact_put_SET_MPLS_LABEL(b); > + > + if (*arg == '\0') { > + return xstrdup("parse_set_mpls_label: expected label."); > + } > + > + mpls_label->label = htonl(atoi(arg)); > + return NULL; > +} > + > +/* Parses 'arg' as the argument to a "set_mpls_tc" action, and appends such > an > + * action to 'b'. > + * > + * Returns NULL if successful, otherwise a malloc()'d string describing the > + * error. The caller is responsible for freeing the returned string. */ > +static char * WARN_UNUSED_RESULT > +parse_set_mpls_tc(struct ofpbuf *b, const char *arg) > +{ > + struct ofpact_mpls_tc *mpls_tc = ofpact_put_SET_MPLS_TC(b); > + > + if (*arg == '\0') { > + return xstrdup("parse_set_mpls_tc: expected tc."); > + } > + > + mpls_tc->tc = atoi(arg); > + return NULL; > +} > + > /* Parses 'arg' as the argument to a "set_mpls_ttl" action, and appends such > an > * action to 'ofpacts'. > * > @@ -815,6 +851,16 @@ parse_named_action(enum ofputil_action_code code, > error = parse_dec_ttl(ofpacts, arg); > break; > > + case OFPUTIL_NXAST_SET_MPLS_LABEL: > + case OFPUTIL_OFPAT11_SET_MPLS_LABEL: > + error = parse_set_mpls_label(ofpacts, arg); > + break; > + > + case OFPUTIL_NXAST_SET_MPLS_TC: > + case OFPUTIL_OFPAT11_SET_MPLS_TC: > + error = parse_set_mpls_tc(ofpacts, arg); > + break; > + > case OFPUTIL_NXAST_SET_MPLS_TTL: > case OFPUTIL_OFPAT11_SET_MPLS_TTL: > error = parse_set_mpls_ttl(ofpacts, arg); > diff --git a/lib/ofp-util.c b/lib/ofp-util.c > index f090539..8828eab 100644 > --- a/lib/ofp-util.c > +++ b/lib/ofp-util.c > @@ -436,11 +436,11 @@ ofputil_match_from_ofp11_match(const struct ofp11_match > *ofmatch, > } > > if (eth_type_mpls(match->flow.dl_type)) { > - enum { OFPFW11_MPLS_ALL = OFPFW11_MPLS_LABEL | OFPFW11_MPLS_TC }; > - > - if ((wc & OFPFW11_MPLS_ALL) != OFPFW11_MPLS_ALL) { > - /* MPLS not supported. */ > - return OFPERR_OFPBMC_BAD_TAG; > + if (!(wc & OFPFW11_MPLS_LABEL)) { > + match_set_mpls_label(match, ofmatch->mpls_label); > + } > + if (!(wc & OFPFW11_MPLS_TC)) { > + match_set_mpls_tc(match, ofmatch->mpls_tc); > } > } > > @@ -533,9 +533,17 @@ ofputil_match_to_ofp11_match(const struct match *match, > ofmatch->tp_dst = match->flow.tp_dst; > } > > - /* MPLS not supported. */ > - wc |= OFPFW11_MPLS_LABEL; > - wc |= OFPFW11_MPLS_TC; > + if (!(match->wc.masks.mpls_lse & htonl(MPLS_LABEL_MASK))) { > + wc |= OFPFW11_MPLS_LABEL; > + } else { > + ofmatch->mpls_label = htonl(mpls_lse_to_label(match->flow.mpls_lse)); > + } > + > + if (!(match->wc.masks.mpls_lse & htonl(MPLS_TC_MASK))) { > + wc |= OFPFW11_MPLS_TC; > + } else { > + ofmatch->mpls_tc = mpls_lse_to_tc(match->flow.mpls_lse); > + } > > ofmatch->metadata = match->flow.metadata; > ofmatch->metadata_mask = ~match->wc.masks.metadata; > diff --git a/lib/ofp-util.def b/lib/ofp-util.def > index 631a6b1..fae2bf2 100644 > --- a/lib/ofp-util.def > +++ b/lib/ofp-util.def > @@ -30,6 +30,8 @@ OFPAT11_ACTION(OFPAT11_SET_NW_TOS, ofp_action_nw_tos, > 0, "mod_nw_tos") > OFPAT11_ACTION(OFPAT11_SET_NW_ECN, ofp11_action_nw_ecn, 0, "mod_nw_ecn") > OFPAT11_ACTION(OFPAT11_SET_TP_SRC, ofp_action_tp_port, 0, "mod_tp_src") > OFPAT11_ACTION(OFPAT11_SET_TP_DST, ofp_action_tp_port, 0, "mod_tp_dst") > +OFPAT11_ACTION(OFPAT11_SET_MPLS_LABEL, ofp11_action_mpls_label, 0, > "set_mpls_label") > +OFPAT11_ACTION(OFPAT11_SET_MPLS_TC, ofp11_action_mpls_tc, 0, "set_mpls_tc") > OFPAT11_ACTION(OFPAT11_SET_MPLS_TTL, ofp11_action_mpls_ttl, 0, > "set_mpls_ttl") > OFPAT11_ACTION(OFPAT11_DEC_MPLS_TTL, ofp_action_header, 0, "dec_mpls_ttl") > OFPAT11_ACTION(OFPAT11_PUSH_VLAN, ofp11_action_push, 0, "push_vlan") > @@ -68,6 +70,8 @@ NXAST_ACTION(NXAST_CONTROLLER, nx_action_controller, > 0, "controller") > NXAST_ACTION(NXAST_DEC_TTL_CNT_IDS, nx_action_cnt_ids, 1, NULL) > NXAST_ACTION(NXAST_WRITE_METADATA, nx_action_write_metadata, 0, > "write_metadata") > +NXAST_ACTION(NXAST_SET_MPLS_LABEL, nx_action_mpls_label, 0, > "set_mpls_label") > +NXAST_ACTION(NXAST_SET_MPLS_TC, nx_action_mpls_tc, 0, "set_mpls_tc") > NXAST_ACTION(NXAST_SET_MPLS_TTL, nx_action_mpls_ttl, 0, > "set_mpls_ttl") > 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") > diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c > index 94c7eec..7626dcb 100644 > --- a/ofproto/ofproto-dpif-xlate.c > +++ b/ofproto/ofproto-dpif-xlate.c > @@ -1984,6 +1984,54 @@ compose_dec_ttl(struct xlate_ctx *ctx, struct > ofpact_cnt_ids *ids) > } > > static bool > +compose_set_mpls_label_action(struct xlate_ctx *ctx, ovs_be32 label) > +{ > + if (!eth_type_mpls(ctx->xin->flow.dl_type)) { > + return true; > + } > + > + /* If mpls_depth_delta is negative then an MPLS POP action has been > + * executed and the resulting MPLS label stack is unknown. This means > + * a SET MPLS LABEL action can't be executed as it needs to manipulate > + * the top-most MPLS LSE. Thus, stop processing. > + * > + * It is planned that in the future this case will be handled > + * by recirculation. > + */ > + if (ctx->mpls_depth_delta < 0) { > + return true; > + } > + > + ctx->xout->wc.masks.mpls_lse |= htonl(MPLS_LABEL_MASK); > + set_mpls_lse_label(&ctx->xin->flow.mpls_lse, label); > + return false; > +} > + > +static bool > +compose_set_mpls_tc_action(struct xlate_ctx *ctx, uint8_t tc) > +{ > + if (!eth_type_mpls(ctx->xin->flow.dl_type)) { > + return true; > + } > + > + /* If mpls_depth_delta is negative then an MPLS POP action has been > + * executed and the resulting MPLS label stack is unknown. This means > + * a SET MPLS TC action can't be executed as it needs to manipulate > + * the top-most MPLS LSE. Thus, stop processing. > + * > + * It is planned that in the future this case will be handled > + * by recirculation. > + */ > + if (ctx->mpls_depth_delta < 0) { > + return true; > + } > + > + ctx->xout->wc.masks.mpls_lse |= htonl(MPLS_TC_MASK); > + set_mpls_lse_tc(&ctx->xin->flow.mpls_lse, tc); > + return false; > +} > + > +static bool > compose_set_mpls_ttl_action(struct xlate_ctx *ctx, uint8_t ttl) > { > if (!eth_type_mpls(ctx->xin->flow.dl_type)) { > @@ -2476,6 +2524,20 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t > ofpacts_len, > } > break; > > + case OFPACT_SET_MPLS_LABEL: > + if (compose_set_mpls_label_action(ctx, > + > ofpact_get_SET_MPLS_LABEL(a)->label)) { > + return; > + } > + break; > + > + case OFPACT_SET_MPLS_TC: > + if (compose_set_mpls_tc_action(ctx, > + ofpact_get_SET_MPLS_TC(a)->tc)) { > + return; > + } > + break; > + > case OFPACT_SET_MPLS_TTL: > if (compose_set_mpls_ttl_action(ctx, > > ofpact_get_SET_MPLS_TTL(a)->ttl)) { > diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at > index d503149..530c633 100644 > --- a/tests/ovs-ofctl.at > +++ b/tests/ovs-ofctl.at > @@ -1517,15 +1517,16 @@ dnl Ignore tp_dst if not TCP/UDP/SCTP: > 0000 00 00 0800 00 16 00000000ffffffff 00000000ffffffff 0000 01bb dnl > 00000000 00 000000 0000000000000000ffffffffffffffff > > -dnl mpls_label not yet supported: > -# bad ofp11_match: OFPBMC_BAD_TAG > +# mpls,mpls_label=284280 > +# 64: 12 -> 00 > +# 65: 34 -> 04 > 0000 0058 00000000 000002f7 dnl > 000000000000ffffffffffff 000000000000ffffffffffff dnl > 0000 00 00 8847 00 00 00000000ffffffff 00000000ffffffff 0000 0000 dnl > 12345678 00 000000 0000000000000000ffffffffffffffff > > -dnl mpls_tc not yet supported: > -# bad ofp11_match: OFPBMC_BAD_TAG > +# mplsm,mpls_tc=2 > +# 68: 5a -> 02 > 0000 0058 00000000 000001f7 dnl > 000000000000ffffffffffff 000000000000ffffffffffff dnl > 0000 00 00 8848 00 00 00000000ffffffff 00000000ffffffff 0000 0000 dnl > -- > 1.7.10.4 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev