Traces should not modify the flow table without the a packet or "-generate" option.
This patch also adds further testing to verify that MPLS recirculation works. Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- ofproto/ofproto-dpif-xlate.c | 59 ++++++++++++++++++++++++------------------ tests/mpls-xlate.at | 14 ++++++++-- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 1133a06..3f866ce 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3255,16 +3255,9 @@ compose_recirculate_action(struct xlate_ctx *ctx, { uint32_t id; int error; - unsigned ofpacts_len; - struct match match; - struct rule *rule; - struct ofpbuf ofpacts; ctx->exit = true; - ofpacts_len = ofpacts_base_len - - ((uint8_t *)ofpact_current - (uint8_t *)ofpacts_base); - if (ctx->rule) { id = rule_dpif_get_recirc_id(ctx->rule); } else { @@ -3283,26 +3276,37 @@ compose_recirculate_action(struct xlate_ctx *ctx, return; } - match_init_catchall(&match); - match_set_recirc_id(&match, id); - ofpbuf_use_const(&ofpacts, ofpact_current, ofpacts_len); - error = ofproto_dpif_add_internal_flow(ctx->xbridge->ofproto, &match, - RECIRC_RULE_PRIORITY, - RECIRC_TIMEOUT, &ofpacts, &rule); - if (error) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); - VLOG_ERR_RL(&rl, "Failed to add post recirculation flow %s", - match_to_string(&match, 0)); + /* Only create the recirculation flow if we have a packet. */ + if (ctx->xin->packet) { + struct match match; + struct rule *rule; + unsigned ofpacts_len; + struct ofpbuf ofpacts; + + ofpacts_len = ofpacts_base_len - + ((uint8_t *)ofpact_current - (uint8_t *)ofpacts_base); + + match_init_catchall(&match); + match_set_recirc_id(&match, id); + ofpbuf_use_const(&ofpacts, ofpact_current, ofpacts_len); + error = ofproto_dpif_add_internal_flow(ctx->xbridge->ofproto, &match, + RECIRC_RULE_PRIORITY, + RECIRC_TIMEOUT, &ofpacts, &rule); + if (error) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + VLOG_ERR_RL(&rl, "Failed to add post recirculation flow %s", + match_to_string(&match, 0)); + if (!ctx->rule) { + ofproto_dpif_free_recirc_id(ctx->xbridge->ofproto, id); + } + return; + } + /* If ctx has no rule then associate the recirc id, which + * was allocated above, with the internal rule. This allows + * the recirc id to be released when the internal rule times out. */ if (!ctx->rule) { - ofproto_dpif_free_recirc_id(ctx->xbridge->ofproto, id); + rule_set_recirc_id(rule, id); } - return; - } - /* If ctx has no rule then associate the recirc id, which - * was allocated above, with the internal rule. This allows - * the recirc id to be released when the internal rule times out. */ - if (!ctx->rule) { - rule_set_recirc_id(rule, id); } ctx->xout->slow |= commit_odp_actions(&ctx->xin->flow, &ctx->base_flow, @@ -3310,6 +3314,11 @@ compose_recirculate_action(struct xlate_ctx *ctx, &ctx->xout->wc, ctx->xbridge->masked_set_action); nl_msg_put_u32(ctx->xout->odp_actions, OVS_ACTION_ATTR_RECIRC, id); + + /* Free recirc id if it was not associated with any rule. */ + if (!ctx->rule && !ctx->xin->packet) { + ofproto_dpif_free_recirc_id(ctx->xbridge->ofproto, id); + } } static void diff --git a/tests/mpls-xlate.at b/tests/mpls-xlate.at index e2ef2e7..47e6680 100644 --- a/tests/mpls-xlate.at +++ b/tests/mpls-xlate.at @@ -32,7 +32,7 @@ AT_CHECK([ovs-ofctl del-flows br0]) AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 in_port=local,dl_type=0x0800,action=push_mpls:0x8847,set_field:10-\>mpls_label,push_mpls:0x8847,set_field:20-\>mpls_label,output:1]) AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 table=0,dl_type=0x8847,in_port=1,mpls_label=60,action=pop_mpls:0x8847,goto_table:1]) -AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 table=1,dl_type=0x8847,in_port=1,mpls_label=50,action=pop_mpls:0x0800,output:LOCAL]) +AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 table=1,dl_type=0x8847,in_port=1,mpls_label=50,action=pop_mpls:0x0800,set_field:10-\>nw_ttl,output:LOCAL]) dnl Double MPLS push AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(100),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout]) @@ -41,10 +41,20 @@ AT_CHECK([tail -1 stdout], [0], ]) dnl Double MPLS pop -AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x8847),mpls(label=60,tc=0/0,ttl=64,bos=0)'], [0], [stdout]) +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x8847),mpls(label=60,tc=0/0,ttl=64,bos=0)' -generate], [0], [stdout]) AT_CHECK([tail -1 stdout], [0], [Datapath actions: pop_mpls(eth_type=0x8847),recirc(300) ]) +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(300),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x8847),mpls(label=50,tc=0/0,ttl=64,bos=0)' -generate], [0], [stdout]) +AT_CHECK([tail -1 stdout], [0], + [Datapath actions: pop_mpls(eth_type=0x800),recirc(301) +]) + +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(301),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)' -generate], [0], [stdout]) +AT_CHECK([tail -1 stdout], [0], + [Datapath actions: set(ipv4(ttl=10)),100 +]) + OVS_VSWITCHD_STOP AT_CLEANUP -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev