mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-17 08:38:42 +00:00
Fixes and enhancements in 'show ospf state' command.
Now it shows a distance, option to change showing reachable/all network nodes and better handling of AS-external LSAs in multiple areas. The command 'show ospf topology' was changed to not show stubnets in both OSPFv2 and OSPFv3 (previously it displayed stubnets in OSPFv2).
This commit is contained in:
parent
1d44ddf20f
commit
0ea8fb4abe
@ -490,13 +490,18 @@ This argument can be omitted if there exists only a single instance.
|
||||
<tag>show ospf neighbors [<m/name/] ["<m/interface/"]</tag>
|
||||
Show a list of OSPF neighbors and a state of adjacency to them.
|
||||
|
||||
<tag>show ospf state [<m/name/]</tag>
|
||||
Show detailed information about OSPF areas based on a content of link-state database.
|
||||
It shows network topology, aggregated networks and routers from other areas and external routes.
|
||||
<tag>show ospf state [all] [<m/name/]</tag>
|
||||
Show detailed information about OSPF areas based on a content
|
||||
of the link-state database. It shows network topology, stub
|
||||
networks, aggregated networks and routers from other areas and
|
||||
external routes. The command shows information about reachable
|
||||
network nodes, use option <cf/all/ to show information about
|
||||
all network nodes in the link-state database.
|
||||
|
||||
<tag>show ospf topology [<m/name/]</tag>
|
||||
Show a topology of OSPF areas based on a content of link-state database.
|
||||
It is just a stripped-down version of 'show ospf state'.
|
||||
<tag>show ospf topology [all] [<m/name/]</tag>
|
||||
Show a topology of OSPF areas based on a content of the
|
||||
link-state database. It is just a stripped-down version of
|
||||
'show ospf state'.
|
||||
|
||||
<tag>show static [<m/name/]</tag>
|
||||
Show detailed information about static routes.
|
||||
|
@ -314,11 +314,21 @@ CF_CLI(SHOW OSPF NEIGHBORS, optsym opttext, [<name>] [\"<interface>\"], [[Show i
|
||||
CF_CLI(SHOW OSPF INTERFACE, optsym opttext, [<name>] [\"<interface>\"], [[Show information about interface]])
|
||||
{ ospf_sh_iface(proto_get_named($4, &proto_ospf), $5); };
|
||||
|
||||
CF_CLI(SHOW OSPF TOPOLOGY, optsym opttext, [<name>], [[Show information about OSPF network topology]])
|
||||
{ ospf_sh_state(proto_get_named($4, &proto_ospf), 0); };
|
||||
CF_CLI_HELP(SHOW OSPF TOPOLOGY, [all] [<name>], [[Show information about OSPF network topology]])
|
||||
|
||||
CF_CLI(SHOW OSPF STATE, optsym opttext, [<name>], [[Show information about OSPF network state]])
|
||||
{ ospf_sh_state(proto_get_named($4, &proto_ospf), 1); };
|
||||
CF_CLI(SHOW OSPF TOPOLOGY, optsym opttext, [<name>], [[Show information about reachable OSPF network topology]])
|
||||
{ ospf_sh_state(proto_get_named($4, &proto_ospf), 0, 1); };
|
||||
|
||||
CF_CLI(SHOW OSPF TOPOLOGY ALL, optsym opttext, [<name>], [[Show information about all OSPF network topology]])
|
||||
{ ospf_sh_state(proto_get_named($5, &proto_ospf), 0, 0); };
|
||||
|
||||
CF_CLI_HELP(SHOW OSPF STATE, [all] [<name>], [[Show information about OSPF network state]])
|
||||
|
||||
CF_CLI(SHOW OSPF STATE, optsym opttext, [<name>], [[Show information about reachable OSPF network state]])
|
||||
{ ospf_sh_state(proto_get_named($4, &proto_ospf), 1, 1); };
|
||||
|
||||
CF_CLI(SHOW OSPF STATE ALL, optsym opttext, [<name>], [[Show information about all OSPF network state]])
|
||||
{ ospf_sh_state(proto_get_named($5, &proto_ospf), 1, 0); };
|
||||
|
||||
CF_CLI(SHOW OSPF LSADB, optsym opttext, [<name>], [[Show content of OSPF LSA database]])
|
||||
{ ospf_sh_lsadb(proto_get_named($4, &proto_ospf)); };
|
||||
|
@ -804,5 +804,4 @@ ospf_iface_shutdown(struct ospf_iface *ifa)
|
||||
{
|
||||
init_list(&ifa->neigh_list);
|
||||
hello_timer_hook(ifa->hello_timer);
|
||||
ospf_sk_close(ifa);
|
||||
}
|
||||
|
@ -45,19 +45,16 @@ ospf_age(struct proto_ospf *po)
|
||||
struct top_hash_entry *en, *nxt;
|
||||
int flush = can_flush_lsa(po);
|
||||
|
||||
if (po->cleanup) OSPF_TRACE(D_EVENTS, "Running ospf_age cleanup");
|
||||
|
||||
WALK_SLIST_DELSAFE(en, nxt, po->lsal)
|
||||
{
|
||||
if (po->cleanup)
|
||||
if (po->calcrt)
|
||||
{
|
||||
/* Cleanup before ospf_rt_spf() */
|
||||
en->color = OUTSPF;
|
||||
en->dist = LSINFINITY;
|
||||
en->nhi = NULL;
|
||||
en->nh = IPA_NONE;
|
||||
en->lb = IPA_NONE;
|
||||
DBG("Infinitying Type: %u, Id: %R, Rt: %R\n", en->lsa.type,
|
||||
en->lsa.id, en->lsa.rt);
|
||||
}
|
||||
if (en->lsa.age == LSA_MAXAGE)
|
||||
{
|
||||
@ -88,7 +85,6 @@ ospf_age(struct proto_ospf *po)
|
||||
en->lsa.age = LSA_MAXAGE;
|
||||
}
|
||||
}
|
||||
po->cleanup = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -75,7 +75,7 @@
|
||||
*
|
||||
* The function area_disp() is
|
||||
* responsible for late originating of router LSA and network LSA
|
||||
* and for cleanup after routing table calculation process in
|
||||
* and for cleanup before routing table calculation process in
|
||||
* the area.
|
||||
* To every &ospf_iface, we connect one or more
|
||||
* &ospf_neighbor's -- a structure containing many timers and queues
|
||||
@ -161,7 +161,6 @@ ospf_start(struct proto *p)
|
||||
fib_init(&po->rtf, p->pool, sizeof(ort), 16, ospf_rt_initort);
|
||||
po->areano = 0;
|
||||
po->gr = ospf_top_new(p->pool);
|
||||
po->cleanup = 1;
|
||||
s_init_list(&(po->lsal));
|
||||
if (EMPTY_LIST(c->area_list))
|
||||
{
|
||||
@ -1134,8 +1133,34 @@ lsa_compare_for_state(const void *p1, const void *p2)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ext_compare_for_state(const void *p1, const void *p2)
|
||||
{
|
||||
struct top_hash_entry * he1 = * (struct top_hash_entry **) p1;
|
||||
struct top_hash_entry * he2 = * (struct top_hash_entry **) p2;
|
||||
struct ospf_lsa_header *lsa1 = &(he1->lsa);
|
||||
struct ospf_lsa_header *lsa2 = &(he2->lsa);
|
||||
|
||||
if (lsa1->rt != lsa2->rt)
|
||||
return lsa1->rt - lsa2->rt;
|
||||
|
||||
if (lsa1->id != lsa2->id)
|
||||
return lsa1->id - lsa2->id;
|
||||
|
||||
return lsa1->sn - lsa2->sn;
|
||||
}
|
||||
|
||||
static inline void
|
||||
show_lsa_router(struct proto_ospf *po, struct top_hash_entry *he)
|
||||
show_lsa_distance(struct top_hash_entry *he)
|
||||
{
|
||||
if (he->color == INSPF)
|
||||
cli_msg(-1016, "\t\tdistance %u", he->dist);
|
||||
else
|
||||
cli_msg(-1016, "\t\tunreachable");
|
||||
}
|
||||
|
||||
static inline void
|
||||
show_lsa_router(struct proto_ospf *po, struct top_hash_entry *he, int first, int verbose)
|
||||
{
|
||||
struct ospf_lsa_header *lsa = &(he->lsa);
|
||||
struct ospf_lsa_rt *rt = he->lsa_body;
|
||||
@ -1143,6 +1168,14 @@ show_lsa_router(struct proto_ospf *po, struct top_hash_entry *he)
|
||||
int max = lsa_rt_count(lsa);
|
||||
int i;
|
||||
|
||||
if (first)
|
||||
{
|
||||
cli_msg(-1016, "");
|
||||
cli_msg(-1016, "\trouter %R", he->lsa.rt);
|
||||
show_lsa_distance(he);
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < max; i++)
|
||||
if (rr[i].type == LSART_VLNK)
|
||||
cli_msg(-1016, "\t\tvlink %R metric %u", rr[i].id, rr[i].metric);
|
||||
@ -1175,6 +1208,9 @@ show_lsa_router(struct proto_ospf *po, struct top_hash_entry *he)
|
||||
}
|
||||
|
||||
#ifdef OSPFv2
|
||||
if (!verbose)
|
||||
return;
|
||||
|
||||
for (i = 0; i < max; i++)
|
||||
if (rr[i].type == LSART_STUB)
|
||||
cli_msg(-1016, "\t\tstubnet %I/%d metric %u", ipa_from_u32(rr[i].id),
|
||||
@ -1198,6 +1234,8 @@ show_lsa_network(struct top_hash_entry *he)
|
||||
cli_msg(-1016, "\tnetwork [%R-%u]", lsa->rt, lsa->id);
|
||||
#endif
|
||||
|
||||
show_lsa_distance(he);
|
||||
|
||||
for (i = 0; i < lsa_net_count(lsa); i++)
|
||||
cli_msg(-1016, "\t\trouter %R", ln->routers[i]);
|
||||
}
|
||||
@ -1251,6 +1289,8 @@ show_lsa_external(struct top_hash_entry *he)
|
||||
int pxlen, ebit, rt_fwaddr_valid;
|
||||
u32 rt_tag, rt_metric;
|
||||
|
||||
he->domain = 0; /* Unmark the LSA */
|
||||
|
||||
rt_metric = ext->metric & METRIC_MASK;
|
||||
ebit = ext->metric & LSA_EXT_EBIT;
|
||||
#ifdef OSPFv2
|
||||
@ -1289,7 +1329,7 @@ show_lsa_external(struct top_hash_entry *he)
|
||||
|
||||
#ifdef OSPFv3
|
||||
static inline void
|
||||
show_lsa_prefix(struct top_hash_entry *he, struct ospf_lsa_header *olsa)
|
||||
show_lsa_prefix(struct top_hash_entry *he, struct ospf_lsa_header *cnode)
|
||||
{
|
||||
struct ospf_lsa_prefix *px = he->lsa_body;
|
||||
ip_addr pxa;
|
||||
@ -1299,10 +1339,14 @@ show_lsa_prefix(struct top_hash_entry *he, struct ospf_lsa_header *olsa)
|
||||
u32 *buf;
|
||||
int i;
|
||||
|
||||
/* We check whether given prefix-LSA is related to the last non-prefix-LSA */
|
||||
if ((olsa == NULL) || (olsa->type != px->ref_type) || (olsa->rt != px->ref_rt) ||
|
||||
!(((px->ref_type == LSA_T_RT) && (px->ref_id == 0)) ||
|
||||
((px->ref_type == LSA_T_NET) && (px->ref_id == olsa->id))))
|
||||
/* We check whether given prefix-LSA is related to the current node */
|
||||
if ((px->ref_type != cnode->type) || (px->ref_rt != cnode->rt))
|
||||
return;
|
||||
|
||||
if ((px->ref_type == LSA_T_RT) && (px->ref_id != 0))
|
||||
return;
|
||||
|
||||
if ((px->ref_type == LSA_T_NET) && (px->ref_id != cnode->id))
|
||||
return;
|
||||
|
||||
buf = px->rest;
|
||||
@ -1319,18 +1363,14 @@ show_lsa_prefix(struct top_hash_entry *he, struct ospf_lsa_header *olsa)
|
||||
#endif
|
||||
|
||||
void
|
||||
ospf_sh_state(struct proto *p, int verbose)
|
||||
ospf_sh_state(struct proto *p, int verbose, int reachable)
|
||||
{
|
||||
struct proto_ospf *po = (struct proto_ospf *) p;
|
||||
struct top_graph *f = po->gr;
|
||||
unsigned int i, j1, j2;
|
||||
u32 last_rt = 0xFFFFFFFF;
|
||||
struct ospf_lsa_header *cnode = NULL;
|
||||
int num = po->gr->hash_entries;
|
||||
unsigned int i, ix, j1, j2, jx;
|
||||
u32 last_area = 0xFFFFFFFF;
|
||||
|
||||
#ifdef OSPFv3
|
||||
struct ospf_lsa_header *olsa = NULL;
|
||||
#endif
|
||||
|
||||
if (p->proto_state != PS_UP)
|
||||
{
|
||||
cli_msg(-1016, "%s: is not up", p->name);
|
||||
@ -1338,10 +1378,14 @@ ospf_sh_state(struct proto *p, int verbose)
|
||||
return;
|
||||
}
|
||||
|
||||
struct top_hash_entry *hea[f->hash_entries];
|
||||
/* We store interesting area-scoped LSAs in array hea and
|
||||
global-scoped (LSA_T_EXT) LSAs in array hex */
|
||||
|
||||
struct top_hash_entry *hea[num];
|
||||
struct top_hash_entry *hex[verbose ? num : 0];
|
||||
struct top_hash_entry *he;
|
||||
|
||||
j1 = j2 = 0;
|
||||
j1 = j2 = jx = 0;
|
||||
WALK_SLIST(he, po->lsal)
|
||||
{
|
||||
int accept;
|
||||
@ -1355,13 +1399,18 @@ ospf_sh_state(struct proto *p, int verbose)
|
||||
|
||||
case LSA_T_SUM_NET:
|
||||
case LSA_T_SUM_RT:
|
||||
case LSA_T_EXT:
|
||||
#ifdef OSPFv3
|
||||
case LSA_T_PREFIX:
|
||||
#endif
|
||||
accept = verbose;
|
||||
break;
|
||||
|
||||
case LSA_T_EXT:
|
||||
if (verbose)
|
||||
{
|
||||
he->domain = 1; /* Abuse domain field to mark the LSA */
|
||||
hex[jx++] = he;
|
||||
}
|
||||
default:
|
||||
accept = 0;
|
||||
}
|
||||
@ -1372,66 +1421,137 @@ ospf_sh_state(struct proto *p, int verbose)
|
||||
j2++;
|
||||
}
|
||||
|
||||
if ((j1 + j2) != f->hash_entries)
|
||||
if ((j1 + j2) != num)
|
||||
die("Fatal mismatch");
|
||||
|
||||
qsort(hea, j1, sizeof(struct top_hash_entry *), lsa_compare_for_state);
|
||||
qsort(hex, jx, sizeof(struct top_hash_entry *), ext_compare_for_state);
|
||||
|
||||
/*
|
||||
* This code is a bit tricky, we have a primary LSAs (router and
|
||||
* network) that are presented as a node, and secondary LSAs that
|
||||
* are presented as a part of a primary node. cnode represents an
|
||||
* currently opened node (whose header was presented). The LSAs are
|
||||
* sorted to get secondary LSAs just after related primary LSA (if
|
||||
* available). We present secondary LSAs only when related primary
|
||||
* LSA is opened.
|
||||
*
|
||||
* AS-external LSAs are stored separately as they might be presented
|
||||
* several times (for each area when related ASBR is opened). When
|
||||
* the node is closed, related external routes are presented. We
|
||||
* also have to take into account that in OSPFv3, there might be
|
||||
* more router-LSAs and only the first should be considered as a
|
||||
* primary. This is handled by not closing old router-LSA when next
|
||||
* one is processed (which is not opened because there is already
|
||||
* one opened).
|
||||
*/
|
||||
|
||||
ix = 0;
|
||||
for (i = 0; i < j1; i++)
|
||||
{
|
||||
if (last_area != hea[i]->domain)
|
||||
he = hea[i];
|
||||
|
||||
/* If there is no opened node, we open the LSA (if appropriate) or skip to the next one */
|
||||
if (!cnode)
|
||||
{
|
||||
cli_msg(-1016, "");
|
||||
cli_msg(-1016, "area %R", hea[i]->domain);
|
||||
last_area = hea[i]->domain;
|
||||
last_rt = 0xFFFFFFFF;
|
||||
if (((he->lsa.type == LSA_T_RT) || (he->lsa.type == LSA_T_NET))
|
||||
&& ((he->color == INSPF) || !reachable))
|
||||
{
|
||||
cnode = &(he->lsa);
|
||||
|
||||
if (he->domain != last_area)
|
||||
{
|
||||
cli_msg(-1016, "");
|
||||
cli_msg(-1016, "area %R", he->domain);
|
||||
last_area = he->domain;
|
||||
ix = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((hea[i]->lsa.rt != last_rt) && (hea[i]->lsa.type != LSA_T_NET)
|
||||
#ifdef OSPFv3
|
||||
&& (hea[i]->lsa.type != LSA_T_PREFIX)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
cli_msg(-1016, "");
|
||||
cli_msg(-1016, (hea[i]->lsa.type != LSA_T_EXT) ? "\trouter %R" : "\txrouter %R", hea[i]->lsa.rt);
|
||||
last_rt = hea[i]->lsa.rt;
|
||||
}
|
||||
ASSERT(cnode && (he->domain == last_area) && (he->lsa.rt == cnode->rt));
|
||||
|
||||
switch (hea[i]->lsa.type)
|
||||
switch (he->lsa.type)
|
||||
{
|
||||
case LSA_T_RT:
|
||||
show_lsa_router(po, hea[i]);
|
||||
show_lsa_router(po, he, he->lsa.id == cnode->id, verbose);
|
||||
break;
|
||||
|
||||
case LSA_T_NET:
|
||||
show_lsa_network(hea[i]);
|
||||
show_lsa_network(he);
|
||||
break;
|
||||
|
||||
case LSA_T_SUM_NET:
|
||||
show_lsa_sum_net(hea[i]);
|
||||
if (cnode->type == LSA_T_RT)
|
||||
show_lsa_sum_net(he);
|
||||
break;
|
||||
|
||||
case LSA_T_SUM_RT:
|
||||
show_lsa_sum_rt(hea[i]);
|
||||
break;
|
||||
|
||||
case LSA_T_EXT:
|
||||
show_lsa_external(hea[i]);
|
||||
if (cnode->type == LSA_T_RT)
|
||||
show_lsa_sum_rt(he);
|
||||
break;
|
||||
|
||||
#ifdef OSPFv3
|
||||
case LSA_T_PREFIX:
|
||||
show_lsa_prefix(hea[i], olsa);
|
||||
show_lsa_prefix(he, cnode);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case LSA_T_EXT:
|
||||
show_lsa_external(he);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef OSPFv3
|
||||
if (hea[i]->lsa.type != LSA_T_PREFIX)
|
||||
olsa = &(hea[i]->lsa);
|
||||
#endif
|
||||
/* In these cases, we close the current node */
|
||||
if ((i+1 == j1)
|
||||
|| (hea[i+1]->domain != last_area)
|
||||
|| (hea[i+1]->lsa.rt != cnode->rt)
|
||||
|| (hea[i+1]->lsa.type == LSA_T_NET))
|
||||
{
|
||||
while ((ix < jx) && (hex[ix]->lsa.rt < cnode->rt))
|
||||
ix++;
|
||||
|
||||
while ((ix < jx) && (hex[ix]->lsa.rt == cnode->rt))
|
||||
show_lsa_external(hex[ix++]);
|
||||
|
||||
cnode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int hdr = 0;
|
||||
u32 last_rt = 0xFFFFFFFF;
|
||||
for (ix = 0; ix < jx; ix++)
|
||||
{
|
||||
he = hex[ix];
|
||||
|
||||
/* If it is still marked, we show it now. */
|
||||
if (he->domain)
|
||||
{
|
||||
he->domain = 0;
|
||||
|
||||
if ((he->color != INSPF) && reachable)
|
||||
continue;
|
||||
|
||||
if (!hdr)
|
||||
{
|
||||
cli_msg(-1016, "");
|
||||
cli_msg(-1016, "other ASBRs");
|
||||
hdr = 1;
|
||||
}
|
||||
|
||||
if (he->lsa.rt != last_rt)
|
||||
{
|
||||
cli_msg(-1016, "");
|
||||
cli_msg(-1016, "\trouter %R", he->lsa.rt);
|
||||
last_rt = he->lsa.rt;
|
||||
}
|
||||
|
||||
show_lsa_external(he);
|
||||
}
|
||||
}
|
||||
|
||||
cli_msg(0, "");
|
||||
}
|
||||
|
||||
@ -1468,7 +1588,7 @@ void
|
||||
ospf_sh_lsadb(struct proto *p)
|
||||
{
|
||||
struct proto_ospf *po = (struct proto_ospf *) p;
|
||||
struct top_graph *f = po->gr;
|
||||
int num = po->gr->hash_entries;
|
||||
unsigned int i, j;
|
||||
int last_dscope = -1;
|
||||
u32 last_domain = 0;
|
||||
@ -1480,14 +1600,14 @@ ospf_sh_lsadb(struct proto *p)
|
||||
return;
|
||||
}
|
||||
|
||||
struct top_hash_entry *hea[f->hash_entries];
|
||||
struct top_hash_entry *hea[num];
|
||||
struct top_hash_entry *he;
|
||||
|
||||
j = 0;
|
||||
WALK_SLIST(he, po->lsal)
|
||||
hea[j++] = he;
|
||||
|
||||
if (j != f->hash_entries)
|
||||
if (j != num)
|
||||
die("Fatal mismatch");
|
||||
|
||||
qsort(hea, j, sizeof(struct top_hash_entry *), lsa_compare_for_lsadb);
|
||||
|
@ -722,7 +722,6 @@ struct proto_ospf
|
||||
slist lsal; /* List of all LSA's */
|
||||
int calcrt; /* Routing table calculation scheduled?
|
||||
0=no, 1=normal, 2=forced reload */
|
||||
int cleanup; /* Should I cleanup after RT calculation? */
|
||||
list iface_list; /* Interfaces we really use */
|
||||
list area_list;
|
||||
int areano; /* Number of area I belong to */
|
||||
@ -808,7 +807,7 @@ static inline void schedule_link_lsa(struct ospf_iface *ifa UNUSED) {}
|
||||
void ospf_sh_neigh(struct proto *p, char *iff);
|
||||
void ospf_sh(struct proto *p);
|
||||
void ospf_sh_iface(struct proto *p, char *iff);
|
||||
void ospf_sh_state(struct proto *p, int verbose);
|
||||
void ospf_sh_state(struct proto *p, int verbose, int reachable);
|
||||
void ospf_sh_lsadb(struct proto *p);
|
||||
|
||||
|
||||
|
@ -681,6 +681,10 @@ ospf_rt_sum(struct ospf_area *oa)
|
||||
if (!(abr->n.options & ORTA_ABR))
|
||||
continue;
|
||||
|
||||
/* This check is not mentioned in RFC 2328 */
|
||||
if (abr->n.type != RTS_OSPF)
|
||||
continue;
|
||||
|
||||
/* 16.2. (5) */
|
||||
orta nf = {
|
||||
.type = RTS_OSPF_IA,
|
||||
@ -966,6 +970,9 @@ ospf_ext_spf(struct proto_ospf *po)
|
||||
nfa.metric2 = LSINFINITY;
|
||||
}
|
||||
|
||||
/* Mark the LSA as reachable */
|
||||
en->color = INSPF;
|
||||
|
||||
/* Whether the route is preferred in route selection according to 16.4.1 */
|
||||
nfa.options = epath_preferred(&nf2->n) ? ORTA_PREF : 0;
|
||||
|
||||
@ -1046,8 +1053,6 @@ ospf_rt_spf(struct proto_ospf *po)
|
||||
|
||||
if (po->areano == 0) return;
|
||||
|
||||
po->cleanup = 1;
|
||||
|
||||
OSPF_TRACE(D_EVENTS, "Starting routing table calculation");
|
||||
|
||||
/* 16. (1) - Invalidate old routing table */
|
||||
|
@ -22,7 +22,7 @@ struct top_hash_entry
|
||||
bird_clock_t inst_t; /* Time of installation into DB */
|
||||
ip_addr nh; /* Next hop */
|
||||
ip_addr lb; /* In OSPFv2, link back address. In OSPFv3, any global address in the area useful for vlinks */
|
||||
struct ospf_iface *nhi; /* Next hop interface */
|
||||
struct ospf_iface *nhi; /* Next hop interface - valid only in ospf_rt_spf()*/
|
||||
#ifdef OSPFv3
|
||||
u32 lb_id; /* Interface ID of link back iface (for bcast or NBMA networks) */
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user