From e8a2cc5323a369d9da23336063c3ee4f73fed6a1 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Jul 2019 12:26:23 +0200 Subject: [PATCH 1/9] ospfd: remove t_external_lsa It's unused... Signed-off-by: David Lamparter --- ospfd/ospf_lsa.c | 2 -- ospfd/ospfd.c | 1 - ospfd/ospfd.h | 1 - 3 files changed, 4 deletions(-) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index bf46d22031..dd9d0ca27a 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2031,8 +2031,6 @@ int ospf_external_lsa_originate_timer(struct thread *thread) struct listnode *node; struct ospf_external *ext; - ospf->t_external_lsa = NULL; - ext_list = ospf->external[type]; if (!ext_list) return 0; diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index a64ddbc3b7..0325b7ba1b 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -702,7 +702,6 @@ static void ospf_finish_final(struct ospf *ospf) /* Cancel all timers. */ OSPF_TIMER_OFF(ospf->t_read); OSPF_TIMER_OFF(ospf->t_write); - OSPF_TIMER_OFF(ospf->t_external_lsa); OSPF_TIMER_OFF(ospf->t_spf_calc); OSPF_TIMER_OFF(ospf->t_ase_calc); OSPF_TIMER_OFF(ospf->t_maxage); diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index cbea033b73..38d4752cbe 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -233,7 +233,6 @@ struct ospf { 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. */ - struct thread *t_external_lsa; /* AS-external-LSA origin timer. */ struct thread *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */ struct thread *t_sr_update; /* Segment Routing update timer */ From fa3c7c7e95638fcafef24fffcd0c49f1b11cc64d Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Jul 2019 12:27:25 +0200 Subject: [PATCH 2/9] ospfd: kill totally misnamed "timers" Neither ospf_external_lsa_originate_timer() nor ospf_default_originate_timer() are actually timers. They're only executed on router-ID changes to refresh a particular LSA type. Signed-off-by: David Lamparter --- ospfd/ospf_lsa.c | 99 ++++++++++++++++++---------------------------- ospfd/ospf_lsa.h | 3 +- ospfd/ospf_zebra.c | 8 +--- ospfd/ospfd.c | 29 +------------- ospfd/ospfd.h | 1 - 5 files changed, 43 insertions(+), 97 deletions(-) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index dd9d0ca27a..c5e2c44275 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2019,48 +2019,6 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf, return new; } -/* Originate AS-external-LSA from external info with initial flag. */ -int ospf_external_lsa_originate_timer(struct thread *thread) -{ - struct ospf *ospf = THREAD_ARG(thread); - struct route_node *rn; - struct external_info *ei; - struct route_table *rt; - int type = THREAD_VAL(thread); - struct list *ext_list; - struct listnode *node; - struct ospf_external *ext; - - ext_list = ospf->external[type]; - if (!ext_list) - return 0; - - for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { - /* Originate As-external-LSA from all type of distribute source. - */ - rt = ext->external_info; - if (!rt) - continue; - - for (rn = route_top(rt); rn; rn = route_next(rn)) { - ei = rn->info; - - if (!ei) - continue; - - if (is_prefix_default((struct prefix_ipv4 *)&ei->p)) - continue; - - if (!ospf_external_lsa_originate(ospf, ei)) - flog_warn( - EC_OSPF_LSA_INSTALL_FAILURE, - "LSA: AS-external-LSA was not originated."); - } - } - - return 0; -} - static struct external_info *ospf_default_external_info(struct ospf *ospf) { int type; @@ -2100,31 +2058,52 @@ static struct external_info *ospf_default_external_info(struct ospf *ospf) return NULL; } -int ospf_default_originate_timer(struct thread *thread) +void ospf_external_lsa_rid_change(struct ospf *ospf) { - struct prefix_ipv4 p; - struct in_addr nexthop; struct external_info *ei; - struct ospf *ospf; + int type; - ospf = THREAD_ARG(thread); + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + struct route_node *rn; + struct route_table *rt; + struct list *ext_list; + struct listnode *node; + struct ospf_external *ext; - p.family = AF_INET; - p.prefix.s_addr = 0; - p.prefixlen = 0; + ext_list = ospf->external[type]; + if (!ext_list) + continue; - if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS) { - /* If there is no default route via redistribute, - then originate AS-external-LSA with nexthop 0 (self). */ - nexthop.s_addr = 0; - ospf_external_info_add(ospf, DEFAULT_ROUTE, 0, p, 0, nexthop, - 0); + for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { + /* Originate As-external-LSA from all type of + * distribute source. + */ + rt = ext->external_info; + if (!rt) + continue; + + for (rn = route_top(rt); rn; rn = route_next(rn)) { + ei = rn->info; + + if (!ei) + continue; + + if (is_prefix_default( + (struct prefix_ipv4 *)&ei->p)) + continue; + + if (!ospf_external_lsa_originate(ospf, ei)) + flog_warn(EC_OSPF_LSA_INSTALL_FAILURE, + "LSA: AS-external-LSA was not originated."); + } + } } - if ((ei = ospf_default_external_info(ospf))) - ospf_external_lsa_originate(ospf, ei); - - return 0; + ei = ospf_default_external_info(ospf); + if (ei && !ospf_external_lsa_originate(ospf, ei)) { + flog_warn(EC_OSPF_LSA_INSTALL_FAILURE, + "LSA: AS-external-LSA for default route was not originated."); + } } /* Flush any NSSA LSAs for given prefix */ diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 5e3dabc27a..4551b83d75 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -275,8 +275,7 @@ extern struct in_addr ospf_get_ip_from_ifp(struct ospf_interface *); extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *, struct external_info *); -extern int ospf_external_lsa_originate_timer(struct thread *); -extern int ospf_default_originate_timer(struct thread *); +extern void ospf_external_lsa_rid_change(struct ospf *ospf); extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *, uint32_t, struct in_addr, struct in_addr); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 951402f47f..c72e5c2d37 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -765,8 +765,6 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, metric_type(ospf, DEFAULT_ROUTE, 0), metric_value(ospf, DEFAULT_ROUTE, 0)); - if (ospf->router_id.s_addr == 0) - ospf->external_origin |= (1 << DEFAULT_ROUTE); if ((originate == DEFAULT_ORIGINATE_ALWAYS) && (ospf->router_id.s_addr)) { @@ -1067,11 +1065,7 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) /* Nothing has changed, so nothing to do; return */ return 0; } - if (ospf->router_id.s_addr == 0) - /* Set flags to generate AS-external-LSA originate event - for each redistributed protocols later. */ - ospf->external_origin |= (1 << rt_type); - else { + if (ospf->router_id.s_addr != 0) { if (ei) { if (is_prefix_default(&p)) ospf_external_lsa_refresh_default(ospf); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 0325b7ba1b..739cb280a6 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -91,7 +91,6 @@ void ospf_router_id_update(struct ospf *ospf) struct ospf_interface *oi; struct interface *ifp; struct listnode *node; - int type; if (!ospf->oi_running) { if (IS_DEBUG_OSPF_EVENT) @@ -135,24 +134,6 @@ void ospf_router_id_update(struct ospf *ospf) ospf_nbr_self_reset(oi, router_id); } - /* If AS-external-LSA is queued, then flush those LSAs. */ - if (router_id_old.s_addr == 0 && ospf->external_origin) { - /* Originate each redistributed external route. */ - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - if (ospf->external_origin & (1 << type)) - thread_add_event( - master, - ospf_external_lsa_originate_timer, - ospf, type, NULL); - /* Originate Deafult. */ - if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX)) - thread_add_event(master, - ospf_default_originate_timer, - ospf, 0, NULL); - - ospf->external_origin = 0; - } - /* Flush (inline) all external LSAs based on the OSPF_LSA_SELF * flag */ if (ospf->lsdb) { @@ -196,20 +177,14 @@ void ospf_router_id_update(struct ospf *ospf) } } - /* Originate each redistributed external route. */ - for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - thread_add_event(master, - ospf_external_lsa_originate_timer, - ospf, type, NULL); - thread_add_event(master, ospf_default_originate_timer, ospf, 0, - NULL); - /* update router-lsa's for each area */ ospf_router_lsa_update(ospf); /* update ospf_interface's */ FOR_ALL_INTERFACES (vrf, ifp) ospf_if_update(ospf, ifp); + + ospf_external_lsa_rid_change(ospf); } } diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 38d4752cbe..b31ad30375 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -202,7 +202,6 @@ struct ospf { struct ospf_lsdb *lsdb; /* Flags. */ - int external_origin; /* AS-external-LSA origin flag. */ int ase_calc; /* ASE calculation flag. */ struct list *opaque_lsa_self; /* Type-11 Opaque-LSAs */ From e410fd7f2961c900bed8301713d7b8b681a0e88a Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Jul 2019 12:32:32 +0200 Subject: [PATCH 3/9] Revert "ospfd: remove default origin max age lsa" This reverts commit 313919d6e3db67eedef77960ea4e2ba2a6018ee1. This is not the correct way to fix this. - touching the LSDB to explicitly remove a MaxAge LSA is always wrong and results in desynchronization of the entire routing domain - the LSDB code correctly handles replacing a MaxAge LSA with a newly issued one - removing the old LSA resets the sequence numbers, which may cause other routers to reject the new LSA as old - the function was horribly misnamed Signed-off-by: David Lamparter --- ospfd/ospf_lsa.c | 16 ---------------- ospfd/ospf_lsa.h | 1 - ospfd/ospf_zebra.c | 3 --- 3 files changed, 20 deletions(-) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index c5e2c44275..7aa4a48d81 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2220,22 +2220,6 @@ void ospf_external_lsa_refresh_default(struct ospf *ospf) } } -void ospf_default_originate_lsa_update(struct ospf *ospf) -{ - struct prefix_ipv4 p; - struct ospf_lsa *lsa; - - p.family = AF_INET; - p.prefixlen = 0; - p.prefix.s_addr = 0; - - lsa = ospf_external_info_find_lsa(ospf, &p); - if (lsa && IS_LSA_MAXAGE(lsa)) { - ospf_discard_from_db(ospf, lsa->lsdb, lsa); - ospf_lsdb_delete(lsa->lsdb, lsa); - } -} - void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type, unsigned short instance, int force) { diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 4551b83d75..4033659bff 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -300,7 +300,6 @@ extern int ospf_lsa_maxage_walker(struct thread *); extern struct ospf_lsa *ospf_lsa_refresh(struct ospf *, struct ospf_lsa *); extern void ospf_external_lsa_refresh_default(struct ospf *); -extern void ospf_default_originate_lsa_update(struct ospf *ospf); extern void ospf_external_lsa_refresh_type(struct ospf *, uint8_t, unsigned short, int); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index c72e5c2d37..714b3bb817 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -856,9 +856,6 @@ int ospf_redistribute_default_unset(struct ospf *ospf) ospf_asbr_status_update(ospf, --ospf->redistribute); - /* clean up maxage default originate external lsa */ - ospf_default_originate_lsa_update(ospf); - return CMD_SUCCESS; } From fd9a1d5afe1c8bcfacb808249e3a1658fc944a0a Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Jul 2019 14:04:06 +0200 Subject: [PATCH 4/9] Revert "ospfd: default route got flushed after lsa refresh timer." This reverts commit a6b4e1fdedb290e8d86f73b0d7f842f7042b26af. This fix is wrong too. The zclient->redist & ->mi_redist arrays are accessed past their size for any external route that is not 0.0.0.0/0. Also, it is incorrect to check default_information for DEFAULT_ROUTE since that's "originate always". Signed-off-by: David Lamparter --- ospfd/ospf_flood.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 6d1e44996e..168dcee449 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -91,7 +91,7 @@ struct external_info *ospf_external_info_check(struct ospf *ospf, p.prefix = lsa->data->id; p.prefixlen = ip_masklen(al->mask); - for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) { + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { int redist_on = 0; redist_on = From 5af13f54dc3b1a6f65052af7a2581354fa719ad0 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Jul 2019 14:44:26 +0200 Subject: [PATCH 5/9] ospfd: re-fix default origination check ospf->external[DEFAULT_ROUTE] and zclient->default_information don't line up with each other; the former is only used for "originate always". Fixes: #4237 Signed-off-by: David Lamparter --- ospfd/ospf_flood.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 168dcee449..1d85a04984 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -83,6 +83,9 @@ struct external_info *ospf_external_info_check(struct ospf *ospf, struct as_external_lsa *al; struct prefix_ipv4 p; struct route_node *rn; + struct list *ext_list; + struct listnode *node; + struct ospf_external *ext; int type; al = (struct as_external_lsa *)lsa->data; @@ -105,10 +108,6 @@ struct external_info *ospf_external_info_check(struct ospf *ospf, ospf->vrf_id)); // Pending: check for MI above. if (redist_on) { - struct list *ext_list; - struct listnode *node; - struct ospf_external *ext; - ext_list = ospf->external[type]; if (!ext_list) continue; @@ -129,6 +128,22 @@ struct external_info *ospf_external_info_check(struct ospf *ospf, } } + if (is_prefix_default(&p) && ospf->external[DEFAULT_ROUTE]) { + ext_list = ospf->external[DEFAULT_ROUTE]; + + for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) { + if (!ext->external_info) + continue; + + rn = route_node_lookup(ext->external_info, + (struct prefix *)&p); + if (!rn) + continue; + route_unlock_node(rn); + if (rn->info != NULL) + return (struct external_info *)rn->info; + } + } return NULL; } From ba50df2b53cf80627e36d7ff7c9ced85cd5141f3 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Jul 2019 12:28:26 +0200 Subject: [PATCH 6/9] ospfd: remove LSA reorigin on NSM change This is a "workaround" for something broken in LSDB sync that has been kept around since the beginning of our git history... (It works correctly without this "workaround".) Signed-off-by: David Lamparter --- ospfd/ospf_nsm.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index f7c73fee33..ee27ec0942 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -616,8 +616,6 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state) struct ospf_interface *oi = nbr->oi; struct ospf_area *vl_area = NULL; uint8_t old_state; - int x; - int force = 1; /* Preserve old status. */ old_state = nbr->state; @@ -664,32 +662,6 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state) if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area) if (++vl_area->full_vls == 1) ospf_schedule_abr_task(oi->ospf); - - /* kevinm: refresh any redistributions */ - for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++) { - struct list *red_list; - struct listnode *node; - struct ospf_redist *red; - - if (x == ZEBRA_ROUTE_OSPF6) - continue; - - red_list = oi->ospf->redist[x]; - if (!red_list) - continue; - - for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) - ospf_external_lsa_refresh_type( - oi->ospf, x, red->instance, - force); - } - /* XXX: Clearly some thing is wrong with refresh of - * external LSAs - * this added to hack around defaults not refreshing - * after a timer - * jump. - */ - ospf_external_lsa_refresh_default(oi->ospf); } else { oi->full_nbrs--; oi->area->full_nbrs--; From bcbe98cca0b52ffd43d2bf49651ea5698390b691 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Jul 2019 12:43:46 +0200 Subject: [PATCH 7/9] ospfd: unset default route external_info Need to clear out the external_info for the "always" default route that we installed in ospf_redistribute_default_set(). Signed-off-by: David Lamparter --- ospfd/ospf_zebra.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 714b3bb817..0519092e40 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -845,6 +845,14 @@ int ospf_redistribute_default_unset(struct ospf *ospf) return CMD_SUCCESS; zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, AFI_IP, ospf->vrf_id); + } else if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS) { + struct prefix_ipv4 p; + + p.family = AF_INET; + p.prefix.s_addr = 0; + p.prefixlen = 0; + + ospf_external_info_delete(ospf, DEFAULT_ROUTE, 0, &p); } ospf->default_originate = DEFAULT_ORIGINATE_NONE; @@ -852,8 +860,6 @@ int ospf_redistribute_default_unset(struct ospf *ospf) if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug("Redistribute[DEFAULT]: Stop"); - // Pending: how does the external_info cleanup work in this case? - ospf_asbr_status_update(ospf, --ospf->redistribute); return CMD_SUCCESS; From f1cf5af6dae136ead1f8233b61d245e7d67863ad Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Jul 2019 14:44:44 +0200 Subject: [PATCH 8/9] ospfd: don't ASE with router-ID 0 The ASEs will be generated later by ospf_external_lsa_rid_change(). Signed-off-by: David Lamparter --- ospfd/ospf_lsa.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 7aa4a48d81..47327ad25c 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -1979,6 +1979,13 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf, */ + if (ospf->router_id.s_addr == 0) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("LSA[Type5:%pI4]: deferring AS-external-LSA origination, router ID is zero", + &ei->p.prefix); + return NULL; + } + /* Check the AS-external-LSA should be originated. */ if (!ospf_redistribute_check(ospf, ei, NULL)) return NULL; From d5eac1e0ca1d067af4e9e261711a37b2025ff612 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Jul 2019 14:46:05 +0200 Subject: [PATCH 9/9] ospfd: clean up default route logic What a mess... Signed-off-by: David Lamparter --- ospfd/ospf_lsa.c | 36 +++++-------- ospfd/ospf_vty.c | 17 +----- ospfd/ospf_zebra.c | 127 ++++++++++++++------------------------------- ospfd/ospfd.c | 2 +- 4 files changed, 55 insertions(+), 127 deletions(-) diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 47327ad25c..db41df7c47 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2202,28 +2202,20 @@ void ospf_external_lsa_refresh_default(struct ospf *ospf) ei = ospf_default_external_info(ospf); lsa = ospf_external_info_find_lsa(ospf, &p); - if (ei) { - if (lsa) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug( - "LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", - (void *)lsa); - ospf_external_lsa_refresh(ospf, lsa, ei, - LSA_REFRESH_FORCE); - } else { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug( - "LSA[Type5:0.0.0.0]: Originate AS-external-LSA"); - ospf_external_lsa_originate(ospf, ei); - } - } else { - if (lsa) { - if (IS_DEBUG_OSPF_EVENT) - zlog_debug( - "LSA[Type5:0.0.0.0]: Flush AS-external-LSA"); - ospf_refresher_unregister_lsa(ospf, lsa); - ospf_lsa_flush_as(ospf, lsa); - } + if (ei && lsa) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", + (void *)lsa); + ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE); + } else if (ei && !lsa) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug( + "LSA[Type5:0.0.0.0]: Originate AS-external-LSA"); + ospf_external_lsa_originate(ospf, ei); + } else if (lsa) { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("LSA[Type5:0.0.0.0]: Flush AS-external-LSA"); + ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &p, 0); } } diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 98ddd6a79e..2564c6f330 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -8487,22 +8487,8 @@ DEFUN (no_ospf_default_information_originate, "Pointer to route-map entries\n") { VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf); - struct prefix_ipv4 p; - struct ospf_external *ext; struct ospf_redist *red; - p.family = AF_INET; - p.prefix.s_addr = 0; - p.prefixlen = 0; - - ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &p, 0); - - ext = ospf_external_lookup(ospf, DEFAULT_ROUTE, 0); - if (ext && EXTERNAL_INFO(ext)) { - ospf_external_info_delete(ospf, DEFAULT_ROUTE, 0, p); - ospf_external_del(ospf, DEFAULT_ROUTE, 0); - } - red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0); if (!red) return CMD_SUCCESS; @@ -8510,7 +8496,8 @@ DEFUN (no_ospf_default_information_originate, ospf_routemap_unset(red); ospf_redist_del(ospf, DEFAULT_ROUTE, 0); - return ospf_redistribute_default_unset(ospf); + return ospf_redistribute_default_set(ospf, DEFAULT_ORIGINATE_NONE, + 0, 0); } DEFUN (ospf_default_metric, diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 0519092e40..47438b985e 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -744,10 +744,10 @@ int ospf_redistribute_unset(struct ospf *ospf, int type, int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, int mvalue) { - struct ospf_external *ext; struct prefix_ipv4 p; struct in_addr nexthop; int cur_originate = ospf->default_originate; + const char *type_str = NULL; nexthop.s_addr = 0; p.family = AF_INET; @@ -756,39 +756,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, ospf->default_originate = originate; - ospf_external_add(ospf, DEFAULT_ROUTE, 0); - - if (cur_originate == DEFAULT_ORIGINATE_NONE) { - /* First time configuration */ - if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Redistribute[DEFAULT]: Start Type[%d], Metric[%d]", - metric_type(ospf, DEFAULT_ROUTE, 0), - metric_value(ospf, DEFAULT_ROUTE, 0)); - - if ((originate == DEFAULT_ORIGINATE_ALWAYS) - && (ospf->router_id.s_addr)) { - - /* always , so originate lsa even it doesn't - * exist in RIB. - */ - ospf_external_info_add(ospf, DEFAULT_ROUTE, 0, - p, 0, nexthop, 0); - ospf_external_lsa_refresh_default(ospf); - - } else if (originate == DEFAULT_ORIGINATE_ZEBRA) { - /* Send msg to Zebra to validate default route - * existance. - */ - zclient_redistribute_default( - ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient, AFI_IP, - ospf->vrf_id); - } - - ospf_asbr_status_update(ospf, ++ospf->redistribute); - return CMD_SUCCESS; - - - } else if (originate == cur_originate) { + if (cur_originate == originate) { /* Refresh the lsa since metric might different */ if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) zlog_debug( @@ -798,70 +766,51 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype, metric_value(ospf, DEFAULT_ROUTE, 0)); ospf_external_lsa_refresh_default(ospf); - - } else { - /* "default-info originate always" configured now, - * where "default-info originate" configured previoulsly. - */ - if (originate == DEFAULT_ORIGINATE_ALWAYS) { - - zclient_redistribute_default( - ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, - zclient, AFI_IP, ospf->vrf_id); - /* here , ex-info should be added since ex-info might - * have not updated earlier if def route is not exist. - * If ex-iinfo ex-info already exist , it will return - * smoothly. - */ - ospf_external_info_add(ospf, DEFAULT_ROUTE, 0, - p, 0, nexthop, 0); - ospf_external_lsa_refresh_default(ospf); - - } else { - /* "default-info originate" configured now,where - * "default-info originate always" configured - * previoulsy. - */ - - ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &p, 0); - - ext = ospf_external_lookup(ospf, DEFAULT_ROUTE, 0); - if (ext && EXTERNAL_INFO(ext)) - ospf_external_info_delete(ospf, - DEFAULT_ROUTE, 0, p); - - zclient_redistribute_default( - ZEBRA_REDISTRIBUTE_DEFAULT_ADD, - zclient, AFI_IP, ospf->vrf_id); - } + return CMD_SUCCESS; } - return CMD_SUCCESS; -} -int ospf_redistribute_default_unset(struct ospf *ospf) -{ - if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA) { - if (!ospf_is_type_redistributed(ospf, DEFAULT_ROUTE, 0)) - return CMD_SUCCESS; + switch (cur_originate) { + case DEFAULT_ORIGINATE_NONE: + break; + case DEFAULT_ORIGINATE_ZEBRA: zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE, zclient, AFI_IP, ospf->vrf_id); - } else if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS) { - struct prefix_ipv4 p; - - p.family = AF_INET; - p.prefix.s_addr = 0; - p.prefixlen = 0; - - ospf_external_info_delete(ospf, DEFAULT_ROUTE, 0, &p); + ospf->redistribute--; + break; + case DEFAULT_ORIGINATE_ALWAYS: + ospf_external_info_delete(ospf, DEFAULT_ROUTE, 0, p); + ospf_external_del(ospf, DEFAULT_ROUTE, 0); + ospf->redistribute--; + break; } - ospf->default_originate = DEFAULT_ORIGINATE_NONE; + switch (originate) { + case DEFAULT_ORIGINATE_NONE: + type_str = "none"; + break; + case DEFAULT_ORIGINATE_ZEBRA: + type_str = "normal"; + ospf->redistribute++; + zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD, + zclient, AFI_IP, ospf->vrf_id); + break; + case DEFAULT_ORIGINATE_ALWAYS: + type_str = "always"; + ospf->redistribute++; + ospf_external_add(ospf, DEFAULT_ROUTE, 0); + ospf_external_info_add(ospf, DEFAULT_ROUTE, 0, p, 0, nexthop, + 0); + break; + } if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) - zlog_debug("Redistribute[DEFAULT]: Stop"); - - ospf_asbr_status_update(ospf, --ospf->redistribute); + zlog_debug("Redistribute[DEFAULT]: %s Type[%d], Metric[%d]", + type_str, + metric_type(ospf, DEFAULT_ROUTE, 0), + metric_value(ospf, DEFAULT_ROUTE, 0)); + ospf_external_lsa_refresh_default(ospf); + ospf_asbr_status_update(ospf, ospf->redistribute); return CMD_SUCCESS; } diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 739cb280a6..b91a55f635 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -608,7 +608,7 @@ static void ospf_finish_final(struct ospf *ospf) ospf_redist_del(ospf, i, red->instance); } } - ospf_redistribute_default_unset(ospf); + ospf_redistribute_default_set(ospf, DEFAULT_ORIGINATE_NONE, 0, 0); for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) ospf_remove_vls_through_area(ospf, area);