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 <ID> 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 <achernavin@netgate.com>
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;
}
/* 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;
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,
};
#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);
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);
/* 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;
}
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);
/* 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. */