When system devices (like veth pairs) are used with userspace datapaths,
dpif_netlink_vport_get() fails with ENODEV instead of ENOENT because
these devices are not vports.

Previously, only ENOENT was treated as an indicator that the device
is in the local namespace. With ENODEV errors, the netns ID remained
NETNSID_UNSET.
This prevented RTM_NEWLINK/RTM_DELLINK events from being processed,
as these events arrive with nsid set to NETNSID_LOCAL.

This commit add a similar fallback for ENODEV as how ENOENT is treated
in netdev_linux_netnsid_update__(), i.e. assuming the netns ID is
NETNSID_LOCAL for system devices.

This ensures RTM events are properly processed for system devices as
well and ensures the possibility of cache invalidation on device removal.

Signed-off-by: Matteo Perin <[email protected]>
---
This approach to make sure the cache is invalidated on veth (and, in general,
system devices) is triggered might probably be too generic.
I found some alternatives but they are quite disruptive and require to
actively lookup the netns the veth is in.

If needed, we could add this lookup in this same place, but then we would
also need to do the same for the device type if we want to limit this behavior
to veths, since we do not have the information at this time yet.

An alternative would be to act when the netdev_linux_update is called, but this
does not seem a very scalable solution.

Of course, I will be really interested in discussing any further alternatives.

 lib/netdev-linux.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index f4d2685a2..879f333cd 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -595,9 +595,9 @@ netdev_linux_netnsid_update__(struct netdev_linux *netdev)
 
     error = dpif_netlink_vport_get(netdev_get_name(&netdev->up), &reply, &buf);
     if (error) {
-        if (error == ENOENT) {
+        if (error == ENOENT || error == ENODEV) {
             /* Assume it is local if there is no API (e.g. if the openvswitch
-             * kernel module is not loaded). */
+             * kernel module is not loaded) or if the device is not a vport. */
             netnsid_set_local(&netdev->netnsid);
         } else {
             netnsid_unset(&netdev->netnsid);
-- 
2.43.0

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

Reply via email to