From 2f43e34de15b61b8e9a8398c18172d9e485e2f2c Mon Sep 17 00:00:00 2001 From: Mobashshera Rasool Date: Wed, 30 Jun 2021 06:13:19 +0000 Subject: [PATCH] ospf6d: route-map config changed, not getting applied on all types of routes Problem Statement: ================== when route-map config is changed from permit to deny, it is not getting applied to both connected and static and vice versa RCA: ================== When route-map changes from permit to deny or vice versa, a notification is sent to ospf6 daemon via ospf6_asbr_routemap_update. In this function, a thread is scheduled after 5 seconds to apply the route-map changes. In this thread (ospf6_asbr_routemap_update_timer), only the first type is passed as argument and only the first type i.e "connected" is passed and hence in callback only on this type of route route-map gets applied. Fix: ==== Need to loop through all the route-types in the call back and process the route-map changes. Added a flag to mark which all route-types needs to be processed. Test Executed: =============== 1. Change route-map from permit to deny. 2. Change route-map from deny to permit. 3. Add new route and checked. 4. Verified summarised routes. Risk: ============ Low Signed-off-by: Mobashshera Rasool --- ospf6d/ospf6_asbr.c | 63 +++++++++++++++++++++++---------------------- ospf6d/ospf6_asbr.h | 3 ++- ospf6d/ospf6_top.h | 3 +++ 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index d7307fe375..315449ae9a 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -1010,53 +1010,55 @@ static void ospf6_asbr_routemap_unset(struct ospf6_redist *red) static int ospf6_asbr_routemap_update_timer(struct thread *thread) { - void **arg; - int arg_type; - struct ospf6 *ospf6; + struct ospf6 *ospf6 = THREAD_ARG(thread); struct ospf6_redist *red; - - arg = THREAD_ARG(thread); - ospf6 = (struct ospf6 *)arg[0]; - arg_type = (int)(intptr_t)arg[1]; + int type; ospf6->t_distribute_update = NULL; - red = ospf6_redist_lookup(ospf6, arg_type, 0); + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + red = ospf6_redist_lookup(ospf6, type, 0); - if (red && ROUTEMAP_NAME(red)) - ROUTEMAP(red) = route_map_lookup_by_name(ROUTEMAP_NAME(red)); - if (red && ROUTEMAP(red)) { - if (IS_OSPF6_DEBUG_ASBR) - zlog_debug("%s: route-map %s update, reset redist %s", - __func__, ROUTEMAP_NAME(red), - ZROUTE_NAME(arg_type)); + if (!red) + continue; + + if (!CHECK_FLAG(red->flag, OSPF6_IS_RMAP_CHANGED)) + continue; + + if (ROUTEMAP_NAME(red)) + ROUTEMAP(red) = + route_map_lookup_by_name(ROUTEMAP_NAME(red)); + + if (ROUTEMAP(red)) { + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug( + "%s: route-map %s update, reset redist %s", + __func__, ROUTEMAP_NAME(red), + ZROUTE_NAME(type)); + + ospf6_zebra_no_redistribute(type, ospf6->vrf_id); + ospf6_zebra_redistribute(type, ospf6->vrf_id); + } - ospf6_zebra_no_redistribute(arg_type, ospf6->vrf_id); - ospf6_zebra_redistribute(arg_type, ospf6->vrf_id); + UNSET_FLAG(red->flag, OSPF6_IS_RMAP_CHANGED); } - XFREE(MTYPE_OSPF6_DIST_ARGS, arg); return 0; } -void ospf6_asbr_distribute_list_update(int type, struct ospf6 *ospf6) +void ospf6_asbr_distribute_list_update(struct ospf6 *ospf6, + struct ospf6_redist *red) { - void **args = NULL; + SET_FLAG(red->flag, OSPF6_IS_RMAP_CHANGED); if (ospf6->t_distribute_update) return; - args = XCALLOC(MTYPE_OSPF6_DIST_ARGS, sizeof(void *) * 2); - - args[0] = ospf6; - args[1] = (void *)((ptrdiff_t)type); - if (IS_OSPF6_DEBUG_ASBR) - zlog_debug("%s: trigger redistribute %s reset thread", __func__, - ZROUTE_NAME(type)); + zlog_debug("%s: trigger redistribute reset thread", __func__); ospf6->t_distribute_update = NULL; - thread_add_timer_msec(master, ospf6_asbr_routemap_update_timer, args, + thread_add_timer_msec(master, ospf6_asbr_routemap_update_timer, ospf6, OSPF_MIN_LS_INTERVAL, &ospf6->t_distribute_update); } @@ -1092,8 +1094,7 @@ void ospf6_asbr_routemap_update(const char *mapname) type)); route_map_counter_increment(ROUTEMAP(red)); - - ospf6_asbr_distribute_list_update(type, ospf6); + ospf6_asbr_distribute_list_update(ospf6, red); } else { /* * if the mapname matches a @@ -1131,7 +1132,7 @@ static void ospf6_asbr_routemap_event(const char *name) red = ospf6_redist_lookup(ospf6, type, 0); if (red && ROUTEMAP_NAME(red) && (strcmp(ROUTEMAP_NAME(red), name) == 0)) - ospf6_asbr_distribute_list_update(type, ospf6); + ospf6_asbr_distribute_list_update(ospf6, red); } } } diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index 8f2135ef30..7ccd1c992b 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -105,7 +105,8 @@ extern void install_element_ospf6_debug_asbr(void); extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, struct ospf6_route *route, struct ospf6 *ospf6); -extern void ospf6_asbr_distribute_list_update(int type, struct ospf6 *ospf6); +extern void ospf6_asbr_distribute_list_update(struct ospf6 *ospf6, + struct ospf6_redist *red); struct ospf6_redist *ospf6_redist_lookup(struct ospf6 *ospf6, int type, unsigned short instance); extern void ospf6_asbr_routemap_update(const char *mapname); diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 51df4b6b8e..7720b222c0 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -38,9 +38,12 @@ enum { OSPF6_LOG_ADJACENCY_DETAIL = (1 << 1), }; +/* For processing route-map change update in the callback */ +#define OSPF6_IS_RMAP_CHANGED 0x01 struct ospf6_redist { uint8_t instance; + uint8_t flag; /* Redistribute metric info. */ struct { int type; /* External metric type (E1 or E2). */ -- 2.39.5