]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: inform upper layer error when reading correct speed interface
authorJulien Floret <julien.floret@6wind.com>
Tue, 6 Aug 2019 09:15:05 +0000 (11:15 +0200)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 17 Sep 2019 16:38:42 +0000 (18:38 +0200)
speed interface is done 15 seconds after interface creation. during that
time, the vrf or the interface may have disappeared. to protect this,
return an error in case it is not possible to create a vrf socket or it
is not possible to get speed of an interface because of a missing
device.

Signed-off-by: Julien Floret <julien.floret@6wind.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
zebra/if_netlink.c
zebra/interface.c
zebra/rt.h
zebra/rt_socket.c

index c71b95f753ad894648408b6962691642db21d69b..6aea7e0702203c811d91deb9361069e02c343ac2 100644 (file)
@@ -365,7 +365,7 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb,
        }
 }
 
-static int get_iflink_speed(struct interface *interface)
+static int get_iflink_speed(struct interface *interface, int *error)
 {
        struct ifreq ifdata;
        struct ethtool_cmd ecmd;
@@ -373,6 +373,8 @@ static int get_iflink_speed(struct interface *interface)
        int rc;
        const char *ifname = interface->name;
 
+       if (error)
+               *error = 0;
        /* initialize struct */
        memset(&ifdata, 0, sizeof(ifdata));
 
@@ -393,6 +395,9 @@ static int get_iflink_speed(struct interface *interface)
                        if (IS_ZEBRA_DEBUG_KERNEL)
                                zlog_debug("Failure to read interface %s speed: %d %s",
                                           ifname, errno, safe_strerror(errno));
+                       /* no vrf socket creation may probably mean vrf issue */
+                       if (error)
+                               *error = -1;
                        return 0;
                }
        /* Get the current link state for the interface */
@@ -404,6 +409,9 @@ static int get_iflink_speed(struct interface *interface)
                        zlog_debug(
                                "IOCTL failure to read interface %s speed: %d %s",
                                ifname, errno, safe_strerror(errno));
+               /* no device means interface unreachable */
+               if (errno == ENODEV && error)
+                       *error = -1;
                ecmd.speed_hi = 0;
                ecmd.speed = 0;
        }
@@ -413,9 +421,9 @@ static int get_iflink_speed(struct interface *interface)
        return (ecmd.speed_hi << 16) | ecmd.speed;
 }
 
-uint32_t kernel_get_speed(struct interface *ifp)
+uint32_t kernel_get_speed(struct interface *ifp, int *error)
 {
-       return get_iflink_speed(ifp);
+       return get_iflink_speed(ifp, error);
 }
 
 static int netlink_extract_bridge_info(struct rtattr *link_data,
@@ -696,7 +704,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        ifp->flags = ifi->ifi_flags & 0x0000fffff;
        ifp->mtu6 = ifp->mtu = *(uint32_t *)RTA_DATA(tb[IFLA_MTU]);
        ifp->metric = 0;
-       ifp->speed = get_iflink_speed(ifp);
+       ifp->speed = get_iflink_speed(ifp, NULL);
        ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN;
 
        /* Set zebra interface type */
index 6486c01430c39bc02c1c8e8538053903c4064558..771f05857b0edb0d964a46bf3939eceae36d4e4b 100644 (file)
@@ -70,10 +70,19 @@ static int if_zebra_speed_update(struct thread *thread)
        struct zebra_if *zif = ifp->info;
        uint32_t new_speed;
        bool changed = false;
+       int error = 0;
 
        zif->speed_update = NULL;
 
-       new_speed = kernel_get_speed(ifp);
+       new_speed = kernel_get_speed(ifp, &error);
+
+       /* error may indicate vrf not available or
+        * interfaces not available.
+        * note that loopback & virtual interfaces can return 0 as speed
+        */
+       if (error < 0)
+               return 1;
+
        if (new_speed != ifp->speed) {
                zlog_info("%s: %s old speed: %u new speed: %u",
                          __PRETTY_FUNCTION__, ifp->name, ifp->speed,
index 59b42fed18ff71e9ad163ce405d3ff155e1f3018..f311a6b9d3e40de888adfa36200912e0ad4adcbe 100644 (file)
@@ -66,7 +66,7 @@ extern int kernel_interface_set_master(struct interface *master,
 
 extern int mpls_kernel_init(void);
 
-extern uint32_t kernel_get_speed(struct interface *ifp);
+extern uint32_t kernel_get_speed(struct interface *ifp, int *error);
 extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
 
 /*
index dc0f29bdbc6e9e063fc78abbacfc65ad0aa0a91b..981ef7a889fdfaee8ca33eb20e90bc5a79c185a1 100644 (file)
@@ -396,7 +396,7 @@ extern int kernel_interface_set_master(struct interface *master,
        return 0;
 }
 
-uint32_t kernel_get_speed(struct interface *ifp)
+uint32_t kernel_get_speed(struct interface *ifp, int *error)
 {
        return ifp->speed;
 }