ospf6d: Fix redist w/ route-map during restart

Add hook for route-map update event.
Add a delay one shot timer to accomodate route-map
update and reset redist with zebra to process
all redistribute routes with route-map info.

Cleanup route-map, prefix cached date during ospf6 exit.

Ticket:CM-13800
Testing Done:
configure redistribute connected with route-map to define
type-2 routes. Restart frr.service and validated
route-map add,update event, thread is scheduled,
once timer is done redist reset with zebra.
Upon redist add notification, all route map info is cached
in ospf6 and processed as type-2 route and send ASE E2 LSA.

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
This commit is contained in:
Chirag Shah 2018-01-24 19:02:19 -08:00
parent 439a309e83
commit 856ae1eb2e
7 changed files with 89 additions and 6 deletions

View File

@ -618,6 +618,56 @@ static void ospf6_asbr_routemap_unset(int type)
ospf6->rmap[type].map = NULL;
}
static int ospf6_asbr_routemap_update_timer(struct thread *thread)
{
void **arg;
int arg_type;
arg = THREAD_ARG(thread);
arg_type = (int)(intptr_t)arg[1];
ospf6->t_distribute_update = NULL;
if (ospf6->rmap[arg_type].name)
ospf6->rmap[arg_type].map = route_map_lookup_by_name(
ospf6->rmap[arg_type].name);
if (ospf6->rmap[arg_type].map) {
if (IS_OSPF6_DEBUG_ASBR)
zlog_debug("%s: route-map %s update, reset redist %s",
__PRETTY_FUNCTION__,
ospf6->rmap[arg_type].name,
ZROUTE_NAME(arg_type));
ospf6_zebra_no_redistribute(arg_type);
ospf6_zebra_redistribute(arg_type);
}
XFREE(MTYPE_OSPF6_DIST_ARGS, arg);
return 0;
}
void ospf6_asbr_distribute_list_update(int type)
{
void **args = NULL;
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",
__PRETTY_FUNCTION__, ZROUTE_NAME(type));
ospf6->t_distribute_update = NULL;
thread_add_timer_msec(master, ospf6_asbr_routemap_update_timer,
(void **)args, OSPF_MIN_LS_INTERVAL,
&ospf6->t_distribute_update);
}
static void ospf6_asbr_routemap_update(const char *mapname)
{
int type;
@ -636,15 +686,27 @@ static void ospf6_asbr_routemap_update(const char *mapname)
zlog_debug("%s: route-map %s update, reset redist %s",
__PRETTY_FUNCTION__, mapname,
ZROUTE_NAME(type));
ospf6_zebra_no_redistribute(type);
ospf6_zebra_redistribute(type);
ospf6_asbr_distribute_list_update(type);
}
} else
ospf6->rmap[type].map = NULL;
}
}
static void ospf6_asbr_routemap_event(route_map_event_t event, const char *name)
{
int type;
if (ospf6 == NULL)
return;
for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
if ((ospf6->rmap[type].name) &&
(strcmp(ospf6->rmap[type].name, name) == 0)) {
ospf6_asbr_distribute_list_update(type);
}
}
}
int ospf6_asbr_is_asbr(struct ospf6 *o)
{
return o->external_table->count;
@ -745,7 +807,6 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
match = ospf6_route_lookup(prefix, ospf6->external_table);
if (match) {
info = match->route_option;
/* copy result of route-map */
if (ospf6->rmap[type].map) {
if (troute.path.metric_type)
@ -779,7 +840,9 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
if (IS_OSPF6_DEBUG_ASBR) {
inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf,
sizeof(ibuf));
zlog_debug("Advertise as AS-External Id:%s", ibuf);
prefix2str(prefix, pbuf, sizeof(pbuf));
zlog_debug("Advertise as AS-External Id:%s prefix %s metric %u",
ibuf, pbuf, match->path.metric_type);
}
match->path.origin.id = htonl(info->id);
@ -830,7 +893,9 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
if (IS_OSPF6_DEBUG_ASBR) {
inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf));
zlog_debug("Advertise as AS-External Id:%s", ibuf);
prefix2str(prefix, pbuf, sizeof(pbuf));
zlog_debug("Advertise as AS-External Id:%s prefix %s metric %u",
ibuf, pbuf, route->path.metric_type);
}
route->path.origin.id = htonl(info->id);
@ -1339,6 +1404,7 @@ static void ospf6_routemap_init(void)
route_map_add_hook(ospf6_asbr_routemap_update);
route_map_delete_hook(ospf6_asbr_routemap_update);
route_map_event_hook(ospf6_asbr_routemap_event);
route_map_set_metric_hook(generic_set_add);
route_map_no_set_metric_hook(generic_set_delete);
@ -1538,6 +1604,10 @@ void ospf6_asbr_redistribute_reset(void)
void ospf6_asbr_terminate(void)
{
/* Cleanup route maps */
route_map_add_hook(NULL);
route_map_delete_hook(NULL);
route_map_event_hook(NULL);
route_map_finish();
}

View File

@ -95,5 +95,6 @@ extern int config_write_ospf6_debug_asbr(struct vty *vty);
extern void install_element_ospf6_debug_asbr(void);
extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
struct ospf6_route *route);
extern void ospf6_asbr_distribute_list_update(int type);
#endif /* OSPF6_ASBR_H */

View File

@ -97,6 +97,14 @@ static void __attribute__((noreturn)) ospf6_exit(int status)
ospf6_asbr_terminate();
ospf6_lsa_terminate();
/* reverse access_list_init */
access_list_reset();
/* reverse prefix_list_init */
prefix_list_add_hook(NULL);
prefix_list_delete_hook(NULL);
prefix_list_reset();
vrf_terminate();
if (zclient) {

View File

@ -42,4 +42,5 @@ DEFINE_MTYPE(OSPF6D, OSPF6_SPFTREE, "OSPF6 SPF tree")
DEFINE_MTYPE(OSPF6D, OSPF6_NEXTHOP, "OSPF6 nexthop")
DEFINE_MTYPE(OSPF6D, OSPF6_EXTERNAL_INFO, "OSPF6 ext. info")
DEFINE_MTYPE(OSPF6D, OSPF6_PATH, "OSPF6 Path")
DEFINE_MTYPE(OSPF6D, OSPF6_DIST_ARGS, "OSPF6 Distribute arguments")
DEFINE_MTYPE(OSPF6D, OSPF6_OTHER, "OSPF6 other")

View File

@ -41,6 +41,7 @@ DECLARE_MTYPE(OSPF6_SPFTREE)
DECLARE_MTYPE(OSPF6_NEXTHOP)
DECLARE_MTYPE(OSPF6_EXTERNAL_INFO)
DECLARE_MTYPE(OSPF6_PATH)
DECLARE_MTYPE(OSPF6_DIST_ARGS)
DECLARE_MTYPE(OSPF6_OTHER)
#endif /* _QUAGGA_OSPF6_MEMORY_H */

View File

@ -224,6 +224,7 @@ static void ospf6_disable(struct ospf6 *o)
THREAD_OFF(o->maxage_remover);
THREAD_OFF(o->t_spf_calc);
THREAD_OFF(o->t_ase_calc);
THREAD_OFF(o->t_distribute_update);
}
}

View File

@ -82,6 +82,7 @@ struct ospf6 {
struct thread *t_spf_calc; /* SPF calculation timer. */
struct thread *t_ase_calc; /* ASE calculation timer. */
struct thread *maxage_remover;
struct thread *t_distribute_update; /* Distirbute update timer. */
u_int32_t ref_bandwidth;