forked from Mirror/frr
Merge pull request #9585 from opensourcerouting/ospf6d-nssa-dflt-originate
ospf6d: add a knob to generate Type-7 default routes
This commit is contained in:
commit
b8beb67ef5
|
@ -178,7 +178,7 @@ OSPF6 area
|
|||
|
||||
.. clicmd:: area A.B.C.D nssa [no-summary]
|
||||
|
||||
.. clicmd:: area (0-4294967295) nssa [no-summary]
|
||||
.. clicmd:: area (0-4294967295) nssa [no-summary] [default-information-originate [metric-type (1-2)] [metric (0-16777214)]]
|
||||
|
||||
Configure the area to be a NSSA (Not-So-Stubby Area).
|
||||
|
||||
|
@ -198,6 +198,12 @@ OSPF6 area
|
|||
advertisement of summaries into the area. In that case, a single Type-3 LSA
|
||||
containing a default route is originated into the NSSA.
|
||||
|
||||
NSSA ABRs and ASBRs can be configured with `default-information-originate`
|
||||
option to originate a Type-7 default route into the NSSA area. In the case
|
||||
of NSSA ASBRs, the origination of the default route is conditioned to the
|
||||
existence of a default route in the RIB that wasn't learned via the OSPF
|
||||
protocol.
|
||||
|
||||
.. clicmd:: area A.B.C.D export-list NAME
|
||||
|
||||
.. clicmd:: area (0-4294967295) export-list NAME
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "ospf6_intra.h"
|
||||
#include "ospf6_abr.h"
|
||||
#include "ospf6_asbr.h"
|
||||
#include "ospf6_zebra.h"
|
||||
#include "ospf6d.h"
|
||||
#include "lib/json.h"
|
||||
#include "ospf6_nssa.h"
|
||||
|
@ -234,6 +235,36 @@ static void ospf6_area_no_summary_unset(struct ospf6 *ospf6,
|
|||
}
|
||||
}
|
||||
|
||||
static void ospf6_nssa_default_originate_set(struct ospf6 *ospf6,
|
||||
struct ospf6_area *area,
|
||||
int metric, int metric_type)
|
||||
{
|
||||
if (!area->nssa_default_originate.enabled) {
|
||||
area->nssa_default_originate.enabled = true;
|
||||
if (++ospf6->nssa_default_import_check.refcnt == 1) {
|
||||
ospf6->nssa_default_import_check.status = false;
|
||||
ospf6_zebra_import_default_route(ospf6, false);
|
||||
}
|
||||
}
|
||||
|
||||
area->nssa_default_originate.metric_value = metric;
|
||||
area->nssa_default_originate.metric_type = metric_type;
|
||||
}
|
||||
|
||||
static void ospf6_nssa_default_originate_unset(struct ospf6 *ospf6,
|
||||
struct ospf6_area *area)
|
||||
{
|
||||
if (area->nssa_default_originate.enabled) {
|
||||
area->nssa_default_originate.enabled = false;
|
||||
if (--ospf6->nssa_default_import_check.refcnt == 0) {
|
||||
ospf6->nssa_default_import_check.status = false;
|
||||
ospf6_zebra_import_default_route(ospf6, true);
|
||||
}
|
||||
area->nssa_default_originate.metric_value = -1;
|
||||
area->nssa_default_originate.metric_type = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make new area structure.
|
||||
*
|
||||
|
@ -648,6 +679,17 @@ void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6)
|
|||
}
|
||||
if (IS_AREA_NSSA(oa)) {
|
||||
vty_out(vty, " area %s nssa", oa->name);
|
||||
if (oa->nssa_default_originate.enabled) {
|
||||
vty_out(vty, " default-information-originate");
|
||||
if (oa->nssa_default_originate.metric_value
|
||||
!= -1)
|
||||
vty_out(vty, " metric %d",
|
||||
oa->nssa_default_originate
|
||||
.metric_value);
|
||||
if (oa->nssa_default_originate.metric_type
|
||||
!= DEFAULT_METRIC_TYPE)
|
||||
vty_out(vty, " metric-type 1");
|
||||
}
|
||||
if (oa->no_summary)
|
||||
vty_out(vty, " no-summary");
|
||||
vty_out(vty, "\n");
|
||||
|
@ -1278,11 +1320,20 @@ DEFUN (no_ospf6_area_stub_no_summary,
|
|||
}
|
||||
|
||||
DEFPY(ospf6_area_nssa, ospf6_area_nssa_cmd,
|
||||
"area <A.B.C.D|(0-4294967295)>$area_str nssa [no-summary$no_summary]",
|
||||
"area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
||||
[{\
|
||||
default-information-originate$dflt_originate [{metric (0-16777214)$mval|metric-type (1-2)$mtype}]\
|
||||
|no-summary$no_summary\
|
||||
}]",
|
||||
"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"
|
||||
"Originate Type 7 default into NSSA area\n"
|
||||
"OSPFv3 default metric\n"
|
||||
"OSPFv3 metric\n"
|
||||
"OSPFv3 metric type for default routes\n"
|
||||
"Set OSPFv3 External Type 1/2 metrics\n"
|
||||
"Do not inject inter-area routes into area\n")
|
||||
{
|
||||
struct ospf6_area *area;
|
||||
|
@ -1296,23 +1347,44 @@ DEFPY(ospf6_area_nssa, ospf6_area_nssa_cmd,
|
|||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
if (dflt_originate) {
|
||||
if (mval_str == NULL)
|
||||
mval = -1;
|
||||
if (mtype_str == NULL)
|
||||
mtype = DEFAULT_METRIC_TYPE;
|
||||
ospf6_nssa_default_originate_set(ospf6, area, mval, mtype);
|
||||
} else
|
||||
ospf6_nssa_default_originate_unset(ospf6, area);
|
||||
|
||||
if (no_summary)
|
||||
ospf6_area_no_summary_set(ospf6, area);
|
||||
else
|
||||
ospf6_area_no_summary_unset(ospf6, area);
|
||||
if (ospf6_check_and_set_router_abr(ospf6))
|
||||
|
||||
if (ospf6_check_and_set_router_abr(ospf6)) {
|
||||
ospf6_abr_defaults_to_stub(ospf6);
|
||||
ospf6_abr_nssa_type_7_defaults(ospf6);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY(no_ospf6_area_nssa, no_ospf6_area_nssa_cmd,
|
||||
"no area <A.B.C.D|(0-4294967295)>$area_str nssa [no-summary$no_summary]",
|
||||
"no area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
||||
[{\
|
||||
default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\
|
||||
|no-summary\
|
||||
}]",
|
||||
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"
|
||||
"Originate Type 7 default into NSSA area\n"
|
||||
"OSPFv3 default metric\n"
|
||||
"OSPFv3 metric\n"
|
||||
"OSPFv3 metric type for default routes\n"
|
||||
"Set OSPFv3 External Type 1/2 metrics\n"
|
||||
"Do not inject inter-area routes into area\n")
|
||||
{
|
||||
struct ospf6_area *area;
|
||||
|
@ -1322,6 +1394,7 @@ DEFPY(no_ospf6_area_nssa, no_ospf6_area_nssa_cmd,
|
|||
|
||||
ospf6_area_nssa_unset(ospf6, area);
|
||||
ospf6_area_no_summary_unset(ospf6, area);
|
||||
ospf6_nssa_default_originate_unset(ospf6, area);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,13 @@ struct ospf6_area {
|
|||
/* Area type */
|
||||
int no_summary;
|
||||
|
||||
/* NSSA default-information-originate */
|
||||
struct {
|
||||
bool enabled;
|
||||
int metric_type;
|
||||
int metric_value;
|
||||
} nssa_default_originate;
|
||||
|
||||
/* Brouter traversal protection */
|
||||
bool intra_brouter_calc;
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "ospf6_abr.h"
|
||||
#include "ospf6_intra.h"
|
||||
#include "ospf6_flood.h"
|
||||
#include "ospf6_nssa.h"
|
||||
#include "ospf6d.h"
|
||||
#include "ospf6_spf.h"
|
||||
#include "ospf6_nssa.h"
|
||||
|
@ -85,7 +86,7 @@ static struct ospf6_lsa *ospf6_originate_type5_type7_lsas(
|
|||
|
||||
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) {
|
||||
if (IS_AREA_NSSA(oa))
|
||||
ospf6_nssa_lsa_originate(route, oa);
|
||||
ospf6_nssa_lsa_originate(route, oa, true);
|
||||
}
|
||||
|
||||
return lsa;
|
||||
|
@ -1433,7 +1434,10 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
|
|||
memset(&tinfo, 0, sizeof(tinfo));
|
||||
|
||||
if (IS_OSPF6_DEBUG_ASBR)
|
||||
zlog_debug("Redistribute %pFX (%s)", prefix, ZROUTE_NAME(type));
|
||||
zlog_debug("Redistribute %pFX (%s)", prefix,
|
||||
type == DEFAULT_ROUTE
|
||||
? "default-information-originate"
|
||||
: ZROUTE_NAME(type));
|
||||
|
||||
/* if route-map was specified but not found, do not advertise */
|
||||
if (ROUTEMAP_NAME(red)) {
|
||||
|
@ -1787,7 +1791,7 @@ int ospf6_redistribute_config_write(struct vty *vty, struct ospf6 *ospf6)
|
|||
vty_out(vty, " redistribute %s", ZROUTE_NAME(type));
|
||||
if (red->dmetric.value >= 0)
|
||||
vty_out(vty, " metric %d", red->dmetric.value);
|
||||
if (red->dmetric.type != DEFAULT_METRIC_TYPE)
|
||||
if (red->dmetric.type == 1)
|
||||
vty_out(vty, " metric-type 1");
|
||||
if (ROUTEMAP_NAME(red))
|
||||
vty_out(vty, " route-map %s", ROUTEMAP_NAME(red));
|
||||
|
|
|
@ -368,6 +368,11 @@ static void ospf6_abr_task(struct ospf6 *ospf6)
|
|||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug("%s : announce stub defaults", __func__);
|
||||
ospf6_abr_defaults_to_stub(ospf6);
|
||||
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
zlog_debug("%s : announce NSSA Type-7 defaults",
|
||||
__func__);
|
||||
ospf6_abr_nssa_type_7_defaults(ospf6);
|
||||
}
|
||||
|
||||
if (IS_OSPF6_DEBUG_ABR)
|
||||
|
@ -872,6 +877,83 @@ static void ospf6_abr_remove_unapproved_translates(struct ospf6 *ospf6)
|
|||
zlog_debug("ospf_abr_remove_unapproved_translates(): Stop");
|
||||
}
|
||||
|
||||
static void ospf6_abr_nssa_type_7_default_create(struct ospf6 *ospf6,
|
||||
struct ospf6_area *oa)
|
||||
{
|
||||
struct ospf6_route *def;
|
||||
int metric;
|
||||
int metric_type;
|
||||
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug("Announcing Type-7 default route into NSSA area %s",
|
||||
oa->name);
|
||||
|
||||
def = ospf6_route_create(ospf6);
|
||||
def->type = OSPF6_DEST_TYPE_NETWORK;
|
||||
def->prefix.family = AF_INET6;
|
||||
def->prefix.prefixlen = 0;
|
||||
memset(&def->prefix.u.prefix6, 0, sizeof(struct in6_addr));
|
||||
def->type = OSPF6_DEST_TYPE_NETWORK;
|
||||
def->path.subtype = OSPF6_PATH_SUBTYPE_DEFAULT_RT;
|
||||
if (CHECK_FLAG(ospf6->flag, OSPF6_FLAG_ABR))
|
||||
def->path.area_id = ospf6->backbone->area_id;
|
||||
else
|
||||
def->path.area_id = oa->area_id;
|
||||
|
||||
/* Compute default route type and metric. */
|
||||
if (oa->nssa_default_originate.metric_value != -1)
|
||||
metric = oa->nssa_default_originate.metric_value;
|
||||
else
|
||||
metric = DEFAULT_DEFAULT_ALWAYS_METRIC;
|
||||
if (oa->nssa_default_originate.metric_type != -1)
|
||||
metric_type = oa->nssa_default_originate.metric_type;
|
||||
else
|
||||
metric_type = DEFAULT_METRIC_TYPE;
|
||||
def->path.metric_type = metric_type;
|
||||
def->path.cost = metric;
|
||||
if (metric_type == 1)
|
||||
def->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
|
||||
else
|
||||
def->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
|
||||
|
||||
ospf6_nssa_lsa_originate(def, oa, false);
|
||||
ospf6_route_delete(def);
|
||||
}
|
||||
|
||||
static void ospf6_abr_nssa_type_7_default_delete(struct ospf6 *ospf6,
|
||||
struct ospf6_area *oa)
|
||||
{
|
||||
struct ospf6_lsa *lsa;
|
||||
|
||||
lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7), 0,
|
||||
oa->ospf6->router_id, oa->lsdb);
|
||||
if (lsa && !OSPF6_LSA_IS_MAXAGE(lsa)) {
|
||||
if (IS_OSPF6_DEBUG_NSSA)
|
||||
zlog_debug(
|
||||
"Withdrawing Type-7 default route from area %s",
|
||||
oa->name);
|
||||
|
||||
ospf6_lsa_purge(lsa);
|
||||
}
|
||||
}
|
||||
|
||||
/* NSSA Type-7 default route. */
|
||||
void ospf6_abr_nssa_type_7_defaults(struct ospf6 *ospf6)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct ospf6_area *oa;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
|
||||
if (IS_AREA_NSSA(oa) && oa->nssa_default_originate.enabled
|
||||
&& (IS_OSPF6_ABR(ospf6)
|
||||
|| (IS_OSPF6_ASBR(ospf6)
|
||||
&& ospf6->nssa_default_import_check.status)))
|
||||
ospf6_abr_nssa_type_7_default_create(ospf6, oa);
|
||||
else
|
||||
ospf6_abr_nssa_type_7_default_delete(ospf6, oa);
|
||||
}
|
||||
}
|
||||
|
||||
static void ospf6_abr_nssa_task(struct ospf6 *ospf6)
|
||||
{
|
||||
/* called only if any_nssa */
|
||||
|
@ -1169,10 +1251,11 @@ static void ospf6_check_and_originate_type7_lsa(struct ospf6_area *area)
|
|||
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);
|
||||
struct ospf6_external_info *info = route->route_option;
|
||||
|
||||
/* This means the Type-5 LSA was originated for this route */
|
||||
if (route->path.origin.id != 0 && info->type != DEFAULT_ROUTE)
|
||||
ospf6_nssa_lsa_originate(route, area, true);
|
||||
}
|
||||
|
||||
/* Loop through the aggregation table to originate type-7 LSAs
|
||||
|
@ -1192,7 +1275,7 @@ static void ospf6_check_and_originate_type7_lsa(struct ospf6_area *area)
|
|||
"Originating Type-7 LSAs for area %s",
|
||||
area->name);
|
||||
|
||||
ospf6_nssa_lsa_originate(aggr->route, area);
|
||||
ospf6_nssa_lsa_originate(aggr->route, area, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1286,7 +1369,7 @@ static struct in6_addr *ospf6_get_nssa_fwd_addr(struct ospf6_area *oa)
|
|||
}
|
||||
|
||||
void ospf6_nssa_lsa_originate(struct ospf6_route *route,
|
||||
struct ospf6_area *area)
|
||||
struct ospf6_area *area, bool p_bit)
|
||||
{
|
||||
char buffer[OSPF6_MAX_LSASIZE];
|
||||
struct ospf6_lsa_header *lsa_header;
|
||||
|
@ -1311,13 +1394,13 @@ void ospf6_nssa_lsa_originate(struct ospf6_route *route,
|
|||
|
||||
/* Fill AS-External-LSA */
|
||||
/* Metric type */
|
||||
if (route->path.metric_type == OSPF6_PATH_TYPE_EXTERNAL2)
|
||||
if (route->path.metric_type == 2)
|
||||
SET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
|
||||
else
|
||||
UNSET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
|
||||
|
||||
/* external route tag */
|
||||
if (info->tag)
|
||||
if (info && info->tag)
|
||||
SET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
|
||||
else
|
||||
UNSET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
|
||||
|
@ -1332,7 +1415,8 @@ void ospf6_nssa_lsa_originate(struct ospf6_route *route,
|
|||
as_external_lsa->prefix.prefix_options = route->prefix_options;
|
||||
|
||||
/* Set the P bit */
|
||||
as_external_lsa->prefix.prefix_options |= OSPF6_PREFIX_OPTION_P;
|
||||
if (p_bit)
|
||||
as_external_lsa->prefix.prefix_options |= OSPF6_PREFIX_OPTION_P;
|
||||
|
||||
/* don't use refer LS-type */
|
||||
as_external_lsa->prefix.prefix_refer_lstype = htons(0);
|
||||
|
@ -1353,7 +1437,8 @@ void ospf6_nssa_lsa_originate(struct ospf6_route *route,
|
|||
UNSET_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
|
||||
|
||||
/* External Route Tag */
|
||||
if (CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T)) {
|
||||
if (info
|
||||
&& CHECK_FLAG(as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T)) {
|
||||
route_tag_t network_order = htonl(info->tag);
|
||||
|
||||
memcpy(p, &network_order, sizeof(network_order));
|
||||
|
|
|
@ -64,8 +64,9 @@ extern void ospf6_schedule_abr_task(struct ospf6 *ospf6);
|
|||
extern void ospf6_area_nssa_update(struct ospf6_area *area);
|
||||
void ospf6_asbr_prefix_readvertise(struct ospf6 *ospf6);
|
||||
extern void ospf6_nssa_lsa_originate(struct ospf6_route *route,
|
||||
struct ospf6_area *area);
|
||||
struct ospf6_area *area, bool p_bit);
|
||||
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,
|
||||
|
|
|
@ -657,8 +657,10 @@ static int ospf6_spf_calculation_thread(struct thread *t)
|
|||
/* External LSA calculation */
|
||||
ospf6_ase_calculate_timer_add(ospf6);
|
||||
|
||||
if (ospf6_check_and_set_router_abr(ospf6))
|
||||
if (ospf6_check_and_set_router_abr(ospf6)) {
|
||||
ospf6_abr_defaults_to_stub(ospf6);
|
||||
ospf6_abr_nssa_type_7_defaults(ospf6);
|
||||
}
|
||||
|
||||
monotime(&end);
|
||||
timersub(&end, &start, &runtime);
|
||||
|
|
|
@ -143,6 +143,18 @@ struct ospf6 {
|
|||
/* OSPF6 redistribute configuration */
|
||||
struct list *redist[ZEBRA_ROUTE_MAX + 1];
|
||||
|
||||
/* NSSA default-information-originate */
|
||||
struct {
|
||||
/* # of NSSA areas requesting default information */
|
||||
uint16_t refcnt;
|
||||
|
||||
/*
|
||||
* Whether a default route known through non-OSPF protocol is
|
||||
* present in the RIB.
|
||||
*/
|
||||
bool status;
|
||||
} nssa_default_import_check;
|
||||
|
||||
uint8_t flag;
|
||||
#define OSPF6_FLAG_ABR 0x04
|
||||
#define OSPF6_FLAG_ASBR 0x08
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "ospf6_lsa.h"
|
||||
#include "ospf6_lsdb.h"
|
||||
#include "ospf6_asbr.h"
|
||||
#include "ospf6_nssa.h"
|
||||
#include "ospf6_zebra.h"
|
||||
#include "ospf6d.h"
|
||||
#include "ospf6_area.h"
|
||||
|
@ -129,6 +130,61 @@ void ospf6_zebra_no_redistribute(int type, vrf_id_t vrf_id)
|
|||
AFI_IP6, type, 0, vrf_id);
|
||||
}
|
||||
|
||||
void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg)
|
||||
{
|
||||
struct prefix prefix = {};
|
||||
int command;
|
||||
|
||||
if (zclient->sock < 0) {
|
||||
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
|
||||
zlog_debug(" Not connected to Zebra");
|
||||
return;
|
||||
}
|
||||
|
||||
prefix.family = AF_INET6;
|
||||
prefix.prefixlen = 0;
|
||||
|
||||
if (unreg)
|
||||
command = ZEBRA_IMPORT_ROUTE_UNREGISTER;
|
||||
else
|
||||
command = ZEBRA_IMPORT_ROUTE_REGISTER;
|
||||
|
||||
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
|
||||
zlog_debug("%s: sending cmd %s for %pFX (vrf %u)", __func__,
|
||||
zserv_command_string(command), &prefix,
|
||||
ospf6->vrf_id);
|
||||
|
||||
if (zclient_send_rnh(zclient, command, &prefix, true, ospf6->vrf_id)
|
||||
== ZCLIENT_SEND_FAILURE)
|
||||
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed",
|
||||
__func__);
|
||||
}
|
||||
|
||||
static int ospf6_zebra_import_check_update(ZAPI_CALLBACK_ARGS)
|
||||
{
|
||||
struct ospf6 *ospf6;
|
||||
struct zapi_route nhr;
|
||||
|
||||
ospf6 = ospf6_lookup_by_vrf_id(vrf_id);
|
||||
if (ospf6 == NULL || !IS_OSPF6_ASBR(ospf6))
|
||||
return 0;
|
||||
|
||||
if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
|
||||
zlog_err("%s[%u]: Failure to decode route", __func__,
|
||||
ospf6->vrf_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nhr.prefix.family != AF_INET6 || nhr.prefix.prefixlen != 0
|
||||
|| nhr.type == ZEBRA_ROUTE_OSPF6)
|
||||
return 0;
|
||||
|
||||
ospf6->nssa_default_import_check.status = !!nhr.nexthop_num;
|
||||
ospf6_abr_nssa_type_7_defaults(ospf6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)
|
||||
{
|
||||
struct connected *c;
|
||||
|
@ -664,6 +720,7 @@ void ospf6_zebra_init(struct thread_master *master)
|
|||
ospf6_zebra_if_address_update_delete;
|
||||
zclient->redistribute_route_add = ospf6_zebra_read_route;
|
||||
zclient->redistribute_route_del = ospf6_zebra_read_route;
|
||||
zclient->import_check_update = ospf6_zebra_import_check_update;
|
||||
|
||||
/* Install command element for zebra node. */
|
||||
install_element(VIEW_NODE, &show_ospf6_zebra_cmd);
|
||||
|
|
|
@ -55,6 +55,7 @@ extern void ospf6_zebra_no_redistribute(int, vrf_id_t vrf_id);
|
|||
#define ospf6_zebra_is_redistribute(type, vrf_id) \
|
||||
vrf_bitmap_check(zclient->redist[AFI_IP6][type], vrf_id)
|
||||
extern void ospf6_zebra_init(struct thread_master *tm);
|
||||
extern void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg);
|
||||
extern void ospf6_zebra_add_discard(struct ospf6_route *request,
|
||||
struct ospf6 *ospf6);
|
||||
extern void ospf6_zebra_delete_discard(struct ospf6_route *request,
|
||||
|
|
|
@ -217,8 +217,8 @@ def test_ospfv3_expected_route_types():
|
|||
{
|
||||
"numberOfIntraAreaRoutes": 1,
|
||||
"numberOfInterAreaRoutes": 2,
|
||||
"numberOfExternal1Routes": 4,
|
||||
"numberOfExternal2Routes": 0,
|
||||
"numberOfExternal1Routes": 0,
|
||||
"numberOfExternal2Routes": 3,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -330,7 +330,7 @@ def test_nssa_lsa_type7():
|
|||
]
|
||||
route = {
|
||||
"2001:db8:100::/64": {
|
||||
"pathType": "E1",
|
||||
"pathType": "E2",
|
||||
"nextHops": [{"nextHop": "::", "interfaceName": "r4-eth0"}],
|
||||
}
|
||||
}
|
||||
|
@ -431,6 +431,50 @@ def test_nssa_no_summary():
|
|||
assert result is None, assertmsg
|
||||
|
||||
|
||||
def test_nssa_default_originate():
|
||||
"""
|
||||
Test the following:
|
||||
* A type-7 default route should be originated into the NSSA area
|
||||
when the default-information-originate option is configured;
|
||||
* Once the default-information-originate option is unconfigured, the
|
||||
previously originated Type-7 default route should be removed.
|
||||
"""
|
||||
tgen = get_topogen()
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
#
|
||||
# Configure r2 to announce a Type-7 default route.
|
||||
#
|
||||
config = """
|
||||
configure terminal
|
||||
router ospf6
|
||||
no default-information originate
|
||||
area 2 nssa default-information-originate
|
||||
"""
|
||||
tgen.gears["r2"].vtysh_cmd(config)
|
||||
|
||||
logger.info("Expecting Type-7 default-route to be added")
|
||||
routes = {"::/0": {}}
|
||||
expect_ospfv3_routes("r4", routes, wait=30, type="external-2")
|
||||
|
||||
#
|
||||
# Configure r2 to stop announcing a Type-7 default route.
|
||||
#
|
||||
config = """
|
||||
configure terminal
|
||||
router ospf6
|
||||
area 2 nssa
|
||||
"""
|
||||
tgen.gears["r2"].vtysh_cmd(config)
|
||||
|
||||
logger.info("Expecting Type-7 default route to be removed")
|
||||
test_func = partial(dont_expect_route, "r4", "::/0", type="external-2")
|
||||
_, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
|
||||
assertmsg = "r4's Type-7 default route still exists"
|
||||
assert result is None, assertmsg
|
||||
|
||||
|
||||
def test_area_filters():
|
||||
"""
|
||||
Test ABR import/export filters.
|
||||
|
|
Loading…
Reference in a new issue