mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 20:55:25 +00:00
zebra: Add one-shot thread to recheck speed
There are certain interfaces that when brought up and we receive the netlink notification about it, the speed of the interface is not set correctly. This creates a one-shot thread that will wait 15 seconds and then requery the speed and if it is different it will renotify the running daemons. The kernel should notify us on speed changes, unfortunately this is not done currently via a netlink message as you would think. As I understand it there is some in-fighting about the proper way to approach this issue and due to the way the kernel release cycle works we are a ways off from getting this fixed. This is a `hack` to make us work correctly while we wait for the true answer. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
c1240044fb
commit
dc7b3caefb
@ -387,6 +387,11 @@ static int get_iflink_speed(const char *ifname)
|
||||
return (ecmd.speed_hi << 16) | ecmd.speed;
|
||||
}
|
||||
|
||||
uint32_t kernel_get_speed(struct interface *ifp)
|
||||
{
|
||||
return get_iflink_speed(ifp->name);
|
||||
}
|
||||
|
||||
static int netlink_extract_bridge_info(struct rtattr *link_data,
|
||||
struct zebra_l2info_bridge *bridge_info)
|
||||
{
|
||||
|
@ -57,8 +57,29 @@ DEFINE_HOOK(zebra_if_extra_info, (struct vty *vty, struct interface *ifp),
|
||||
DEFINE_HOOK(zebra_if_config_wr, (struct vty *vty, struct interface *ifp),
|
||||
(vty, ifp))
|
||||
|
||||
|
||||
static void if_down_del_nbr_connected(struct interface *ifp);
|
||||
|
||||
static int if_zebra_speed_update(struct thread *thread)
|
||||
{
|
||||
struct interface *ifp = THREAD_ARG(thread);
|
||||
struct zebra_if *zif = ifp->info;
|
||||
uint32_t new_speed;
|
||||
|
||||
zif->speed_update = NULL;
|
||||
|
||||
new_speed = kernel_get_speed(ifp);
|
||||
if (new_speed != ifp->speed) {
|
||||
zlog_info("%s: %s old speed: %u new speed: %u",
|
||||
__PRETTY_FUNCTION__, ifp->name,
|
||||
ifp->speed, new_speed);
|
||||
ifp->speed = new_speed;
|
||||
if_add_update(ifp);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void zebra_if_node_destroy(route_table_delegate_t *delegate,
|
||||
struct route_table *table,
|
||||
struct route_node *node)
|
||||
@ -119,6 +140,16 @@ static int if_zebra_new_hook(struct interface *ifp)
|
||||
route_table_init_with_delegate(&zebra_if_table_delegate);
|
||||
|
||||
ifp->info = zebra_if;
|
||||
|
||||
/*
|
||||
* Some platforms are telling us that the interface is
|
||||
* up and ready to go. When we check the speed we
|
||||
* sometimes get the wrong value. Wait a couple
|
||||
* of seconds and ask again. Hopefully it's all settled
|
||||
* down upon startup.
|
||||
*/
|
||||
thread_add_timer(zebrad.master, if_zebra_speed_update,
|
||||
ifp, 15, &zebra_if->speed_update);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -141,6 +172,8 @@ static int if_zebra_delete_hook(struct interface *ifp)
|
||||
list_delete_and_null(&rtadv->AdvPrefixList);
|
||||
#endif /* HAVE_RTADV */
|
||||
|
||||
THREAD_OFF(zebra_if->speed_update);
|
||||
|
||||
XFREE(MTYPE_TMP, zebra_if);
|
||||
}
|
||||
|
||||
|
@ -273,6 +273,8 @@ struct zebra_if {
|
||||
/* Link fields - for sub-interfaces. */
|
||||
ifindex_t link_ifindex;
|
||||
struct interface *link;
|
||||
|
||||
struct thread *speed_update;
|
||||
};
|
||||
|
||||
DECLARE_HOOK(zebra_if_extra_info, (struct vty *vty, struct interface *ifp),
|
||||
|
@ -98,6 +98,7 @@ extern void kernel_lsp_pass_fail(zebra_lsp_t *lsp,
|
||||
|
||||
extern int mpls_kernel_init(void);
|
||||
|
||||
extern uint32_t kernel_get_speed(struct interface *ifp);
|
||||
extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute);
|
||||
extern int kernel_add_vtep(vni_t vni, struct interface *ifp,
|
||||
struct in_addr *vtep_ip);
|
||||
|
@ -473,4 +473,9 @@ extern int kernel_interface_set_master(struct interface *master,
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t kernel_get_speed(struct interface *ifp)
|
||||
{
|
||||
return ifp->speed;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_NETLINK */
|
||||
|
Loading…
Reference in New Issue
Block a user