From 1c1c342d2a22c9d600c36dde2d7d48c8b6b3ba41 Mon Sep 17 00:00:00 2001 From: Alexander Chernavin Date: Mon, 12 Apr 2021 09:34:20 -0400 Subject: [PATCH] ospfd: install Type-7 when NSSA area is configured after redistribution Currently, if NSSA area is configured before redistribution is enabled, Type-7 LSA's are installed and flooded. But if NSSA area is configured after redistribution is enabled, Type-7 LSA's are not installed. With this change, when NSSA area is configured, schedule a task that scans for external LSA's. If they exist, install Type-7 and flood to all NSSA Areas. There already was an attempt to fix this problem in 0f321812f where ospf_asbr_nssa_redist_task() was triggered in ospf_abr_task_timer(). This turns out to be incorrect place for this operation because it's a one-off operation needed only after "area nssa" execution. And ospf_abr_task_timer() is a periodic operation. Triggering ospf_asbr_nssa_redist_task() in ospf_abr_task_timer() caused a problem that was fixed in 945eec2b6 making the problem with NSSA area configured after redistribution actual again. Signed-off-by: Alexander Chernavin --- ospfd/ospf_abr.c | 1 - ospfd/ospf_asbr.c | 22 ++++++++++++++++++++-- ospfd/ospf_asbr.h | 3 ++- ospfd/ospf_vty.c | 1 + ospfd/ospfd.c | 1 + ospfd/ospfd.h | 2 ++ 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index b5c97eda3c..a6027ee9d1 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -1818,7 +1818,6 @@ static int ospf_abr_task_timer(struct thread *thread) ospf_abr_task(ospf); ospf_abr_nssa_task(ospf); /* if nssa-abr, then scan Type-7 LSDB */ - ospf_asbr_nssa_redist_task(ospf); return 0; } diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 0b4e5d7762..6d80725ae6 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -277,10 +277,16 @@ void ospf_asbr_status_update(struct ospf *ospf, uint8_t status) /* If there's redistribution configured, we need to refresh external * LSAs in order to install Type-7 and flood to all NSSA Areas */ -void ospf_asbr_nssa_redist_task(struct ospf *ospf) +static int ospf_asbr_nssa_redist_update_timer(struct thread *thread) { + struct ospf *ospf = THREAD_ARG(thread); int type; + ospf->t_asbr_nssa_redist_update = NULL; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Running ASBR NSSA redistribution update on timer"); + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { struct list *red_list; struct listnode *node; @@ -293,10 +299,22 @@ void ospf_asbr_nssa_redist_task(struct ospf *ospf) for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) ospf_external_lsa_refresh_type(ospf, type, red->instance, - LSA_REFRESH_IF_CHANGED); + LSA_REFRESH_FORCE); } ospf_external_lsa_refresh_default(ospf); + + return 0; +} + +void ospf_schedule_asbr_nssa_redist_update(struct ospf *ospf) +{ + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("Scheduling ASBR NSSA redistribution update"); + + thread_add_timer(master, ospf_asbr_nssa_redist_update_timer, ospf, + OSPF_ASBR_NSSA_REDIST_UPDATE_DELAY, + &ospf->t_asbr_nssa_redist_update); } void ospf_redistribute_withdraw(struct ospf *ospf, uint8_t type, diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h index 7759d45455..d3e50903ef 100644 --- a/ospfd/ospf_asbr.h +++ b/ospfd/ospf_asbr.h @@ -104,6 +104,7 @@ struct ospf_external_aggr_rt { }; #define OSPF_ASBR_CHECK_DELAY 30 +#define OSPF_ASBR_NSSA_REDIST_UPDATE_DELAY 9 extern void ospf_external_route_remove(struct ospf *, struct prefix_ipv4 *); extern struct external_info *ospf_external_info_new(uint8_t, unsigned short); @@ -121,7 +122,7 @@ extern struct external_info *ospf_external_info_lookup(struct ospf *, uint8_t, unsigned short, struct prefix_ipv4 *); extern void ospf_asbr_status_update(struct ospf *, uint8_t); -extern void ospf_asbr_nssa_redist_task(struct ospf *ospf); +extern void ospf_schedule_asbr_nssa_redist_update(struct ospf *ospf); extern void ospf_redistribute_withdraw(struct ospf *, uint8_t, unsigned short); extern void ospf_asbr_check(void); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 92d13e616c..8d6176fd37 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -1546,6 +1546,7 @@ static int ospf_area_nssa_cmd_handler(struct vty *vty, int argc, /* Flush the external LSA for the specified area */ ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA); ospf_schedule_abr_task(ospf); + ospf_schedule_asbr_nssa_redist_update(ospf); return CMD_SUCCESS; } diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 259209a736..b455d0b411 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -791,6 +791,7 @@ static void ospf_finish_final(struct ospf *ospf) OSPF_TIMER_OFF(ospf->t_maxage_walker); OSPF_TIMER_OFF(ospf->t_abr_task); OSPF_TIMER_OFF(ospf->t_asbr_check); + OSPF_TIMER_OFF(ospf->t_asbr_nssa_redist_update); OSPF_TIMER_OFF(ospf->t_distribute_update); OSPF_TIMER_OFF(ospf->t_lsa_refresher); OSPF_TIMER_OFF(ospf->t_opaque_lsa_self); diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 2093eb2e42..318400e968 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -242,6 +242,8 @@ struct ospf { /* Threads. */ struct thread *t_abr_task; /* ABR task timer. */ struct thread *t_asbr_check; /* ASBR check timer. */ + struct thread *t_asbr_nssa_redist_update; /* ASBR NSSA redistribution + update timer. */ struct thread *t_distribute_update; /* Distirbute list update timer. */ struct thread *t_spf_calc; /* SPF calculation timer. */ struct thread *t_ase_calc; /* ASE calculation timer. */ -- 2.39.5