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)
{
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;
ospf6_zebra_no_redistribute(arg_type, ospf6->vrf_id);
ospf6_zebra_redistribute(arg_type, ospf6->vrf_id);
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);
}
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);
}
}
}

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,
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);

View File

@ -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). */