mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 20:04:11 +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
|
configured not to advertise forwarding addresses into the backbone to direct
|
||||||
forwarded traffic to the NSSA ABR translator.
|
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)
|
.. 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__);
|
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,
|
static int ospf_abr_remove_unapproved_translates_apply(struct ospf *ospf,
|
||||||
struct ospf_lsa *lsa)
|
struct ospf_lsa *lsa)
|
||||||
{
|
{
|
||||||
@ -2031,6 +2107,11 @@ void ospf_abr_task(struct ospf *ospf)
|
|||||||
zlog_debug("%s: announce stub defaults", __func__);
|
zlog_debug("%s: announce stub defaults", __func__);
|
||||||
ospf_abr_announce_stub_defaults(ospf);
|
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) {
|
if (ospf->fr_configured) {
|
||||||
OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
|
OSPF_LOG_DEBUG(IS_DEBUG_OSPF_EVENT,
|
||||||
"%s(): announce non-DNArouters",
|
"%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,
|
extern void ospf_abr_announce_network_to_area(struct prefix_ipv4 *, uint32_t,
|
||||||
struct ospf_area *);
|
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_nssa_check_status(struct ospf *ospf);
|
||||||
extern void ospf_abr_generate_indication_lsa(struct ospf *ospf,
|
extern void ospf_abr_generate_indication_lsa(struct ospf *ospf,
|
||||||
const struct ospf_area *area);
|
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 */
|
/* As Type-7 */
|
||||||
static void ospf_install_flood_nssa(struct ospf *ospf, struct ospf_lsa *lsa,
|
static void ospf_install_flood_nssa(struct ospf *ospf, struct ospf_lsa *lsa)
|
||||||
struct external_info *ei)
|
|
||||||
{
|
{
|
||||||
struct ospf_lsa *new;
|
struct ospf_lsa *new;
|
||||||
struct as_external_lsa *extlsa;
|
struct as_external_lsa *extlsa;
|
||||||
@ -2253,7 +2252,7 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
|
|||||||
/* stay away from translated LSAs! */
|
/* stay away from translated LSAs! */
|
||||||
!(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)))
|
!(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)))
|
||||||
ospf_install_flood_nssa(
|
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. */
|
/* Debug logging. */
|
||||||
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
||||||
@ -2266,6 +2265,100 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
|
|||||||
return new;
|
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)
|
static struct external_info *ospf_default_external_info(struct ospf *ospf)
|
||||||
{
|
{
|
||||||
int type;
|
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 any attached NSSA, install as Type-7, flood to all NSSA Areas */
|
||||||
if (ospf->anyNSSA && !(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)))
|
if (ospf->anyNSSA && !(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)))
|
||||||
ospf_install_flood_nssa(ospf, new,
|
ospf_install_flood_nssa(ospf,
|
||||||
ei); /* Install/Flood per new rules */
|
new); /* Install/Flood per new rules */
|
||||||
|
|
||||||
/* Register self-originated LSA to refresh queue.
|
/* Register self-originated LSA to refresh queue.
|
||||||
* Translated LSAs should not be registered, but refreshed upon
|
* 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 *,
|
extern struct ospf_lsa *ospf_external_lsa_originate(struct ospf *,
|
||||||
struct external_info *);
|
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 void ospf_external_lsa_rid_change(struct ospf *ospf);
|
||||||
extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *,
|
extern struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *,
|
||||||
uint32_t, struct in_addr,
|
uint32_t, struct in_addr,
|
||||||
|
@ -1438,6 +1438,7 @@ DEFPY (ospf_area_nssa,
|
|||||||
"area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
"area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
||||||
[{\
|
[{\
|
||||||
<translate-candidate|translate-never|translate-always>$translator_role\
|
<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\
|
|no-summary$no_summary\
|
||||||
|suppress-fa$suppress_fa\
|
|suppress-fa$suppress_fa\
|
||||||
}]",
|
}]",
|
||||||
@ -1448,6 +1449,11 @@ DEFPY (ospf_area_nssa,
|
|||||||
"Configure NSSA-ABR for translate election (default)\n"
|
"Configure NSSA-ABR for translate election (default)\n"
|
||||||
"Configure NSSA-ABR to never translate\n"
|
"Configure NSSA-ABR to never translate\n"
|
||||||
"Configure NSSA-ABR to always 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"
|
"Do not inject inter-area routes into nssa\n"
|
||||||
"Suppress forwarding address\n")
|
"Suppress forwarding address\n")
|
||||||
{
|
{
|
||||||
@ -1481,6 +1487,18 @@ DEFPY (ospf_area_nssa,
|
|||||||
OSPF_NSSA_ROLE_CANDIDATE);
|
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)
|
if (no_summary)
|
||||||
ospf_area_nssa_no_summary_set(ospf, area_id);
|
ospf_area_nssa_no_summary_set(ospf, area_id);
|
||||||
else
|
else
|
||||||
@ -1504,6 +1522,7 @@ DEFPY (no_ospf_area_nssa,
|
|||||||
"no area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
"no area <A.B.C.D|(0-4294967295)>$area_str nssa\
|
||||||
[{\
|
[{\
|
||||||
<translate-candidate|translate-never|translate-always>\
|
<translate-candidate|translate-never|translate-always>\
|
||||||
|
|default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\
|
||||||
|no-summary\
|
|no-summary\
|
||||||
|suppress-fa\
|
|suppress-fa\
|
||||||
}]",
|
}]",
|
||||||
@ -1515,6 +1534,11 @@ DEFPY (no_ospf_area_nssa,
|
|||||||
"Configure NSSA-ABR for translate election (default)\n"
|
"Configure NSSA-ABR for translate election (default)\n"
|
||||||
"Configure NSSA-ABR to never translate\n"
|
"Configure NSSA-ABR to never translate\n"
|
||||||
"Configure NSSA-ABR to always 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"
|
"Do not inject inter-area routes into nssa\n"
|
||||||
"Suppress forwarding address\n")
|
"Suppress forwarding address\n")
|
||||||
{
|
{
|
||||||
@ -1527,6 +1551,7 @@ DEFPY (no_ospf_area_nssa,
|
|||||||
/* Flush the NSSA LSA for the specified area */
|
/* Flush the NSSA LSA for the specified area */
|
||||||
ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_NSSA_LSA);
|
ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_NSSA_LSA);
|
||||||
ospf_area_no_summary_unset(ospf, area_id);
|
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_suppress_fa_unset(ospf, area_id);
|
||||||
ospf_area_nssa_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, " no-summary\n");
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
} else if (area->external_routing == OSPF_AREA_NSSA) {
|
} else if (area->external_routing == OSPF_AREA_NSSA) {
|
||||||
|
vty_out(vty, " area %s nssa", buf);
|
||||||
|
|
||||||
switch (area->NSSATranslatorRole) {
|
switch (area->NSSATranslatorRole) {
|
||||||
case OSPF_NSSA_ROLE_NEVER:
|
case OSPF_NSSA_ROLE_NEVER:
|
||||||
vty_out(vty,
|
vty_out(vty, " translate-never");
|
||||||
" area %s nssa translate-never\n",
|
|
||||||
buf);
|
|
||||||
break;
|
break;
|
||||||
case OSPF_NSSA_ROLE_ALWAYS:
|
case OSPF_NSSA_ROLE_ALWAYS:
|
||||||
vty_out(vty,
|
vty_out(vty, " translate-always");
|
||||||
" area %s nssa translate-always\n",
|
|
||||||
buf);
|
|
||||||
break;
|
break;
|
||||||
case OSPF_NSSA_ROLE_CANDIDATE:
|
case OSPF_NSSA_ROLE_CANDIDATE:
|
||||||
vty_out(vty, " area %s nssa \n", buf);
|
|
||||||
break;
|
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)
|
if (area->no_summary)
|
||||||
vty_out(vty,
|
vty_out(vty, " no-summary");
|
||||||
" area %s nssa no-summary\n",
|
|
||||||
buf);
|
|
||||||
if (area->suppress_fa)
|
if (area->suppress_fa)
|
||||||
vty_out(vty,
|
vty_out(vty, " suppress-fa");
|
||||||
" area %s nssa suppress-fa\n",
|
vty_out(vty, "\n");
|
||||||
buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (area->default_cost != 1)
|
if (area->default_cost != 1)
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "route_opaque.h"
|
#include "route_opaque.h"
|
||||||
#include "lib/bfd.h"
|
#include "lib/bfd.h"
|
||||||
|
#include "lib/lib_errors.h"
|
||||||
#include "nexthop.h"
|
#include "nexthop.h"
|
||||||
|
|
||||||
#include "ospfd/ospfd.h"
|
#include "ospfd/ospfd.h"
|
||||||
@ -1470,6 +1471,61 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
|
|||||||
return 0;
|
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)
|
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_ADD] = ospf_zebra_read_route,
|
||||||
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = 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,
|
[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);
|
unsigned short, int, int);
|
||||||
extern int ospf_redistribute_unset(struct ospf *, int, unsigned short);
|
extern int ospf_redistribute_unset(struct ospf *, int, unsigned short);
|
||||||
extern int ospf_redistribute_default_set(struct ospf *, int, int, int);
|
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_set(struct ospf *, int, const char *);
|
||||||
extern int ospf_distribute_list_out_unset(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 *);
|
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;
|
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,
|
int ospf_area_export_list_set(struct ospf *ospf, struct ospf_area *area,
|
||||||
const char *list_name)
|
const char *list_name)
|
||||||
{
|
{
|
||||||
|
@ -302,6 +302,18 @@ struct ospf {
|
|||||||
|
|
||||||
int default_metric; /* Default metric for redistribute. */
|
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_GRANULARITY 10
|
||||||
#define OSPF_LSA_REFRESHER_SLOTS \
|
#define OSPF_LSA_REFRESHER_SLOTS \
|
||||||
((OSPF_LS_REFRESH_TIME + OSPF_LS_REFRESH_SHIFT) \
|
((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_LIST_OUT(A) (A)->plist_out.list
|
||||||
#define PREFIX_NAME_OUT(A) (A)->plist_out.name
|
#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. */
|
/* Shortest Path Tree. */
|
||||||
struct vertex *spf;
|
struct vertex *spf;
|
||||||
struct list *spf_vertex_list;
|
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);
|
struct in_addr area_id);
|
||||||
extern int ospf_area_nssa_translator_role_set(struct ospf *ospf,
|
extern int ospf_area_nssa_translator_role_set(struct ospf *ospf,
|
||||||
struct in_addr area_id, int role);
|
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,
|
extern int ospf_area_export_list_set(struct ospf *ospf,
|
||||||
struct ospf_area *area_id,
|
struct ospf_area *area_id,
|
||||||
const char *list_name);
|
const char *list_name);
|
||||||
|
Loading…
Reference in New Issue
Block a user