diff mbox series

[ovs-dev] ofproto-dpif-xlate: Fix recirculation with patch port and controller.

Message ID 168416411341.7139.6924271138928930871.stgit@rawp
State Superseded
Headers show
Series [ovs-dev] ofproto-dpif-xlate: Fix recirculation with patch port and controller. | expand

Checks

Context Check Description
ovsrobot/apply-robot warning apply and check: warning
ovsrobot/github-robot-_Build_and_Test fail github build: failed
ovsrobot/intel-ovs-compilation success test: success

Commit Message

Paolo Valerio May 15, 2023, 3:21 p.m. UTC
If a packet originating from the controller recirculates after going
through a patch port, it gets dropped with the following message:

ofproto_dpif_upcall(handler8)|INFO|received packet on unassociated
  datapath port 4294967295

This happens because there's no xport_uuid in the recirculation node
and at the same type in_port refers to the patch port.

The patch, in the case of zeroed uuid, retrieves the xport starting
from the ofproto_uuid stored in the recirc node.

Signed-off-by: Paolo Valerio <pvalerio@redhat.com>
---
 ofproto/ofproto-dpif-xlate.c |   11 +++++++++--
 tests/ofproto-dpif.at        |   34 ++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index c01177718..3509cc73c 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -1533,8 +1533,15 @@  xlate_lookup_ofproto_(const struct dpif_backer *backer,
 
         ofp_port_t in_port = recirc_id_node->state.metadata.in_port;
         if (in_port != OFPP_NONE && in_port != OFPP_CONTROLLER) {
-            struct uuid xport_uuid = recirc_id_node->state.xport_uuid;
-            xport = xport_lookup_by_uuid(xcfg, &xport_uuid);
+            if (uuid_is_zero(&recirc_id_node->state.xport_uuid)) {
+                const struct xbridge *bridge =
+                    xbridge_lookup_by_uuid(xcfg, &recirc_id_node->state.ofproto_uuid);
+                xport = bridge ? get_ofp_port(bridge, in_port) : NULL;
+            } else {
+                struct uuid xport_uuid = recirc_id_node->state.xport_uuid;
+                xport = xport_lookup_by_uuid(xcfg, &xport_uuid);
+            }
+
             if (xport && xport->xbridge && xport->xbridge->ofproto) {
                 goto out;
             }
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 6824ce0bb..8b9447c74 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -5854,6 +5854,40 @@  OVS_WAIT_UNTIL([check_flows], [ovs-ofctl dump-flows br0])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+# Checks for regression against a bug in which OVS dropped packets
+# originating from the the controller passing through a patch port
+AT_SETUP([ofproto-dpif - packet-out recirculation OFPP_CONTROLLER and patch port])
+OVS_VSWITCHD_START(
+    [add-port br0 patch-br1 -- \
+     set interface patch-br1 type=patch options:peer=patch-br0 -- \
+     add-br br1 -- set bridge br1 datapath-type=dummy fail-mode=secure -- \
+     add-port br1 patch-br0 -- set interface patch-br0 type=patch options:peer=patch-br1
+])
+
+add_of_ports --pcap br1 1
+
+AT_DATA([flows-br0.txt], [dnl
+table=0 icmp actions=output:patch-br1
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows-br0.txt])
+
+AT_DATA([flows-br1.txt], [dnl
+table=0, icmp actions=ct(table=1,zone=1)
+table=1, ct_state=+trk, icmp actions=p1
+])
+AT_CHECK([ovs-ofctl add-flows br1 flows-br1.txt])
+
+packet=50540000000750540000000508004500005c000000008001b94dc0a80001c0a80002080013fc00000000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f
+AT_CHECK([ovs-ofctl packet-out br0 "in_port=controller packet=$packet actions=table"])
+
+OVS_WAIT_UNTIL_EQUAL([ovs-ofctl dump-flows -m br1 | grep "ct_state" | ofctl_strip], [dnl
+ table=1, n_packets=1, n_bytes=106, ct_state=+trk,icmp actions=output:2])
+
+OVS_WAIT_UNTIL([ovs-pcap p1-tx.pcap | grep -q "$packet"])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 AT_SETUP([ofproto-dpif - debug_slow action])
 OVS_VSWITCHD_START
 add_of_ports br0 1 2 3