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<mrasool@vmware.com>
This commit is contained in:
Mobashshera Rasool 2021-07-09 09:47:40 +00:00
parent 4dc4388691
commit c3a70f6517
5 changed files with 172 additions and 119 deletions

View file

@ -71,6 +71,25 @@ unsigned char conf_debug_ospf6_asbr = 0;
#define ZROUTE_NAME(x) zebra_route_string(x) #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 */ /* AS External LSA origination */
struct ospf6_lsa *ospf6_as_external_lsa_originate(struct ospf6_route *route, struct ospf6_lsa *ospf6_as_external_lsa_originate(struct ospf6_route *route,
struct ospf6 *ospf6) struct ospf6 *ospf6)
@ -1334,8 +1353,6 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
struct ospf6 *ospf6) struct ospf6 *ospf6)
{ {
route_map_result_t ret; route_map_result_t ret;
struct listnode *lnode;
struct ospf6_area *oa;
struct ospf6_route troute; struct ospf6_route troute;
struct ospf6_external_info tinfo; struct ospf6_external_info tinfo;
struct ospf6_route *route, *match; 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_handle_external_lsa_origination(ospf6, match, prefix);
ospf6_asbr_status_update(ospf6, ospf6->redistribute); 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; return;
} }
@ -1494,18 +1507,15 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
ospf6_handle_external_lsa_origination(ospf6, route, prefix); ospf6_handle_external_lsa_origination(ospf6, route, prefix);
ospf6_asbr_status_update(ospf6, ospf6->redistribute); 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, static void ospf6_asbr_external_lsa_remove_by_id(struct ospf6 *ospf6,
uint32_t id) uint32_t id)
{ {
struct ospf6_lsa *lsa; struct ospf6_lsa *lsa;
struct ospf6_area *oa;
struct listnode *lnode;
lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL),
htonl(id), ospf6->router_id, ospf6->lsdb); 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); 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 static void
@ -1526,8 +1549,9 @@ ospf6_link_route_to_aggr(struct ospf6_external_aggr_rt *aggr,
} }
static void static void
ospf6_unlink_route_from_aggr(struct ospf6 *ospf6, struct ospf6_external_aggr_rt *aggr, ospf6_unlink_route_from_aggr(struct ospf6 *ospf6,
struct ospf6_route *rt) struct ospf6_external_aggr_rt *aggr,
struct ospf6_route *rt)
{ {
if (IS_OSPF6_DEBUG_AGGR) if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: Unlinking external route(%pFX) from aggregator(%pFX), external route count:%ld", 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) if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: Flushing the aggregate route)", zlog_debug("%s: Flushing the aggregate route)",
__func__);; __func__);
aggr->id = 0; aggr->id = 0;
/* Unset the Origination flag */ /* Unset the Origination flag */
UNSET_FLAG(aggr->aggrflags, OSPF6_EXTERNAL_AGGRT_ORIGINATED); 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, void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
struct prefix *prefix, struct ospf6 *ospf6) struct prefix *prefix, struct ospf6 *ospf6)
{ {
struct ospf6_area *oa;
struct ospf6_route *match; struct ospf6_route *match;
struct ospf6_external_info *info = NULL; struct ospf6_external_info *info = NULL;
struct ospf6_lsa *lsa;
struct listnode *lnode;
match = ospf6_route_lookup(prefix, ospf6->external_table); match = ospf6_route_lookup(prefix, ospf6->external_table);
if (match == NULL) { if (match == NULL) {
@ -1581,20 +1602,6 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
return; 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 /* This means aggregation on this route was not done, hence remove LSA
* if any originated for this prefix * if any originated for this prefix
*/ */
@ -1603,6 +1610,10 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
else else
ospf6_unlink_route_from_aggr(ospf6, match->aggr_route, match); 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); ospf6_route_remove(match, ospf6->external_table);
XFREE(MTYPE_OSPF6_EXTERNAL_INFO, info); XFREE(MTYPE_OSPF6_EXTERNAL_INFO, info);
@ -1621,6 +1632,7 @@ DEFUN (ospf6_redistribute,
VTY_DECLVAR_CONTEXT(ospf6, ospf6); VTY_DECLVAR_CONTEXT(ospf6, ospf6);
char *proto = argv[argc - 1]->text; char *proto = argv[argc - 1]->text;
type = proto_redistnum(AFI_IP6, proto); type = proto_redistnum(AFI_IP6, proto);
if (type < 0) if (type < 0)
return CMD_WARNING_CONFIG_FAILED; 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); rt_aggr->path.origin.id = htonl(aggr->id);
/* Originate summary LSA */ /* Originate summary LSA */
lsa = ospf6_as_external_lsa_originate(rt_aggr, ospf6); lsa = ospf6_originate_type5_type7_lsas(rt_aggr, ospf6);
if (lsa) { if (lsa) {
if (IS_OSPF6_DEBUG_AGGR) if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: Set the origination bit for aggregator", zlog_debug("%s: Set the origination bit for aggregator",
__func__); __func__);
SET_FLAG(aggr->aggrflags, OSPF6_EXTERNAL_AGGRT_ORIGINATED); 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_external_info *ei_aggr,
struct ospf6_route *rt_aggr, struct ospf6_route *rt_aggr,
struct ospf6_external_aggr_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 */ /* When metric is not configured, apply the default metric */
rt_aggr->path.cost = ((aggr->metric == -1) ? 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.metric_type = aggr->mtype;
rt_aggr->path.origin.id = htonl(aggr->id); 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.", zlog_debug("%s: Don't originate the summary address,It is configured to not-advertise.",
__func__); __func__);
if (CHECK_FLAG(aggr->aggrflags, OSPF6_EXTERNAL_AGGRT_ORIGINATED)) { if (CHECK_FLAG(aggr->aggrflags,
OSPF6_EXTERNAL_AGGRT_ORIGINATED)) {
if (IS_OSPF6_DEBUG_AGGR) if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: No-advertise,So Flush the Aggregate route(%pFX)", zlog_debug("%s: No-advertise,So Flush the Aggregate route(%pFX)",
__func__, __func__,
@ -2746,7 +2758,8 @@ ospf6_aggr_handle_advertise_change(struct ospf6 *ospf6,
ospf6_asbr_external_lsa_remove_by_id(ospf6, aggr->id); ospf6_asbr_external_lsa_remove_by_id(ospf6, aggr->id);
/* Setting it here as 0, so that it is considered as /* Setting it here as 0, so that it is considered as
* invalid */ * invalid
*/
aggr->id = 0; aggr->id = 0;
UNSET_FLAG(aggr->aggrflags, UNSET_FLAG(aggr->aggrflags,
OSPF6_EXTERNAL_AGGRT_ORIGINATED); 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 /* 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 (OSPF6_EXTERNAL_RT_COUNT(aggr) == 0) {
if (IS_OSPF6_DEBUG_AGGR) if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: No routes present under this aggregation", 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", zlog_debug("%s: Now it is advertisable",
__func__); __func__);
/* Prepare the external_info for aggregator */ /* Prepare the external_info for aggregator
/* Fill all the details which will get advertised */ * Fill all the details which will get advertised
*/
ospf6_fill_aggr_route_details(ospf6, &ei_aggr, &rt_aggr, aggr); ospf6_fill_aggr_route_details(ospf6, &ei_aggr, &rt_aggr, aggr);
ospf6_originate_new_aggr_lsa(ospf6, aggr, &rt_aggr); ospf6_originate_new_aggr_lsa(ospf6, aggr, &rt_aggr);
@ -2815,7 +2830,8 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6,
assert(info); assert(info);
if (info->id) { if (info->id) {
lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), 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); assert(lsa);
} }
@ -2875,12 +2891,12 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6,
return; return;
} }
external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END
aggr_lsa->header); (aggr_lsa->header);
metric = (unsigned long)OSPF6_ASBR_METRIC(external); metric = (unsigned long)OSPF6_ASBR_METRIC(external);
tag = ospf6_as_external_lsa_get_tag(aggr_lsa); tag = ospf6_as_external_lsa_get_tag(aggr_lsa);
mtype = CHECK_FLAG(external->bits_metric,\ mtype = CHECK_FLAG(external->bits_metric,
OSPF6_ASBR_BIT_E)? 2 : 1; OSPF6_ASBR_BIT_E) ? 2 : 1;
/* If tag/metric/metric-type modified , then re-originate the /* If tag/metric/metric-type modified , then re-originate the
* route with modified tag/metric/metric-type details. * route with modified tag/metric/metric-type details.
@ -2898,7 +2914,8 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6,
mtype, aggr->mtype, mtype, aggr->mtype,
&aggr->p); &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) if (aggr_lsa)
SET_FLAG(aggr->aggrflags, SET_FLAG(aggr->aggrflags,
OSPF6_EXTERNAL_AGGRT_ORIGINATED); OSPF6_EXTERNAL_AGGRT_ORIGINATED);
@ -2928,7 +2945,6 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6,
} }
ospf6_originate_new_aggr_lsa(ospf6, aggr, &rt_aggr); ospf6_originate_new_aggr_lsa(ospf6, aggr, &rt_aggr);
return;
} }
static void ospf6_aggr_handle_external_info(void *data) 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; info = rt->route_option;
if (info->id) { if (info->id) {
lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), 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 (lsa) {
if (IS_OSPF6_DEBUG_AGGR) 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_OFF(lsa->refresh);
thread_add_event(master, ospf6_lsa_refresh, lsa, 0, thread_add_event(master, ospf6_lsa_refresh, lsa, 0,
&lsa->refresh); &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 = route_node_get(ospf6->external_id_table, &prefix_id);
node->info = rt; node->info = rt;
lsa = ospf6_as_external_lsa_originate(rt, ospf6); (void)ospf6_originate_type5_type7_lsas(rt, ospf6);
return;
} }
static void static void
@ -3056,8 +3072,10 @@ static void ospf6_handle_external_aggr_update(struct ospf6 *ospf6)
&& !CHECK_FLAG(aggr->aggrflags, && !CHECK_FLAG(aggr->aggrflags,
OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE)) { OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE)) {
lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), lsa = ospf6_lsdb_lookup(
htonl(aggr->id), ospf6->router_id, ospf6->lsdb); htons(OSPF6_LSTYPE_AS_EXTERNAL),
htonl(aggr->id), ospf6->router_id,
ospf6->lsdb);
if (!lsa) { if (!lsa) {
zlog_warn( zlog_warn(
"%s: Could not refresh/originate %pFX", "%s: Could not refresh/originate %pFX",
@ -3067,14 +3085,14 @@ static void ospf6_handle_external_aggr_update(struct ospf6 *ospf6)
continue; continue;
} }
asel = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( asel = (struct ospf6_as_external_lsa *)
lsa->header); OSPF6_LSA_HEADER_END(lsa->header);
metric = (unsigned long)OSPF6_ASBR_METRIC(asel); metric = (unsigned long)OSPF6_ASBR_METRIC(asel);
tag = ospf6_as_external_lsa_get_tag(lsa); tag = ospf6_as_external_lsa_get_tag(lsa);
mtype = CHECK_FLAG(asel->bits_metric,\ mtype = CHECK_FLAG(asel->bits_metric,
OSPF6_ASBR_BIT_E)? 2 : 1; 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, ospf6_fill_aggr_route_details(ospf6, &ei_aggr,
&rt_aggr, aggr); &rt_aggr, aggr);
@ -3089,19 +3107,17 @@ static void ospf6_handle_external_aggr_update(struct ospf6 *ospf6)
!= aggr->mtype)) { != aggr->mtype)) {
if (IS_OSPF6_DEBUG_AGGR) if (IS_OSPF6_DEBUG_AGGR)
zlog_debug( 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)", "%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, __func__, tag,
ei_aggr.tag, ei_aggr.tag,
metric, metric,
(unsigned int)rt_aggr.path.cost, (unsigned int)rt_aggr.path.cost,
mtype, aggr->mtype, mtype, aggr->mtype,
&aggr->p); &aggr->p);
lsa = ospf6_as_external_lsa_originate(&rt_aggr, ospf6);
if (lsa)
SET_FLAG(aggr->aggrflags,
OSPF6_EXTERNAL_AGGRT_ORIGINATED);
(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_OFF(lsa->refresh);
thread_add_event(master, ospf6_lsa_refresh, lsa, 0, thread_add_event(master, ospf6_lsa_refresh, lsa, 0,
&lsa->refresh); &lsa->refresh);
} } else {
else {
if (IS_OSPF6_DEBUG_AGGR) if (IS_OSPF6_DEBUG_AGGR)
zlog_debug("%s: Originate external route(%pFX)", zlog_debug("%s: Originate external route(%pFX)",
__func__, __func__,
&rt->prefix); &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); 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; ei = rt->route_option;
if (ei != NULL) { if (ei != NULL) {
if (is_default_prefix(&rt->prefix)) 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)) if (!OSPF6_EXTERNAL_RT_COUNT(aggr))
return OSPF6_SUCCESS; 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; return OSPF6_SUCCESS;
} }
@ -3568,7 +3585,6 @@ void ospf6_handle_external_lsa_origination(struct ospf6 *ospf6,
struct ospf6_external_info *info; struct ospf6_external_info *info;
struct prefix prefix_id; struct prefix prefix_id;
struct route_node *node; struct route_node *node;
char pbuf[PREFIX2STR_BUFFER], ibuf[16];
if (!is_default_prefix(p)) { if (!is_default_prefix(p)) {
aggr = ospf6_external_aggr_match(ospf6, 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 = route_node_get(ospf6->external_id_table, &prefix_id);
node->info = rt; node->info = rt;
} } else {
else {
prefix_id.family = AF_INET; prefix_id.family = AF_INET;
prefix_id.prefixlen = 32; prefix_id.prefixlen = 32;
prefix_id.u.prefix4.s_addr = htonl(info->id); 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); rt->path.origin.id = htonl(info->id);
if (IS_OSPF6_DEBUG_ASBR) { if (IS_OSPF6_DEBUG_ASBR) {
inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf)); zlog_debug("Advertise new AS-External Id:%pI4 prefix %pFX metric %u",
prefix2str(p, pbuf, sizeof(pbuf)); &prefix_id.u.prefix4, p, rt->path.metric_type);
zlog_debug("Advertise new AS-External Id:%s prefix %s metric %u",
ibuf, pbuf, 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) 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"); zlog_debug("Unset the origination bit for all aggregator");
/* Resetting the running external ID counter so that the origination /* 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; ospf6->external_id = OSPF6_EXT_INIT_LS_ID;
for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) { for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) {

View file

@ -55,13 +55,13 @@ typedef enum {
OSPF6_ROUTE_AGGR_ADD, OSPF6_ROUTE_AGGR_ADD,
OSPF6_ROUTE_AGGR_DEL, OSPF6_ROUTE_AGGR_DEL,
OSPF6_ROUTE_AGGR_MODIFY OSPF6_ROUTE_AGGR_MODIFY
}ospf6_aggr_action_t; } ospf6_aggr_action_t;
#define OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE 0x1 #define OSPF6_EXTERNAL_AGGRT_NO_ADVERTISE 0x1
#define OSPF6_EXTERNAL_AGGRT_ORIGINATED 0x2 #define OSPF6_EXTERNAL_AGGRT_ORIGINATED 0x2
#define OSPF6_EXTERNAL_RT_COUNT(aggr) \ #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 { struct ospf6_external_aggr_rt {
/* range address and masklen */ /* range address and masklen */
@ -84,9 +84,6 @@ struct ospf6_external_aggr_rt {
/* To Store the LS ID when LSA is originated */ /* To Store the LS ID when LSA is originated */
uint32_t id; uint32_t id;
/* How many prefixes are using this range */
uint32_t refcount;
/* Action to be done after delay timer expiry */ /* Action to be done after delay timer expiry */
int action; 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, struct ospf6_redist *ospf6_redist_lookup(struct ospf6 *ospf6, int type,
unsigned short instance); unsigned short instance);
extern void ospf6_asbr_routemap_update(const char *mapname); extern void ospf6_asbr_routemap_update(const char *mapname);
extern struct ospf6_lsa *ospf6_as_external_lsa_originate(struct ospf6_route *route, extern struct ospf6_lsa *
struct ospf6 *ospf6); ospf6_as_external_lsa_originate(struct ospf6_route *route,
struct ospf6 *ospf6);
extern void ospf6_asbr_status_update(struct ospf6 *ospf6, int status); extern void ospf6_asbr_status_update(struct ospf6 *ospf6, int status);
int ospf6_asbr_external_rt_advertise(struct ospf6 *ospf6, 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, 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, int ospf6_asbr_external_rt_no_advertise(struct ospf6 *ospf6,
struct prefix *p); struct prefix *p);
struct ospf6_external_aggr_rt * struct ospf6_external_aggr_rt *
ospf6_external_aggr_config_lookup(struct ospf6 *ospf6, struct prefix *p); ospf6_external_aggr_config_lookup(struct ospf6 *ospf6, struct prefix *p);
int ospf6_external_aggr_config_set(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, int ospf6_external_aggr_config_unset(struct ospf6 *ospf6,
struct prefix *p); struct prefix *p);
@ -180,4 +178,8 @@ void ospf6_handle_external_lsa_origination(struct ospf6 *ospf6,
struct prefix *p); struct prefix *p);
void ospf6_external_aggregator_free(struct ospf6_external_aggr_rt *aggr); void ospf6_external_aggregator_free(struct ospf6_external_aggr_rt *aggr);
void ospf6_unset_all_aggr_flag(struct ospf6 *ospf6); 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 */ #endif /* OSPF6_ASBR_H */

