]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Allow tunneldump data to work properly on non-supported kernels 12060/head
authorDonald Sharp <sharpd@nvidia.com>
Tue, 4 Oct 2022 12:51:38 +0000 (08:51 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Tue, 4 Oct 2022 19:05:44 +0000 (15:05 -0400)
When zebra requests tunnel data it is sending a RTM_GETTUNNEL per
interface that is a VXLAN tunnel.  If the kernel that is being
used does not support the particular request type then zebra
will get a error message per tunnel request back.  Unfortunately
netlink_parse_info *stops* reading on the first error message.
Therefor one kernels that are returning an error message
let's gather all of those errors.  This will allow things
like route reads to actually work properly

Fixes: #12056
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
zebra/if_netlink.c

index 0927bdc1d9ec8676c0c7851fd822d8a2d6e7e7ba..b28c468a969dcb268f7a206895ba1fe7866a5adb 100644 (file)
@@ -1182,13 +1182,19 @@ int interface_lookup_netlink(struct zebra_ns *zns)
        if (ret < 0)
                return ret;
 
+       /*
+        * So netlink_tunneldump_read will initiate a request
+        * per tunnel to get data.  If we are on a kernel that
+        * does not support this then we will get X error messages
+        * (one per tunnel request )back which netlink_parse_info will
+        * stop after the first one.  So we need to read equivalent
+        * error messages per tunnel then we can continue.
+        * if we do not gather all the read failures then
+        * later requests will not work right.
+        */
        ret = netlink_tunneldump_read(zns);
        if (ret < 0)
                return ret;
-       ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0,
-                                true);
-       if (ret < 0)
-               return ret;
 
        /* fixup linkages */
        zebra_if_update_all_links(zns);
@@ -2322,6 +2328,7 @@ int netlink_tunneldump_read(struct zebra_ns *zns)
        struct route_node *rn;
        struct interface *tmp_if = NULL;
        struct zebra_if *zif;
+       struct nlsock *netlink_cmd = &zns->netlink_cmd;
 
        zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/);
 
@@ -2337,7 +2344,14 @@ int netlink_tunneldump_read(struct zebra_ns *zns)
                                                 tmp_if->ifindex);
                if (ret < 0)
                        return ret;
+
+               ret = netlink_parse_info(netlink_interface, netlink_cmd,
+                                        &dp_info, 0, true);
+
+               if (ret < 0)
+                       return ret;
        }
+
        return 0;
 }
 #endif /* GNU_LINUX */