mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 21:20:48 +00:00
ospfd: implement Type-7 default routes for NSSA areas
Add the "default-information-originate" option to the "area X nssa" command. That option allows the origination of Type-7 default routes on NSSA ABRs and ASBRs. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
e85194f572
commit
017714e3ad
@ -431,6 +431,16 @@ Areas
|
||||
configured not to advertise forwarding addresses into the backbone to direct
|
||||
forwarded traffic to the NSSA ABR translator.
|
||||
|
||||
.. clicmd:: area A.B.C.D nssa default-information-originate [metric-type (1-2)] [metric (0-16777214)]
|
||||
|
||||
.. clicmd:: area (0-4294967295) nssa default-information-originate [metric-type (1-2)] [metric (0-16777214)]
|
||||
|
||||
NSSA ABRs and ASBRs can be configured with the `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 default-cost (0-16777215)
|
||||
|
||||
|
||||
|
@ -1807,6 +1807,82 @@ static void ospf_abr_announce_non_dna_routers(struct event *thread)
|
||||
OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT, "%s(): Stop", __func__);
|
||||
}
|
||||
|
||||
static void ospf_abr_nssa_type7_default_create(struct ospf *ospf,
|
||||
struct ospf_area *area,
|
||||
struct ospf_lsa *lsa)
|
||||
{
|
||||
struct external_info ei;
|
||||
|
||||
if (IS_DEBUG_OSPF_NSSA)
|
||||
zlog_debug(
|
||||
"Announcing Type-7 default route into NSSA area %pI4",
|
||||
&area->area_id);
|
||||
|
||||
/* Prepare the extrenal_info for aggregator */
|
||||
memset(&ei, 0, sizeof(struct external_info));
|
||||
ei.p.family = AF_INET;
|
||||
ei.p.prefixlen = 0;
|
||||
ei.tag = 0;
|
||||
ei.type = 0;
|
||||
ei.instance = ospf->instance;
|
||||
|
||||
/* Compute default route type and metric. */
|
||||
if (area->nssa_default_originate.metric_value != -1)
|
||||
ei.route_map_set.metric =
|
||||
area->nssa_default_originate.metric_value;
|
||||
else
|
||||
ei.route_map_set.metric = DEFAULT_DEFAULT_ALWAYS_METRIC;
|
||||
if (area->nssa_default_originate.metric_type != -1)
|
||||
ei.route_map_set.metric_type =
|
||||
area->nssa_default_originate.metric_type;
|
||||
else
|
||||
ei.route_map_set.metric_type = DEFAULT_METRIC_TYPE;
|
||||
|
||||
if (!lsa)
|
||||
ospf_nssa_lsa_originate(area, &ei);
|
||||
else
|
||||
ospf_nssa_lsa_refresh(area, lsa, &ei);
|
||||
}
|
||||
|
||||
static void ospf_abr_nssa_type7_default_delete(struct ospf *ospf,
|
||||
struct ospf_area *area,
|
||||
struct ospf_lsa *lsa)
|
||||
{
|
||||
if (lsa && !CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) {
|
||||
if (IS_DEBUG_OSPF_NSSA)
|
||||
zlog_debug(
|
||||
"Withdrawing Type-7 default route from area %pI4",
|
||||
&area->area_id);
|
||||
|
||||
ospf_ls_retransmit_delete_nbr_area(area, lsa);
|
||||
ospf_refresher_unregister_lsa(ospf, lsa);
|
||||
ospf_lsa_flush_area(lsa, area);
|
||||
}
|
||||
}
|
||||
|
||||
/* NSSA Type-7 default route. */
|
||||
void ospf_abr_nssa_type7_defaults(struct ospf *ospf)
|
||||
{
|
||||
struct ospf_area *area;
|
||||
struct listnode *node;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
||||
struct in_addr id = {};
|
||||
struct ospf_lsa *lsa;
|
||||
|
||||
lsa = ospf_lsdb_lookup_by_id(area->lsdb, OSPF_AS_NSSA_LSA, id,
|
||||
area->ospf->router_id);
|
||||
if (area->external_routing == OSPF_AREA_NSSA
|
||||
&& area->nssa_default_originate.enabled
|
||||
&& (IS_OSPF_ABR(ospf)
|
||||
|| (IS_OSPF_ASBR(ospf)
|
||||
&& ospf->nssa_default_import_check.status)))
|
||||
ospf_abr_nssa_type7_default_create(ospf, area, lsa);
|
||||
else
|
||||
ospf_abr_nssa_type7_default_delete(ospf, area, lsa);
|
||||
}
|
||||
}
|
||||
|
||||
static int ospf_abr_remove_unapproved_translates_apply(struct ospf *ospf,
|
||||
struct ospf_lsa *lsa)
|
||||
{
|
||||
@ -2031,6 +2107,11 @@ void ospf_abr_task(struct ospf *ospf)
|
||||
zlog_debug("%s: announce stub defaults", __func__);
|
||||
ospf_abr_announce_stub_defaults(ospf);
|
||||
|
||||
if (IS_DEBUG_OSPF_EVENT)
|
||||
zlog_debug("%s: announce NSSA Type-7 defaults",
|
||||
__func__);
|
||||
ospf_abr_nssa_type7_defaults(ospf);
|
||||
|
||||
if (ospf->fr_configured) {
|
||||
OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
|
||||
"%s(): announce non-DNArouters",
|
||||
|
@ -73,6 +73,7 @@ extern void ospf_schedule_abr_task(struct ospf *);
|
||||
|
||||
extern void ospf_abr_announce_network_to_area(struct prefix_ipv4 *, uint32_t,
|
||||
struct ospf_area *);
|
||||
extern void ospf_abr_nssa_type7_defaults(struct ospf *ospf);
|
||||
extern void ospf_abr_nssa_check_status(struct ospf *ospf);
|
||||
extern void ospf_abr_generate_indication_lsa(struct ospf *ospf,
|
||||
const struct ospf_area *area);
|
||||
|
103
ospfd/ospf_lsa.c
103
ospfd/ospf_lsa.c
@ -1868,8 +1868,7 @@ static struct ospf_lsa *ospf_external_lsa_new(struct ospf *ospf,
|
||||
}
|
||||
|
||||
/* As Type-7 */
|
||||
static void ospf_install_flood_nssa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||
struct external_info *ei)
|
||||
static void ospf_install_flood_nssa(struct ospf *ospf, struct ospf_lsa *lsa)
|
||||
{
|
||||
struct ospf_lsa *new;
|
||||
struct as_external_lsa *extlsa;
|
||||
@ -2253,7 +2252,7 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
|
||||
/* stay away from translated LSAs! */
|
||||
!(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)))
|
||||
ospf_install_flood_nssa(
|
||||
ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
|
||||
ospf, new); /* Install/Flood Type-7 to all NSSAs */
|
||||
|
||||
/* Debug logging. */
|
||||
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
||||
@ -2266,6 +2265,100 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Originate an NSSA-LSA, install and flood. */
|
||||
struct ospf_lsa *ospf_nssa_lsa_originate(struct ospf_area *area,
|
||||
struct external_info *ei)
|
||||
{
|
||||
struct ospf *ospf = area->ospf;
|
||||
struct ospf_lsa *new;
|
||||
|
||||
if (ospf->gr_info.restart_in_progress) {
|
||||
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
||||
zlog_debug(
|
||||
"LSA[Type7]: Graceful Restart in progress, don't originate");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ospf->router_id.s_addr == INADDR_ANY) {
|
||||
if (IS_DEBUG_OSPF_EVENT)
|
||||
zlog_debug(
|
||||
"LSA[Type7:%pI4]: deferring NSSA-LSA origination, router ID is zero",
|
||||
&ei->p.prefix);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create new NSSA-LSA instance. */
|
||||
if ((new = ospf_external_lsa_new(ospf, ei, NULL)) == NULL) {
|
||||
if (IS_DEBUG_OSPF_EVENT)
|
||||
zlog_debug(
|
||||
"LSA[Type7:%pI4]: Could not originate NSSA-LSA",
|
||||
&ei->p.prefix);
|
||||
return NULL;
|
||||
}
|
||||
new->data->type = OSPF_AS_NSSA_LSA;
|
||||
new->area = area;
|
||||
|
||||
/* Install newly created LSA into Type-7 LSDB. */
|
||||
ospf_lsa_install(ospf, NULL, new);
|
||||
|
||||
/* Update LSA origination count. */
|
||||
ospf->lsa_originate_count++;
|
||||
|
||||
/* Flooding new LSA */
|
||||
ospf_flood_through_area(area, NULL, new);
|
||||
|
||||
/* Debug logging. */
|
||||
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
||||
zlog_debug("LSA[Type%d:%pI4]: Originate NSSA-LSA %p",
|
||||
new->data->type, &new->data->id, (void *)new);
|
||||
ospf_lsa_header_dump(new->data);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Refresh NSSA-LSA. */
|
||||
struct ospf_lsa *ospf_nssa_lsa_refresh(struct ospf_area *area,
|
||||
struct ospf_lsa *lsa,
|
||||
struct external_info *ei)
|
||||
{
|
||||
struct ospf *ospf = area->ospf;
|
||||
struct ospf_lsa *new;
|
||||
|
||||
/* Delete LSA from neighbor retransmit-list. */
|
||||
ospf_ls_retransmit_delete_nbr_as(ospf, lsa);
|
||||
|
||||
/* Unregister AS-external-LSA from refresh-list. */
|
||||
ospf_refresher_unregister_lsa(ospf, lsa);
|
||||
|
||||
/* Create new NSSA-LSA instance. */
|
||||
if ((new = ospf_external_lsa_new(ospf, ei, NULL)) == NULL) {
|
||||
if (IS_DEBUG_OSPF_EVENT)
|
||||
zlog_debug(
|
||||
"LSA[Type7:%pI4]: Could not originate NSSA-LSA",
|
||||
&ei->p.prefix);
|
||||
return NULL;
|
||||
}
|
||||
new->data->type = OSPF_AS_NSSA_LSA;
|
||||
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
||||
new->area = area;
|
||||
|
||||
/* Install newly created LSA into Type-7 LSDB. */
|
||||
ospf_lsa_install(ospf, NULL, new);
|
||||
|
||||
/* Flooding new LSA */
|
||||
ospf_flood_through_area(area, NULL, new);
|
||||
|
||||
/* Debug logging. */
|
||||
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
||||
zlog_debug("LSA[Type%d:%pI4]: NSSA-LSA refresh",
|
||||
new->data->type, &new->data->id);
|
||||
ospf_lsa_header_dump(new->data);
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
static struct external_info *ospf_default_external_info(struct ospf *ospf)
|
||||
{
|
||||
int type;
|
||||
@ -2611,8 +2704,8 @@ struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf,
|
||||
|
||||
/* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
|
||||
if (ospf->anyNSSA && !(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)))
|
||||
ospf_install_flood_nssa(ospf, new,
|
||||
ei); /* Install/Flood per new rules */
|
||||
ospf_install_flood_nssa(ospf,
|
||||
new); /* Install/Flood per new rules */
|
||||
|
||||
/* Register self-originated LSA to refresh queue.
|
||||
* Translated LSAs should not be registered, but refreshed upon
|
||||
|
@ -278,6 +278,11 @@ extern struct in_addr ospf_get_ip_from_ifp(struct ospf_interface *);
|
||||
|
||||
extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *,
|
||||
struct external_info *);
|
||||
extern struct ospf_lsa *ospf_nssa_lsa_originate(struct ospf_area *area,
|
||||
struct external_info *ei);
|
||||
extern struct ospf_lsa *ospf_nssa_lsa_refresh(struct ospf_area *area,
|
||||
struct ospf_lsa *lsa,
|
||||
struct external_info *ei);
|
||||
extern void ospf_external_lsa_rid_change(struct ospf *ospf);
|
||||
extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *,
|
||||
uint32_t, struct in_addr,
|
||||
|
@ -1438,6 +1438,7 @@ DEFPY (ospf_area_nssa,
|
||||
"area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
||||
[{\
|
||||
<translate-candidate|translate-never|translate-always>$translator_role\
|
||||
|default-information-originate$dflt_originate [{metric (0-16777214)$mval|metric-type (1-2)$mtype}]\
|
||||
|no-summary$no_summary\
|
||||
|suppress-fa$suppress_fa\
|
||||
}]",
|
||||
@ -1448,6 +1449,11 @@ DEFPY (ospf_area_nssa,
|
||||
"Configure NSSA-ABR for translate election (default)\n"
|
||||
"Configure NSSA-ABR to never translate\n"
|
||||
"Configure NSSA-ABR to always translate\n"
|
||||
"Originate Type 7 default into NSSA area\n"
|
||||
"OSPF default metric\n"
|
||||
"OSPF metric\n"
|
||||
"OSPF metric type for default routes\n"
|
||||
"Set OSPF External Type 1/2 metrics\n"
|
||||
"Do not inject inter-area routes into nssa\n"
|
||||
"Suppress forwarding address\n")
|
||||
{
|
||||
@ -1481,6 +1487,18 @@ DEFPY (ospf_area_nssa,
|
||||
OSPF_NSSA_ROLE_CANDIDATE);
|
||||
}
|
||||
|
||||
if (dflt_originate) {
|
||||
int metric_type = DEFAULT_METRIC_TYPE;
|
||||
|
||||
if (mval_str == NULL)
|
||||
mval = -1;
|
||||
if (mtype_str)
|
||||
(void)str2metric_type(mtype_str, &metric_type);
|
||||
ospf_area_nssa_default_originate_set(ospf, area_id, mval,
|
||||
metric_type);
|
||||
} else
|
||||
ospf_area_nssa_default_originate_unset(ospf, area_id);
|
||||
|
||||
if (no_summary)
|
||||
ospf_area_nssa_no_summary_set(ospf, area_id);
|
||||
else
|
||||
@ -1504,6 +1522,7 @@ DEFPY (no_ospf_area_nssa,
|
||||
"no area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
||||
[{\
|
||||
<translate-candidate|translate-never|translate-always>\
|
||||
|default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\
|
||||
|no-summary\
|
||||
|suppress-fa\
|
||||
}]",
|
||||
@ -1515,6 +1534,11 @@ DEFPY (no_ospf_area_nssa,
|
||||
"Configure NSSA-ABR for translate election (default)\n"
|
||||
"Configure NSSA-ABR to never translate\n"
|
||||
"Configure NSSA-ABR to always translate\n"
|
||||
"Originate Type 7 default into NSSA area\n"
|
||||
"OSPF default metric\n"
|
||||
"OSPF metric\n"
|
||||
"OSPF metric type for default routes\n"
|
||||
"Set OSPF External Type 1/2 metrics\n"
|
||||
"Do not inject inter-area routes into nssa\n"
|
||||
"Suppress forwarding address\n")
|
||||
{
|
||||
@ -1527,6 +1551,7 @@ DEFPY (no_ospf_area_nssa,
|
||||
/* Flush the NSSA LSA for the specified area */
|
||||
ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_NSSA_LSA);
|
||||
ospf_area_no_summary_unset(ospf, area_id);
|
||||
ospf_area_nssa_default_originate_unset(ospf, area_id);
|
||||
ospf_area_nssa_suppress_fa_unset(ospf, area_id);
|
||||
ospf_area_nssa_unset(ospf, area_id);
|
||||
|
||||
@ -11872,29 +11897,39 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf)
|
||||
vty_out(vty, " no-summary\n");
|
||||
vty_out(vty, "\n");
|
||||
} else if (area->external_routing == OSPF_AREA_NSSA) {
|
||||
vty_out(vty, " area %s nssa", buf);
|
||||
|
||||
switch (area->NSSATranslatorRole) {
|
||||
case OSPF_NSSA_ROLE_NEVER:
|
||||
vty_out(vty,
|
||||
" area %s nssa translate-never\n",
|
||||
buf);
|
||||
vty_out(vty, " translate-never");
|
||||
break;
|
||||
case OSPF_NSSA_ROLE_ALWAYS:
|
||||
vty_out(vty,
|
||||
" area %s nssa translate-always\n",
|
||||
buf);
|
||||
vty_out(vty, " translate-always");
|
||||
break;
|
||||
case OSPF_NSSA_ROLE_CANDIDATE:
|
||||
vty_out(vty, " area %s nssa \n", buf);
|
||||
break;
|
||||
}
|
||||
|
||||
if (area->nssa_default_originate.enabled) {
|
||||
vty_out(vty,
|
||||
" default-information-originate");
|
||||
if (area->nssa_default_originate
|
||||
.metric_value
|
||||
!= -1)
|
||||
vty_out(vty, " metric %d",
|
||||
area->nssa_default_originate
|
||||
.metric_value);
|
||||
if (area->nssa_default_originate
|
||||
.metric_type
|
||||
!= DEFAULT_METRIC_TYPE)
|
||||
vty_out(vty, " metric-type 1");
|
||||
}
|
||||
|
||||
if (area->no_summary)
|
||||
vty_out(vty,
|
||||
" area %s nssa no-summary\n",
|
||||
buf);
|
||||
vty_out(vty, " no-summary");
|
||||
if (area->suppress_fa)
|
||||
vty_out(vty,
|
||||
" area %s nssa suppress-fa\n",
|
||||
buf);
|
||||
vty_out(vty, " suppress-fa");
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
if (area->default_cost != 1)
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "log.h"
|
||||
#include "route_opaque.h"
|
||||
#include "lib/bfd.h"
|
||||
#include "lib/lib_errors.h"
|
||||
#include "nexthop.h"
|
||||
|
||||
#include "ospfd/ospfd.h"
|
||||
@ -1470,6 +1471,61 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg)
|
||||
{
|
||||
struct prefix prefix = {};
|
||||
int command;
|
||||
|
||||
if (zclient->sock < 0) {
|
||||
if (IS_DEBUG_OSPF(zebra, ZEBRA))
|
||||
zlog_debug(" Not connected to Zebra");
|
||||
return;
|
||||
}
|
||||
|
||||
prefix.family = AF_INET;
|
||||
prefix.prefixlen = 0;
|
||||
|
||||
if (unreg)
|
||||
command = ZEBRA_NEXTHOP_UNREGISTER;
|
||||
else
|
||||
command = ZEBRA_NEXTHOP_REGISTER;
|
||||
|
||||
if (IS_DEBUG_OSPF(zebra, ZEBRA))
|
||||
zlog_debug("%s: sending cmd %s for %pFX (vrf %u)", __func__,
|
||||
zserv_command_string(command), &prefix,
|
||||
ospf->vrf_id);
|
||||
|
||||
if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, false,
|
||||
true, ospf->vrf_id) == ZCLIENT_SEND_FAILURE)
|
||||
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed",
|
||||
__func__);
|
||||
}
|
||||
|
||||
static int ospf_zebra_import_check_update(ZAPI_CALLBACK_ARGS)
|
||||
{
|
||||
struct ospf *ospf;
|
||||
struct zapi_route nhr;
|
||||
struct prefix matched;
|
||||
|
||||
ospf = ospf_lookup_by_vrf_id(vrf_id);
|
||||
if (ospf == NULL || !IS_OSPF_ASBR(ospf))
|
||||
return 0;
|
||||
|
||||
if (!zapi_nexthop_update_decode(zclient->ibuf, &matched, &nhr)) {
|
||||
zlog_err("%s[%u]: Failure to decode route", __func__,
|
||||
ospf->vrf_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (matched.family != AF_INET || matched.prefixlen != 0 ||
|
||||
nhr.type == ZEBRA_ROUTE_OSPF)
|
||||
return 0;
|
||||
|
||||
ospf->nssa_default_import_check.status = !!nhr.nexthop_num;
|
||||
ospf_abr_nssa_type7_defaults(ospf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ospf_distribute_list_out_set(struct ospf *ospf, int type, const char *name)
|
||||
{
|
||||
@ -2132,6 +2188,7 @@ static zclient_handler *const ospf_handlers[] = {
|
||||
|
||||
[ZEBRA_REDISTRIBUTE_ROUTE_ADD] = ospf_zebra_read_route,
|
||||
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf_zebra_read_route,
|
||||
[ZEBRA_NEXTHOP_UPDATE] = ospf_zebra_import_check_update,
|
||||
|
||||
[ZEBRA_OPAQUE_MESSAGE] = ospf_opaque_msg_handler,
|
||||
|
||||
|
@ -69,6 +69,7 @@ extern int ospf_redistribute_set(struct ospf *, struct ospf_redist *, int,
|
||||
unsigned short, int, int);
|
||||
extern int ospf_redistribute_unset(struct ospf *, int, unsigned short);
|
||||
extern int ospf_redistribute_default_set(struct ospf *, int, int, int);
|
||||
extern void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg);
|
||||
extern int ospf_distribute_list_out_set(struct ospf *, int, const char *);
|
||||
extern int ospf_distribute_list_out_unset(struct ospf *, int, const char *);
|
||||
extern void ospf_routemap_set(struct ospf_redist *, const char *);
|
||||
|
@ -1774,6 +1774,51 @@ int ospf_area_nssa_translator_role_set(struct ospf *ospf,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ospf_area_nssa_default_originate_set(struct ospf *ospf,
|
||||
struct in_addr area_id, int metric,
|
||||
int metric_type)
|
||||
{
|
||||
struct ospf_area *area;
|
||||
|
||||
area = ospf_area_lookup_by_area_id(ospf, area_id);
|
||||
if (area == NULL)
|
||||
return;
|
||||
|
||||
if (!area->nssa_default_originate.enabled) {
|
||||
area->nssa_default_originate.enabled = true;
|
||||
if (++ospf->nssa_default_import_check.refcnt == 1) {
|
||||
ospf->nssa_default_import_check.status = false;
|
||||
ospf_zebra_import_default_route(ospf, false);
|
||||
}
|
||||
}
|
||||
|
||||
area->nssa_default_originate.metric_value = metric;
|
||||
area->nssa_default_originate.metric_type = metric_type;
|
||||
}
|
||||
|
||||
void ospf_area_nssa_default_originate_unset(struct ospf *ospf,
|
||||
struct in_addr area_id)
|
||||
{
|
||||
struct ospf_area *area;
|
||||
|
||||
area = ospf_area_lookup_by_area_id(ospf, area_id);
|
||||
if (area == NULL)
|
||||
return;
|
||||
|
||||
if (area->nssa_default_originate.enabled) {
|
||||
area->nssa_default_originate.enabled = false;
|
||||
if (--ospf->nssa_default_import_check.refcnt == 0) {
|
||||
ospf->nssa_default_import_check.status = false;
|
||||
ospf_zebra_import_default_route(ospf, true);
|
||||
}
|
||||
area->nssa_default_originate.metric_value = -1;
|
||||
area->nssa_default_originate.metric_type = -1;
|
||||
|
||||
if (!IS_OSPF_ABR(ospf))
|
||||
ospf_abr_nssa_type7_defaults(ospf);
|
||||
}
|
||||
}
|
||||
|
||||
int ospf_area_export_list_set(struct ospf *ospf, struct ospf_area *area,
|
||||
const char *list_name)
|
||||
{
|
||||
|
@ -302,6 +302,18 @@ struct ospf {
|
||||
|
||||
int default_metric; /* Default metric for redistribute. */
|
||||
|
||||
/* 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;
|
||||
|
||||
#define OSPF_LSA_REFRESHER_GRANULARITY 10
|
||||
#define OSPF_LSA_REFRESHER_SLOTS \
|
||||
((OSPF_LS_REFRESH_TIME + OSPF_LS_REFRESH_SHIFT) \
|
||||
@ -561,6 +573,13 @@ struct ospf_area {
|
||||
#define PREFIX_LIST_OUT(A) (A)->plist_out.list
|
||||
#define PREFIX_NAME_OUT(A) (A)->plist_out.name
|
||||
|
||||
/* NSSA default-information-originate */
|
||||
struct {
|
||||
bool enabled;
|
||||
int metric_type;
|
||||
int metric_value;
|
||||
} nssa_default_originate;
|
||||
|
||||
/* Shortest Path Tree. */
|
||||
struct vertex *spf;
|
||||
struct list *spf_vertex_list;
|
||||
@ -704,6 +723,11 @@ extern int ospf_area_nssa_suppress_fa_unset(struct ospf *ospf,
|
||||
struct in_addr area_id);
|
||||
extern int ospf_area_nssa_translator_role_set(struct ospf *ospf,
|
||||
struct in_addr area_id, int role);
|
||||
extern void ospf_area_nssa_default_originate_set(struct ospf *ospf,
|
||||
struct in_addr area_id,
|
||||
int metric, int metric_type);
|
||||
extern void ospf_area_nssa_default_originate_unset(struct ospf *ospf,
|
||||
struct in_addr area_id);
|
||||
extern int ospf_area_export_list_set(struct ospf *ospf,
|
||||
struct ospf_area *area_id,
|
||||
const char *list_name);
|
||||
|
Loading…
Reference in New Issue
Block a user