View file

@ -52,7 +52,7 @@
(ospf6_lstype_debug(type) & OSPF6_LSA_DEBUG_EXAMIN) (ospf6_lstype_debug(type) & OSPF6_LSA_DEBUG_EXAMIN)
#define IS_OSPF6_DEBUG_FLOOD_TYPE(type) \ #define IS_OSPF6_DEBUG_FLOOD_TYPE(type) \
(ospf6_lstype_debug(type) & OSPF6_LSA_DEBUG_FLOOD) (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) \ (ospf6_lstype_debug(OSPF6_LSTYPE_AS_EXTERNAL) & OSPF6_LSA_DEBUG_AGGR) \
/* LSA definition */ /* 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_lsa_age_set(struct ospf6_lsa *lsa);
extern void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6); extern void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6);
extern struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa); 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 */ #endif /* OSPF6_LSA_H */

View file

@ -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) static void ospf6_area_nssa_update(struct ospf6_area *area)
{ {
struct ospf6_route *route;
if (IS_AREA_NSSA(area)) { if (IS_AREA_NSSA(area)) {
if (!ospf6_check_and_set_router_abr(area->ospf6)) if (!ospf6_check_and_set_router_abr(area->ospf6))
OSPF6_OPT_CLEAR(area->options, OSPF6_OPT_E); 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); zlog_debug("NSSA area %s", area->name);
/* Originate NSSA LSA */ /* Originate NSSA LSA */
for (route = ospf6_route_head( ospf6_check_and_originate_type7_lsa(area);
area->ospf6->external_table);
route; route = ospf6_route_next(route))
ospf6_nssa_lsa_originate(route, area);
} }
} else { } else {
/* Disable NSSA */ /* Disable NSSA */

View file

@ -715,6 +715,7 @@ static void ospf6_process_reset(struct ospf6 *ospf6)
struct interface *ifp; struct interface *ifp;
struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id); struct vrf *vrf = vrf_lookup_by_id(ospf6->vrf_id);
ospf6_unset_all_aggr_flag(ospf6);
ospf6_flush_self_originated_lsas_now(ospf6); ospf6_flush_self_originated_lsas_now(ospf6);
ospf6->inst_shutdown = 0; ospf6->inst_shutdown = 0;
ospf6_db_clear(ospf6); ospf6_db_clear(ospf6);
@ -1710,13 +1711,13 @@ bool ospf6_is_valid_summary_addr(struct vty *vty, struct prefix *p)
return false; return false;
} }
/* Host route should not be configured as summary address */ /* Host route should not be configured as summary address */
if (p->prefixlen == IPV6_MAX_PREFIXLEN) { if (p->prefixlen == IPV6_MAX_BITLEN) {
vty_out(vty, "Host route should not be configured as summary address.\n"); vty_out(vty, "Host route should not be configured as summary address.\n");
return false; return false;
} }
return true; return true;
} }
/* External Route Aggregation */ /* External Route Aggregation */
@ -1736,6 +1737,7 @@ DEFPY (ospf6_external_route_aggregation,
struct prefix p; struct prefix p;
int ret = CMD_SUCCESS; int ret = CMD_SUCCESS;
p.family = AF_INET6; p.family = AF_INET6;
ret = str2prefix(prefix_str, &p); ret = str2prefix(prefix_str, &p);
if (ret == 0) { if (ret == 0) {
@ -1832,7 +1834,7 @@ DEFPY (ospf6_external_route_aggregation_no_advertise,
if (ret == OSPF6_INVALID) if (ret == OSPF6_INVALID)
vty_out(vty, "!!Invalid configuration\n"); vty_out(vty, "!!Invalid configuration\n");
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFPY (no_ospf6_external_route_aggregation_no_advertise, 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) bool uj, const char *detail)
{ {
struct route_node *rn; 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) { if (!uj) {
vty_out(vty, "aggregation delay interval :%d(in seconds)\n\n", vty_out(vty, "aggregation delay interval :%d(in seconds)\n\n",
ospf6->aggr_delay_interval); ospf6->aggr_delay_interval);
vty_out(vty, "%s\n", header); vty_out(vty, "%s\n", header);
} } else {
else
json_object_int_add(json, "aggregation delay interval", json_object_int_add(json, "aggregation delay interval",
ospf6->aggr_delay_interval); ospf6->aggr_delay_interval);
}
for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn)) for (rn = route_top(ospf6->rt_aggr_tbl); rn; rn = route_next(rn))
if (rn->info) { 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", "E2")
: vty_out(vty, "%-16s", "E1"); : vty_out(vty, "%-16s", "E1");
vty_out(vty, "%-11d", (aggr->metric != -1) vty_out(vty, "%-11d", (aggr->metric != -1)
? aggr->metric ? aggr->metric
: DEFAULT_DEFAULT_METRIC); : DEFAULT_DEFAULT_METRIC);
vty_out(vty, "%-12u", aggr->tag); vty_out(vty, "%-12u", aggr->tag);
@ -2047,7 +2049,7 @@ DEFPY (show_ipv6_ospf6_external_aggregator,
{ {
bool uj = use_json(argc, argv); bool uj = use_json(argc, argv);
struct ospf6 *ospf6 = NULL; struct ospf6 *ospf6 = NULL;
json_object *json = NULL; json_object *json = NULL;
if (uj) if (uj)
json = json_object_new_object(); json = json_object_new_object();
@ -2069,7 +2071,7 @@ DEFPY (show_ipv6_ospf6_external_aggregator,
ospf6_show_summary_address(vty, ospf6, json, uj, detail); ospf6_show_summary_address(vty, ospf6, json, uj, detail);
if (uj) { 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, JSON_C_TO_STRING_PRETTY));
json_object_free(json); json_object_free(json);
} }