}
}
-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;
int rc;
const char *ifname = interface->name;
+ if (error)
+ *error = 0;
/* initialize struct */
memset(&ifdata, 0, sizeof(ifdata));
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 */
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;
}
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,
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 */
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,
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);
/*