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 <mrasool@vmware.com>
This commit is contained in:
Mobashshera Rasool 2021-06-30 06:13:19 +00:00
parent 309f6af605
commit 2f43e34de1
3 changed files with 37 additions and 32 deletions

View File

@ -1010,53 +1010,55 @@ static void ospf6_asbr_routemap_unset(struct ospf6_redist *red)
static int ospf6_asbr_routemap_update_timer(struct thread *thread) static int ospf6_asbr_routemap_update_timer(struct thread *thread)
{ {
void **arg; struct ospf6 *ospf6 = THREAD_ARG(thread);
int arg_type;
struct ospf6 *ospf6;
struct ospf6_redist *red; struct ospf6_redist *red;
int type;
arg = THREAD_ARG(thread);
ospf6 = (struct ospf6 *)arg[0];
arg_type = (int)(intptr_t)arg[1];
ospf6->t_distribute_update = NULL; 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)) if (!red)
ROUTEMAP(red) = route_map_lookup_by_name(ROUTEMAP_NAME(red)); continue;
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));
ospf6_zebra_no_redistribute(arg_type, ospf6->vrf_id); if (!CHECK_FLAG(red->flag, OSPF6_IS_RMAP_CHANGED))
ospf6_zebra_redistribute(arg_type, ospf6->vrf_id); 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);
}
UNSET_FLAG(red->flag, OSPF6_IS_RMAP_CHANGED);
} }
XFREE(MTYPE_OSPF6_DIST_ARGS, arg);
return 0; 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) if (ospf6->t_distribute_update)
return; return;
args = XCALLOC(MTYPE_OSPF6_DIST_ARGS, sizeof(void *) * 2);
args[0] = ospf6;
args[1] = (void *)((ptrdiff_t)type);
if (IS_OSPF6_DEBUG_ASBR) if (IS_OSPF6_DEBUG_ASBR)
zlog_debug("%s: trigger redistribute %s reset thread", __func__, zlog_debug("%s: trigger redistribute reset thread", __func__);
ZROUTE_NAME(type));
ospf6->t_distribute_update = NULL; 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, OSPF_MIN_LS_INTERVAL,
&ospf6->t_distribute_update); &ospf6->t_distribute_update);
} }
@ -1092,8 +1094,7 @@ void ospf6_asbr_routemap_update(const char *mapname)
type)); type));
route_map_counter_increment(ROUTEMAP(red)); route_map_counter_increment(ROUTEMAP(red));
ospf6_asbr_distribute_list_update(ospf6, red);
ospf6_asbr_distribute_list_update(type, ospf6);
} else { } else {
/* /*
* if the mapname matches a * 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); red = ospf6_redist_lookup(ospf6, type, 0);
if (red && ROUTEMAP_NAME(red) if (red && ROUTEMAP_NAME(red)
&& (strcmp(ROUTEMAP_NAME(red), name) == 0)) && (strcmp(ROUTEMAP_NAME(red), name) == 0))
ospf6_asbr_distribute_list_update(type, ospf6); ospf6_asbr_distribute_list_update(ospf6, red);
} }
} }
} }

View File

@ -105,7 +105,8 @@ extern void install_element_ospf6_debug_asbr(void);
extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
struct ospf6_route *route, struct ospf6_route *route,
struct ospf6 *ospf6); 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, struct ospf6_redist *ospf6_redist_lookup(struct ospf6 *ospf6, int type,
unsigned short instance); unsigned short instance);
extern void ospf6_asbr_routemap_update(const char *mapname); extern void ospf6_asbr_routemap_update(const char *mapname);

View File

@ -38,9 +38,12 @@ enum {
OSPF6_LOG_ADJACENCY_DETAIL = (1 << 1), OSPF6_LOG_ADJACENCY_DETAIL = (1 << 1),
}; };
/* For processing route-map change update in the callback */
#define OSPF6_IS_RMAP_CHANGED 0x01
struct ospf6_redist { struct ospf6_redist {
uint8_t instance; uint8_t instance;
uint8_t flag;
/* Redistribute metric info. */ /* Redistribute metric info. */
struct { struct {
int type; /* External metric type (E1 or E2). */ int type; /* External metric type (E1 or E2). */