From 1774d762da192d26f0f1a6176d20358adfe57dd5 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Mon, 16 Mar 2015 17:33:16 -0700 Subject: [PATCH] ofproto-dpif-xlate: Preserve stack across patch port. Prevent a peer patch port bridge from popping data off or pushing data to the stack of the first bridge. Found by inspection. Signed-off-by: Jarno Rajahalme Acked-by: Ben Pfaff --- lib/nx-match.c | 2 +- ofproto/ofproto-dpif-xlate.c | 5 ++++ tests/ofproto-dpif.at | 49 ++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/lib/nx-match.c b/lib/nx-match.c index fd0e0c8bd..721fce526 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -1518,7 +1518,7 @@ nxm_execute_stack_pop(const struct ofpact_stack *pop, } else { if (!VLOG_DROP_WARN(&rl)) { char *flow_str = flow_to_string(flow); - VLOG_WARN_RL(&rl, "Failed to pop from an empty stack. On flow \n" + VLOG_WARN_RL(&rl, "Failed to pop from an empty stack. On flow\n" " %s", flow_str); free(flow_str); } diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index a1928cd80..3691d728b 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -2731,7 +2731,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, struct flow old_flow = ctx->xin->flow; enum slow_path_reason special; uint8_t table_id = rule_dpif_lookup_get_init_table_id(&ctx->xin->flow); + struct ofpbuf old_stack = ctx->stack; + union mf_subvalue new_stack[1024 / sizeof(union mf_subvalue)]; + ofpbuf_use_stub(&ctx->stack, new_stack, sizeof new_stack); ctx->xbridge = peer->xbridge; flow->in_port.ofp_port = peer->ofp_port; flow->metadata = htonll(0); @@ -2763,6 +2766,8 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, ctx->xin->flow = old_flow; ctx->xbridge = xport->xbridge; + ofpbuf_uninit(&ctx->stack); + ctx->stack = old_stack; if (ctx->xin->resubmit_stats) { netdev_vport_inc_tx(xport->netdev, ctx->xin->resubmit_stats); diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 6c396ea78..897df4e62 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -5519,6 +5519,55 @@ OFPST_PORT reply (xid=0x4): 1 ports OVS_VSWITCHD_STOP AT_CLEANUP +AT_SETUP([ofproto-dpif - patch ports - stack]) +OVS_VSWITCHD_START([add-br br1 \ +-- set bridge br1 datapath-type=dummy fail-mode=secure \ +-- add-port br1 pbr1 -- set int pbr1 type=patch options:peer=pbr0 \ +-- add-port br0 pbr0 -- set int pbr0 type=patch options:peer=pbr1]) + +ADD_OF_PORTS([br0], [2]) +ADD_OF_PORTS([br1], [3]) + +AT_CHECK([ovs-appctl upcall/disable-ufid], [0], [Datapath dumping tersely using UFID disabled +], []) +AT_CHECK([ovs-appctl time/stop]) +AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg]) + +AT_CHECK([ovs-ofctl add-flow br0 "ip actions=push:OXM_OF_IN_PORT[[0..31]],output:1,pop:OXM_OF_IPV4_SRC[[0..31]],output:2"]) +# Try to pop from empty stack, and push and leave data to stack. +AT_CHECK([ovs-ofctl add-flow br1 "ip actions=pop:OXM_OF_IPV4_DST[[0..31]],push:NXM_NX_REG1[[0..31]],LOCAL"]) + +ovs-appctl netdev-dummy/receive br0 'in_port(100),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' + +AT_CHECK([ovs-appctl time/warp 500], [0], +[warped +]) + +OVS_WAIT_UNTIL([test `grep flow_add ovs-vswitchd.log | wc -l` -ge 1]) + +AT_CHECK([ovs-appctl dpif/show], [0], [dnl +dummy@ovs-dummy: hit:0 missed:1 + br0: + br0 65534/100: (dummy) + p2 2/2: (dummy) + pbr0 1/none: (patch: peer=pbr1) + br1: + br1 65534/101: (dummy) + p3 3/3: (dummy) + pbr1 1/none: (patch: peer=pbr0) +]) + +AT_CHECK([cat ovs-vswitchd.log | STRIP_UFID | FILTER_FLOW_INSTALL | STRIP_USED], [0], [dnl +recirc_id=0,ip,in_port=100,nw_src=192.168.0.1,nw_frag=no, actions:101,set(ipv4(src=255.255.255.254)),2 +]) + +AT_CHECK([cat ovs-vswitchd.log | grep -e '|nx_match|WARN|' | sed "s/^.*|WARN|//"], [0], [dnl +Failed to pop from an empty stack. On flow +]) + +OVS_VSWITCHD_STOP(["/Failed to pop from an empty stack/d"]) +AT_CLEANUP + AT_SETUP([ofproto-dpif - port duration]) OVS_VSWITCHD_START([set Bridge br0 protocols=OpenFlow13]) ADD_OF_PORTS([br0], 1, 2) -- 2.20.1