Patch ports are implemented entirely in userspace and are never
added to the datapath.  During vswitchd restart, construct() would
call dpif_port_exists() for every port from iface_hints, including
patch ports.  With the kernel datapath, this could either collide
with an unrelated kernel device of the same name, or fail with
EINVAL if the name exceeds IFNAMSIZ.

Use the interface type from iface_hint to skip the dpif query for
patch ports.

Also filter out patch ports in process_dpif_all_ports_changed(),
which collects all ofport names and queries the datapath for each.

Signed-off-by: Reuven Plevinsky <[email protected]>
---
 ofproto/ofproto-dpif.c    |  8 ++++++--
 tests/system-interface.at | 24 ++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 06e966503ae6..729bc6f1d4ac 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -573,7 +573,10 @@ process_dpif_all_ports_changed(struct dpif_backer *backer)
             struct ofport *ofport;
 
             HMAP_FOR_EACH (ofport, hmap_node, &ofproto->up.ports) {
-                sset_add(&devnames, netdev_get_name(ofport->netdev));
+                /* Patch ports are not in the datapath. */
+                if (!netdev_vport_is_patch(ofport->netdev)) {
+                    sset_add(&devnames, netdev_get_name(ofport->netdev));
+                }
             }
         }
     }
@@ -1833,7 +1836,8 @@ construct(struct ofproto *ofproto_)
 
         if (!strcmp(iface_hint->br_name, ofproto->up.name)) {
             /* Check if the datapath already has this port. */
-            if (dpif_port_exists(ofproto->backer->dpif, node->name)) {
+            if (strcmp(iface_hint->iface_type, "patch")
+                && dpif_port_exists(ofproto->backer->dpif, node->name)) {
                 sset_add(&ofproto->ports, node->name);
             }
 
diff --git a/tests/system-interface.at b/tests/system-interface.at
index 20a882d1cfe6..640bfd638fb7 100644
--- a/tests/system-interface.at
+++ b/tests/system-interface.at
@@ -231,3 +231,27 @@ AT_CHECK([grep 'name too long' stderr], [0], [ignore])
 
 OVS_TRAFFIC_VSWITCHD_STOP(["/could not open network device.*name too long/d"])
 AT_CLEANUP
+
+AT_SETUP([interface - patch port name exceeds IFNAMSIZ on vswitchd restart])
+
+OVS_TRAFFIC_VSWITCHD_START()
+
+dnl Kernel datapath only.
+AT_SKIP_IF([! ovs-appctl dpctl/show | grep -q ovs-system])
+
+AT_CHECK([ovs-vsctl -- \
+          add-br br1 -- set bridge br1 fail-mode=secure \
+          -- add-port br0 long_patch_peer_one \
+          -- set interface long_patch_peer_one type=patch \
+          options:peer=long_patch_peer_two \
+          -- add-port br1 long_patch_peer_two \
+          -- set interface long_patch_peer_two type=patch \
+          options:peer=long_patch_peer_one])
+
+dnl Restart ovs-vswitchd. The test will fail if any warnings are detected in 
logs.
+OVS_APP_EXIT_AND_WAIT([ovs-vswitchd])
+AT_CHECK([ovs-vswitchd --detach --no-chdir --pidfile --log-file -vvconn 
-vofproto_dpif -vunixctl],
+         [0], [], [stderr])
+
+OVS_TRAFFIC_VSWITCHD_STOP
+AT_CLEANUP
-- 
2.43.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to