mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 02:46:26 +00:00
zebra: inform upper layer error when reading correct speed interface
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>
This commit is contained in:
parent
215e03fe53
commit
594c287816
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user