OSPF NSSA translator election.
This commit is contained in:
parent
41b612c31b
commit
4160a9dd94
5 changed files with 93 additions and 2 deletions
|
@ -101,7 +101,7 @@ CF_KEYWORDS(NONBROADCAST, NBMA, POINTOPOINT, PTP, POINTOMULTIPOINT, PTMP)
|
||||||
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
|
CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
|
||||||
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
|
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
|
||||||
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
|
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY)
|
||||||
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA)
|
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY)
|
||||||
|
|
||||||
%type <t> opttext
|
%type <t> opttext
|
||||||
|
|
||||||
|
@ -159,6 +159,8 @@ ospf_area_item:
|
||||||
| STUB bool { this_area->type = $2 ? 0 : OPT_E; /* We should remove the option */ }
|
| STUB bool { this_area->type = $2 ? 0 : OPT_E; /* We should remove the option */ }
|
||||||
| NSSA { this_area->type = OPT_N; }
|
| NSSA { this_area->type = OPT_N; }
|
||||||
| SUMMARY bool { this_area->summary = $2; }
|
| SUMMARY bool { this_area->summary = $2; }
|
||||||
|
| TRANSLATOR bool { this_area->translator = $2; }
|
||||||
|
| TRANSLATOR STABILITY bool { this_area->transint = $3; }
|
||||||
| NETWORKS '{' pref_list '}'
|
| NETWORKS '{' pref_list '}'
|
||||||
| STUBNET ospf_stubnet
|
| STUBNET ospf_stubnet
|
||||||
| INTERFACE ospf_iface
|
| INTERFACE ospf_iface
|
||||||
|
|
|
@ -178,6 +178,9 @@ ospf_area_remove(struct ospf_area *oa)
|
||||||
fib_free(&oa->rtr);
|
fib_free(&oa->rtr);
|
||||||
fib_free(&oa->net_fib);
|
fib_free(&oa->net_fib);
|
||||||
|
|
||||||
|
if (oa->translator_timer)
|
||||||
|
rfree(oa->translator_timer);
|
||||||
|
|
||||||
oa->po->areano--;
|
oa->po->areano--;
|
||||||
rem_node(NODE oa);
|
rem_node(NODE oa);
|
||||||
mb_free(oa);
|
mb_free(oa);
|
||||||
|
@ -803,6 +806,8 @@ ospf_sh(struct proto *p)
|
||||||
}
|
}
|
||||||
// FIXME NSSA:
|
// FIXME NSSA:
|
||||||
// cli_msg(-1014, "\t\tStub:\t%s", oa->stub ? "Yes" : "No");
|
// cli_msg(-1014, "\t\tStub:\t%s", oa->stub ? "Yes" : "No");
|
||||||
|
cli_msg(-1014, "\t\tNSSA translation:\t%s%s", oa->translate ? "Yes" : "No",
|
||||||
|
oa->translate == TRANS_WAIT ? " (run down)" : "");
|
||||||
cli_msg(-1014, "\t\tTransit:\t%s", oa->trcap ? "Yes" : "No");
|
cli_msg(-1014, "\t\tTransit:\t%s", oa->trcap ? "Yes" : "No");
|
||||||
cli_msg(-1014, "\t\tNumber of interfaces:\t%u", ifano);
|
cli_msg(-1014, "\t\tNumber of interfaces:\t%u", ifano);
|
||||||
cli_msg(-1014, "\t\tNumber of neighbors:\t%u", nno);
|
cli_msg(-1014, "\t\tNumber of neighbors:\t%u", nno);
|
||||||
|
|
|
@ -127,6 +127,8 @@ struct ospf_area_config
|
||||||
u8 type; /* Area type (standard, stub, NSSA), represented
|
u8 type; /* Area type (standard, stub, NSSA), represented
|
||||||
by option flags (OPT_E, OPT_N) */
|
by option flags (OPT_E, OPT_N) */
|
||||||
u8 summary; /* Import summaries to this stub/NSSA area, valid for ABR */
|
u8 summary; /* Import summaries to this stub/NSSA area, valid for ABR */
|
||||||
|
u8 translator; /* Translator role, for NSSA ABR */
|
||||||
|
u32 transint; /* Translator stability interval */
|
||||||
list patt_list;
|
list patt_list;
|
||||||
list net_list; /* List of aggregate networks for that area */
|
list net_list; /* List of aggregate networks for that area */
|
||||||
list stubnet_list; /* List of stub networks added to Router LSA */
|
list stubnet_list; /* List of stub networks added to Router LSA */
|
||||||
|
@ -736,10 +738,16 @@ struct ospf_area
|
||||||
byte origrt; /* Rt lsa origination scheduled? */
|
byte origrt; /* Rt lsa origination scheduled? */
|
||||||
byte trcap; /* Transit capability? */
|
byte trcap; /* Transit capability? */
|
||||||
byte marked; /* Used in OSPF reconfigure */
|
byte marked; /* Used in OSPF reconfigure */
|
||||||
|
byte translate; /* Translator state (TRANS_*), for NSSA ABR */
|
||||||
|
timer *translator_timer; /* For NSSA translator switch */
|
||||||
struct proto_ospf *po;
|
struct proto_ospf *po;
|
||||||
struct fib rtr; /* Routing tables for routers */
|
struct fib rtr; /* Routing tables for routers */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TRANS_OFF 0
|
||||||
|
#define TRANS_ON 1
|
||||||
|
#define TRANS_WAIT 2 /* Waiting before the end of translation */
|
||||||
|
|
||||||
struct proto_ospf
|
struct proto_ospf
|
||||||
{
|
{
|
||||||
struct proto proto;
|
struct proto proto;
|
||||||
|
|
|
@ -1000,12 +1000,26 @@ ospf_check_vlinks(struct proto_ospf *po)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
translator_timer_hook(timer *timer)
|
||||||
|
{
|
||||||
|
struct ospf_area *oa = timer->data;
|
||||||
|
|
||||||
|
if (oa->translate != TRANS_WAIT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
oa->translate = TRANS_OFF;
|
||||||
|
schedule_rtcalc(oa->po);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Miscellaneous route processing that needs to be done by ABRs */
|
/* Miscellaneous route processing that needs to be done by ABRs */
|
||||||
static void
|
static void
|
||||||
ospf_rt_abr(struct proto_ospf *po)
|
ospf_rt_abr(struct proto_ospf *po)
|
||||||
{
|
{
|
||||||
|
struct top_hash_entry *en;
|
||||||
struct area_net *anet;
|
struct area_net *anet;
|
||||||
ort *nf, *default_nf;
|
ort *nf, *nf2, *default_nf;
|
||||||
|
|
||||||
FIB_WALK(&po->rtf, nftmp)
|
FIB_WALK(&po->rtf, nftmp)
|
||||||
{
|
{
|
||||||
|
@ -1073,6 +1087,62 @@ ospf_rt_abr(struct proto_ospf *po)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* RFC 3103 3.1 - type-7 translator election */
|
||||||
|
struct ospf_area *bb = oa->po->backbone;
|
||||||
|
WALK_LIST(oa, po->area_list)
|
||||||
|
if (oa_is_nssa(oa))
|
||||||
|
{
|
||||||
|
int translate = 1;
|
||||||
|
|
||||||
|
if (oa->ac->translator)
|
||||||
|
goto decided;
|
||||||
|
|
||||||
|
FIB_WALK(&oa->rtr, nftmp)
|
||||||
|
{
|
||||||
|
nf = (ort *) nftmp;
|
||||||
|
if (!nf->n.type || !(nf->n.options & ORTA_ABR))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
nf2 = fib_find(&bb->rtr, &nf->fn.prefix, MAX_PREFIX_LENGTH);
|
||||||
|
if (!nf2 || !nf2->n.type || !(nf2->n.options & ORTA_ABR))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
en = ospf_hash_find_rt(po->gr, oa->areaid, nf->n.rid);
|
||||||
|
if (!en || (en->color != INSPF))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct ospf_lsa_rt *rt = en->lsa_body;
|
||||||
|
/* There is better candidate - Nt-bit or higher Router ID */
|
||||||
|
if ((rt->options & OPT_RT_NT) || (po->router_id < nf->n.rid))
|
||||||
|
{
|
||||||
|
translate = 0;
|
||||||
|
goto decided;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FIB_WALK_END;
|
||||||
|
|
||||||
|
decided:
|
||||||
|
if (translate && (oa->translate != TRANS_ON))
|
||||||
|
{
|
||||||
|
if (oa->translate == TRANS_WAIT)
|
||||||
|
tm_stop(oa->translator_timer);
|
||||||
|
|
||||||
|
oa->translate = TRANS_ON;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!translate && (oa->translate == TRANS_ON))
|
||||||
|
{
|
||||||
|
if (oa->translator_timer == NULL)
|
||||||
|
oa->translator_timer = tm_new_set(po->proto.pool, translator_timer_hook, oa, 0, 0);
|
||||||
|
|
||||||
|
/* Schedule the end of translation */
|
||||||
|
tm_start(oa->translator_timer, oa->ac->transint);
|
||||||
|
oa->translate = TRANS_WAIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Originate or flush ASBR summary LSAs */
|
/* Originate or flush ASBR summary LSAs */
|
||||||
FIB_WALK(&po->backbone->rtr, nftmp)
|
FIB_WALK(&po->backbone->rtr, nftmp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -222,6 +222,9 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
if (po->areano > 1)
|
if (po->areano > 1)
|
||||||
rt->options |= OPT_RT_B;
|
rt->options |= OPT_RT_B;
|
||||||
|
|
||||||
|
if ((po->areano > 1) && oa_is_nssa(oa) && oa->ac->translator)
|
||||||
|
rt->options |= OPT_RT_NT;
|
||||||
|
|
||||||
if (po->ebit && !oa_is_stub(oa))
|
if (po->ebit && !oa_is_stub(oa))
|
||||||
rt->options |= OPT_RT_E;
|
rt->options |= OPT_RT_E;
|
||||||
|
|
||||||
|
@ -388,6 +391,9 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length)
|
||||||
if (po->areano > 1)
|
if (po->areano > 1)
|
||||||
rt->options |= OPT_RT_B;
|
rt->options |= OPT_RT_B;
|
||||||
|
|
||||||
|
if ((po->areano > 1) && oa_is_nssa(oa) && oa->ac->translator)
|
||||||
|
rt->options |= OPT_RT_NT;
|
||||||
|
|
||||||
if (po->ebit && !oa_is_stub(oa))
|
if (po->ebit && !oa_is_stub(oa))
|
||||||
rt->options |= OPT_RT_E;
|
rt->options |= OPT_RT_E;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue