mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-30 00:56:38 +00:00
ospfd: add support for suppress_fa
This command will trigger the OSPF forwarding address suppression in translated type-5 LSAs, causing a NSSA ABR to use 0.0.0.0 as a forwarding address instead of copying the address from the type-7 LSA Example: In a topology like: R1 --- R2(ABR) --- R3(ASBR) R3 is announcing a type-7 LSA that is translated to type-5 by the R2 ABR. The forwarding address in the type-5 is by default copied from the type-7 r1# sh ip os da external AS External Link States LS age: 6 Options: 0x2 : *|-|-|-|-|-|E|- LS Flags: 0x6 LS Type: AS-external-LSA Link State ID: 3.3.3.3 (External Network Number) Advertising Router: 10.0.25.2 LS Seq Number: 80000001 Checksum: 0xcf99 Length: 36 Network Mask: /32 Metric Type: 2 (Larger than any link state path) TOS: 0 Metric: 20 Forward Address: 10.0.23.3 <--- address copied from type-7 lsa External Route Tag: 0 r2# sh ip os database NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.23.3 8 0x80000001 0x431d E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 0 0x80000001 0xcf99 E2 3.3.3.3/32 [0x0] r2# conf t r2(config)# router ospf r2(config-router)# area 1 nssa suppress-fa r2(config-router)# exit r2(config)# exit r2# sh ip os database NSSA-external Link States (Area 0.0.0.1 [NSSA]) Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.23.3 66 0x80000001 0x431d E2 3.3.3.3/32 [0x0] AS External Link States Link ID ADV Router Age Seq# CkSum Route 3.3.3.3 10.0.25.2 16 0x80000002 0x0983 E2 3.3.3.3/32 [0x0] r1# sh ip os da external OSPF Router with ID (11.11.11.11) AS External Link States LS age: 34 Options: 0x2 : *|-|-|-|-|-|E|- LS Flags: 0x6 LS Type: AS-external-LSA Link State ID: 3.3.3.3 (External Network Number) Advertising Router: 10.0.25.2 LS Seq Number: 80000002 Checksum: 0x0983 Length: 36 Network Mask: /32 Metric Type: 2 (Larger than any link state path) TOS: 0 Metric: 20 Forward Address: 0.0.0.0 <--- address set to 0 External Route Tag: 0 r2# conf t r2(config)# router ospf r2(config-router)# no area 1 nssa suppress-fa r2(config-router)# exit r1# sh ip os da external OSPF Router with ID (11.11.11.11) AS External Link States LS age: 1 Options: 0x2 : *|-|-|-|-|-|E|- LS Flags: 0x6 LS Type: AS-external-LSA Link State ID: 3.3.3.3 (External Network Number) Advertising Router: 10.0.25.2 LS Seq Number: 80000003 Checksum: 0xcb9b Length: 36 Network Mask: /32 Metric Type: 2 (Larger than any link state path) TOS: 0 Metric: 20 Forward Address: 0.0.0.0 <--- address set to 0 External Route Tag: 0 r2# conf t r2(config)# router ospf r2(config-router)# no area 1 nssa suppress-fa r2(config-router)# exit r1# sh ip os da external OSPF Router with ID (11.11.11.11) AS External Link States LS age: 1 Options: 0x2 : *|-|-|-|-|-|E|- LS Flags: 0x6 LS Type: AS-external-LSA Link State ID: 3.3.3.3 (External Network Number) Advertising Router: 10.0.25.2 LS Seq Number: 80000003 Checksum: 0xcb9b Length: 36 Network Mask: /32 Metric Type: 2 (Larger than any link state path) TOS: 0 Metric: 20 Forward Address: 10.0.23.3 <--- address copied from type-7 lsa External Route Tag: 0 Signed-off-by: ckishimo <carles.kishimoto@gmail.com>
This commit is contained in:
parent
d71494e6a4
commit
c317eddbce
@ -675,7 +675,8 @@ static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa)
|
|||||||
* originate translated LSA
|
* originate translated LSA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ospf_translated_nssa_originate(area->ospf, lsa) == NULL) {
|
if (ospf_translated_nssa_originate(area->ospf, lsa, old)
|
||||||
|
== NULL) {
|
||||||
if (IS_DEBUG_OSPF_NSSA)
|
if (IS_DEBUG_OSPF_NSSA)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"ospf_abr_translate_nssa(): Could not translate Type-7 for %pI4 to Type-5",
|
"ospf_abr_translate_nssa(): Could not translate Type-7 for %pI4 to Type-5",
|
||||||
|
@ -1765,7 +1765,14 @@ static struct ospf_lsa *ospf_lsa_translated_nssa_new(struct ospf *ospf,
|
|||||||
/* copy over Type-7 data to new */
|
/* copy over Type-7 data to new */
|
||||||
extnew->e[0].tos = ext->e[0].tos;
|
extnew->e[0].tos = ext->e[0].tos;
|
||||||
extnew->e[0].route_tag = ext->e[0].route_tag;
|
extnew->e[0].route_tag = ext->e[0].route_tag;
|
||||||
extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
|
if (type7->area->suppress_fa) {
|
||||||
|
extnew->e[0].fwd_addr.s_addr = 0;
|
||||||
|
if (IS_DEBUG_OSPF_NSSA)
|
||||||
|
zlog_debug(
|
||||||
|
"ospf_lsa_translated_nssa_new(): Suppress forwarding address for %pI4",
|
||||||
|
&ei.p.prefix);
|
||||||
|
} else
|
||||||
|
extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
|
||||||
new->data->ls_seqnum = type7->data->ls_seqnum;
|
new->data->ls_seqnum = type7->data->ls_seqnum;
|
||||||
|
|
||||||
/* add translated flag, checksum and lock new lsa */
|
/* add translated flag, checksum and lock new lsa */
|
||||||
@ -1777,7 +1784,8 @@ static struct ospf_lsa *ospf_lsa_translated_nssa_new(struct ospf *ospf,
|
|||||||
|
|
||||||
/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
|
/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
|
||||||
struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
|
struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
|
||||||
struct ospf_lsa *type7)
|
struct ospf_lsa *type7,
|
||||||
|
struct ospf_lsa *type5)
|
||||||
{
|
{
|
||||||
struct ospf_lsa *new;
|
struct ospf_lsa *new;
|
||||||
struct as_external_lsa *extnew;
|
struct as_external_lsa *extnew;
|
||||||
@ -1796,6 +1804,10 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
|
|||||||
|
|
||||||
extnew = (struct as_external_lsa *)new->data;
|
extnew = (struct as_external_lsa *)new->data;
|
||||||
|
|
||||||
|
/* Update LSA sequence number from translated Type-5 LSA */
|
||||||
|
if (type5)
|
||||||
|
new->data->ls_seqnum = lsa_seqnum_increment(type5);
|
||||||
|
|
||||||
if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) {
|
if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) {
|
||||||
flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
|
flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
|
||||||
"%s: Could not install LSA id %pI4", __func__,
|
"%s: Could not install LSA id %pI4", __func__,
|
||||||
@ -1823,6 +1835,8 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
|
|||||||
struct ospf_lsa *type5)
|
struct ospf_lsa *type5)
|
||||||
{
|
{
|
||||||
struct ospf_lsa *new = NULL;
|
struct ospf_lsa *new = NULL;
|
||||||
|
struct as_external_lsa *extold = NULL;
|
||||||
|
uint32_t ls_seqnum = 0;
|
||||||
|
|
||||||
/* Sanity checks. */
|
/* Sanity checks. */
|
||||||
assert(type7 || type5);
|
assert(type7 || type5);
|
||||||
@ -1887,6 +1901,12 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extold = (struct as_external_lsa *)type5->data;
|
||||||
|
if (type7->area->suppress_fa == 1) {
|
||||||
|
if (extold->e[0].fwd_addr.s_addr == 0)
|
||||||
|
ls_seqnum = ntohl(type5->data->ls_seqnum);
|
||||||
|
}
|
||||||
|
|
||||||
/* Delete LSA from neighbor retransmit-list. */
|
/* Delete LSA from neighbor retransmit-list. */
|
||||||
ospf_ls_retransmit_delete_nbr_as(ospf, type5);
|
ospf_ls_retransmit_delete_nbr_as(ospf, type5);
|
||||||
|
|
||||||
@ -1899,6 +1919,11 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type7->area->suppress_fa == 1) {
|
||||||
|
if (extold->e[0].fwd_addr.s_addr == 0)
|
||||||
|
new->data->ls_seqnum = htonl(ls_seqnum + 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (!(new = ospf_lsa_install(ospf, NULL, new))) {
|
if (!(new = ospf_lsa_install(ospf, NULL, new))) {
|
||||||
flog_warn(
|
flog_warn(
|
||||||
EC_OSPF_LSA_INSTALL_FAILURE,
|
EC_OSPF_LSA_INSTALL_FAILURE,
|
||||||
|
@ -341,11 +341,12 @@ extern char link_info_set(struct stream **s, struct in_addr id,
|
|||||||
|
|
||||||
extern struct in_addr ospf_get_nssa_ip(struct ospf_area *);
|
extern struct in_addr ospf_get_nssa_ip(struct ospf_area *);
|
||||||
extern int ospf_translated_nssa_compare(struct ospf_lsa *, struct ospf_lsa *);
|
extern int ospf_translated_nssa_compare(struct ospf_lsa *, struct ospf_lsa *);
|
||||||
extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *,
|
extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
|
||||||
struct ospf_lsa *,
|
struct ospf_lsa *type7,
|
||||||
struct ospf_lsa *);
|
struct ospf_lsa *type5);
|
||||||
extern struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *,
|
extern struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
|
||||||
struct ospf_lsa *);
|
struct ospf_lsa *type7,
|
||||||
|
struct ospf_lsa *type5);
|
||||||
extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id,
|
extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id,
|
||||||
int type);
|
int type);
|
||||||
#endif /* _ZEBRA_OSPF_LSA_H */
|
#endif /* _ZEBRA_OSPF_LSA_H */
|
||||||
|
@ -1574,6 +1574,58 @@ DEFUN (ospf_area_nssa,
|
|||||||
return ospf_area_nssa_cmd_handler(vty, argc, argv, 0, 0);
|
return ospf_area_nssa_cmd_handler(vty, argc, argv, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFUN(ospf_area_nssa_suppress_fa, ospf_area_nssa_suppress_fa_cmd,
|
||||||
|
"area <A.B.C.D|(0-4294967295)> nssa suppress-fa",
|
||||||
|
"OSPF area parameters\n"
|
||||||
|
"OSPF area ID in IP address format\n"
|
||||||
|
"OSPF area ID as a decimal value\n"
|
||||||
|
"Configure OSPF area as nssa\n"
|
||||||
|
"Suppress forwarding address\n")
|
||||||
|
{
|
||||||
|
int idx_ipv4_number = 1;
|
||||||
|
struct in_addr area_id;
|
||||||
|
int format;
|
||||||
|
|
||||||
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
||||||
|
VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format,
|
||||||
|
argv[idx_ipv4_number]->arg);
|
||||||
|
|
||||||
|
ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
|
||||||
|
format);
|
||||||
|
ospf_area_nssa_suppress_fa_set(ospf, area_id);
|
||||||
|
|
||||||
|
ospf_schedule_abr_task(ospf);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN(no_ospf_area_nssa_suppress_fa, no_ospf_area_nssa_suppress_fa_cmd,
|
||||||
|
"no area <A.B.C.D|(0-4294967295)> nssa suppress-fa",
|
||||||
|
NO_STR
|
||||||
|
"OSPF area parameters\n"
|
||||||
|
"OSPF area ID in IP address format\n"
|
||||||
|
"OSPF area ID as a decimal value\n"
|
||||||
|
"Configure OSPF area as nssa\n"
|
||||||
|
"Suppress forwarding address\n")
|
||||||
|
{
|
||||||
|
int idx_ipv4_number = 2;
|
||||||
|
struct in_addr area_id;
|
||||||
|
int format;
|
||||||
|
|
||||||
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
||||||
|
|
||||||
|
VTY_GET_OSPF_AREA_ID_NO_BB("nssa", area_id, format,
|
||||||
|
argv[idx_ipv4_number]->arg);
|
||||||
|
|
||||||
|
ospf_area_display_format_set(ospf, ospf_area_get(ospf, area_id),
|
||||||
|
format);
|
||||||
|
ospf_area_nssa_suppress_fa_unset(ospf, area_id);
|
||||||
|
|
||||||
|
ospf_schedule_abr_task(ospf);
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (ospf_area_nssa_no_summary,
|
DEFUN (ospf_area_nssa_no_summary,
|
||||||
ospf_area_nssa_no_summary_cmd,
|
ospf_area_nssa_no_summary_cmd,
|
||||||
"area <A.B.C.D|(0-4294967295)> nssa no-summary",
|
"area <A.B.C.D|(0-4294967295)> nssa no-summary",
|
||||||
@ -11823,6 +11875,10 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf)
|
|||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
" area %s nssa no-summary\n",
|
" area %s nssa no-summary\n",
|
||||||
buf);
|
buf);
|
||||||
|
if (area->suppress_fa)
|
||||||
|
vty_out(vty,
|
||||||
|
" area %s nssa suppress-fa\n",
|
||||||
|
buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (area->default_cost != 1)
|
if (area->default_cost != 1)
|
||||||
@ -12684,6 +12740,8 @@ void ospf_vty_init(void)
|
|||||||
install_element(OSPF_NODE, &ospf_area_nssa_translate_cmd);
|
install_element(OSPF_NODE, &ospf_area_nssa_translate_cmd);
|
||||||
install_element(OSPF_NODE, &ospf_area_nssa_no_summary_cmd);
|
install_element(OSPF_NODE, &ospf_area_nssa_no_summary_cmd);
|
||||||
install_element(OSPF_NODE, &no_ospf_area_nssa_no_summary_cmd);
|
install_element(OSPF_NODE, &no_ospf_area_nssa_no_summary_cmd);
|
||||||
|
install_element(OSPF_NODE, &ospf_area_nssa_suppress_fa_cmd);
|
||||||
|
install_element(OSPF_NODE, &no_ospf_area_nssa_suppress_fa_cmd);
|
||||||
install_element(OSPF_NODE, &no_ospf_area_nssa_cmd);
|
install_element(OSPF_NODE, &no_ospf_area_nssa_cmd);
|
||||||
|
|
||||||
install_element(OSPF_NODE, &ospf_area_default_cost_cmd);
|
install_element(OSPF_NODE, &ospf_area_default_cost_cmd);
|
||||||
|
@ -1672,6 +1672,7 @@ int ospf_area_nssa_set(struct ospf *ospf, struct in_addr area_id)
|
|||||||
|
|
||||||
/* set NSSA area defaults */
|
/* set NSSA area defaults */
|
||||||
area->no_summary = 0;
|
area->no_summary = 0;
|
||||||
|
area->suppress_fa = 0;
|
||||||
area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
|
area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
|
||||||
area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
|
area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
|
||||||
area->NSSATranslatorStabilityInterval =
|
area->NSSATranslatorStabilityInterval =
|
||||||
@ -1693,6 +1694,7 @@ int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id, int argc)
|
|||||||
ospf->anyNSSA--;
|
ospf->anyNSSA--;
|
||||||
/* set NSSA area defaults */
|
/* set NSSA area defaults */
|
||||||
area->no_summary = 0;
|
area->no_summary = 0;
|
||||||
|
area->suppress_fa = 0;
|
||||||
area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
|
area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
|
||||||
area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
|
area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
|
||||||
area->NSSATranslatorStabilityInterval =
|
area->NSSATranslatorStabilityInterval =
|
||||||
@ -1708,6 +1710,32 @@ int ospf_area_nssa_unset(struct ospf *ospf, struct in_addr area_id, int argc)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ospf_area_nssa_suppress_fa_set(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 0;
|
||||||
|
|
||||||
|
area->suppress_fa = 1;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ospf_area_nssa_suppress_fa_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 0;
|
||||||
|
|
||||||
|
area->suppress_fa = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int ospf_area_nssa_translator_role_set(struct ospf *ospf,
|
int ospf_area_nssa_translator_role_set(struct ospf *ospf,
|
||||||
struct in_addr area_id, int role)
|
struct in_addr area_id, int role)
|
||||||
{
|
{
|
||||||
|
@ -476,7 +476,7 @@ struct ospf_area {
|
|||||||
int shortcut_capability; /* Other ABRs agree on S-bit */
|
int shortcut_capability; /* Other ABRs agree on S-bit */
|
||||||
uint32_t default_cost; /* StubDefaultCost. */
|
uint32_t default_cost; /* StubDefaultCost. */
|
||||||
int auth_type; /* Authentication type. */
|
int auth_type; /* Authentication type. */
|
||||||
|
int suppress_fa; /* Suppress forwarding address in NSSA ABR */
|
||||||
|
|
||||||
uint8_t NSSATranslatorRole; /* NSSA configured role */
|
uint8_t NSSATranslatorRole; /* NSSA configured role */
|
||||||
#define OSPF_NSSA_ROLE_NEVER 0
|
#define OSPF_NSSA_ROLE_NEVER 0
|
||||||
@ -668,6 +668,10 @@ extern int ospf_area_no_summary_set(struct ospf *, struct in_addr);
|
|||||||
extern int ospf_area_no_summary_unset(struct ospf *, struct in_addr);
|
extern int ospf_area_no_summary_unset(struct ospf *, struct in_addr);
|
||||||
extern int ospf_area_nssa_set(struct ospf *, struct in_addr);
|
extern int ospf_area_nssa_set(struct ospf *, struct in_addr);
|
||||||
extern int ospf_area_nssa_unset(struct ospf *, struct in_addr, int);
|
extern int ospf_area_nssa_unset(struct ospf *, struct in_addr, int);
|
||||||
|
extern int ospf_area_nssa_suppress_fa_set(struct ospf *ospf,
|
||||||
|
struct in_addr area_id);
|
||||||
|
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 *, struct in_addr,
|
extern int ospf_area_nssa_translator_role_set(struct ospf *, struct in_addr,
|
||||||
int);
|
int);
|
||||||
extern int ospf_area_export_list_set(struct ospf *, struct ospf_area *,
|
extern int ospf_area_export_list_set(struct ospf *, struct ospf_area *,
|
||||||
|
Loading…
Reference in New Issue
Block a user