ofproto-dpif-xlate: Preserve stack across patch port.
authorJarno Rajahalme <jrajahalme@nicira.com>
Tue, 17 Mar 2015 00:33:16 +0000 (17:33 -0700)
committerJarno Rajahalme <jrajahalme@nicira.com>
Tue, 17 Mar 2015 00:33:16 +0000 (17:33 -0700)
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 <jrajahalme@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
lib/nx-match.c
ofproto/ofproto-dpif-xlate.c
tests/ofproto-dpif.at

index fd0e0c8..721fce5 100644 (file)
@@ -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);
         }
index a1928cd..3691d72 100644 (file)
@@ -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);
index 6c396ea..897df4e 100644 (file)
@@ -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)