mirror of https://github.com/FRRouting/frr.git
Merge pull request #9752 from opensourcerouting/ospf6d-nssa-ranges
ospf6d: add support for NSSA Type-7 address ranges
This commit is contained in:
commit
ed131d8b74
|
@ -181,7 +181,7 @@ OSPF6 area
|
|||
The `not-advertise` option, when present, prevents the summary route from
|
||||
being advertised, effectively filtering the summarized routes.
|
||||
|
||||
.. clicmd:: area A.B.C.D nssa [no-summary]
|
||||
.. clicmd:: area A.B.C.D nssa [no-summary] [default-information-originate [metric-type (1-2)] [metric (0-16777214)]]
|
||||
|
||||
.. clicmd:: area (0-4294967295) nssa [no-summary] [default-information-originate [metric-type (1-2)] [metric (0-16777214)]]
|
||||
|
||||
|
@ -209,6 +209,21 @@ OSPF6 area
|
|||
existence of a default route in the RIB that wasn't learned via the OSPF
|
||||
protocol.
|
||||
|
||||
.. clicmd:: area A.B.C.D nssa range X:X::X:X/M [<not-advertise|cost (0-16777215)>]
|
||||
|
||||
.. clicmd:: area (0-4294967295) nssa range X:X::X:X/M [<not-advertise|cost (0-16777215)>]
|
||||
|
||||
Summarize a group of external subnets into a single Type-7 LSA, which is
|
||||
then translated to a Type-5 LSA and avertised to the backbone.
|
||||
This command can only be used at the area boundary (NSSA ABR router).
|
||||
|
||||
By default, the metric of the summary route is calculated as the highest
|
||||
metric among the summarized routes. The `cost` option, however, can be used
|
||||
to set an explicit metric.
|
||||
|
||||
The `not-advertise` option, when present, prevents the summary route from
|
||||
being advertised, effectively filtering the summarized routes.
|
||||
|
||||
.. clicmd:: area A.B.C.D export-list NAME
|
||||
|
||||
.. clicmd:: area (0-4294967295) export-list NAME
|
||||
|
|
|
@ -106,8 +106,7 @@ static int ospf6_abr_nexthops_belong_to_area(struct ospf6_route *route,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ospf6_abr_delete_route(struct ospf6_route *range,
|
||||
struct ospf6_route *summary,
|
||||
static void ospf6_abr_delete_route(struct ospf6_route *summary,
|
||||
struct ospf6_route_table *summary_table,
|
||||
struct ospf6_lsa *old)
|
||||
{
|
||||
|
@ -385,8 +384,8 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
|
|||
zlog_debug(
|
||||
"The range is not active. withdraw");
|
||||
|
||||
ospf6_abr_delete_route(route, summary,
|
||||
summary_table, old);
|
||||
ospf6_abr_delete_route(summary, summary_table,
|
||||
old);
|
||||
}
|
||||
} else if (old) {
|
||||
ospf6_route_remove(summary, summary_table);
|
||||
|
@ -400,7 +399,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
|
|||
zlog_debug(
|
||||
"Area has been stubbed, purge Inter-Router LSA");
|
||||
|
||||
ospf6_abr_delete_route(route, summary, summary_table, old);
|
||||
ospf6_abr_delete_route(summary, summary_table, old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -409,7 +408,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
|
|||
if (is_debug)
|
||||
zlog_debug("Area has been stubbed, purge prefix LSA");
|
||||
|
||||
ospf6_abr_delete_route(route, summary, summary_table, old);
|
||||
ospf6_abr_delete_route(summary, summary_table, old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -444,8 +443,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
|
|||
if (is_debug)
|
||||
zlog_debug(
|
||||
"This is the secondary path to the ASBR, ignore");
|
||||
ospf6_abr_delete_route(route, summary, summary_table,
|
||||
old);
|
||||
ospf6_abr_delete_route(summary, summary_table, old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -475,8 +473,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
|
|||
zlog_debug(
|
||||
"Suppressed by range %pFX of area %s",
|
||||
&range->prefix, route_area->name);
|
||||
ospf6_abr_delete_route(route, summary, summary_table,
|
||||
old);
|
||||
ospf6_abr_delete_route(summary, summary_table, old);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -488,8 +485,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
|
|||
if (is_debug)
|
||||
zlog_debug(
|
||||
"This is the range with DoNotAdvertise set. ignore");
|
||||
ospf6_abr_delete_route(route, summary, summary_table,
|
||||
old);
|
||||
ospf6_abr_delete_route(summary, summary_table, old);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -497,8 +493,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
|
|||
if (!CHECK_FLAG(route->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)) {
|
||||
if (is_debug)
|
||||
zlog_debug("The range is not active. withdraw");
|
||||
ospf6_abr_delete_route(route, summary, summary_table,
|
||||
old);
|
||||
ospf6_abr_delete_route(summary, summary_table, old);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -608,10 +603,14 @@ void ospf6_abr_range_reset_cost(struct ospf6 *ospf6)
|
|||
struct ospf6_area *oa;
|
||||
struct ospf6_route *range;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa))
|
||||
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
|
||||
for (range = ospf6_route_head(oa->range_table); range;
|
||||
range = ospf6_route_next(range))
|
||||
OSPF6_ABR_RANGE_CLEAR_COST(range);
|
||||
for (range = ospf6_route_head(oa->nssa_range_table); range;
|
||||
range = ospf6_route_next(range))
|
||||
OSPF6_ABR_RANGE_CLEAR_COST(range);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t ospf6_abr_range_compute_cost(struct ospf6_route *range,
|
||||
|
@ -622,10 +621,19 @@ static inline uint32_t ospf6_abr_range_compute_cost(struct ospf6_route *range,
|
|||
|
||||
for (ro = ospf6_route_match_head(&range->prefix, o->route_table); ro;
|
||||
ro = ospf6_route_match_next(&range->prefix, ro)) {
|
||||
if (ro->path.area_id == range->path.area_id
|
||||
&& (ro->path.type == OSPF6_PATH_TYPE_INTRA)
|
||||
&& !CHECK_FLAG(ro->flag, OSPF6_ROUTE_REMOVE))
|
||||
cost = MAX(cost, ro->path.cost);
|
||||
if (CHECK_FLAG(ro->flag, OSPF6_ROUTE_REMOVE))
|
||||
continue;
|
||||
if (ro->path.area_id != range->path.area_id)
|
||||
continue;
|
||||
if (CHECK_FLAG(range->flag, OSPF6_ROUTE_NSSA_RANGE)
|
||||
&& ro->path.type != OSPF6_PATH_TYPE_EXTERNAL1
|
||||
&& ro->path.type != OSPF6_PATH_TYPE_EXTERNAL2)
|
||||
continue;
|
||||
if (!CHECK_FLAG(range->flag, OSPF6_ROUTE_NSSA_RANGE)
|
||||
&& ro->path.type != OSPF6_PATH_TYPE_INTRA)
|
||||
continue;
|
||||
|
||||
cost = MAX(cost, ro->path.cost);
|
||||
}
|
||||
|
||||
return cost;
|
||||
|
@ -674,6 +682,8 @@ void ospf6_abr_range_update(struct ospf6_route *range, struct ospf6 *ospf6)
|
|||
int summary_orig = 0;
|
||||
|
||||
assert(range->type == OSPF6_DEST_TYPE_RANGE);
|
||||
oa = ospf6_area_lookup(range->path.area_id, ospf6);
|
||||
assert(oa);
|
||||
|
||||
/* update range's cost and active flag */
|
||||
cost = ospf6_abr_range_compute_cost(range, ospf6);
|
||||
|
@ -696,34 +706,49 @@ void ospf6_abr_range_update(struct ospf6_route *range, struct ospf6 *ospf6)
|
|||
* if there
|
||||
* were active ranges.
|
||||
*/
|
||||
if (!ospf6_abr_range_summary_needs_update(range, cost))
|
||||
return;
|
||||
|
||||
if (ospf6_abr_range_summary_needs_update(range, cost)) {
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug("%s: range %pFX update", __func__,
|
||||
&range->prefix);
|
||||
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa))
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug("%s: range %pFX update", __func__, &range->prefix);
|
||||
|
||||
if (CHECK_FLAG(range->flag, OSPF6_ROUTE_NSSA_RANGE)) {
|
||||
if (CHECK_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)
|
||||
&& !CHECK_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE)) {
|
||||
ospf6_nssa_lsa_originate(range, oa, true);
|
||||
summary_orig = 1;
|
||||
} else {
|
||||
struct ospf6_lsa *lsa;
|
||||
|
||||
lsa = ospf6_lsdb_lookup(range->path.origin.type,
|
||||
range->path.origin.id,
|
||||
ospf6->router_id, oa->lsdb);
|
||||
if (lsa)
|
||||
ospf6_lsa_premature_aging(lsa);
|
||||
}
|
||||
} else {
|
||||
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
|
||||
summary_orig +=
|
||||
ospf6_abr_originate_summary_to_area(range, oa);
|
||||
}
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)
|
||||
&& summary_orig) {
|
||||
if (!CHECK_FLAG(range->flag,
|
||||
OSPF6_ROUTE_BLACKHOLE_ADDED)) {
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug("Add discard route");
|
||||
if (CHECK_FLAG(range->flag, OSPF6_ROUTE_ACTIVE_SUMMARY)
|
||||
&& summary_orig) {
|
||||
if (!CHECK_FLAG(range->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug("Add discard route");
|
||||
|
||||
ospf6_zebra_add_discard(range, ospf6);
|
||||
}
|
||||
} else {
|
||||
/* Summary removed or no summary generated as no
|
||||
* specifics exist */
|
||||
if (CHECK_FLAG(range->flag,
|
||||
OSPF6_ROUTE_BLACKHOLE_ADDED)) {
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug("Delete discard route");
|
||||
ospf6_zebra_add_discard(range, ospf6);
|
||||
}
|
||||
} else {
|
||||
/* Summary removed or no summary generated as no
|
||||
* specifics exist */
|
||||
if (CHECK_FLAG(range->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug("Delete discard route");
|
||||
|
||||
ospf6_zebra_delete_discard(range, ospf6);
|
||||
}
|
||||
ospf6_zebra_delete_discard(range, ospf6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -306,7 +306,8 @@ struct ospf6_area *ospf6_area_create(uint32_t area_id, struct ospf6 *o, int df)
|
|||
|
||||
oa->range_table = OSPF6_ROUTE_TABLE_CREATE(AREA, PREFIX_RANGES);
|
||||
oa->range_table->scope = oa;
|
||||
bf_init(oa->range_table->idspace, 32);
|
||||
oa->nssa_range_table = OSPF6_ROUTE_TABLE_CREATE(AREA, PREFIX_RANGES);
|
||||
oa->nssa_range_table->scope = oa;
|
||||
oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE(AREA, SUMMARY_PREFIXES);
|
||||
oa->summary_prefix->scope = oa;
|
||||
oa->summary_router = OSPF6_ROUTE_TABLE_CREATE(AREA, SUMMARY_ROUTERS);
|
||||
|
@ -361,6 +362,7 @@ void ospf6_area_delete(struct ospf6_area *oa)
|
|||
ospf6_route_table_delete(oa->route_table);
|
||||
|
||||
ospf6_route_table_delete(oa->range_table);
|
||||
ospf6_route_table_delete(oa->nssa_range_table);
|
||||
ospf6_route_table_delete(oa->summary_prefix);
|
||||
ospf6_route_table_delete(oa->summary_router);
|
||||
|
||||
|
@ -576,8 +578,6 @@ DEFUN (area_range,
|
|||
|
||||
range->path.u.cost_config = cost;
|
||||
|
||||
zlog_debug("%s: for prefix %s, flag = %x", __func__,
|
||||
argv[idx_ipv6_prefixlen]->arg, range->flag);
|
||||
if (range->rnode == NULL) {
|
||||
ospf6_route_add(range, oa->range_table);
|
||||
}
|
||||
|
@ -694,6 +694,22 @@ void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6)
|
|||
vty_out(vty, " no-summary");
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
for (range = ospf6_route_head(oa->nssa_range_table); range;
|
||||
range = ospf6_route_next(range)) {
|
||||
vty_out(vty, " area %s nssa range %pFX", oa->name,
|
||||
&range->prefix);
|
||||
|
||||
if (CHECK_FLAG(range->flag,
|
||||
OSPF6_ROUTE_DO_NOT_ADVERTISE)) {
|
||||
vty_out(vty, " not-advertise");
|
||||
} else {
|
||||
if (range->path.u.cost_config
|
||||
!= OSPF_AREA_RANGE_COST_UNSPEC)
|
||||
vty_out(vty, " cost %u",
|
||||
range->path.u.cost_config);
|
||||
}
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
if (PREFIX_NAME_IN(oa))
|
||||
vty_out(vty, " area %s filter-list prefix %s in\n",
|
||||
oa->name, PREFIX_NAME_IN(oa));
|
||||
|
|
|
@ -46,6 +46,7 @@ struct ospf6_area {
|
|||
/* Summary routes to be originated (includes Configured Address Ranges)
|
||||
*/
|
||||
struct ospf6_route_table *range_table;
|
||||
struct ospf6_route_table *nssa_range_table;
|
||||
struct ospf6_route_table *summary_prefix;
|
||||
struct ospf6_route_table *summary_router;
|
||||
|
||||
|
|
|
@ -266,10 +266,14 @@ void ospf6_decrement_retrans_count(struct ospf6_lsa *lsa)
|
|||
/* RFC2328 section 13.2 Installing LSAs in the database */
|
||||
void ospf6_install_lsa(struct ospf6_lsa *lsa)
|
||||
{
|
||||
struct ospf6 *ospf6;
|
||||
struct timeval now;
|
||||
struct ospf6_lsa *old;
|
||||
struct ospf6_area *area = NULL;
|
||||
|
||||
ospf6 = ospf6_get_by_lsdb(lsa);
|
||||
assert(ospf6);
|
||||
|
||||
/* Remove the old instance from all neighbors' Link state
|
||||
retransmission list (RFC2328 13.2 last paragraph) */
|
||||
old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
|
||||
|
@ -330,20 +334,14 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa)
|
|||
&& !CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)) {
|
||||
|
||||
/* check if it is new lsa ? or existing lsa got modified ?*/
|
||||
if (!old || OSPF6_LSA_IS_CHANGED(old, lsa)) {
|
||||
struct ospf6 *ospf6;
|
||||
|
||||
ospf6 = ospf6_get_by_lsdb(lsa);
|
||||
|
||||
assert(ospf6);
|
||||
|
||||
if (!old || OSPF6_LSA_IS_CHANGED(old, lsa))
|
||||
ospf6_helper_handle_topo_chg(ospf6, lsa);
|
||||
}
|
||||
}
|
||||
|
||||
ospf6_lsdb_add(lsa, lsa->lsdb);
|
||||
|
||||
if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7) {
|
||||
if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
|
||||
&& lsa->header->adv_router != ospf6->router_id) {
|
||||
area = OSPF6_AREA(lsa->lsdb->data);
|
||||
ospf6_translated_nssa_refresh(area, lsa, NULL);
|
||||
ospf6_schedule_abr_task(area->ospf6);
|
||||
|
|
|
@ -1241,7 +1241,6 @@ struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp)
|
|||
{
|
||||
struct listnode *n;
|
||||
struct connected *c;
|
||||
struct in6_addr *l = (struct in6_addr *)NULL;
|
||||
|
||||
/* for each connected address */
|
||||
for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) {
|
||||
|
@ -1250,9 +1249,10 @@ struct in6_addr *ospf6_interface_get_global_address(struct interface *ifp)
|
|||
continue;
|
||||
|
||||
if (!IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
|
||||
l = &c->address->u.prefix6;
|
||||
return &c->address->u.prefix6;
|
||||
}
|
||||
return l;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1070,7 +1070,7 @@ DEFPY (debug_ospf6_lsa_aggregation,
|
|||
|
||||
DEFUN (debug_ospf6_lsa_type,
|
||||
debug_ospf6_lsa_hex_cmd,
|
||||
"debug ospf6 lsa <router|network|inter-prefix|inter-router|as-external|link|intra-prefix|unknown> [<originate|examine|flooding>]",
|
||||
"debug ospf6 lsa <router|network|inter-prefix|inter-router|as-external|nssa|link|intra-prefix|unknown> [<originate|examine|flooding>]",
|
||||
DEBUG_STR
|
||||
OSPF6_STR
|
||||
"Debug Link State Advertisements (LSAs)\n"
|
||||
|
@ -1079,6 +1079,7 @@ DEFUN (debug_ospf6_lsa_type,
|
|||
"Display Inter-Area-Prefix LSAs\n"
|
||||
"Display Inter-Router LSAs\n"
|
||||
"Display As-External LSAs\n"
|
||||
"Display NSSA LSAs\n"
|
||||
"Display Link LSAs\n"
|
||||
"Display Intra-Area-Prefix LSAs\n"
|
||||
"Display LSAs of unknown origin\n"
|
||||
|
@ -1122,7 +1123,7 @@ DEFUN (debug_ospf6_lsa_type,
|
|||
|
||||
DEFUN (no_debug_ospf6_lsa_type,
|
||||
no_debug_ospf6_lsa_hex_cmd,
|
||||
"no debug ospf6 lsa <router|network|inter-prefix|inter-router|as-external|link|intra-prefix|unknown> [<originate|examine|flooding>]",
|
||||
"no debug ospf6 lsa <router|network|inter-prefix|inter-router|as-external|nssa|link|intra-prefix|unknown> [<originate|examine|flooding>]",
|
||||
NO_STR
|
||||
DEBUG_STR
|
||||
OSPF6_STR
|
||||
|
@ -1132,6 +1133,7 @@ DEFUN (no_debug_ospf6_lsa_type,
|
|||
"Display Inter-Area-Prefix LSAs\n"
|
||||
"Display Inter-Router LSAs\n"
|
||||
"Display As-External LSAs\n"
|
||||
"Display NSSA LSAs\n"
|
||||
"Display Link LSAs\n"
|
||||
"Display Intra-Area-Prefix LSAs\n"
|
||||
"Display LSAs of unknown origin\n"
|
||||
|
|
|
@ -87,11 +87,6 @@
|
|||
#define OSPF6_SCOPE_AS 0x4000
|
||||
#define OSPF6_SCOPE_RESERVED 0x6000
|
||||
|
||||
/* AS-external-LSA refresh method. */
|
||||
#define LSA_REFRESH_IF_CHANGED 0
|
||||
#define LSA_REFRESH_FORCE 1
|
||||
|
||||
|
||||
/* XXX U-bit handling should be treated here */
|
||||
#define OSPF6_LSA_SCOPE(type) (ntohs(type) & OSPF6_LSTYPE_SCOPE_MASK)
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "ospf6_gr.h"
|
||||
#include "lib/json.h"
|
||||
|
||||
DEFINE_MTYPE(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor");
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_NEIGHBOR, "OSPF6 neighbor");
|
||||
|
||||
DEFINE_HOOK(ospf6_neighbor_change,
|
||||
(struct ospf6_neighbor * on, int state, int next_state),
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
#include "ospf6_asbr.h"
|
||||
#include "ospf6d.h"
|
||||
#include "ospf6_nssa.h"
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
#include "ospf6d/ospf6_nssa_clippy.c"
|
||||
#endif
|
||||
|
||||
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_LSA, "OSPF6 LSA");
|
||||
unsigned char config_debug_ospf6_nssa = 0;
|
||||
|
@ -262,22 +265,20 @@ static void ospf6_abr_announce_aggregates(struct ospf6 *ospf6)
|
|||
{
|
||||
struct ospf6_area *area;
|
||||
struct ospf6_route *range;
|
||||
struct listnode *node, *nnode;
|
||||
struct listnode *node;
|
||||
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug("ospf6_abr_announce_aggregates(): Start");
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) {
|
||||
for (range = ospf6_route_head(area->range_table); range;
|
||||
range = ospf6_route_next(range))
|
||||
ospf6_abr_range_update(range, ospf6);
|
||||
}
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, area)) {
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug(
|
||||
"ospf_abr_announce_aggregates(): looking at area %pI4",
|
||||
&area->area_id);
|
||||
|
||||
for (range = ospf6_route_head(area->range_table); range;
|
||||
range = ospf6_route_next(range))
|
||||
ospf6_abr_range_update(range, ospf6);
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
|
@ -381,22 +382,18 @@ static void ospf6_abr_unapprove_translates(struct ospf6 *ospf6)
|
|||
{
|
||||
struct ospf6_lsa *lsa;
|
||||
uint16_t type;
|
||||
struct ospf6_area *oa;
|
||||
struct listnode *node;
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("ospf6_abr_unapprove_translates(): Start");
|
||||
|
||||
type = htons(OSPF6_LSTYPE_AS_EXTERNAL);
|
||||
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
|
||||
for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) {
|
||||
if (CHECK_FLAG(lsa->flag, OSPF6_LSA_LOCAL_XLT)) {
|
||||
SET_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED);
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"%s : approved unset on link id %pI4",
|
||||
__func__, &lsa->header->id);
|
||||
}
|
||||
for (ALL_LSDB_TYPED(ospf6->lsdb, type, lsa)) {
|
||||
if (CHECK_FLAG(lsa->flag, OSPF6_LSA_LOCAL_XLT)) {
|
||||
SET_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED);
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"%s : approved unset on link id %pI4",
|
||||
__func__, &lsa->header->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,17 +405,17 @@ static void ospf6_abr_unapprove_translates(struct ospf6 *ospf6)
|
|||
static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area,
|
||||
struct ospf6_lsa *type7)
|
||||
{
|
||||
char *buffer;
|
||||
char buffer[OSPF6_MAX_LSASIZE];
|
||||
struct ospf6_lsa *lsa;
|
||||
struct ospf6_as_external_lsa *ext, *extnew;
|
||||
struct ospf6_lsa_header *lsa_header;
|
||||
caddr_t old_ptr, new_ptr;
|
||||
struct ospf6_as_external_lsa *nssa;
|
||||
struct prefix prefix;
|
||||
struct ospf6_route *match;
|
||||
struct ospf6 *ospf6 = area->ospf6;
|
||||
ptrdiff_t tag_offset = 0;
|
||||
route_tag_t network_order;
|
||||
struct ospf6_route *range;
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("%s : Start", __func__);
|
||||
|
@ -430,7 +427,27 @@ static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
buffer = XCALLOC(MTYPE_OSPF6_LSA, OSPF6_MAX_LSASIZE);
|
||||
/* find the translated Type-5 for this Type-7 */
|
||||
nssa = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END(
|
||||
type7->header);
|
||||
prefix.family = AF_INET6;
|
||||
prefix.prefixlen = nssa->prefix.prefix_length;
|
||||
ospf6_prefix_in6_addr(&prefix.u.prefix6, nssa, &nssa->prefix);
|
||||
|
||||
/* Check if the Type-7 LSA should be suppressed by aggregation. */
|
||||
range = ospf6_route_lookup_bestmatch(&prefix, area->nssa_range_table);
|
||||
if (range && !prefix_same(&prefix, &range->prefix)
|
||||
&& !CHECK_FLAG(range->flag, OSPF6_ROUTE_REMOVE)) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"%s: LSA %s suppressed by range %pFX of area %s",
|
||||
__func__, type7->name, &range->prefix,
|
||||
area->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* prepare buffer */
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
lsa_header = (struct ospf6_lsa_header *)buffer;
|
||||
extnew = (struct ospf6_as_external_lsa
|
||||
*)((caddr_t)lsa_header
|
||||
|
@ -445,23 +462,6 @@ static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area,
|
|||
|
||||
memcpy(extnew, ext, sizeof(struct ospf6_as_external_lsa));
|
||||
|
||||
/* find the translated Type-5 for this Type-7 */
|
||||
nssa = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END(
|
||||
type7->header);
|
||||
|
||||
prefix.family = AF_INET6;
|
||||
prefix.prefixlen = nssa->prefix.prefix_length;
|
||||
ospf6_prefix_in6_addr(&prefix.u.prefix6, nssa, &nssa->prefix);
|
||||
|
||||
/* Find the LSA from the external route */
|
||||
match = ospf6_route_lookup(&prefix, area->route_table);
|
||||
if (match == NULL) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("%s : no matching route %pFX", __func__,
|
||||
&prefix);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set Prefix */
|
||||
memcpy(new_ptr, old_ptr, OSPF6_PREFIX_SPACE(ext->prefix.prefix_length));
|
||||
ospf6_prefix_apply_mask(&extnew->prefix);
|
||||
|
@ -542,7 +542,6 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area,
|
|||
struct ospf6_lsa *type5)
|
||||
{
|
||||
struct ospf6_lsa *new = NULL;
|
||||
struct ospf6_as_external_lsa *ext_lsa;
|
||||
struct prefix prefix;
|
||||
struct ospf6 *ospf6 = area->ospf6;
|
||||
|
||||
|
@ -554,27 +553,27 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area,
|
|||
|
||||
/* Find the AS external LSA */
|
||||
if (type5 == NULL) {
|
||||
struct ospf6_as_external_lsa *ext_lsa;
|
||||
struct ospf6_route *match;
|
||||
|
||||
/* Find the AS external LSA from Type-7 LSA */
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"%s: No translated Type-5 found for Type-7 with Id %pI4",
|
||||
__func__, &type7->header->id);
|
||||
"%s: try to find translated Type-5 LSA for %s",
|
||||
__func__, type7->name);
|
||||
|
||||
/* find the translated Type-5 for this Type-7 */
|
||||
ext_lsa = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END(
|
||||
type7->header);
|
||||
|
||||
prefix.family = AF_INET6;
|
||||
prefix.prefixlen = ext_lsa->prefix.prefix_length;
|
||||
ospf6_prefix_in6_addr(&prefix.u.prefix6, ext_lsa,
|
||||
&ext_lsa->prefix);
|
||||
|
||||
/* Find the AS external LSA from Type-7 LSA */
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("%s: try to find external LSA id %d",
|
||||
__func__, type7->external_lsa_id);
|
||||
type5 = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL),
|
||||
type7->external_lsa_id,
|
||||
ospf6->router_id, ospf6->lsdb);
|
||||
match = ospf6_route_lookup(&prefix, ospf6->external_table);
|
||||
if (match)
|
||||
type5 = ospf6_lsdb_lookup(
|
||||
OSPF6_LSTYPE_AS_EXTERNAL, match->path.origin.id,
|
||||
ospf6->router_id, ospf6->lsdb);
|
||||
}
|
||||
|
||||
if (type5) {
|
||||
|
@ -602,6 +601,7 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area,
|
|||
__func__, &type7->header->id);
|
||||
return NULL;
|
||||
}
|
||||
UNSET_FLAG(new->flag, OSPF6_LSA_UNAPPROVED);
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
|
@ -610,32 +610,11 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area,
|
|||
return new;
|
||||
}
|
||||
|
||||
/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
|
||||
struct ospf6_lsa *ospf6_translated_nssa_originate(struct ospf6_area *oa,
|
||||
struct ospf6_lsa *type7)
|
||||
{
|
||||
struct ospf6_lsa *new;
|
||||
|
||||
if (ntohs(type7->header->type) != OSPF6_LSTYPE_TYPE_7)
|
||||
return NULL;
|
||||
|
||||
if ((new = ospf6_lsa_translated_nssa_new(oa, type7)) == NULL) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"%s : Could not translate Type-7, Id %pI4, to Type-5",
|
||||
__func__, &type7->header->id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa)
|
||||
static void ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa)
|
||||
{
|
||||
/* Incoming Type-7 or later aggregated Type-7
|
||||
*
|
||||
* LSA is skipped if P-bit is off.
|
||||
* LSA is aggregated if within range.
|
||||
*
|
||||
* The Type-7 is translated, Installed/Approved as a Type-5 into
|
||||
* global LSDB, then Flooded through AS
|
||||
|
@ -659,7 +638,7 @@ int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa)
|
|||
zlog_debug(
|
||||
"%s : LSA Id %pI4, P-bit off, NO Translation",
|
||||
__func__, &lsa->header->id);
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
|
@ -676,7 +655,7 @@ int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa)
|
|||
zlog_debug(
|
||||
"%s : LSA Id %pI4, Forward address is 0, NO Translation",
|
||||
__func__, &lsa->header->id);
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the existing AS-External LSA for this prefix */
|
||||
|
@ -687,23 +666,13 @@ int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa)
|
|||
ospf6->lsdb);
|
||||
}
|
||||
|
||||
/* Check Type 5 LSA using the matching external ID */
|
||||
if (old == NULL) {
|
||||
old = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL),
|
||||
lsa->external_lsa_id, ospf6->router_id,
|
||||
ospf6->lsdb);
|
||||
if (OSPF6_LSA_IS_MAXAGE(lsa)) {
|
||||
if (old)
|
||||
ospf6_lsa_premature_aging(old);
|
||||
return;
|
||||
}
|
||||
|
||||
if (old) {
|
||||
/* Do not continue if type 5 LSA not approved */
|
||||
if (CHECK_FLAG(old->flag, OSPF6_LSA_UNAPPROVED)) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"%s : LSA Id %pI4 type 5 is not approved",
|
||||
__func__, &old->header->id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"%s : found old translated LSA Id %pI4, refreshing",
|
||||
|
@ -722,16 +691,14 @@ int ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6_lsa *lsa)
|
|||
* originate translated LSA
|
||||
*/
|
||||
|
||||
if (ospf6_translated_nssa_originate(area, lsa) == NULL) {
|
||||
if (ospf6_lsa_translated_nssa_new(area, lsa) == NULL) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"%s : Could not translate Type-7 for %pI4 to Type-5",
|
||||
__func__, &lsa->header->id);
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ospf6_abr_process_nssa_translates(struct ospf6 *ospf6)
|
||||
|
@ -751,6 +718,8 @@ static void ospf6_abr_process_nssa_translates(struct ospf6 *ospf6)
|
|||
zlog_debug("%s : Start", __func__);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
|
||||
if (!IS_AREA_NSSA(oa))
|
||||
continue;
|
||||
|
||||
/* skip if not translator */
|
||||
if (oa->NSSATranslatorState == OSPF6_NSSA_TRANSLATE_DISABLED) {
|
||||
|
@ -760,13 +729,6 @@ static void ospf6_abr_process_nssa_translates(struct ospf6 *ospf6)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* skip if not Nssa Area */
|
||||
if (!IS_AREA_NSSA(oa)) {
|
||||
zlog_debug("%s area %pI4 Flag %x", __func__,
|
||||
&oa->area_id, oa->flag);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("%s : looking at area %pI4", __func__,
|
||||
&oa->area_id);
|
||||
|
@ -784,71 +746,30 @@ static void ospf6_abr_process_nssa_translates(struct ospf6 *ospf6)
|
|||
zlog_debug("%s : Stop", __func__);
|
||||
}
|
||||
|
||||
/* Generate translated type-5 LSA from the configured area ranges*/
|
||||
static void ospf6_abr_translate_nssa_range(struct ospf6 *ospf6)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct ospf6_area *oa;
|
||||
struct ospf6_route *range;
|
||||
struct ospf6_lsa *lsa;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
|
||||
for (range = ospf6_route_head(oa->range_table); range;
|
||||
range = ospf6_route_next(range)) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"Translating range %pFX of area %pI4",
|
||||
&range->prefix, &oa->area_id);
|
||||
if (CHECK_FLAG(range->flag,
|
||||
OSPF6_ROUTE_DO_NOT_ADVERTISE))
|
||||
continue;
|
||||
|
||||
/* Find the NSSA LSA from the route */
|
||||
/* Generate and flood external LSA */
|
||||
lsa = ospf6_lsdb_lookup(OSPF6_LSTYPE_TYPE_7,
|
||||
range->path.origin.id,
|
||||
ospf6->router_id, oa->lsdb);
|
||||
if (lsa)
|
||||
ospf6_abr_translate_nssa(oa, lsa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ospf6_abr_send_nssa_aggregates(struct ospf6 *ospf6)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct ospf6_area *area;
|
||||
struct ospf6_route *range;
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("%s : Start", __func__);
|
||||
zlog_debug("%s: Start", __func__);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, area)) {
|
||||
if (area->NSSATranslatorState == OSPF6_NSSA_TRANSLATE_DISABLED)
|
||||
continue;
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("%s : looking at area %pI4", __func__,
|
||||
zlog_debug("%s: looking at area %pI4", __func__,
|
||||
&area->area_id);
|
||||
|
||||
ospf6_abr_translate_nssa_range(ospf6);
|
||||
for (range = ospf6_route_head(area->nssa_range_table); range;
|
||||
range = ospf6_route_next(range))
|
||||
ospf6_abr_range_update(range, ospf6);
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("%s : Stop", __func__);
|
||||
}
|
||||
|
||||
/*Flood max age LSA's for the unapproved LSA's */
|
||||
static int ospf6_abr_remove_unapproved_translates_apply(struct ospf6_lsa *lsa)
|
||||
{
|
||||
if (CHECK_FLAG(lsa->flag, OSPF6_LSA_LOCAL_XLT)
|
||||
&& CHECK_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED)) {
|
||||
zlog_debug("%s : removing unapproved translates, lsa : %s",
|
||||
__func__, lsa->name);
|
||||
|
||||
/* FLUSH THROUGHOUT AS */
|
||||
ospf6_lsa_premature_aging(lsa);
|
||||
}
|
||||
return 0;
|
||||
zlog_debug("%s: Stop", __func__);
|
||||
}
|
||||
|
||||
static void ospf6_abr_remove_unapproved_translates(struct ospf6 *ospf6)
|
||||
|
@ -862,8 +783,16 @@ static void ospf6_abr_remove_unapproved_translates(struct ospf6 *ospf6)
|
|||
zlog_debug("ospf6_abr_remove_unapproved_translates(): Start");
|
||||
|
||||
type = htons(OSPF6_LSTYPE_AS_EXTERNAL);
|
||||
for (ALL_LSDB_TYPED(ospf6->lsdb, type, lsa))
|
||||
ospf6_abr_remove_unapproved_translates_apply(lsa);
|
||||
for (ALL_LSDB_TYPED(ospf6->lsdb, type, lsa)) {
|
||||
if (CHECK_FLAG(lsa->flag, OSPF6_LSA_LOCAL_XLT)
|
||||
&& CHECK_FLAG(lsa->flag, OSPF6_LSA_UNAPPROVED)) {
|
||||
zlog_debug(
|
||||
"%s : removing unapproved translates, lsa : %s",
|
||||
__func__, lsa->name);
|
||||
|
||||
ospf6_lsa_premature_aging(lsa);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("ospf_abr_remove_unapproved_translates(): Stop");
|
||||
|
@ -948,11 +877,6 @@ void ospf6_abr_nssa_type_7_defaults(struct ospf6 *ospf6)
|
|||
|
||||
static void ospf6_abr_nssa_task(struct ospf6 *ospf6)
|
||||
{
|
||||
/* called only if any_nssa */
|
||||
struct ospf6_route *range;
|
||||
struct ospf6_area *area;
|
||||
struct listnode *node, *nnode;
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("Check for NSSA-ABR Tasks():");
|
||||
|
||||
|
@ -978,10 +902,10 @@ static void ospf6_abr_nssa_task(struct ospf6 *ospf6)
|
|||
|
||||
ospf6_abr_unapprove_translates(ospf6);
|
||||
|
||||
/* RESET all Ranges in every Area, same as summaries */
|
||||
/* Originate Type-7 aggregates */
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("ospf6_abr_nssa_task(): NSSA initialize aggregates");
|
||||
ospf6_abr_range_reset_cost(ospf6);
|
||||
zlog_debug("ospf6_abr_nssa_task(): send NSSA aggregates");
|
||||
ospf6_abr_send_nssa_aggregates(ospf6);
|
||||
|
||||
/* For all NSSAs, Type-7s, translate to 5's, INSTALL/FLOOD, or
|
||||
* Aggregate as Type-7
|
||||
|
@ -991,32 +915,12 @@ static void ospf6_abr_nssa_task(struct ospf6 *ospf6)
|
|||
zlog_debug("ospf6_abr_nssa_task(): process translates");
|
||||
ospf6_abr_process_nssa_translates(ospf6);
|
||||
|
||||
/* Translate/Send any "ranged" aggregates, and also 5-Install and
|
||||
* Approve
|
||||
* Scan Type-7's for aggregates, translate to Type-5's,
|
||||
* Install/Flood/Approve
|
||||
*/
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("ospf6_abr_nssa_task(): send NSSA aggregates");
|
||||
ospf6_abr_send_nssa_aggregates(ospf6); /*TURNED OFF FOR NOW */
|
||||
|
||||
/* Flush any unapproved previous translates from Global Data Base */
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"ospf6_abr_nssa_task(): remove unapproved translates");
|
||||
ospf6_abr_remove_unapproved_translates(ospf6);
|
||||
|
||||
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, area)) {
|
||||
for (range = ospf6_route_head(area->range_table); range;
|
||||
range = ospf6_route_next(range)) {
|
||||
if (CHECK_FLAG(range->flag,
|
||||
OSPF6_ROUTE_DO_NOT_ADVERTISE))
|
||||
ospf6_zebra_delete_discard(range, ospf6);
|
||||
else
|
||||
ospf6_zebra_add_discard(range, ospf6);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("ospf6_abr_nssa_task(): Stop");
|
||||
}
|
||||
|
@ -1063,106 +967,6 @@ int ospf6_redistribute_check(struct ospf6 *ospf6, struct ospf6_route *route,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void ospf6_external_lsa_refresh_type(struct ospf6 *ospf6, uint8_t type,
|
||||
unsigned short instance, int force)
|
||||
{
|
||||
struct ospf6_route *route;
|
||||
struct ospf6_external_info *info;
|
||||
struct ospf6_lsa *lsa;
|
||||
|
||||
if (type == ZEBRA_ROUTE_MAX)
|
||||
return;
|
||||
|
||||
for (route = ospf6_route_head(ospf6->external_table); route;
|
||||
route = ospf6_route_next(route)) {
|
||||
info = route->route_option;
|
||||
|
||||
/* Find the external LSA in the database */
|
||||
if (!is_default_prefix(&route->prefix)) {
|
||||
lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL),
|
||||
htonl(info->id),
|
||||
ospf6->router_id, ospf6->lsdb);
|
||||
|
||||
if (lsa) {
|
||||
THREAD_OFF(lsa->refresh);
|
||||
|
||||
/* LSA is maxage, immediate refresh */
|
||||
if (OSPF6_LSA_IS_MAXAGE(lsa))
|
||||
ospf6_flood(NULL, lsa);
|
||||
else
|
||||
thread_add_timer(master,
|
||||
ospf6_lsa_refresh, lsa,
|
||||
OSPF_LS_REFRESH_TIME,
|
||||
&lsa->refresh);
|
||||
} else {
|
||||
/* LSA not found in the database
|
||||
* Verify and originate external LSA
|
||||
*/
|
||||
if (ospf6_redistribute_check(ospf6, route,
|
||||
type))
|
||||
ospf6_as_external_lsa_originate(route,
|
||||
ospf6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Refresh default route */
|
||||
static void ospf6_external_lsa_refresh_default(struct ospf6 *ospf6)
|
||||
{
|
||||
struct ospf6_route *route;
|
||||
struct ospf6_external_info *info;
|
||||
struct ospf6_lsa *lsa;
|
||||
|
||||
for (route = ospf6_route_head(ospf6->external_table); route;
|
||||
route = ospf6_route_next(route)) {
|
||||
if (is_default_prefix(&route->prefix)) {
|
||||
info = route->route_option;
|
||||
lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL),
|
||||
htonl(info->id),
|
||||
ospf6->router_id, ospf6->lsdb);
|
||||
|
||||
if (lsa) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p",
|
||||
(void *)lsa);
|
||||
if (OSPF6_LSA_IS_MAXAGE(lsa))
|
||||
ospf6_flood(NULL, lsa);
|
||||
else
|
||||
thread_add_timer(master,
|
||||
ospf6_lsa_refresh, lsa,
|
||||
OSPF_LS_REFRESH_TIME,
|
||||
&lsa->refresh);
|
||||
} else if (!lsa) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
|
||||
ospf6_as_external_lsa_originate(route, ospf6);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's redistribution configured, we need to refresh external
|
||||
* LSAs in order to install Type-7 and flood to all NSSA Areas
|
||||
*/
|
||||
void ospf6_asbr_nssa_redist_task(struct ospf6 *ospf6)
|
||||
{
|
||||
int type;
|
||||
struct ospf6_redist *red;
|
||||
|
||||
for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
|
||||
red = ospf6_redist_lookup(ospf6, type, 0);
|
||||
if (!red)
|
||||
return;
|
||||
|
||||
ospf6_external_lsa_refresh_type(ospf6, type, red->instance,
|
||||
LSA_REFRESH_IF_CHANGED);
|
||||
}
|
||||
ospf6_external_lsa_refresh_default(ospf6);
|
||||
}
|
||||
|
||||
/* This function performs ABR related processing */
|
||||
static int ospf6_abr_task_timer(struct thread *thread)
|
||||
{
|
||||
|
@ -1176,7 +980,6 @@ static int ospf6_abr_task_timer(struct thread *thread)
|
|||
ospf6_abr_task(ospf6);
|
||||
/* if nssa-abr, then scan Type-7 LSDB */
|
||||
ospf6_abr_nssa_task(ospf6);
|
||||
ospf6_asbr_nssa_redist_task(ospf6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1337,6 +1140,13 @@ int ospf6_area_nssa_unset(struct ospf6 *ospf6, struct ospf6_area *area)
|
|||
UNSET_FLAG(area->flag, OSPF6_AREA_NSSA);
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("area %s nssa reset", area->name);
|
||||
|
||||
/* Clear the table of NSSA ranges. */
|
||||
ospf6_route_table_delete(area->nssa_range_table);
|
||||
area->nssa_range_table =
|
||||
OSPF6_ROUTE_TABLE_CREATE(AREA, PREFIX_RANGES);
|
||||
area->nssa_range_table->scope = area;
|
||||
|
||||
ospf6_area_nssa_update(area);
|
||||
}
|
||||
|
||||
|
@ -1350,10 +1160,14 @@ static struct in6_addr *ospf6_get_nssa_fwd_addr(struct ospf6_area *oa)
|
|||
struct ospf6_interface *oi;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
|
||||
if (if_is_operative(oi->interface))
|
||||
if (oi->area && IS_AREA_NSSA(oi->area))
|
||||
return ospf6_interface_get_global_address(
|
||||
oi->interface);
|
||||
struct in6_addr *addr;
|
||||
|
||||
if (!if_is_operative(oi->interface))
|
||||
continue;
|
||||
|
||||
addr = ospf6_interface_get_global_address(oi->interface);
|
||||
if (addr)
|
||||
return addr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1463,17 +1277,119 @@ void ospf6_abr_check_translate_nssa(struct ospf6_area *area,
|
|||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("%s : start", __func__);
|
||||
|
||||
if (!ospf6_check_and_set_router_abr(ospf6))
|
||||
return;
|
||||
|
||||
type5 = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL),
|
||||
lsa->external_lsa_id, ospf6->router_id,
|
||||
ospf6->lsdb);
|
||||
|
||||
if (ospf6_check_and_set_router_abr(ospf6) && (type5 == NULL)) {
|
||||
if (!type5) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("%s : Originating type5 LSA", __func__);
|
||||
ospf6_lsa_translated_nssa_new(area, lsa);
|
||||
}
|
||||
}
|
||||
|
||||
DEFPY (area_nssa_range,
|
||||
area_nssa_range_cmd,
|
||||
"area <A.B.C.D|(0-4294967295)>$area nssa range X:X::X:X/M$prefix [<not-advertise$not_adv|cost (0-16777215)$cost>]",
|
||||
"OSPF6 area parameters\n"
|
||||
"OSPF6 area ID in IP address format\n"
|
||||
"OSPF6 area ID as a decimal value\n"
|
||||
"Configure OSPF6 area as nssa\n"
|
||||
"Configured address range\n"
|
||||
"Specify IPv6 prefix\n"
|
||||
"Do not advertise\n"
|
||||
"User specified metric for this range\n"
|
||||
"Advertised metric for this range\n")
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
struct ospf6_route *range;
|
||||
|
||||
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
||||
|
||||
OSPF6_CMD_AREA_GET(area, oa, ospf6);
|
||||
|
||||
if (!IS_AREA_NSSA(oa)) {
|
||||
vty_out(vty, "%% First configure %s as an NSSA area\n", area);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
range = ospf6_route_lookup((struct prefix *)prefix,
|
||||
oa->nssa_range_table);
|
||||
if (range == NULL) {
|
||||
range = ospf6_route_create(ospf6);
|
||||
range->type = OSPF6_DEST_TYPE_RANGE;
|
||||
SET_FLAG(range->flag, OSPF6_ROUTE_NSSA_RANGE);
|
||||
prefix_copy(&range->prefix, prefix);
|
||||
range->path.area_id = oa->area_id;
|
||||
range->path.metric_type = 2;
|
||||
range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
|
||||
range->path.origin.type = htons(OSPF6_LSTYPE_TYPE_7);
|
||||
range->path.origin.id = htonl(ospf6->external_id++);
|
||||
range->path.origin.adv_router = ospf6->router_id;
|
||||
ospf6_route_add(range, oa->nssa_range_table);
|
||||
}
|
||||
|
||||
/* process "not-advertise" */
|
||||
if (not_adv)
|
||||
SET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
|
||||
else
|
||||
UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
|
||||
|
||||
/* process "cost" */
|
||||
if (!cost_str)
|
||||
cost = OSPF_AREA_RANGE_COST_UNSPEC;
|
||||
range->path.u.cost_config = cost;
|
||||
|
||||
/* Redo summaries if required */
|
||||
if (ospf6_check_and_set_router_abr(ospf6))
|
||||
ospf6_schedule_abr_task(ospf6);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY (no_area_nssa_range,
|
||||
no_area_nssa_range_cmd,
|
||||
"no area <A.B.C.D|(0-4294967295)>$area nssa range X:X::X:X/M$prefix [<not-advertise|cost (0-16777215)>]",
|
||||
NO_STR
|
||||
"OSPF6 area parameters\n"
|
||||
"OSPF6 area ID in IP address format\n"
|
||||
"OSPF6 area ID as a decimal value\n"
|
||||
"Configure OSPF6 area as nssa\n"
|
||||
"Configured address range\n"
|
||||
"Specify IPv6 prefix\n"
|
||||
"Do not advertise\n"
|
||||
"User specified metric for this range\n"
|
||||
"Advertised metric for this range\n")
|
||||
{
|
||||
struct ospf6_area *oa;
|
||||
struct ospf6_route *range;
|
||||
|
||||
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
|
||||
|
||||
OSPF6_CMD_AREA_GET(area, oa, ospf6);
|
||||
|
||||
range = ospf6_route_lookup((struct prefix *)prefix,
|
||||
oa->nssa_range_table);
|
||||
if (range == NULL) {
|
||||
vty_out(vty, "%% range %s does not exists.\n", prefix_str);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
if (ospf6_check_and_set_router_abr(oa->ospf6)) {
|
||||
/* Blow away the aggregated LSA and route */
|
||||
SET_FLAG(range->flag, OSPF6_ROUTE_REMOVE);
|
||||
|
||||
/* Redo summaries if required */
|
||||
thread_execute(master, ospf6_abr_task_timer, ospf6, 0);
|
||||
}
|
||||
|
||||
ospf6_route_remove(range, oa->nssa_range_table);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(debug_ospf6_nssa, debug_ospf6_nssa_cmd,
|
||||
"debug ospf6 nssa",
|
||||
DEBUG_STR
|
||||
|
@ -1503,6 +1419,9 @@ void config_write_ospf6_debug_nssa(struct vty *vty)
|
|||
|
||||
void install_element_ospf6_debug_nssa(void)
|
||||
{
|
||||
install_element(OSPF6_NODE, &area_nssa_range_cmd);
|
||||
install_element(OSPF6_NODE, &no_area_nssa_range_cmd);
|
||||
|
||||
install_element(ENABLE_NODE, &debug_ospf6_nssa_cmd);
|
||||
install_element(ENABLE_NODE, &no_debug_ospf6_nssa_cmd);
|
||||
install_element(CONFIG_NODE, &debug_ospf6_nssa_cmd);
|
||||
|
|
|
@ -55,8 +55,6 @@ extern void ospf6_nssa_lsa_flush(struct ospf6 *ospf6, struct prefix_ipv6 *p);
|
|||
extern struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *oa,
|
||||
struct ospf6_lsa *type7,
|
||||
struct ospf6_lsa *type5);
|
||||
extern struct ospf6_lsa *
|
||||
ospf6_translated_nssa_originate(struct ospf6_area *oa, struct ospf6_lsa *type7);
|
||||
|
||||
extern void ospf6_asbr_nssa_redist_task(struct ospf6 *ospf6);
|
||||
|
||||
|
@ -69,8 +67,6 @@ extern void install_element_ospf6_debug_nssa(void);
|
|||
extern void ospf6_abr_nssa_type_7_defaults(struct ospf6 *osof6);
|
||||
int ospf6_redistribute_check(struct ospf6 *ospf6, struct ospf6_route *route,
|
||||
int type);
|
||||
extern int ospf6_abr_translate_nssa(struct ospf6_area *area,
|
||||
struct ospf6_lsa *lsa);
|
||||
extern void ospf6_abr_check_translate_nssa(struct ospf6_area *area,
|
||||
struct ospf6_lsa *lsa);
|
||||
extern void ospf6_abr_nssa_check_status(struct ospf6 *ospf6);
|
||||
|
|
|
@ -1098,7 +1098,6 @@ struct ospf6_route_table *ospf6_route_table_create(int s, int t)
|
|||
void ospf6_route_table_delete(struct ospf6_route_table *table)
|
||||
{
|
||||
ospf6_route_remove_all(table);
|
||||
bf_free(table->idspace);
|
||||
route_table_finish(table->table);
|
||||
XFREE(MTYPE_OSPF6_ROUTE_TABLE, table);
|
||||
}
|
||||
|
|
|
@ -186,7 +186,7 @@ struct ospf6_route {
|
|||
struct timeval changed;
|
||||
|
||||
/* flag */
|
||||
uint8_t flag;
|
||||
uint16_t flag;
|
||||
|
||||
/* Prefix Options */
|
||||
uint8_t prefix_options;
|
||||
|
@ -221,14 +221,15 @@ struct ospf6_route {
|
|||
#define OSPF6_DEST_TYPE_RANGE 5
|
||||
#define OSPF6_DEST_TYPE_MAX 6
|
||||
|
||||
#define OSPF6_ROUTE_CHANGE 0x01
|
||||
#define OSPF6_ROUTE_ADD 0x02
|
||||
#define OSPF6_ROUTE_REMOVE 0x04
|
||||
#define OSPF6_ROUTE_BEST 0x08
|
||||
#define OSPF6_ROUTE_ACTIVE_SUMMARY 0x10
|
||||
#define OSPF6_ROUTE_DO_NOT_ADVERTISE 0x20
|
||||
#define OSPF6_ROUTE_WAS_REMOVED 0x40
|
||||
#define OSPF6_ROUTE_BLACKHOLE_ADDED 0x80
|
||||
#define OSPF6_ROUTE_CHANGE 0x0001
|
||||
#define OSPF6_ROUTE_ADD 0x0002
|
||||
#define OSPF6_ROUTE_REMOVE 0x0004
|
||||
#define OSPF6_ROUTE_BEST 0x0008
|
||||
#define OSPF6_ROUTE_ACTIVE_SUMMARY 0x0010
|
||||
#define OSPF6_ROUTE_DO_NOT_ADVERTISE 0x0020
|
||||
#define OSPF6_ROUTE_WAS_REMOVED 0x0040
|
||||
#define OSPF6_ROUTE_BLACKHOLE_ADDED 0x0080
|
||||
#define OSPF6_ROUTE_NSSA_RANGE 0x0100
|
||||
struct ospf6;
|
||||
|
||||
struct ospf6_route_table {
|
||||
|
@ -241,8 +242,6 @@ struct ospf6_route_table {
|
|||
|
||||
uint32_t count;
|
||||
|
||||
bitfield_t idspace;
|
||||
|
||||
/* hooks */
|
||||
void (*hook_add)(struct ospf6_route *);
|
||||
void (*hook_change)(struct ospf6_route *);
|
||||
|
|
|
@ -99,6 +99,7 @@ clippy_scan += \
|
|||
ospf6d/ospf6_lsa.c \
|
||||
ospf6d/ospf6_gr_helper.c \
|
||||
ospf6d/ospf6_gr.c \
|
||||
ospf6d/ospf6_nssa.c \
|
||||
ospf6d/ospf6_route.c \
|
||||
# end
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@ debug ospf6 lsa router
|
|||
debug ospf6 lsa router originate
|
||||
debug ospf6 lsa router examine
|
||||
debug ospf6 lsa router flooding
|
||||
debug ospf6 lsa nssa
|
||||
debug ospf6 lsa nssa originate
|
||||
debug ospf6 lsa nssa examine
|
||||
debug ospf6 lsa nssa flooding
|
||||
debug ospf6 lsa as-external
|
||||
debug ospf6 lsa as-external originate
|
||||
debug ospf6 lsa as-external examine
|
||||
|
@ -15,7 +19,6 @@ debug ospf6 zebra
|
|||
debug ospf6 interface
|
||||
debug ospf6 neighbor
|
||||
debug ospf6 flooding
|
||||
debug ospf6 gr helper
|
||||
debug ospf6 spf process
|
||||
debug ospf6 route intra-area
|
||||
debug ospf6 route inter-area
|
||||
|
@ -24,11 +27,11 @@ debug ospf6 asbr
|
|||
debug ospf6 nssa
|
||||
!
|
||||
interface r1-eth0
|
||||
ipv6 ospf6 area 0.0.0.1
|
||||
ipv6 ospf6 hello-interval 2
|
||||
ipv6 ospf6 dead-interval 10
|
||||
!
|
||||
router ospf6
|
||||
ospf6 router-id 10.254.254.1
|
||||
area 0.0.0.1 stub
|
||||
interface r1-eth0 area 0.0.0.1
|
||||
!
|
||||
|
|
|
@ -2,6 +2,10 @@ debug ospf6 lsa router
|
|||
debug ospf6 lsa router originate
|
||||
debug ospf6 lsa router examine
|
||||
debug ospf6 lsa router flooding
|
||||
debug ospf6 lsa nssa
|
||||
debug ospf6 lsa nssa originate
|
||||
debug ospf6 lsa nssa examine
|
||||
debug ospf6 lsa nssa flooding
|
||||
debug ospf6 lsa as-external
|
||||
debug ospf6 lsa as-external originate
|
||||
debug ospf6 lsa as-external examine
|
||||
|
@ -15,7 +19,6 @@ debug ospf6 zebra
|
|||
debug ospf6 interface
|
||||
debug ospf6 neighbor
|
||||
debug ospf6 flooding
|
||||
debug ospf6 gr helper
|
||||
debug ospf6 spf process
|
||||
debug ospf6 route intra-area
|
||||
debug ospf6 route inter-area
|
||||
|
@ -24,14 +27,17 @@ debug ospf6 asbr
|
|||
debug ospf6 nssa
|
||||
!
|
||||
interface r2-eth0
|
||||
ipv6 ospf6 area 0.0.0.1
|
||||
ipv6 ospf6 hello-interval 2
|
||||
ipv6 ospf6 dead-interval 10
|
||||
!
|
||||
interface r2-eth1
|
||||
ipv6 ospf6 area 0.0.0.0
|
||||
ipv6 ospf6 hello-interval 2
|
||||
ipv6 ospf6 dead-interval 10
|
||||
!
|
||||
interface r2-eth2
|
||||
ipv6 ospf6 area 0.0.0.2
|
||||
ipv6 ospf6 hello-interval 2
|
||||
ipv6 ospf6 dead-interval 10
|
||||
!
|
||||
|
@ -42,7 +48,4 @@ router ospf6
|
|||
default-information originate always metric 123
|
||||
area 0.0.0.1 stub
|
||||
area 0.0.0.2 nssa
|
||||
interface r2-eth0 area 0.0.0.1
|
||||
interface r2-eth1 area 0.0.0.0
|
||||
interface r2-eth2 area 0.0.0.2
|
||||
!
|
||||
|
|
|
@ -2,6 +2,10 @@ debug ospf6 lsa router
|
|||
debug ospf6 lsa router originate
|
||||
debug ospf6 lsa router examine
|
||||
debug ospf6 lsa router flooding
|
||||
debug ospf6 lsa nssa
|
||||
debug ospf6 lsa nssa originate
|
||||
debug ospf6 lsa nssa examine
|
||||
debug ospf6 lsa nssa flooding
|
||||
debug ospf6 lsa as-external
|
||||
debug ospf6 lsa as-external originate
|
||||
debug ospf6 lsa as-external examine
|
||||
|
@ -15,7 +19,6 @@ debug ospf6 zebra
|
|||
debug ospf6 interface
|
||||
debug ospf6 neighbor
|
||||
debug ospf6 flooding
|
||||
debug ospf6 gr helper
|
||||
debug ospf6 spf process
|
||||
debug ospf6 route intra-area
|
||||
debug ospf6 route inter-area
|
||||
|
@ -24,6 +27,7 @@ debug ospf6 asbr
|
|||
debug ospf6 nssa
|
||||
!
|
||||
interface r3-eth0
|
||||
ipv6 ospf6 area 0.0.0.0
|
||||
ipv6 ospf6 hello-interval 2
|
||||
ipv6 ospf6 dead-interval 10
|
||||
!
|
||||
|
@ -31,5 +35,4 @@ router ospf6
|
|||
ospf6 router-id 10.254.254.3
|
||||
redistribute connected
|
||||
redistribute static
|
||||
interface r3-eth0 area 0.0.0.0
|
||||
!
|
||||
|
|
|
@ -2,6 +2,10 @@ debug ospf6 lsa router
|
|||
debug ospf6 lsa router originate
|
||||
debug ospf6 lsa router examine
|
||||
debug ospf6 lsa router flooding
|
||||
debug ospf6 lsa nssa
|
||||
debug ospf6 lsa nssa originate
|
||||
debug ospf6 lsa nssa examine
|
||||
debug ospf6 lsa nssa flooding
|
||||
debug ospf6 lsa as-external
|
||||
debug ospf6 lsa as-external originate
|
||||
debug ospf6 lsa as-external examine
|
||||
|
@ -15,7 +19,6 @@ debug ospf6 zebra
|
|||
debug ospf6 interface
|
||||
debug ospf6 neighbor
|
||||
debug ospf6 flooding
|
||||
debug ospf6 gr helper
|
||||
debug ospf6 spf process
|
||||
debug ospf6 route intra-area
|
||||
debug ospf6 route inter-area
|
||||
|
@ -24,11 +27,11 @@ debug ospf6 asbr
|
|||
debug ospf6 nssa
|
||||
!
|
||||
interface r4-eth0
|
||||
ipv6 ospf6 area 0.0.0.2
|
||||
ipv6 ospf6 hello-interval 2
|
||||
ipv6 ospf6 dead-interval 10
|
||||
!
|
||||
router ospf6
|
||||
ospf6 router-id 10.254.254.4
|
||||
area 0.0.0.2 nssa
|
||||
interface r4-eth0 area 0.0.0.2
|
||||
!
|
||||
|
|
|
@ -131,6 +131,8 @@ def build_topo(tgen):
|
|||
switch.add_link(tgen.gears["r2"])
|
||||
switch.add_link(tgen.gears["r4"])
|
||||
|
||||
switch = tgen.add_switch("s4")
|
||||
switch.add_link(tgen.gears["r4"], nodeif="r4-stubnet")
|
||||
|
||||
def setup_module(mod):
|
||||
"Sets up the pytest environment"
|
||||
|
@ -484,7 +486,7 @@ def test_area_filters():
|
|||
pytest.skip(tgen.errors)
|
||||
|
||||
#
|
||||
# Configure import/export filters on r2 (ABR for area 1).
|
||||
# Configure import/export filters on r2 (ABR for area 2).
|
||||
#
|
||||
config = """
|
||||
configure terminal
|
||||
|
@ -544,6 +546,102 @@ def test_area_filters():
|
|||
expect_ospfv3_routes("r1", routes, wait=30, type="inter-area")
|
||||
|
||||
|
||||
def test_nssa_range():
|
||||
"""
|
||||
Test NSSA ABR ranges.
|
||||
"""
|
||||
tgen = get_topogen()
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
# Configure new addresses on r4 and enable redistribution of connected
|
||||
# routes.
|
||||
config = """
|
||||
configure terminal
|
||||
interface r4-stubnet
|
||||
ipv6 address 2001:db8:1000::1/128
|
||||
ipv6 address 2001:db8:1000::2/128
|
||||
router ospf6
|
||||
redistribute connected
|
||||
"""
|
||||
tgen.gears["r4"].vtysh_cmd(config)
|
||||
logger.info("Expecting NSSA-translated external routes to be added on r3")
|
||||
routes = {"2001:db8:1000::1/128": {}, "2001:db8:1000::2/128": {}}
|
||||
expect_ospfv3_routes("r3", routes, wait=30, type="external-2")
|
||||
|
||||
# Configure an NSSA range on r2 (ABR for area 2).
|
||||
config = """
|
||||
configure terminal
|
||||
router ospf6
|
||||
area 2 nssa range 2001:db8:1000::/64
|
||||
"""
|
||||
tgen.gears["r2"].vtysh_cmd(config)
|
||||
logger.info("Expecting summarized routes to be removed from r3")
|
||||
for route in ["2001:db8:1000::1/128", "2001:db8:1000::2/128"]:
|
||||
test_func = partial(dont_expect_route, "r3", route, type="external-2")
|
||||
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = "{}'s {} summarized route still exists".format("r3", route)
|
||||
assert result is None, assertmsg
|
||||
logger.info("Expecting NSSA range to be added on r3")
|
||||
routes = {
|
||||
"2001:db8:1000::/64": {
|
||||
"metricType":2,
|
||||
"metricCost":20,
|
||||
"metricCostE2":10,
|
||||
}}
|
||||
expect_ospfv3_routes("r3", routes, wait=30, type="external-2", detail=True)
|
||||
|
||||
# Change the NSSA range cost.
|
||||
config = """
|
||||
configure terminal
|
||||
router ospf6
|
||||
area 2 nssa range 2001:db8:1000::/64 cost 1000
|
||||
"""
|
||||
tgen.gears["r2"].vtysh_cmd(config)
|
||||
logger.info("Expecting NSSA range to be updated with new cost")
|
||||
routes = {
|
||||
"2001:db8:1000::/64": {
|
||||
"metricType":2,
|
||||
"metricCost":20,
|
||||
"metricCostE2":1000,
|
||||
}}
|
||||
expect_ospfv3_routes("r3", routes, wait=30, type="external-2", detail=True)
|
||||
|
||||
# Configure the NSSA range to not be advertised.
|
||||
config = """
|
||||
configure terminal
|
||||
router ospf6
|
||||
area 2 nssa range 2001:db8:1000::/64 not-advertise
|
||||
"""
|
||||
tgen.gears["r2"].vtysh_cmd(config)
|
||||
logger.info("Expecting NSSA summary route to be removed")
|
||||
route = "2001:db8:1000::/64"
|
||||
test_func = partial(dont_expect_route, "r3", route, type="external-2")
|
||||
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = "{}'s {} NSSA summary route still exists".format("r3", route)
|
||||
assert result is None, assertmsg
|
||||
|
||||
# Remove the NSSA range.
|
||||
config = """
|
||||
configure terminal
|
||||
router ospf6
|
||||
no area 2 nssa range 2001:db8:1000::/64
|
||||
"""
|
||||
tgen.gears["r2"].vtysh_cmd(config)
|
||||
logger.info("Expecting previously summarized routes to be re-added")
|
||||
routes = {
|
||||
"2001:db8:1000::1/128": {
|
||||
"metricType":2,
|
||||
"metricCost":20,
|
||||
},
|
||||
"2001:db8:1000::2/128": {
|
||||
"metricType":2,
|
||||
"metricCost":20,
|
||||
},
|
||||
}
|
||||
expect_ospfv3_routes("r3", routes, wait=30, type="external-2", detail=True)
|
||||
|
||||
|
||||
def teardown_module(_mod):
|
||||
"Teardown the pytest environment"
|
||||
tgen = get_topogen()
|
||||
|
|
Loading…
Reference in New Issue