From dc7b3caefbd8baccb7fc3787a774e78d1a96636f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 10 Jan 2018 19:01:57 -0500 Subject: 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 --- zebra/interface.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'zebra/interface.c') diff --git a/zebra/interface.c b/zebra/interface.c index 18588ee52c..906f796136 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -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); } -- cgit v1.2.3 From 4030583f6a80ac9c620937d1d526438bfd881280 Mon Sep 17 00:00:00 2001 From: vivek Date: Sat, 20 Jan 2018 13:21:05 -0800 Subject: zebra: Install connected routes during VRF change only if interface is up During VRF change handling, the connected route for the interface should be installed only if the interface is up. Otherwise, we end up with duplicate connected routes which can lead to other problems. Signed-off-by: Vivek Venkatraman Reviewed-by: Don Slice Ticket: CM-19364 Reviewed By: CCR-7099 Testing Done: Manual verification --- zebra/interface.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'zebra/interface.c') diff --git a/zebra/interface.c b/zebra/interface.c index 906f796136..07570e64bf 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -768,7 +768,8 @@ void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id) zebra_interface_vrf_update_add(ifp, old_vrf_id); /* Install connected routes (in new VRF). */ - if_install_connected(ifp); + if (if_is_operative(ifp)) + if_install_connected(ifp); static_ifindex_update(ifp, true); -- cgit v1.2.3