From c3a70f651758d34d16f98c84f4daaf4488a277a9 Mon Sep 17 00:00:00 2001 From: Mobashshera Rasool Date: Fri, 9 Jul 2021 09:47:40 +0000 Subject: [PATCH] ospf6d: ASBR summarisation feature changes for NSSA area 1. ASBR summarisation for Type-7 LSAs are done here. 2. Fixed Code warnings Signed-off-by: Mobashshera Rasool --- ospf6d/ospf6_asbr.c | 189 +++++++++++++++++++++++--------------------- ospf6d/ospf6_asbr.h | 24 +++--- ospf6d/ospf6_lsa.h | 5 +- ospf6d/ospf6_nssa.c | 47 +++++++++-- ospf6d/ospf6_top.c | 26 +++--- 5 files changed, 172 insertions(+), 119 deletions(-) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 8cb3a4e0b3..f587c209a7 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -71,6 +71,25 @@ unsigned char conf_debug_ospf6_asbr = 0; #define ZROUTE_NAME(x) zebra_route_string(x) +/* Originate Type-5 and Type-7 LSA */ +static struct ospf6_lsa *ospf6_originate_type5_type7_lsas( + struct ospf6_route *route, + struct ospf6 *ospf6) +{ + struct ospf6_lsa *lsa; + struct listnode *lnode; + struct ospf6_area *oa = NULL; + + lsa = ospf6_as_external_lsa_originate(route, ospf6); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) { + if (IS_AREA_NSSA(oa)) + ospf6_nssa_lsa_originate(route, oa); + } + + return lsa; +} + /* AS External LSA origination */ struct ospf6_lsa *ospf6_as_external_lsa_originate(struct ospf6_route *route, struct ospf6 *ospf6) @@ -1334,8 +1353,6 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, struct ospf6 *ospf6) { route_map_result_t ret; - struct listnode *lnode; - struct ospf6_area *oa; struct ospf6_route troute; struct ospf6_external_info tinfo; struct ospf6_route *route, *match; @@ -1444,10 +1461,6 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, ospf6_handle_external_lsa_origination(ospf6, match, prefix); ospf6_asbr_status_update(ospf6, ospf6->redistribute); - for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) { - if (IS_AREA_NSSA(oa)) - ospf6_nssa_lsa_originate(match, oa); - } return; } @@ -1494,18 +1507,15 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, ospf6_handle_external_lsa_origination(ospf6, route, prefix); ospf6_asbr_status_update(ospf6, ospf6->redistribute); - for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) { - if (IS_AREA_NSSA(oa)) - ospf6_nssa_lsa_originate(route, oa); - } - return; } static void ospf6_asbr_external_lsa_remove_by_id(struct ospf6 *ospf6, uint32_t id) { struct ospf6_lsa *lsa; + struct ospf6_area *oa; + struct listnode *lnode; lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), htonl(id), ospf6->router_id, ospf6->lsdb); @@ -1514,7 +1524,20 @@ static void ospf6_asbr_external_lsa_remove_by_id(struct ospf6 *ospf6, ospf6_external_lsa_purge(ospf6, lsa); - return; + /* Delete the NSSA LSA */ + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) { + lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7), + htonl(id), ospf6->router_id, + oa->lsdb); + if (lsa) { + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug("withdraw type 7 lsa, LS ID: %u", + htonl(id)); + + ospf6_lsa_purge(lsa); + } + } + } static void @@ -1526,8 +1549,9 @@ ospf6_link_route_to_aggr(struct ospf6_external_aggr_rt *aggr, } static void -ospf6_unlink_route_from_aggr(struct ospf6 *ospf6, struct ospf6_external_aggr_rt *aggr, - struct ospf6_route *rt) +ospf6_unlink_route_from_aggr(struct ospf6 *ospf6, + struct ospf6_external_aggr_rt *aggr, + struct ospf6_route *rt) { if (IS_OSPF6_DEBUG_AGGR) zlog_debug("%s: Unlinking external route(%pFX) from aggregator(%pFX), external route count:%ld", @@ -1549,7 +1573,7 @@ ospf6_unlink_route_from_aggr(struct ospf6 *ospf6, struct ospf6_external_aggr_rt if (IS_OSPF6_DEBUG_AGGR) zlog_debug("%s: Flushing the aggregate route)", - __func__);; + __func__); aggr->id = 0; /* Unset the Origination flag */ UNSET_FLAG(aggr->aggrflags, OSPF6_EXTERNAL_AGGRT_ORIGINATED); @@ -1559,11 +1583,8 @@ ospf6_unlink_route_from_aggr(struct ospf6 *ospf6, struct ospf6_external_aggr_rt void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, struct prefix *prefix, struct ospf6 *ospf6) { - struct ospf6_area *oa; struct ospf6_route *match; struct ospf6_external_info *info = NULL; - struct ospf6_lsa *lsa; - struct listnode *lnode; match = ospf6_route_lookup(prefix, ospf6->external_table); if (match == NULL) { @@ -1581,20 +1602,6 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, return; } - /* Delete the NSSA LSA */ - for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) { - lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7), - htonl(info->id), ospf6->router_id, - oa->lsdb); - if (lsa) { - if (IS_OSPF6_DEBUG_ASBR) { - zlog_debug("withdraw type 7 LSA for route %pFX", - prefix); - } - ospf6_lsa_purge(lsa); - } - } - /* This means aggregation on this route was not done, hence remove LSA * if any originated for this prefix */ @@ -1603,6 +1610,10 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, else ospf6_unlink_route_from_aggr(ospf6, match->aggr_route, match); + if (IS_OSPF6_DEBUG_ASBR) + zlog_debug("Removing route from external table %pFX", + prefix); + ospf6_route_remove(match, ospf6->external_table); XFREE(MTYPE_OSPF6_EXTERNAL_INFO, info); @@ -1621,6 +1632,7 @@ DEFUN (ospf6_redistribute, VTY_DECLVAR_CONTEXT(ospf6, ospf6); char *proto = argv[argc - 1]->text; + type = proto_redistnum(AFI_IP6, proto); if (type < 0) return CMD_WARNING_CONFIG_FAILED; @@ -2691,18 +2703,16 @@ static void ospf6_originate_new_aggr_lsa(struct ospf6 *ospf6, rt_aggr->path.origin.id = htonl(aggr->id); /* Originate summary LSA */ - lsa = ospf6_as_external_lsa_originate(rt_aggr, ospf6); + lsa = ospf6_originate_type5_type7_lsas(rt_aggr, ospf6); if (lsa) { if (IS_OSPF6_DEBUG_AGGR) zlog_debug("%s: Set the origination bit for aggregator", __func__); SET_FLAG(aggr->aggrflags, OSPF6_EXTERNAL_AGGRT_ORIGINATED); } - - return; } -static void ospf6_fill_aggr_route_details(struct ospf6 *ospf6, +void ospf6_fill_aggr_route_details(struct ospf6 *ospf6, struct ospf6_external_info *ei_aggr, struct ospf6_route *rt_aggr, struct ospf6_external_aggr_rt *aggr) @@ -2719,7 +2729,8 @@ static void ospf6_fill_aggr_route_details(struct ospf6 *ospf6, /* When metric is not configured, apply the default metric */ rt_aggr->path.cost = ((aggr->metric == -1) ? - DEFAULT_DEFAULT_METRIC : (unsigned)(aggr->metric)); + DEFAULT_DEFAULT_METRIC + : (unsigned int)(aggr->metric)); rt_aggr->path.metric_type = aggr->mtype; rt_aggr->path.origin.id = htonl(aggr->id); @@ -2738,7 +2749,8 @@ ospf6_aggr_handle_advertise_change(struct ospf6 *ospf6, zlog_debug("%s: Don't originate the summary address,It is configured to not-advertise.", __func__); - if (CHECK_FLAG(aggr->aggrflags, OSPF6_EXTERNAL_AGGRT_ORIGINATED)) { + if (CHECK_FLAG(aggr->aggrflags, + OSPF6_EXTERNAL_AGGRT_ORIGINATED)) { if (IS_OSPF6_DEBUG_AGGR) zlog_debug("%s: No-advertise,So Flush the Aggregate route(%pFX)", __func__, @@ -2746,7 +2758,8 @@ ospf6_aggr_handle_advertise_change(struct ospf6 *ospf6, ospf6_asbr_external_lsa_remove_by_id(ospf6, aggr->id); /* Setting it here as 0, so that it is considered as - * invalid */ + * invalid + */ aggr->id = 0; UNSET_FLAG(aggr->aggrflags, OSPF6_EXTERNAL_AGGRT_ORIGINATED); @@ -2755,7 +2768,8 @@ ospf6_aggr_handle_advertise_change(struct ospf6 *ospf6, } /* There are no routes present under this aggregation config, hence - * nothing to originate here */ + * nothing to originate here + */ if (OSPF6_EXTERNAL_RT_COUNT(aggr) == 0) { if (IS_OSPF6_DEBUG_AGGR) zlog_debug("%s: No routes present under this aggregation", @@ -2768,8 +2782,9 @@ ospf6_aggr_handle_advertise_change(struct ospf6 *ospf6, zlog_debug("%s: Now it is advertisable", __func__); - /* Prepare the external_info for aggregator */ - /* Fill all the details which will get advertised */ + /* Prepare the external_info for aggregator + * Fill all the details which will get advertised + */ ospf6_fill_aggr_route_details(ospf6, &ei_aggr, &rt_aggr, aggr); ospf6_originate_new_aggr_lsa(ospf6, aggr, &rt_aggr); @@ -2815,7 +2830,8 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6, assert(info); if (info->id) { lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), - htonl(info->id), ospf6->router_id, ospf6->lsdb); + htonl(info->id), ospf6->router_id, + ospf6->lsdb); assert(lsa); } @@ -2875,12 +2891,12 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6, return; } - external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( - aggr_lsa->header); + external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END + (aggr_lsa->header); metric = (unsigned long)OSPF6_ASBR_METRIC(external); tag = ospf6_as_external_lsa_get_tag(aggr_lsa); - mtype = CHECK_FLAG(external->bits_metric,\ - OSPF6_ASBR_BIT_E)? 2 : 1; + mtype = CHECK_FLAG(external->bits_metric, + OSPF6_ASBR_BIT_E) ? 2 : 1; /* If tag/metric/metric-type modified , then re-originate the * route with modified tag/metric/metric-type details. @@ -2898,7 +2914,8 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6, mtype, aggr->mtype, &aggr->p); - aggr_lsa = ospf6_as_external_lsa_originate(&rt_aggr, ospf6); + aggr_lsa = ospf6_originate_type5_type7_lsas(&rt_aggr, + ospf6); if (aggr_lsa) SET_FLAG(aggr->aggrflags, OSPF6_EXTERNAL_AGGRT_ORIGINATED); @@ -2928,7 +2945,6 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6, } ospf6_originate_new_aggr_lsa(ospf6, aggr, &rt_aggr); - return; } static void ospf6_aggr_handle_external_info(void *data) @@ -2963,10 +2979,12 @@ static void ospf6_aggr_handle_external_info(void *data) info = rt->route_option; if (info->id) { lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), - htonl(info->id), ospf6->router_id, ospf6->lsdb); + htonl(info->id), ospf6->router_id, + ospf6->lsdb); if (lsa) { if (IS_OSPF6_DEBUG_AGGR) - zlog_debug("%s: LSA found, refresh it", __func__); + zlog_debug("%s: LSA found, refresh it", + __func__); THREAD_OFF(lsa->refresh); thread_add_event(master, ospf6_lsa_refresh, lsa, 0, &lsa->refresh); @@ -2984,9 +3002,7 @@ static void ospf6_aggr_handle_external_info(void *data) node = route_node_get(ospf6->external_id_table, &prefix_id); node->info = rt; - lsa = ospf6_as_external_lsa_originate(rt, ospf6); - - return; + (void)ospf6_originate_type5_type7_lsas(rt, ospf6); } static void @@ -3056,8 +3072,10 @@ static void ospf6_handle_external_aggr_update(struct ospf6 *ospf6) && !CHECK_FLAG(aggr->aggrflags, OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE)) { - lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), - htonl(aggr->id), ospf6->router_id, ospf6->lsdb); + lsa = ospf6_lsdb_lookup( + htons(OSPF6_LSTYPE_AS_EXTERNAL), + htonl(aggr->id), ospf6->router_id, + ospf6->lsdb); if (!lsa) { zlog_warn( "%s: Could not refresh/originate %pFX", @@ -3067,14 +3085,14 @@ static void ospf6_handle_external_aggr_update(struct ospf6 *ospf6) continue; } - asel = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( - lsa->header); + asel = (struct ospf6_as_external_lsa *) + OSPF6_LSA_HEADER_END(lsa->header); metric = (unsigned long)OSPF6_ASBR_METRIC(asel); tag = ospf6_as_external_lsa_get_tag(lsa); - mtype = CHECK_FLAG(asel->bits_metric,\ - OSPF6_ASBR_BIT_E)? 2 : 1; + mtype = CHECK_FLAG(asel->bits_metric, + OSPF6_ASBR_BIT_E) ? 2 : 1; - /* Fill all the details which will get advertised */ + /* Fill all the details for advertisement */ ospf6_fill_aggr_route_details(ospf6, &ei_aggr, &rt_aggr, aggr); @@ -3089,19 +3107,17 @@ static void ospf6_handle_external_aggr_update(struct ospf6 *ospf6) != aggr->mtype)) { if (IS_OSPF6_DEBUG_AGGR) zlog_debug( - "%s: Changed tag(old:%d new:%d)/metric(o:%u n:%d)/mtype(o:%d n:%d),So refresh the summary route.(%pFX)", - __func__, tag, - ei_aggr.tag, - metric, - (unsigned int)rt_aggr.path.cost, - mtype, aggr->mtype, - &aggr->p); - - lsa = ospf6_as_external_lsa_originate(&rt_aggr, ospf6); - if (lsa) - SET_FLAG(aggr->aggrflags, - OSPF6_EXTERNAL_AGGRT_ORIGINATED); + "%s: Changed tag(old:%d new:%d)/metric(o:%u n:%d)/mtype(o:%d n:%d),So refresh the summary route.(%pFX)", + __func__, tag, + ei_aggr.tag, + metric, + (unsigned int)rt_aggr.path.cost, + mtype, aggr->mtype, + &aggr->p); + (void)ospf6_originate_type5_type7_lsas( + &rt_aggr, + ospf6); } } @@ -3182,14 +3198,13 @@ static void ospf6_handle_exnl_rt_after_aggr_del(struct ospf6 *ospf6, THREAD_OFF(lsa->refresh); thread_add_event(master, ospf6_lsa_refresh, lsa, 0, &lsa->refresh); - } - else { + } else { if (IS_OSPF6_DEBUG_AGGR) zlog_debug("%s: Originate external route(%pFX)", __func__, &rt->prefix); - lsa = ospf6_as_external_lsa_originate(rt, ospf6); + (void)ospf6_originate_type5_type7_lsas(rt, ospf6); } } @@ -3248,7 +3263,8 @@ ospf6_handle_external_aggr_add(struct ospf6 *ospf6) */ ospf6_delete_all_marked_aggregators(ospf6); - for (rt = ospf6_route_head(ospf6->external_table); rt; rt = ospf6_route_next(rt)) { + for (rt = ospf6_route_head(ospf6->external_table); rt; + rt = ospf6_route_next(rt)) { ei = rt->route_option; if (ei != NULL) { if (is_default_prefix(&rt->prefix)) @@ -3370,7 +3386,8 @@ int ospf6_asbr_external_rt_advertise(struct ospf6 *ospf6, if (!OSPF6_EXTERNAL_RT_COUNT(aggr)) return OSPF6_SUCCESS; - ospf6_start_asbr_summary_delay_timer(ospf6, aggr, OSPF6_ROUTE_AGGR_MODIFY); + ospf6_start_asbr_summary_delay_timer(ospf6, aggr, + OSPF6_ROUTE_AGGR_MODIFY); return OSPF6_SUCCESS; } @@ -3568,7 +3585,6 @@ void ospf6_handle_external_lsa_origination(struct ospf6 *ospf6, struct ospf6_external_info *info; struct prefix prefix_id; struct route_node *node; - char pbuf[PREFIX2STR_BUFFER], ibuf[16]; if (!is_default_prefix(p)) { aggr = ospf6_external_aggr_match(ospf6, @@ -3612,8 +3628,7 @@ void ospf6_handle_external_lsa_origination(struct ospf6 *ospf6, node = route_node_get(ospf6->external_id_table, &prefix_id); node->info = rt; - } - else { + } else { prefix_id.family = AF_INET; prefix_id.prefixlen = 32; prefix_id.u.prefix4.s_addr = htonl(info->id); @@ -3622,15 +3637,12 @@ void ospf6_handle_external_lsa_origination(struct ospf6 *ospf6, rt->path.origin.id = htonl(info->id); if (IS_OSPF6_DEBUG_ASBR) { - inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf)); - prefix2str(p, pbuf, sizeof(pbuf)); - zlog_debug("Advertise new AS-External Id:%s prefix %s metric %u", - ibuf, pbuf, rt->path.metric_type); + zlog_debug("Advertise new AS-External Id:%pI4 prefix %pFX metric %u", + &prefix_id.u.prefix4, p, rt->path.metric_type); } - ospf6_as_external_lsa_originate(rt, ospf6); + ospf6_originate_type5_type7_lsas(rt, ospf6); - return; } void ospf6_unset_all_aggr_flag(struct ospf6 *ospf6) @@ -3642,7 +3654,8 @@ void ospf6_unset_all_aggr_flag(struct ospf6 *ospf6) zlog_debug("Unset the origination bit for all aggregator"); /* Resetting the running external ID counter so that the origination - * of external LSAs starts from the beginning 0.0.0.1 */ + * of external LSAs starts from the beginning 0.0.0.1 + */ ospf6->external_id = OSPF6_EXT_INIT_LS_ID; for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) { diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index a4a6f5f3c9..d5c2edf090 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -55,13 +55,13 @@ typedef enum { OSPF6_ROUTE_AGGR_ADD, OSPF6_ROUTE_AGGR_DEL, OSPF6_ROUTE_AGGR_MODIFY -}ospf6_aggr_action_t; +} ospf6_aggr_action_t; #define OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE 0x1 #define OSPF6_EXTERNAL_AGGRT_ORIGINATED 0x2 #define OSPF6_EXTERNAL_RT_COUNT(aggr) \ - (((struct ospf6_external_aggr_rt *)aggr)->match_extnl_hash->count) + (((struct ospf6_external_aggr_rt *)aggr)->match_extnl_hash->count) struct ospf6_external_aggr_rt { /* range address and masklen */ @@ -84,9 +84,6 @@ struct ospf6_external_aggr_rt { /* To Store the LS ID when LSA is originated */ uint32_t id; - /* How many prefixes are using this range */ - uint32_t refcount; - /* Action to be done after delay timer expiry */ int action; @@ -156,22 +153,23 @@ extern void ospf6_asbr_distribute_list_update(struct ospf6 *ospf6, struct ospf6_redist *ospf6_redist_lookup(struct ospf6 *ospf6, int type, unsigned short instance); extern void ospf6_asbr_routemap_update(const char *mapname); -extern struct ospf6_lsa *ospf6_as_external_lsa_originate(struct ospf6_route *route, - struct ospf6 *ospf6); +extern struct ospf6_lsa * +ospf6_as_external_lsa_originate(struct ospf6_route *route, + struct ospf6 *ospf6); extern void ospf6_asbr_status_update(struct ospf6 *ospf6, int status); int ospf6_asbr_external_rt_advertise(struct ospf6 *ospf6, - struct prefix *p); + struct prefix *p); int ospf6_external_aggr_delay_timer_set(struct ospf6 *ospf6, - unsigned int interval); + unsigned int interval); int ospf6_asbr_external_rt_no_advertise(struct ospf6 *ospf6, - struct prefix *p); + struct prefix *p); struct ospf6_external_aggr_rt * ospf6_external_aggr_config_lookup(struct ospf6 *ospf6, struct prefix *p); int ospf6_external_aggr_config_set(struct ospf6 *ospf6, struct prefix *p, - route_tag_t tag, int metric, int mtype); + route_tag_t tag, int metric, int mtype); int ospf6_external_aggr_config_unset(struct ospf6 *ospf6, struct prefix *p); @@ -180,4 +178,8 @@ void ospf6_handle_external_lsa_origination(struct ospf6 *ospf6, struct prefix *p); void ospf6_external_aggregator_free(struct ospf6_external_aggr_rt *aggr); void ospf6_unset_all_aggr_flag(struct ospf6 *ospf6); +void ospf6_fill_aggr_route_details(struct ospf6 *ospf6, + struct ospf6_external_info *ei_aggr, + struct ospf6_route *rt_aggr, + struct ospf6_external_aggr_rt *aggr); #endif /* OSPF6_ASBR_H */ diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index 7b4fce6ff3..4c95ee69bd 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -52,7 +52,7 @@ (ospf6_lstype_debug(type) & OSPF6_LSA_DEBUG_EXAMIN) #define IS_OSPF6_DEBUG_FLOOD_TYPE(type) \ (ospf6_lstype_debug(type) & OSPF6_LSA_DEBUG_FLOOD) -#define IS_OSPF6_DEBUG_AGGR \ +#define IS_OSPF6_DEBUG_AGGR \ (ospf6_lstype_debug(OSPF6_LSTYPE_AS_EXTERNAL) & OSPF6_LSA_DEBUG_AGGR) \ /* LSA definition */ @@ -266,5 +266,6 @@ extern void install_element_ospf6_debug_lsa(void); extern void ospf6_lsa_age_set(struct ospf6_lsa *lsa); extern void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6); extern struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa); -struct ospf6_lsa *ospf6_find_external_lsa(struct ospf6 *ospf6, struct prefix *p); +struct ospf6_lsa *ospf6_find_external_lsa(struct ospf6 *ospf6, + struct prefix *p); #endif /* OSPF6_LSA_H */ diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index 9f8cdf8fb7..9810ccb498 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -1159,10 +1159,48 @@ static void ospf6_nssa_flush_area(struct ospf6_area *area) } } +static void ospf6_check_and_originate_type7_lsa(struct ospf6_area *area) +{ + struct ospf6_route rt_aggr, *route; + struct route_node *rn = NULL; + struct ospf6_external_info ei_aggr; + struct ospf6_external_aggr_rt *aggr; + + /* Loop through the external_table to find the LSAs originated + * without aggregation and originate type-7 LSAs for them. + */ + for (route = ospf6_route_head( + area->ospf6->external_table); + route; route = ospf6_route_next(route)) { + /* This means the Type-5 LSA was originated for this route */ + if (route->path.origin.id != 0) + ospf6_nssa_lsa_originate(route, area); + + } + + /* Loop through the aggregation table to originate type-7 LSAs + * for the aggregated type-5 LSAs + */ + for (rn = route_top(area->ospf6->rt_aggr_tbl); rn; + rn = route_next(rn)) { + if (!rn->info) + continue; + + aggr = rn->info; + + if (CHECK_FLAG(aggr->aggrflags, + OSPF6_EXTERNAL_AGGRT_ORIGINATED)) { + /* Prepare the external_info for aggregator */ + ospf6_fill_aggr_route_details(area->ospf6, &ei_aggr, + &rt_aggr, aggr); + ospf6_nssa_lsa_originate(&rt_aggr, area); + } + } + +} + static void ospf6_area_nssa_update(struct ospf6_area *area) { - struct ospf6_route *route; - if (IS_AREA_NSSA(area)) { if (!ospf6_check_and_set_router_abr(area->ospf6)) OSPF6_OPT_CLEAR(area->options, OSPF6_OPT_E); @@ -1194,10 +1232,7 @@ static void ospf6_area_nssa_update(struct ospf6_area *area) zlog_debug("NSSA area %s", area->name); /* Originate NSSA LSA */ - for (route = ospf6_route_head( - area->ospf6->external_table); - route; route = ospf6_route_next(route)) - ospf6_nssa_lsa_originate(route, area); + ospf6_check_and_originate_type7_lsa(area); } } else { /* Disable NSSA */ diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 513dfb14bc..65d96067cd 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -715,6 +715,7 @@ static void ospf6_process_reset(struct ospf6 *ospf6) struct interface *ifp; struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id); + ospf6_unset_all_aggr_flag(ospf6); ospf6_flush_self_originated_lsas_now(ospf6); ospf6->inst_shutdown = 0; ospf6_db_clear(ospf6); @@ -1710,13 +1711,13 @@ bool ospf6_is_valid_summary_addr(struct vty *vty, struct prefix *p) return false; } - /* Host route should not be configured as summary address */ - if (p->prefixlen == IPV6_MAX_PREFIXLEN) { + /* Host route should not be configured as summary address */ + if (p->prefixlen == IPV6_MAX_BITLEN) { vty_out(vty, "Host route should not be configured as summary address.\n"); - return false; + return false; } - return true; + return true; } /* External Route Aggregation */ @@ -1736,6 +1737,7 @@ DEFPY (ospf6_external_route_aggregation, struct prefix p; int ret = CMD_SUCCESS; + p.family = AF_INET6; ret = str2prefix(prefix_str, &p); if (ret == 0) { @@ -1832,7 +1834,7 @@ DEFPY (ospf6_external_route_aggregation_no_advertise, if (ret == OSPF6_INVALID) vty_out(vty, "!!Invalid configuration\n"); - return CMD_SUCCESS; + return CMD_SUCCESS; } DEFPY (no_ospf6_external_route_aggregation_no_advertise, @@ -1945,16 +1947,16 @@ ospf6_show_summary_address(struct vty *vty, struct ospf6 *ospf6, bool uj, const char *detail) { struct route_node *rn; - static char header[] = "Summary-address Metric-type Metric Tag External_Rt_count\n"; + static const char header[] = "Summary-address Metric-type Metric Tag External_Rt_count\n"; if (!uj) { vty_out(vty, "aggregation delay interval :%d(in seconds)\n\n", ospf6->aggr_delay_interval); vty_out(vty, "%s\n", header); - } - else + } else { json_object_int_add(json, "aggregation delay interval", ospf6->aggr_delay_interval); + } for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) if (rn->info) { @@ -2011,8 +2013,8 @@ ospf6_show_summary_address(struct vty *vty, struct ospf6 *ospf6, ? vty_out(vty, "%-16s", "E2") : vty_out(vty, "%-16s", "E1"); vty_out(vty, "%-11d", (aggr->metric != -1) - ? aggr->metric - : DEFAULT_DEFAULT_METRIC); + ? aggr->metric + : DEFAULT_DEFAULT_METRIC); vty_out(vty, "%-12u", aggr->tag); @@ -2047,7 +2049,7 @@ DEFPY (show_ipv6_ospf6_external_aggregator, { bool uj = use_json(argc, argv); struct ospf6 *ospf6 = NULL; - json_object *json = NULL; + json_object *json = NULL; if (uj) json = json_object_new_object(); @@ -2069,7 +2071,7 @@ DEFPY (show_ipv6_ospf6_external_aggregator, ospf6_show_summary_address(vty, ospf6, json, uj, detail); if (uj) { - vty_out(vty, "%s\n",json_object_to_json_string_ext( + vty_out(vty, "%s\n", json_object_to_json_string_ext( json, JSON_C_TO_STRING_PRETTY)); json_object_free(json); }