mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-26 02:13:04 +00:00
isisd: refactor handling of SR Prefix-SIDs
Embed Prefix-SID information inside SPF data structures so that Prefix-SIDs can be installed together with their associated routes at the end of the SPF algorithm. This is different from the current implementation where Prefix-SIDs are parsed and processed separately, which is vastly suboptimal. Advantages of the new code: * No need to parse the LSPDB an additional time to detect and process SR-related changes; * Routes are installed with their Prefix-SID labels in the same ZAPI message. This can prevent packet dropping for a few milliseconds after each SPF run if there are BGP-labeled routes (e.g. L3VPN) that recurse on IGP labeled routes; * Much easier to support Anycast-SIDs, as the SPF code will naturally figure out the best nexthops and use only them (that can't be done in any reasonable way if the Prefix-SID Sub-TVLs are processed separately); * Less code to maintain and reduced memory footprint; The "show isis segment-routing prefix-sids" command was removed as it doesn't make sense anymore now that "show isis route" exists. Prefix-SIDs are a property of routes, so what was done was to extend the "show isis route" command with a new "prefix-sid" option that changes the output table to show the Prefix-SID information associated to each route. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
d4fcd8bd82
commit
d47d6089e0
@ -423,8 +423,8 @@ Showing ISIS information
|
||||
Show topology IS-IS paths to Intermediate Systems, globally, in area
|
||||
(level-1) or domain (level-2).
|
||||
|
||||
.. index:: show isis route [level-1|level-2] [backup]
|
||||
.. clicmd:: show isis route [level-1|level-2] [backup]
|
||||
.. index:: show isis route [level-1|level-2] [prefix-sid|backup]
|
||||
.. clicmd:: show isis route [level-1|level-2] [prefix-sid|backup]
|
||||
|
||||
Show the ISIS routing table, as determined by the most recent SPF
|
||||
calculation.
|
||||
|
@ -180,23 +180,6 @@ bool isis_lfa_excise_node_check(const struct isis_spftree *spftree,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Find SRGB associated to a System ID. */
|
||||
static struct isis_sr_block *tilfa_find_srgb(struct lspdb_head *lspdb,
|
||||
const uint8_t *sysid)
|
||||
{
|
||||
struct isis_lsp *lsp;
|
||||
|
||||
lsp = isis_root_system_lsp(lspdb, sysid);
|
||||
if (!lsp)
|
||||
return NULL;
|
||||
|
||||
if (!lsp->tlvs->router_cap
|
||||
|| lsp->tlvs->router_cap->srgb.range_size == 0)
|
||||
return NULL;
|
||||
|
||||
return &lsp->tlvs->router_cap->srgb;
|
||||
}
|
||||
|
||||
struct tilfa_find_pnode_prefix_sid_args {
|
||||
uint32_t sid_index;
|
||||
};
|
||||
@ -313,7 +296,7 @@ tilfa_compute_label_stack(struct lspdb_head *lspdb,
|
||||
|
||||
switch (sid->type) {
|
||||
case TILFA_SID_PREFIX:
|
||||
srgb = tilfa_find_srgb(lspdb, sadj->id);
|
||||
srgb = isis_sr_find_srgb(lspdb, sadj->id);
|
||||
if (!srgb) {
|
||||
zlog_warn("%s: SRGB not found for node %s",
|
||||
__func__,
|
||||
@ -704,7 +687,7 @@ int isis_lfa_check(struct isis_spftree *spftree_pc, struct isis_vertex *vertex)
|
||||
struct route_table *route_table;
|
||||
|
||||
route_table = spftree_pc->lfa.old.spftree->route_table_backup;
|
||||
if (route_node_lookup(route_table, &vertex->N.ip.dest)) {
|
||||
if (route_node_lookup(route_table, &vertex->N.ip.p.dest)) {
|
||||
if (IS_DEBUG_TILFA)
|
||||
zlog_debug(
|
||||
"ISIS-TI-LFA: %s %s already covered by node protection",
|
||||
|
@ -71,7 +71,6 @@ static struct isis_nexthop *isis_nexthop_create(int family, union g_addr *ip,
|
||||
nexthop->family = family;
|
||||
nexthop->ifindex = ifindex;
|
||||
nexthop->ip = *ip;
|
||||
isis_sr_nexthop_reset(&nexthop->sr);
|
||||
|
||||
return nexthop;
|
||||
}
|
||||
@ -117,7 +116,7 @@ static struct isis_nexthop *nexthoplookup(struct list *nexthops, int family,
|
||||
}
|
||||
|
||||
void adjinfo2nexthop(int family, struct list *nexthops,
|
||||
struct isis_adjacency *adj,
|
||||
struct isis_adjacency *adj, struct isis_sr_psid_info *sr,
|
||||
struct mpls_label_stack *label_stack)
|
||||
{
|
||||
struct isis_nexthop *nh;
|
||||
@ -134,6 +133,8 @@ void adjinfo2nexthop(int family, struct list *nexthops,
|
||||
AF_INET, &ip,
|
||||
adj->circuit->interface->ifindex);
|
||||
memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid));
|
||||
if (sr)
|
||||
nh->sr = *sr;
|
||||
nh->label_stack = label_stack;
|
||||
listnode_add(nexthops, nh);
|
||||
break;
|
||||
@ -150,6 +151,8 @@ void adjinfo2nexthop(int family, struct list *nexthops,
|
||||
AF_INET6, &ip,
|
||||
adj->circuit->interface->ifindex);
|
||||
memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid));
|
||||
if (sr)
|
||||
nh->sr = *sr;
|
||||
nh->label_stack = label_stack;
|
||||
listnode_add(nexthops, nh);
|
||||
break;
|
||||
@ -165,22 +168,22 @@ void adjinfo2nexthop(int family, struct list *nexthops,
|
||||
|
||||
static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo,
|
||||
const uint8_t *sysid,
|
||||
struct isis_sr_psid_info *sr,
|
||||
struct mpls_label_stack *label_stack)
|
||||
{
|
||||
struct isis_nexthop *nh;
|
||||
|
||||
nh = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop));
|
||||
memcpy(nh->sysid, sysid, sizeof(nh->sysid));
|
||||
isis_sr_nexthop_reset(&nh->sr);
|
||||
nh->sr = *sr;
|
||||
nh->label_stack = label_stack;
|
||||
listnode_add(rinfo->nexthops, nh);
|
||||
}
|
||||
|
||||
static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
||||
struct prefix_ipv6 *src_p,
|
||||
uint32_t cost,
|
||||
uint32_t depth,
|
||||
struct list *adjacencies)
|
||||
static struct isis_route_info *
|
||||
isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p,
|
||||
uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr,
|
||||
struct list *adjacencies)
|
||||
{
|
||||
struct isis_route_info *rinfo;
|
||||
struct isis_vertex_adj *vadj;
|
||||
@ -192,6 +195,7 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
||||
for (ALL_LIST_ELEMENTS_RO(adjacencies, node, vadj)) {
|
||||
struct isis_spf_adj *sadj = vadj->sadj;
|
||||
struct isis_adjacency *adj = sadj->adj;
|
||||
struct isis_sr_psid_info *sr = &vadj->sr;
|
||||
struct mpls_label_stack *label_stack = vadj->label_stack;
|
||||
|
||||
/*
|
||||
@ -199,7 +203,7 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
||||
* environment.
|
||||
*/
|
||||
if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) {
|
||||
isis_route_add_dummy_nexthops(rinfo, sadj->id,
|
||||
isis_route_add_dummy_nexthops(rinfo, sadj->id, sr,
|
||||
label_stack);
|
||||
continue;
|
||||
}
|
||||
@ -227,12 +231,13 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
||||
prefix->family);
|
||||
exit(1);
|
||||
}
|
||||
adjinfo2nexthop(prefix->family, rinfo->nexthops, adj,
|
||||
adjinfo2nexthop(prefix->family, rinfo->nexthops, adj, sr,
|
||||
label_stack);
|
||||
}
|
||||
|
||||
rinfo->cost = cost;
|
||||
rinfo->depth = depth;
|
||||
rinfo->sr = *sr;
|
||||
|
||||
return rinfo;
|
||||
}
|
||||
@ -254,12 +259,28 @@ void isis_route_node_cleanup(struct route_table *table, struct route_node *node)
|
||||
isis_route_info_delete(node->info);
|
||||
}
|
||||
|
||||
static bool isis_sr_psid_info_same(struct isis_sr_psid_info *new,
|
||||
struct isis_sr_psid_info *old)
|
||||
{
|
||||
if (new->present != old->present)
|
||||
return false;
|
||||
|
||||
if (new->label != old->label)
|
||||
return false;
|
||||
|
||||
if (new->sid.flags != old->sid.flags
|
||||
|| new->sid.value != old->sid.value)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int isis_route_info_same(struct isis_route_info *new,
|
||||
struct isis_route_info *old, char *buf,
|
||||
size_t buf_size)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_nexthop *nexthop;
|
||||
struct isis_nexthop *new_nh, *old_nh;
|
||||
|
||||
if (new->cost != old->cost) {
|
||||
if (buf)
|
||||
@ -275,6 +296,12 @@ static int isis_route_info_same(struct isis_route_info *new,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!isis_sr_psid_info_same(&new->sr, &old->sr)) {
|
||||
if (buf)
|
||||
snprintf(buf, buf_size, "SR input label");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (new->nexthops->count != old->nexthops->count) {
|
||||
if (buf)
|
||||
snprintf(buf, buf_size, "nhops num (old: %u, new: %u)",
|
||||
@ -282,14 +309,20 @@ static int isis_route_info_same(struct isis_route_info *new,
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, nexthop)) {
|
||||
if (!nexthoplookup(old->nexthops, nexthop->family, &nexthop->ip,
|
||||
nexthop->ifindex)) {
|
||||
for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, new_nh)) {
|
||||
old_nh = nexthoplookup(old->nexthops, new_nh->family,
|
||||
&new_nh->ip, new_nh->ifindex);
|
||||
if (!old_nh) {
|
||||
if (buf)
|
||||
snprintf(buf, buf_size,
|
||||
"new nhop"); /* TODO: print nhop */
|
||||
return 0;
|
||||
}
|
||||
if (!isis_sr_psid_info_same(&new_nh->sr, &old_nh->sr)) {
|
||||
if (buf)
|
||||
snprintf(buf, buf_size, "nhop SR label");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* only the resync flag needs to be checked */
|
||||
@ -303,13 +336,11 @@ static int isis_route_info_same(struct isis_route_info *new,
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct isis_route_info *isis_route_create(struct prefix *prefix,
|
||||
struct prefix_ipv6 *src_p,
|
||||
uint32_t cost,
|
||||
uint32_t depth,
|
||||
struct list *adjacencies,
|
||||
struct isis_area *area,
|
||||
struct route_table *table)
|
||||
struct isis_route_info *
|
||||
isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p,
|
||||
uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr,
|
||||
struct list *adjacencies, struct isis_area *area,
|
||||
struct route_table *table)
|
||||
{
|
||||
struct route_node *route_node;
|
||||
struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL;
|
||||
@ -318,8 +349,8 @@ struct isis_route_info *isis_route_create(struct prefix *prefix,
|
||||
if (!table)
|
||||
return NULL;
|
||||
|
||||
rinfo_new = isis_route_info_new(prefix, src_p, cost,
|
||||
depth, adjacencies);
|
||||
rinfo_new = isis_route_info_new(prefix, src_p, cost, depth, sr,
|
||||
adjacencies);
|
||||
route_node = srcdest_rnode_get(table, prefix, src_p);
|
||||
|
||||
rinfo_old = route_node->info;
|
||||
@ -351,6 +382,7 @@ struct isis_route_info *isis_route_create(struct prefix *prefix,
|
||||
zlog_debug(
|
||||
"ISIS-Rte (%s): route changed: %pFX, change: %s",
|
||||
area->area_tag, prefix, change_buf);
|
||||
rinfo_new->sr_previous = rinfo_old->sr;
|
||||
isis_route_info_delete(rinfo_old);
|
||||
route_info = rinfo_new;
|
||||
UNSET_FLAG(route_info->flag,
|
||||
@ -406,7 +438,25 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix,
|
||||
if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
|
||||
return;
|
||||
|
||||
isis_zebra_route_add_route(area->isis, prefix, src_p, route_info);
|
||||
/*
|
||||
* Explicitly uninstall previous Prefix-SID label if it has
|
||||
* changed or was removed.
|
||||
*/
|
||||
if (route_info->sr_previous.present
|
||||
&& (!route_info->sr.present
|
||||
|| route_info->sr_previous.label
|
||||
!= route_info->sr.label))
|
||||
isis_zebra_prefix_sid_uninstall(
|
||||
area, prefix, route_info,
|
||||
&route_info->sr_previous);
|
||||
|
||||
/* Install route. */
|
||||
isis_zebra_route_add_route(area->isis, prefix, src_p,
|
||||
route_info);
|
||||
/* Install/reinstall Prefix-SID label. */
|
||||
if (route_info->sr.present)
|
||||
isis_zebra_prefix_sid_install(area, prefix, route_info,
|
||||
&route_info->sr);
|
||||
hook_call(isis_route_update_hook, area, prefix, route_info);
|
||||
|
||||
SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
|
||||
@ -415,7 +465,13 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix,
|
||||
if (!CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
|
||||
return;
|
||||
|
||||
isis_zebra_route_del_route(area->isis, prefix, src_p, route_info);
|
||||
/* Uninstall Prefix-SID label. */
|
||||
if (route_info->sr.present)
|
||||
isis_zebra_prefix_sid_uninstall(
|
||||
area, prefix, route_info, &route_info->sr);
|
||||
/* Uninstall route. */
|
||||
isis_zebra_route_del_route(area->isis, prefix, src_p,
|
||||
route_info);
|
||||
hook_call(isis_route_update_hook, area, prefix, route_info);
|
||||
|
||||
UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
|
||||
|
@ -32,7 +32,7 @@ struct isis_nexthop {
|
||||
int family;
|
||||
union g_addr ip;
|
||||
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||
struct sr_nexthop_info sr;
|
||||
struct isis_sr_psid_info sr;
|
||||
struct mpls_label_stack *label_stack;
|
||||
};
|
||||
|
||||
@ -43,6 +43,8 @@ struct isis_route_info {
|
||||
uint8_t flag;
|
||||
uint32_t cost;
|
||||
uint32_t depth;
|
||||
struct isis_sr_psid_info sr;
|
||||
struct isis_sr_psid_info sr_previous;
|
||||
struct list *nexthops;
|
||||
struct isis_route_info *backup;
|
||||
};
|
||||
@ -54,15 +56,13 @@ DECLARE_HOOK(isis_route_update_hook,
|
||||
|
||||
void isis_nexthop_delete(struct isis_nexthop *nexthop);
|
||||
void adjinfo2nexthop(int family, struct list *nexthops,
|
||||
struct isis_adjacency *adj,
|
||||
struct isis_adjacency *adj, struct isis_sr_psid_info *sr,
|
||||
struct mpls_label_stack *label_stack);
|
||||
struct isis_route_info *isis_route_create(struct prefix *prefix,
|
||||
struct prefix_ipv6 *src_p,
|
||||
uint32_t cost,
|
||||
uint32_t depth,
|
||||
struct list *adjacencies,
|
||||
struct isis_area *area,
|
||||
struct route_table *table);
|
||||
struct isis_route_info *
|
||||
isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p,
|
||||
uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr,
|
||||
struct list *adjacencies, struct isis_area *area,
|
||||
struct route_table *table);
|
||||
|
||||
/* Walk the given table and install new routes to zebra and remove old ones.
|
||||
* route status is tracked using ISIS_ROUTE_FLAG_ACTIVE */
|
||||
|
378
isisd/isis_spf.c
378
isisd/isis_spf.c
@ -176,9 +176,8 @@ const char *vid2string(const struct isis_vertex *vertex, char *buff, int size)
|
||||
}
|
||||
|
||||
if (VTYPE_IP(vertex->type)) {
|
||||
srcdest2str(&vertex->N.ip.dest,
|
||||
&vertex->N.ip.src,
|
||||
buff, size);
|
||||
srcdest2str(&vertex->N.ip.p.dest, &vertex->N.ip.p.src, buff,
|
||||
size);
|
||||
return buff;
|
||||
}
|
||||
|
||||
@ -215,13 +214,33 @@ static struct isis_vertex *isis_vertex_new(struct isis_spftree *spftree,
|
||||
return vertex;
|
||||
}
|
||||
|
||||
static struct isis_vertex_adj *isis_vertex_adj_add(struct isis_vertex *vertex,
|
||||
struct isis_spf_adj *sadj)
|
||||
static struct isis_vertex_adj *isis_vertex_adj_add(struct isis_spftree *spftree,
|
||||
struct isis_vertex *vertex,
|
||||
struct isis_spf_adj *sadj,
|
||||
struct isis_prefix_sid *psid)
|
||||
{
|
||||
struct isis_vertex_adj *vadj;
|
||||
|
||||
vadj = XCALLOC(MTYPE_ISIS_VERTEX_ADJ, sizeof(*vadj));
|
||||
vadj->sadj = sadj;
|
||||
if (psid) {
|
||||
if (vertex->N.ip.sr.present
|
||||
&& vertex->N.ip.sr.sid.value != psid->value)
|
||||
zlog_warn(
|
||||
"ISIS-SPF: ignoring different Prefix-SID for route %pFX",
|
||||
&vertex->N.ip.p.dest);
|
||||
else {
|
||||
bool last_hop;
|
||||
|
||||
last_hop = (vertex->depth == 2);
|
||||
vadj->sr.sid = *psid;
|
||||
vadj->sr.label = sr_prefix_out_label(
|
||||
spftree->lspdb, vertex->N.ip.p.dest.family,
|
||||
psid, sadj->id, last_hop);
|
||||
if (vadj->sr.label != MPLS_INVALID_LABEL)
|
||||
vadj->sr.present = true;
|
||||
}
|
||||
}
|
||||
listnode_add(vertex->Adj_N, vadj);
|
||||
|
||||
return vadj;
|
||||
@ -466,11 +485,10 @@ static void vertex_update_firsthops(struct isis_vertex *vertex,
|
||||
/*
|
||||
* Add a vertex to TENT sorted by cost and by vertextype on tie break situation
|
||||
*/
|
||||
static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
|
||||
enum vertextype vtype, void *id,
|
||||
uint32_t cost, int depth,
|
||||
struct isis_spf_adj *sadj,
|
||||
struct isis_vertex *parent)
|
||||
static struct isis_vertex *
|
||||
isis_spf_add2tent(struct isis_spftree *spftree, enum vertextype vtype, void *id,
|
||||
uint32_t cost, int depth, struct isis_spf_adj *sadj,
|
||||
struct isis_prefix_sid *psid, struct isis_vertex *parent)
|
||||
{
|
||||
struct isis_vertex *vertex;
|
||||
struct listnode *node;
|
||||
@ -496,6 +514,16 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
|
||||
vertex = isis_vertex_new(spftree, id, vtype);
|
||||
vertex->d_N = cost;
|
||||
vertex->depth = depth;
|
||||
if (VTYPE_IP(vtype) && psid) {
|
||||
bool local;
|
||||
|
||||
local = (vertex->depth == 1);
|
||||
vertex->N.ip.sr.sid = *psid;
|
||||
vertex->N.ip.sr.label =
|
||||
sr_prefix_in_label(spftree->area, psid, local);
|
||||
if (vertex->N.ip.sr.label != MPLS_INVALID_LABEL)
|
||||
vertex->N.ip.sr.present = true;
|
||||
}
|
||||
|
||||
if (parent) {
|
||||
listnode_add(vertex->parents, parent);
|
||||
@ -508,9 +536,10 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
|
||||
struct isis_vertex_adj *parent_vadj;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, parent_vadj))
|
||||
isis_vertex_adj_add(vertex, parent_vadj->sadj);
|
||||
isis_vertex_adj_add(spftree, vertex, parent_vadj->sadj,
|
||||
psid);
|
||||
} else if (sadj) {
|
||||
isis_vertex_adj_add(vertex, sadj);
|
||||
isis_vertex_adj_add(spftree, vertex, sadj, psid);
|
||||
}
|
||||
|
||||
#ifdef EXTREME_DEBUG
|
||||
@ -528,6 +557,7 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
|
||||
static void isis_spf_add_local(struct isis_spftree *spftree,
|
||||
enum vertextype vtype, void *id,
|
||||
struct isis_spf_adj *sadj, uint32_t cost,
|
||||
struct isis_prefix_sid *psid,
|
||||
struct isis_vertex *parent)
|
||||
{
|
||||
struct isis_vertex *vertex;
|
||||
@ -538,7 +568,8 @@ static void isis_spf_add_local(struct isis_spftree *spftree,
|
||||
/* C.2.5 c) */
|
||||
if (vertex->d_N == cost) {
|
||||
if (sadj)
|
||||
isis_vertex_adj_add(vertex, sadj);
|
||||
isis_vertex_adj_add(spftree, vertex, sadj,
|
||||
psid);
|
||||
/* d) */
|
||||
if (!CHECK_FLAG(spftree->flags,
|
||||
F_SPFTREE_NO_ADJACENCIES)
|
||||
@ -558,13 +589,13 @@ static void isis_spf_add_local(struct isis_spftree *spftree,
|
||||
}
|
||||
}
|
||||
|
||||
isis_spf_add2tent(spftree, vtype, id, cost, 1, sadj, parent);
|
||||
isis_spf_add2tent(spftree, vtype, id, cost, 1, sadj, psid, parent);
|
||||
return;
|
||||
}
|
||||
|
||||
static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
|
||||
void *id, uint32_t dist, uint16_t depth,
|
||||
struct isis_vertex *parent)
|
||||
struct isis_prefix_sid *psid, struct isis_vertex *parent)
|
||||
{
|
||||
struct isis_vertex *vertex;
|
||||
#ifdef EXTREME_DEBUG
|
||||
@ -628,8 +659,9 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
|
||||
parent_vadj))
|
||||
if (!isis_vertex_adj_exists(spftree, vertex,
|
||||
parent_vadj->sadj))
|
||||
isis_vertex_adj_add(vertex,
|
||||
parent_vadj->sadj);
|
||||
isis_vertex_adj_add(spftree, vertex,
|
||||
parent_vadj->sadj,
|
||||
psid);
|
||||
if (CHECK_FLAG(spftree->flags,
|
||||
F_SPFTREE_HOPCOUNT_METRIC))
|
||||
vertex_update_firsthops(vertex, parent);
|
||||
@ -656,7 +688,7 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
|
||||
(parent ? print_sys_hostname(parent->N.id) : "null"));
|
||||
#endif /* EXTREME_DEBUG */
|
||||
|
||||
isis_spf_add2tent(spftree, vtype, id, dist, depth, NULL, parent);
|
||||
isis_spf_add2tent(spftree, vtype, id, dist, depth, NULL, psid, parent);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -675,6 +707,7 @@ static int isis_spf_process_lsp(struct isis_spftree *spftree,
|
||||
static const uint8_t null_sysid[ISIS_SYS_ID_LEN];
|
||||
struct isis_mt_router_info *mt_router_info = NULL;
|
||||
struct prefix_pair ip_info;
|
||||
bool has_valid_psid;
|
||||
|
||||
if (isis_lfa_excise_node_check(spftree, lsp->hdr.lsp_id)) {
|
||||
if (IS_DEBUG_TILFA)
|
||||
@ -739,7 +772,7 @@ lspfragloop:
|
||||
LSP_PSEUDO_ID(r->id)
|
||||
? VTYPE_PSEUDO_IS
|
||||
: VTYPE_NONPSEUDO_IS,
|
||||
(void *)r->id, dist, depth + 1,
|
||||
(void *)r->id, dist, depth + 1, NULL,
|
||||
parent);
|
||||
}
|
||||
}
|
||||
@ -773,7 +806,8 @@ lspfragloop:
|
||||
process_N(spftree,
|
||||
LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS
|
||||
: VTYPE_NONPSEUDO_TE_IS,
|
||||
(void *)er->id, dist, depth + 1, parent);
|
||||
(void *)er->id, dist, depth + 1, NULL,
|
||||
parent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -798,7 +832,7 @@ lspfragloop:
|
||||
ip_info.dest.u.prefix4 = r->prefix.prefix;
|
||||
ip_info.dest.prefixlen = r->prefix.prefixlen;
|
||||
process_N(spftree, vtype, &ip_info,
|
||||
dist, depth + 1, parent);
|
||||
dist, depth + 1, NULL, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -823,8 +857,34 @@ lspfragloop:
|
||||
dist = cost + r->metric;
|
||||
ip_info.dest.u.prefix4 = r->prefix.prefix;
|
||||
ip_info.dest.prefixlen = r->prefix.prefixlen;
|
||||
process_N(spftree, VTYPE_IPREACH_TE, &ip_info,
|
||||
dist, depth + 1, parent);
|
||||
|
||||
/* Parse list of Prefix-SID subTLVs */
|
||||
has_valid_psid = false;
|
||||
if (r->subtlvs) {
|
||||
for (struct isis_item *i =
|
||||
r->subtlvs->prefix_sids.head;
|
||||
i; i = i->next) {
|
||||
struct isis_prefix_sid *psid =
|
||||
(struct isis_prefix_sid *)i;
|
||||
|
||||
if (psid->algorithm != SR_ALGORITHM_SPF)
|
||||
continue;
|
||||
|
||||
has_valid_psid = true;
|
||||
process_N(spftree, VTYPE_IPREACH_TE,
|
||||
&ip_info, dist, depth + 1,
|
||||
psid, parent);
|
||||
/*
|
||||
* Stop the Prefix-SID iteration since
|
||||
* we only support the SPF algorithm for
|
||||
* now.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_valid_psid)
|
||||
process_N(spftree, VTYPE_IPREACH_TE, &ip_info,
|
||||
dist, depth + 1, NULL, parent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -865,8 +925,34 @@ lspfragloop:
|
||||
}
|
||||
ip_info.src = *r->subtlvs->source_prefix;
|
||||
}
|
||||
process_N(spftree, vtype, &ip_info, dist,
|
||||
depth + 1, parent);
|
||||
|
||||
/* Parse list of Prefix-SID subTLVs */
|
||||
has_valid_psid = false;
|
||||
if (r->subtlvs) {
|
||||
for (struct isis_item *i =
|
||||
r->subtlvs->prefix_sids.head;
|
||||
i; i = i->next) {
|
||||
struct isis_prefix_sid *psid =
|
||||
(struct isis_prefix_sid *)i;
|
||||
|
||||
if (psid->algorithm != SR_ALGORITHM_SPF)
|
||||
continue;
|
||||
|
||||
has_valid_psid = true;
|
||||
process_N(spftree, vtype, &ip_info,
|
||||
dist, depth + 1, psid,
|
||||
parent);
|
||||
/*
|
||||
* Stop the Prefix-SID iteration since
|
||||
* we only support the SPF algorithm for
|
||||
* now.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_valid_psid)
|
||||
process_N(spftree, vtype, &ip_info, dist,
|
||||
depth + 1, NULL, parent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -922,6 +1008,7 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix,
|
||||
struct isis_vertex *parent = args->parent;
|
||||
struct prefix_pair ip_info;
|
||||
enum vertextype vtype;
|
||||
bool has_valid_psid = false;
|
||||
|
||||
if (external)
|
||||
return LSP_ITER_CONTINUE;
|
||||
@ -936,7 +1023,30 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix,
|
||||
else
|
||||
vtype = VTYPE_IP6REACH_INTERNAL;
|
||||
|
||||
isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, parent);
|
||||
/* Parse list of Prefix-SID subTLVs */
|
||||
if (subtlvs) {
|
||||
for (struct isis_item *i = subtlvs->prefix_sids.head; i;
|
||||
i = i->next) {
|
||||
struct isis_prefix_sid *psid =
|
||||
(struct isis_prefix_sid *)i;
|
||||
|
||||
if (psid->algorithm != SR_ALGORITHM_SPF)
|
||||
continue;
|
||||
|
||||
has_valid_psid = true;
|
||||
isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0,
|
||||
psid, parent);
|
||||
|
||||
/*
|
||||
* Stop the Prefix-SID iteration since we only support
|
||||
* the SPF algorithm for now.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_valid_psid)
|
||||
isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, NULL,
|
||||
parent);
|
||||
|
||||
return LSP_ITER_CONTINUE;
|
||||
}
|
||||
@ -985,7 +1095,8 @@ static void isis_spf_preload_tent(struct isis_spftree *spftree,
|
||||
F_ISIS_SPF_ADJ_OLDMETRIC)
|
||||
? VTYPE_NONPSEUDO_IS
|
||||
: VTYPE_NONPSEUDO_TE_IS,
|
||||
sadj->id, sadj, metric, parent);
|
||||
sadj->id, sadj, metric, NULL,
|
||||
parent);
|
||||
} else if (sadj->lan.lsp_pseudo) {
|
||||
isis_spf_process_lsp(spftree, sadj->lan.lsp_pseudo,
|
||||
metric, 0, spftree->sysid, parent);
|
||||
@ -1291,8 +1402,9 @@ static void spf_path_process(struct isis_spftree *spftree,
|
||||
} else
|
||||
route_table = spftree->route_table;
|
||||
|
||||
isis_route_create(&vertex->N.ip.dest, &vertex->N.ip.src,
|
||||
vertex->d_N, vertex->depth,
|
||||
isis_route_create(&vertex->N.ip.p.dest,
|
||||
&vertex->N.ip.p.src, vertex->d_N,
|
||||
vertex->depth, &vertex->N.ip.sr,
|
||||
vertex->Adj_N, area, route_table);
|
||||
} else if (IS_DEBUG_SPF_EVENTS)
|
||||
zlog_debug(
|
||||
@ -1532,8 +1644,6 @@ static int isis_run_spf_cb(struct thread *thread)
|
||||
|
||||
isis_area_verify_routes(area);
|
||||
|
||||
isis_area_verify_sr(area);
|
||||
|
||||
/* walk all circuits and reset any spf specific flags */
|
||||
struct listnode *node;
|
||||
struct isis_circuit *circuit;
|
||||
@ -1824,12 +1934,126 @@ DEFUN(show_isis_topology, show_isis_topology_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void isis_print_route(struct ttable *tt, const struct prefix *prefix,
|
||||
struct isis_route_info *rinfo, bool prefix_sid,
|
||||
bool no_adjacencies)
|
||||
{
|
||||
struct isis_nexthop *nexthop;
|
||||
struct listnode *node;
|
||||
bool first = true;
|
||||
char buf_prefix[BUFSIZ];
|
||||
|
||||
(void)prefix2str(prefix, buf_prefix, sizeof(buf_prefix));
|
||||
for (ALL_LIST_ELEMENTS_RO(rinfo->nexthops, node, nexthop)) {
|
||||
struct interface *ifp;
|
||||
char buf_iface[BUFSIZ];
|
||||
char buf_nhop[BUFSIZ];
|
||||
|
||||
if (!no_adjacencies) {
|
||||
inet_ntop(nexthop->family, &nexthop->ip, buf_nhop,
|
||||
sizeof(buf_nhop));
|
||||
ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT);
|
||||
if (ifp)
|
||||
strlcpy(buf_iface, ifp->name,
|
||||
sizeof(buf_iface));
|
||||
else
|
||||
snprintf(buf_iface, sizeof(buf_iface),
|
||||
"ifindex %u", nexthop->ifindex);
|
||||
} else {
|
||||
strlcpy(buf_nhop, print_sys_hostname(nexthop->sysid),
|
||||
sizeof(buf_nhop));
|
||||
strlcpy(buf_iface, "-", sizeof(buf_iface));
|
||||
}
|
||||
|
||||
if (prefix_sid) {
|
||||
char buf_sid[BUFSIZ] = {};
|
||||
char buf_lblop[BUFSIZ] = {};
|
||||
|
||||
if (nexthop->sr.present) {
|
||||
snprintf(buf_sid, sizeof(buf_sid), "%u",
|
||||
nexthop->sr.sid.value);
|
||||
sr_op2str(buf_lblop, sizeof(buf_lblop),
|
||||
rinfo->sr.label, nexthop->sr.label);
|
||||
} else {
|
||||
strlcpy(buf_sid, "-", sizeof(buf_sid));
|
||||
strlcpy(buf_lblop, "-", sizeof(buf_lblop));
|
||||
}
|
||||
|
||||
if (first) {
|
||||
ttable_add_row(tt, "%s|%u|%s|%s|%s|%s",
|
||||
buf_prefix, rinfo->cost,
|
||||
buf_iface, buf_nhop, buf_sid,
|
||||
buf_lblop);
|
||||
first = false;
|
||||
} else
|
||||
ttable_add_row(tt, "||%s|%s|%s|%s", buf_iface,
|
||||
buf_nhop, buf_sid, buf_lblop);
|
||||
} else {
|
||||
char buf_labels[BUFSIZ] = {};
|
||||
|
||||
if (nexthop->label_stack) {
|
||||
for (int i = 0;
|
||||
i < nexthop->label_stack->num_labels;
|
||||
i++) {
|
||||
char buf_label[BUFSIZ];
|
||||
|
||||
label2str(
|
||||
nexthop->label_stack->label[i],
|
||||
buf_label, sizeof(buf_label));
|
||||
if (i != 0)
|
||||
strlcat(buf_labels, "/",
|
||||
sizeof(buf_labels));
|
||||
strlcat(buf_labels, buf_label,
|
||||
sizeof(buf_labels));
|
||||
}
|
||||
} else if (nexthop->sr.present)
|
||||
label2str(nexthop->sr.label, buf_labels,
|
||||
sizeof(buf_labels));
|
||||
else
|
||||
strlcpy(buf_labels, "-", sizeof(buf_labels));
|
||||
|
||||
if (first) {
|
||||
ttable_add_row(tt, "%s|%u|%s|%s|%s", buf_prefix,
|
||||
rinfo->cost, buf_iface, buf_nhop,
|
||||
buf_labels);
|
||||
first = false;
|
||||
} else
|
||||
ttable_add_row(tt, "||%s|%s|%s", buf_iface,
|
||||
buf_nhop, buf_labels);
|
||||
}
|
||||
}
|
||||
if (list_isempty(rinfo->nexthops)) {
|
||||
if (prefix_sid) {
|
||||
char buf_sid[BUFSIZ] = {};
|
||||
char buf_lblop[BUFSIZ] = {};
|
||||
|
||||
if (rinfo->sr.present) {
|
||||
snprintf(buf_sid, sizeof(buf_sid), "%u",
|
||||
rinfo->sr.sid.value);
|
||||
sr_op2str(buf_lblop, sizeof(buf_lblop),
|
||||
rinfo->sr.label,
|
||||
MPLS_LABEL_IMPLICIT_NULL);
|
||||
} else {
|
||||
strlcpy(buf_sid, "-", sizeof(buf_sid));
|
||||
strlcpy(buf_lblop, "-", sizeof(buf_lblop));
|
||||
}
|
||||
|
||||
ttable_add_row(tt, "%s|%u|%s|%s|%s|%s", buf_prefix,
|
||||
rinfo->cost, "-", "-", buf_sid,
|
||||
buf_lblop);
|
||||
} else
|
||||
ttable_add_row(tt, "%s|%u|%s|%s|%s", buf_prefix,
|
||||
rinfo->cost, "-", "-", "-");
|
||||
}
|
||||
}
|
||||
|
||||
void isis_print_routes(struct vty *vty, struct isis_spftree *spftree,
|
||||
bool backup)
|
||||
bool prefix_sid, bool backup)
|
||||
{
|
||||
struct route_table *route_table;
|
||||
struct ttable *tt;
|
||||
struct route_node *rn;
|
||||
bool no_adjacencies = false;
|
||||
const char *tree_id_text = NULL;
|
||||
|
||||
if (!spftree)
|
||||
@ -1855,82 +2079,28 @@ void isis_print_routes(struct vty *vty, struct isis_spftree *spftree,
|
||||
|
||||
/* Prepare table. */
|
||||
tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
|
||||
ttable_add_row(tt, "Prefix|Metric|Interface|Nexthop|Label(s)");
|
||||
if (prefix_sid)
|
||||
ttable_add_row(tt, "Prefix|Metric|Interface|Nexthop|SID|Label Op.");
|
||||
else
|
||||
ttable_add_row(tt, "Prefix|Metric|Interface|Nexthop|Label(s)");
|
||||
tt->style.cell.rpad = 2;
|
||||
tt->style.corner = '+';
|
||||
ttable_restyle(tt);
|
||||
ttable_rowseps(tt, 0, BOTTOM, true, '-');
|
||||
|
||||
if (CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES))
|
||||
no_adjacencies = true;
|
||||
|
||||
route_table =
|
||||
(backup) ? spftree->route_table_backup : spftree->route_table;
|
||||
for (rn = route_top(route_table); rn; rn = route_next(rn)) {
|
||||
struct isis_route_info *rinfo;
|
||||
struct isis_nexthop *nexthop;
|
||||
struct listnode *node;
|
||||
bool first = true;
|
||||
char buf_prefix[BUFSIZ];
|
||||
|
||||
rinfo = rn->info;
|
||||
if (!rinfo)
|
||||
continue;
|
||||
|
||||
(void)prefix2str(&rn->p, buf_prefix, sizeof(buf_prefix));
|
||||
for (ALL_LIST_ELEMENTS_RO(rinfo->nexthops, node, nexthop)) {
|
||||
struct interface *ifp;
|
||||
char buf_iface[BUFSIZ];
|
||||
char buf_nhop[BUFSIZ];
|
||||
char buf_labels[BUFSIZ] = {};
|
||||
|
||||
if (!CHECK_FLAG(spftree->flags,
|
||||
F_SPFTREE_NO_ADJACENCIES)) {
|
||||
inet_ntop(nexthop->family, &nexthop->ip,
|
||||
buf_nhop, sizeof(buf_nhop));
|
||||
ifp = if_lookup_by_index(nexthop->ifindex,
|
||||
VRF_DEFAULT);
|
||||
if (ifp)
|
||||
strlcpy(buf_iface, ifp->name,
|
||||
sizeof(buf_iface));
|
||||
else
|
||||
snprintf(buf_iface, sizeof(buf_iface),
|
||||
"ifindex %u",
|
||||
nexthop->ifindex);
|
||||
} else {
|
||||
strlcpy(buf_nhop,
|
||||
print_sys_hostname(nexthop->sysid),
|
||||
sizeof(buf_nhop));
|
||||
strlcpy(buf_iface, "-", sizeof(buf_iface));
|
||||
}
|
||||
|
||||
if (nexthop->label_stack) {
|
||||
for (int i = 0;
|
||||
i < nexthop->label_stack->num_labels;
|
||||
i++) {
|
||||
char buf_label[BUFSIZ];
|
||||
|
||||
label2str(
|
||||
nexthop->label_stack->label[i],
|
||||
buf_label, sizeof(buf_label));
|
||||
if (i != 0)
|
||||
strlcat(buf_labels, "/",
|
||||
sizeof(buf_labels));
|
||||
strlcat(buf_labels, buf_label,
|
||||
sizeof(buf_labels));
|
||||
}
|
||||
} else if (nexthop->sr.label != MPLS_INVALID_LABEL)
|
||||
label2str(nexthop->sr.label, buf_labels,
|
||||
sizeof(buf_labels));
|
||||
else
|
||||
strlcpy(buf_labels, "-", sizeof(buf_labels));
|
||||
|
||||
if (first) {
|
||||
ttable_add_row(tt, "%s|%u|%s|%s|%s", buf_prefix,
|
||||
rinfo->cost, buf_iface, buf_nhop,
|
||||
buf_labels);
|
||||
first = false;
|
||||
} else
|
||||
ttable_add_row(tt, "||%s|%s|%s", buf_iface,
|
||||
buf_nhop, buf_labels);
|
||||
}
|
||||
isis_print_route(tt, &rn->p, rinfo, prefix_sid, no_adjacencies);
|
||||
}
|
||||
|
||||
/* Dump the generated table. */
|
||||
@ -1945,7 +2115,8 @@ void isis_print_routes(struct vty *vty, struct isis_spftree *spftree,
|
||||
}
|
||||
|
||||
static void show_isis_route_common(struct vty *vty, int levels,
|
||||
struct isis *isis, bool backup)
|
||||
struct isis *isis, bool prefix_sid,
|
||||
bool backup)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_area *area;
|
||||
@ -1965,19 +2136,19 @@ static void show_isis_route_common(struct vty *vty, int levels,
|
||||
isis_print_routes(
|
||||
vty,
|
||||
area->spftree[SPFTREE_IPV4][level - 1],
|
||||
backup);
|
||||
prefix_sid, backup);
|
||||
}
|
||||
if (area->ipv6_circuits > 0) {
|
||||
isis_print_routes(
|
||||
vty,
|
||||
area->spftree[SPFTREE_IPV6][level - 1],
|
||||
backup);
|
||||
prefix_sid, backup);
|
||||
}
|
||||
if (isis_area_ipv6_dstsrc_enabled(area)) {
|
||||
isis_print_routes(vty,
|
||||
area->spftree[SPFTREE_DSTSRC]
|
||||
[level - 1],
|
||||
backup);
|
||||
prefix_sid, backup);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1989,13 +2160,14 @@ DEFUN(show_isis_route, show_isis_route_cmd,
|
||||
#ifndef FABRICD
|
||||
" [<level-1|level-2>]"
|
||||
#endif
|
||||
" [backup]",
|
||||
" [<prefix-sid|backup>]",
|
||||
SHOW_STR PROTO_HELP VRF_FULL_CMD_HELP_STR
|
||||
"IS-IS routing table\n"
|
||||
#ifndef FABRICD
|
||||
"level-1 routes\n"
|
||||
"level-2 routes\n"
|
||||
#endif
|
||||
"Show Prefix-SID information\n"
|
||||
"Show backup routes\n")
|
||||
{
|
||||
int levels;
|
||||
@ -2003,6 +2175,7 @@ DEFUN(show_isis_route, show_isis_route_cmd,
|
||||
struct listnode *node;
|
||||
const char *vrf_name = VRF_DEFAULT_NAME;
|
||||
bool all_vrf = false;
|
||||
bool prefix_sid = false;
|
||||
bool backup = false;
|
||||
int idx = 0;
|
||||
|
||||
@ -2019,6 +2192,8 @@ DEFUN(show_isis_route, show_isis_route_cmd,
|
||||
}
|
||||
ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf);
|
||||
|
||||
if (argv_find(argv, argc, "prefix-sid", &idx))
|
||||
prefix_sid = true;
|
||||
if (argv_find(argv, argc, "backup", &idx))
|
||||
backup = true;
|
||||
|
||||
@ -2026,12 +2201,13 @@ DEFUN(show_isis_route, show_isis_route_cmd,
|
||||
if (all_vrf) {
|
||||
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||
show_isis_route_common(vty, levels, isis,
|
||||
backup);
|
||||
prefix_sid, backup);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
isis = isis_lookup_by_vrfname(vrf_name);
|
||||
if (isis != NULL)
|
||||
show_isis_route_common(vty, levels, isis, backup);
|
||||
show_isis_route_common(vty, levels, isis, prefix_sid,
|
||||
backup);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -68,7 +68,7 @@ int _isis_spf_schedule(struct isis_area *area, int level,
|
||||
const char *func, const char *file, int line);
|
||||
void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree);
|
||||
void isis_print_routes(struct vty *vty, struct isis_spftree *spftree,
|
||||
bool backup);
|
||||
bool prefix_sid, bool backup);
|
||||
void isis_spf_init(void);
|
||||
void isis_spf_print(struct isis_spftree *spftree, struct vty *vty);
|
||||
void isis_run_spf(struct isis_spftree *spftree);
|
||||
|
@ -52,6 +52,7 @@ struct prefix_pair {
|
||||
|
||||
struct isis_vertex_adj {
|
||||
struct isis_spf_adj *sadj;
|
||||
struct isis_sr_psid_info sr;
|
||||
struct mpls_label_stack *label_stack;
|
||||
};
|
||||
|
||||
@ -62,7 +63,10 @@ struct isis_vertex {
|
||||
enum vertextype type;
|
||||
union {
|
||||
uint8_t id[ISIS_SYS_ID_LEN + 1];
|
||||
struct prefix_pair ip;
|
||||
struct {
|
||||
struct prefix_pair p;
|
||||
struct isis_sr_psid_info sr;
|
||||
} ip;
|
||||
} N;
|
||||
uint32_t d_N; /* d(N) Distance from this IS */
|
||||
uint16_t depth; /* The depth in the imaginary tree */
|
||||
@ -91,8 +95,8 @@ static unsigned isis_vertex_queue_hash_key(const void *vp)
|
||||
if (VTYPE_IP(vertex->type)) {
|
||||
uint32_t key;
|
||||
|
||||
key = prefix_hash_key(&vertex->N.ip.dest);
|
||||
key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key);
|
||||
key = prefix_hash_key(&vertex->N.ip.p.dest);
|
||||
key = jhash_1word(prefix_hash_key(&vertex->N.ip.p.src), key);
|
||||
return key;
|
||||
}
|
||||
|
||||
@ -108,11 +112,12 @@ static bool isis_vertex_queue_hash_cmp(const void *a, const void *b)
|
||||
return false;
|
||||
|
||||
if (VTYPE_IP(va->type)) {
|
||||
if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest))
|
||||
if (prefix_cmp(&va->N.ip.p.dest, &vb->N.ip.p.dest))
|
||||
return false;
|
||||
|
||||
return prefix_cmp((const struct prefix *)&va->N.ip.src,
|
||||
(const struct prefix *)&vb->N.ip.src) == 0;
|
||||
return prefix_cmp((const struct prefix *)&va->N.ip.p.src,
|
||||
(const struct prefix *)&vb->N.ip.p.src)
|
||||
== 0;
|
||||
}
|
||||
|
||||
return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0;
|
||||
@ -351,7 +356,7 @@ static void isis_vertex_id_init(struct isis_vertex *vertex, const void *id,
|
||||
if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) {
|
||||
memcpy(vertex->N.id, id, ISIS_SYS_ID_LEN + 1);
|
||||
} else if (VTYPE_IP(vtype)) {
|
||||
memcpy(&vertex->N.ip, id, sizeof(vertex->N.ip));
|
||||
memcpy(&vertex->N.ip.p, id, sizeof(vertex->N.ip.p));
|
||||
} else {
|
||||
flog_err(EC_LIB_DEVELOPMENT, "Unknown Vertex Type");
|
||||
}
|
||||
|
1416
isisd/isis_sr.c
1416
isisd/isis_sr.c
File diff suppressed because it is too large
Load Diff
119
isisd/isis_sr.h
119
isisd/isis_sr.h
@ -57,11 +57,25 @@
|
||||
#define SRLB_UPPER_BOUND 15999
|
||||
|
||||
/* Segment Routing Data Base (SRDB) RB-Tree structure */
|
||||
PREDECL_RBTREE_UNIQ(srdb_node)
|
||||
PREDECL_RBTREE_UNIQ(srdb_node_prefix)
|
||||
PREDECL_RBTREE_UNIQ(srdb_area_prefix)
|
||||
PREDECL_RBTREE_UNIQ(srdb_prefix_cfg)
|
||||
|
||||
/*
|
||||
* Segment Routing Prefix-SID information.
|
||||
*
|
||||
* This structure is intended to be embedded inside other structures that
|
||||
* might or might not contain Prefix-SID information.
|
||||
*/
|
||||
struct isis_sr_psid_info {
|
||||
/* Prefix-SID Sub-TLV information. */
|
||||
struct isis_prefix_sid sid;
|
||||
|
||||
/* Resolved input/output label. */
|
||||
mpls_label_t label;
|
||||
|
||||
/* Indicates whether the Prefix-SID is present or not. */
|
||||
bool present;
|
||||
};
|
||||
|
||||
/* Segment Routing Local Block allocation */
|
||||
struct sr_local_block {
|
||||
bool active;
|
||||
@ -106,85 +120,6 @@ struct sr_adjacency {
|
||||
struct isis_adjacency *adj;
|
||||
};
|
||||
|
||||
/* Segment Routing Prefix-SID type. */
|
||||
enum sr_prefix_type {
|
||||
ISIS_SR_PREFIX_LOCAL = 0,
|
||||
ISIS_SR_PREFIX_REMOTE,
|
||||
};
|
||||
|
||||
/* Segment Routing Nexthop Information. */
|
||||
struct sr_nexthop_info {
|
||||
mpls_label_t label;
|
||||
time_t uptime;
|
||||
};
|
||||
|
||||
/* State of Object (SR-Node and SR-Prefix) stored in SRDB */
|
||||
enum srdb_state {
|
||||
SRDB_STATE_VALIDATED = 0,
|
||||
SRDB_STATE_NEW,
|
||||
SRDB_STATE_MODIFIED,
|
||||
SRDB_STATE_UNCHANGED
|
||||
};
|
||||
|
||||
/* Segment Routing Prefix-SID. */
|
||||
struct sr_prefix {
|
||||
/* SRDB RB-tree entries. */
|
||||
struct srdb_node_prefix_item node_entry;
|
||||
struct srdb_area_prefix_item area_entry;
|
||||
|
||||
/* IP prefix. */
|
||||
struct prefix prefix;
|
||||
|
||||
/* SID value, algorithm and flags subTLVs. */
|
||||
struct isis_prefix_sid sid;
|
||||
|
||||
/* Input label value. */
|
||||
mpls_label_t input_label;
|
||||
|
||||
/* Prefix-SID type. */
|
||||
enum sr_prefix_type type;
|
||||
union {
|
||||
struct {
|
||||
/* Information about this local Prefix-SID. */
|
||||
struct sr_nexthop_info info;
|
||||
} local;
|
||||
struct {
|
||||
/* Route associated to this remote Prefix-SID. */
|
||||
struct isis_route_info *rinfo;
|
||||
} remote;
|
||||
} u;
|
||||
|
||||
/* Backpointer to Segment Routing node. */
|
||||
struct sr_node *srn;
|
||||
|
||||
/* SR-Prefix State used while the LSPDB is being parsed. */
|
||||
enum srdb_state state;
|
||||
};
|
||||
|
||||
/* Segment Routing node. */
|
||||
struct sr_node {
|
||||
/* SRDB RB-tree entry. */
|
||||
struct srdb_node_item entry;
|
||||
|
||||
/* IS-IS level: ISIS_LEVEL1 or ISIS_LEVEL2. */
|
||||
int level;
|
||||
|
||||
/* IS-IS node identifier. */
|
||||
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||
|
||||
/* Segment Routing node capabilities (SRGB, SR Algorithms) subTLVs. */
|
||||
struct isis_router_cap cap;
|
||||
|
||||
/* List of Prefix-SIDs advertised by this node. */
|
||||
struct srdb_node_prefix_head prefix_sids;
|
||||
|
||||
/* Backpointer to IS-IS area. */
|
||||
struct isis_area *area;
|
||||
|
||||
/* SR-Node State used while the LSPDB is being parsed. */
|
||||
enum srdb_state state;
|
||||
};
|
||||
|
||||
/* SID type. NOTE: these values must be in sync with the YANG module. */
|
||||
enum sr_sid_value_type {
|
||||
SR_SID_VALUE_TYPE_INDEX = 0,
|
||||
@ -235,12 +170,6 @@ struct isis_sr_db {
|
||||
/* List of local Adjacency-SIDs. */
|
||||
struct list *adj_sids;
|
||||
|
||||
/* Segment Routing Node information per IS-IS level. */
|
||||
struct srdb_node_head sr_nodes[ISIS_LEVELS];
|
||||
|
||||
/* Segment Routing Prefix-SIDs per IS-IS level. */
|
||||
struct srdb_area_prefix_head prefix_sids[ISIS_LEVELS];
|
||||
|
||||
/* Management of SRLB & SRGB allocation */
|
||||
struct sr_local_block srlb;
|
||||
bool srgb_active;
|
||||
@ -267,6 +196,14 @@ struct isis_sr_db {
|
||||
};
|
||||
|
||||
/* Prototypes. */
|
||||
extern struct isis_sr_block *isis_sr_find_srgb(struct lspdb_head *lspdb,
|
||||
const uint8_t *sysid);
|
||||
extern mpls_label_t sr_prefix_in_label(struct isis_area *area,
|
||||
struct isis_prefix_sid *psid,
|
||||
bool local);
|
||||
extern mpls_label_t sr_prefix_out_label(struct lspdb_head *lspdb, int family,
|
||||
struct isis_prefix_sid *psid,
|
||||
const uint8_t *nh_sysid, bool last_hop);
|
||||
extern int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound,
|
||||
uint32_t upper_bound);
|
||||
extern int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
|
||||
@ -279,16 +216,14 @@ isis_sr_cfg_prefix_find(struct isis_area *area, union prefixconstptr prefix);
|
||||
extern void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg,
|
||||
bool external,
|
||||
struct isis_prefix_sid *psid);
|
||||
extern void isis_sr_nexthop_update(struct sr_nexthop_info *srnh,
|
||||
mpls_label_t label);
|
||||
extern void isis_sr_nexthop_reset(struct sr_nexthop_info *srnh);
|
||||
extern void sr_adj_sid_add_single(struct isis_adjacency *adj, int family,
|
||||
bool backup, struct list *nexthops);
|
||||
extern struct sr_adjacency *isis_sr_adj_sid_find(struct isis_adjacency *adj,
|
||||
int family,
|
||||
enum sr_adj_type type);
|
||||
extern void isis_area_delete_backup_adj_sids(struct isis_area *area, int level);
|
||||
extern void isis_area_verify_sr(struct isis_area *area);
|
||||
extern char *sr_op2str(char *buf, size_t size, mpls_label_t label_in,
|
||||
mpls_label_t label_out);
|
||||
extern int isis_sr_start(struct isis_area *area);
|
||||
extern void isis_sr_stop(struct isis_area *area);
|
||||
extern void isis_sr_area_init(struct isis_area *area);
|
||||
|
@ -2603,8 +2603,8 @@ static void format_tlv_router_cap(const struct isis_router_cap *router_cap,
|
||||
sbuf_push(
|
||||
buf, indent,
|
||||
" Segment Routing: I:%s V:%s, Global Block Base: %u Range: %u\n",
|
||||
IS_SR_IPV4(router_cap->srgb) ? "1" : "0",
|
||||
IS_SR_IPV6(router_cap->srgb) ? "1" : "0",
|
||||
IS_SR_IPV4(&router_cap->srgb) ? "1" : "0",
|
||||
IS_SR_IPV6(&router_cap->srgb) ? "1" : "0",
|
||||
router_cap->srgb.lower_bound,
|
||||
router_cap->srgb.range_size);
|
||||
|
||||
|
@ -138,8 +138,8 @@ struct isis_threeway_adj {
|
||||
/* Segment Routing subTLV's as per RFC8667 */
|
||||
#define ISIS_SUBTLV_SRGB_FLAG_I 0x80
|
||||
#define ISIS_SUBTLV_SRGB_FLAG_V 0x40
|
||||
#define IS_SR_IPV4(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_I)
|
||||
#define IS_SR_IPV6(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_V)
|
||||
#define IS_SR_IPV4(srgb) ((srgb)->flags & ISIS_SUBTLV_SRGB_FLAG_I)
|
||||
#define IS_SR_IPV6(srgb) ((srgb)->flags & ISIS_SUBTLV_SRGB_FLAG_V)
|
||||
#define SUBTLV_SR_BLOCK_SIZE 6
|
||||
#define SUBTLV_RANGE_INDEX_SIZE 10
|
||||
#define SUBTLV_RANGE_LABEL_SIZE 9
|
||||
|
@ -155,16 +155,14 @@ static int isis_zebra_link_params(ZAPI_CALLBACK_ARGS)
|
||||
}
|
||||
|
||||
enum isis_zebra_nexthop_type {
|
||||
ISIS_ROUTE_NEXTHOP_MAIN = 0,
|
||||
ISIS_ROUTE_NEXTHOP_BACKUP,
|
||||
ISIS_MPLS_NEXTHOP_MAIN,
|
||||
ISIS_MPLS_NEXTHOP_BACKUP,
|
||||
ISIS_NEXTHOP_MAIN = 0,
|
||||
ISIS_NEXTHOP_BACKUP,
|
||||
};
|
||||
|
||||
static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops,
|
||||
struct zapi_nexthop zapi_nexthops[],
|
||||
enum isis_zebra_nexthop_type type,
|
||||
uint8_t backup_nhs)
|
||||
bool mpls_lsp, uint8_t backup_nhs)
|
||||
{
|
||||
struct isis_nexthop *nexthop;
|
||||
struct listnode *node;
|
||||
@ -210,23 +208,18 @@ static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops,
|
||||
|
||||
/* Add MPLS label(s). */
|
||||
switch (type) {
|
||||
case ISIS_ROUTE_NEXTHOP_MAIN:
|
||||
case ISIS_ROUTE_NEXTHOP_BACKUP:
|
||||
/*
|
||||
* SR/TI-LFA labels are installed using separate
|
||||
* messages.
|
||||
*/
|
||||
break;
|
||||
case ISIS_MPLS_NEXTHOP_MAIN:
|
||||
if (nexthop->sr.label != MPLS_INVALID_LABEL) {
|
||||
case ISIS_NEXTHOP_MAIN:
|
||||
if (nexthop->sr.present) {
|
||||
api_nh->label_num = 1;
|
||||
api_nh->labels[0] = nexthop->sr.label;
|
||||
} else {
|
||||
api_nh->label_num = 1;
|
||||
api_nh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
|
||||
}
|
||||
} else if (mpls_lsp)
|
||||
/*
|
||||
* Do not use non-SR enabled nexthops to prevent
|
||||
* broken LSPs from being formed.
|
||||
*/
|
||||
continue;
|
||||
break;
|
||||
case ISIS_MPLS_NEXTHOP_BACKUP:
|
||||
case ISIS_NEXTHOP_BACKUP:
|
||||
if (nexthop->label_stack) {
|
||||
api_nh->label_num =
|
||||
nexthop->label_stack->num_labels;
|
||||
@ -234,7 +227,11 @@ static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops,
|
||||
nexthop->label_stack->label,
|
||||
sizeof(mpls_label_t)
|
||||
* api_nh->label_num);
|
||||
} else {
|
||||
} else if (mpls_lsp) {
|
||||
/*
|
||||
* This is necessary because zebra requires
|
||||
* the nexthops of MPLS LSPs to be labeled.
|
||||
*/
|
||||
api_nh->label_num = 1;
|
||||
api_nh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
|
||||
}
|
||||
@ -266,7 +263,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix,
|
||||
struct zapi_route api;
|
||||
int count = 0;
|
||||
|
||||
if (zclient->sock < 0)
|
||||
if (zclient->sock < 0 || list_isempty(route_info->nexthops))
|
||||
return;
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
@ -286,7 +283,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix,
|
||||
if (route_info->backup) {
|
||||
count = isis_zebra_add_nexthops(
|
||||
isis, route_info->backup->nexthops, api.backup_nexthops,
|
||||
ISIS_ROUTE_NEXTHOP_BACKUP, 0);
|
||||
ISIS_NEXTHOP_BACKUP, false, 0);
|
||||
if (count > 0) {
|
||||
SET_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS);
|
||||
api.backup_nexthop_num = count;
|
||||
@ -295,7 +292,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix,
|
||||
|
||||
/* Add primary nexthops. */
|
||||
count = isis_zebra_add_nexthops(isis, route_info->nexthops,
|
||||
api.nexthops, ISIS_ROUTE_NEXTHOP_MAIN,
|
||||
api.nexthops, ISIS_NEXTHOP_MAIN, false,
|
||||
count);
|
||||
if (!count)
|
||||
return;
|
||||
@ -328,31 +325,39 @@ void isis_zebra_route_del_route(struct isis *isis,
|
||||
}
|
||||
|
||||
/**
|
||||
* Install Prefix-SID in the forwarding plane through Zebra.
|
||||
* Install Prefix-SID label entry in the forwarding plane through Zebra.
|
||||
*
|
||||
* @param srp Segment Routing Prefix-SID
|
||||
* @param area IS-IS area
|
||||
* @param prefix Route prefix
|
||||
* @param rinfo Route information
|
||||
* @param psid Prefix-SID information
|
||||
*/
|
||||
static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
|
||||
void isis_zebra_prefix_sid_install(struct isis_area *area,
|
||||
struct prefix *prefix,
|
||||
struct isis_route_info *rinfo,
|
||||
struct isis_sr_psid_info *psid)
|
||||
{
|
||||
struct isis *isis = srp->srn->area->isis;
|
||||
struct zapi_labels zl;
|
||||
struct zapi_nexthop *znh;
|
||||
struct interface *ifp;
|
||||
struct isis_route_info *rinfo;
|
||||
int count = 0;
|
||||
|
||||
sr_debug("ISIS-Sr (%s): update label %u for prefix %pFX",
|
||||
area->area_tag, psid->label, prefix);
|
||||
|
||||
/* Prepare message. */
|
||||
memset(&zl, 0, sizeof(zl));
|
||||
zl.type = ZEBRA_LSP_ISIS_SR;
|
||||
zl.local_label = srp->input_label;
|
||||
zl.local_label = psid->label;
|
||||
|
||||
/* Local routes don't have any nexthop and require special handling. */
|
||||
if (list_isempty(rinfo->nexthops)) {
|
||||
struct zapi_nexthop *znh;
|
||||
struct interface *ifp;
|
||||
|
||||
switch (srp->type) {
|
||||
case ISIS_SR_PREFIX_LOCAL:
|
||||
ifp = if_lookup_by_name("lo", VRF_DEFAULT);
|
||||
if (!ifp) {
|
||||
zlog_warn(
|
||||
"%s: couldn't install Prefix-SID %pFX: loopback interface not found",
|
||||
__func__, &srp->prefix);
|
||||
__func__, prefix);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -361,21 +366,12 @@ static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
|
||||
znh->ifindex = ifp->ifindex;
|
||||
znh->label_num = 1;
|
||||
znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
|
||||
break;
|
||||
case ISIS_SR_PREFIX_REMOTE:
|
||||
/* Update route in the RIB too. */
|
||||
SET_FLAG(zl.message, ZAPI_LABELS_FTN);
|
||||
zl.route.prefix = srp->prefix;
|
||||
zl.route.type = ZEBRA_ROUTE_ISIS;
|
||||
zl.route.instance = 0;
|
||||
|
||||
rinfo = srp->u.remote.rinfo;
|
||||
|
||||
} else {
|
||||
/* Add backup nexthops first. */
|
||||
if (rinfo->backup) {
|
||||
count = isis_zebra_add_nexthops(
|
||||
isis, rinfo->backup->nexthops,
|
||||
zl.backup_nexthops, ISIS_MPLS_NEXTHOP_BACKUP,
|
||||
area->isis, rinfo->backup->nexthops,
|
||||
zl.backup_nexthops, ISIS_NEXTHOP_BACKUP, true,
|
||||
0);
|
||||
if (count > 0) {
|
||||
SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
|
||||
@ -384,13 +380,12 @@ static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
|
||||
}
|
||||
|
||||
/* Add primary nexthops. */
|
||||
count = isis_zebra_add_nexthops(isis, rinfo->nexthops,
|
||||
zl.nexthops,
|
||||
ISIS_MPLS_NEXTHOP_MAIN, count);
|
||||
count = isis_zebra_add_nexthops(area->isis, rinfo->nexthops,
|
||||
zl.nexthops, ISIS_NEXTHOP_MAIN,
|
||||
true, count);
|
||||
if (!count)
|
||||
return;
|
||||
zl.nexthop_num = count;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Send message to zebra. */
|
||||
@ -398,57 +393,32 @@ static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall Prefix-SID from the forwarding plane through Zebra.
|
||||
* Uninstall Prefix-SID label entry from the forwarding plane through Zebra.
|
||||
*
|
||||
* @param srp Segment Routing Prefix-SID
|
||||
* @param area IS-IS area
|
||||
* @param prefix Route prefix
|
||||
* @param rinfo Route information
|
||||
* @param psid Prefix-SID information
|
||||
*/
|
||||
static void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp)
|
||||
void isis_zebra_prefix_sid_uninstall(struct isis_area *area,
|
||||
struct prefix *prefix,
|
||||
struct isis_route_info *rinfo,
|
||||
struct isis_sr_psid_info *psid)
|
||||
{
|
||||
struct zapi_labels zl;
|
||||
|
||||
sr_debug("ISIS-Sr (%s): delete label %u for prefix %pFX",
|
||||
area->area_tag, psid->label, prefix);
|
||||
|
||||
/* Prepare message. */
|
||||
memset(&zl, 0, sizeof(zl));
|
||||
zl.type = ZEBRA_LSP_ISIS_SR;
|
||||
zl.local_label = srp->input_label;
|
||||
|
||||
if (srp->type == ISIS_SR_PREFIX_REMOTE) {
|
||||
/* Update route in the RIB too. */
|
||||
SET_FLAG(zl.message, ZAPI_LABELS_FTN);
|
||||
zl.route.prefix = srp->prefix;
|
||||
zl.route.type = ZEBRA_ROUTE_ISIS;
|
||||
zl.route.instance = 0;
|
||||
}
|
||||
zl.local_label = psid->label;
|
||||
|
||||
/* Send message to zebra. */
|
||||
(void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Prefix-SID to ZEBRA for installation or deletion.
|
||||
*
|
||||
* @param cmd ZEBRA_MPLS_LABELS_REPLACE or ZEBRA_ROUTE_DELETE
|
||||
* @param srp Segment Routing Prefix-SID
|
||||
*/
|
||||
void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp)
|
||||
{
|
||||
|
||||
if (cmd != ZEBRA_MPLS_LABELS_REPLACE
|
||||
&& cmd != ZEBRA_MPLS_LABELS_DELETE) {
|
||||
flog_warn(EC_LIB_DEVELOPMENT, "%s: wrong ZEBRA command",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
sr_debug(" |- %s label %u for prefix %pFX",
|
||||
cmd == ZEBRA_MPLS_LABELS_REPLACE ? "Update" : "Delete",
|
||||
srp->input_label, &srp->prefix);
|
||||
|
||||
if (cmd == ZEBRA_MPLS_LABELS_REPLACE)
|
||||
isis_zebra_prefix_install_prefix_sid(srp);
|
||||
else
|
||||
isis_zebra_uninstall_prefix_sid(srp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send (LAN)-Adjacency-SID to ZEBRA for installation or deletion.
|
||||
*
|
||||
@ -490,7 +460,7 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra)
|
||||
|
||||
count = isis_zebra_add_nexthops(isis, sra->backup_nexthops,
|
||||
zl.backup_nexthops,
|
||||
ISIS_MPLS_NEXTHOP_BACKUP, 0);
|
||||
ISIS_NEXTHOP_BACKUP, true, 0);
|
||||
if (count > 0) {
|
||||
SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
|
||||
zl.backup_nexthop_num = count;
|
||||
|
@ -37,7 +37,6 @@ void isis_zebra_init(struct thread_master *master, int instance);
|
||||
void isis_zebra_stop(void);
|
||||
|
||||
struct isis_route_info;
|
||||
struct sr_prefix;
|
||||
struct sr_adjacency;
|
||||
|
||||
void isis_zebra_route_add_route(struct isis *isis,
|
||||
@ -48,7 +47,14 @@ void isis_zebra_route_del_route(struct isis *isis,
|
||||
struct prefix *prefix,
|
||||
struct prefix_ipv6 *src_p,
|
||||
struct isis_route_info *route_info);
|
||||
void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp);
|
||||
void isis_zebra_prefix_sid_install(struct isis_area *area,
|
||||
struct prefix *prefix,
|
||||
struct isis_route_info *rinfo,
|
||||
struct isis_sr_psid_info *psid);
|
||||
void isis_zebra_prefix_sid_uninstall(struct isis_area *area,
|
||||
struct prefix *prefix,
|
||||
struct isis_route_info *rinfo,
|
||||
struct isis_sr_psid_info *psid);
|
||||
void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra);
|
||||
int isis_distribute_list_update(int routetype);
|
||||
void isis_zebra_redistribute_set(afi_t afi, int type);
|
||||
|
@ -66,7 +66,7 @@ static void test_run_spf(struct vty *vty, const struct isis_topology *topology,
|
||||
|
||||
/* Print the SPT and the corresponding routing table. */
|
||||
isis_print_spftree(vty, spftree);
|
||||
isis_print_routes(vty, spftree, false);
|
||||
isis_print_routes(vty, spftree, false, false);
|
||||
|
||||
/* Cleanup SPF tree. */
|
||||
isis_spftree_del(spftree);
|
||||
@ -122,7 +122,7 @@ static void test_run_ti_lfa(struct vty *vty,
|
||||
|
||||
/* Print the post-convergence SPT and the correspoding routing table. */
|
||||
isis_print_spftree(vty, spftree_pc);
|
||||
isis_print_routes(vty, spftree_self, true);
|
||||
isis_print_routes(vty, spftree_self, false, true);
|
||||
|
||||
/* Cleanup everything. */
|
||||
isis_spftree_del(spftree_self);
|
||||
|
@ -18,14 +18,15 @@ rt6 TE-IS 30 rt2 - rt4(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
10.0.255.5/32 30 - rt3 -
|
||||
10.0.255.6/32 40 - rt2 -
|
||||
- rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
10.0.255.5/32 30 - rt3 16050
|
||||
10.0.255.6/32 40 - rt2 16060
|
||||
- rt3 16060
|
||||
|
||||
IS-IS paths to level-1 routers that speak IPv6
|
||||
Vertex Type Metric Next-Hop Interface Parent
|
||||
@ -46,14 +47,15 @@ rt6 TE-IS 30 rt2 - rt4(4)
|
||||
|
||||
IS-IS L1 IPv6 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-------------------------------------------------------
|
||||
2001:db8::2/128 20 - rt2 -
|
||||
2001:db8::3/128 20 - rt3 -
|
||||
2001:db8::4/128 30 - rt2 -
|
||||
2001:db8::5/128 30 - rt3 -
|
||||
2001:db8::6/128 40 - rt2 -
|
||||
- rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------------
|
||||
2001:db8::1/128 0 - - -
|
||||
2001:db8::2/128 20 - rt2 implicit-null
|
||||
2001:db8::3/128 20 - rt3 implicit-null
|
||||
2001:db8::4/128 30 - rt2 16041
|
||||
2001:db8::5/128 30 - rt3 16051
|
||||
2001:db8::6/128 40 - rt2 16061
|
||||
- rt3 16061
|
||||
|
||||
test# test isis topology 2 root rt1 spf
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -76,14 +78,15 @@ rt3 TE-IS 30 rt3 - rt1(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 25 - rt2 -
|
||||
10.0.255.3/32 40 - rt3 -
|
||||
10.0.255.4/32 20 - rt4 -
|
||||
10.0.255.5/32 20 - rt5 -
|
||||
10.0.255.6/32 30 - rt4 -
|
||||
- rt5 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 25 - rt2 implicit-null
|
||||
10.0.255.3/32 40 - rt3 implicit-null
|
||||
10.0.255.4/32 20 - rt4 implicit-null
|
||||
10.0.255.5/32 20 - rt5 implicit-null
|
||||
10.0.255.6/32 30 - rt4 16060
|
||||
- rt5 16060
|
||||
|
||||
IS-IS paths to level-1 routers that speak IPv6
|
||||
Vertex Type Metric Next-Hop Interface Parent
|
||||
@ -105,14 +108,15 @@ rt3 TE-IS 30 rt3 - rt1(4)
|
||||
|
||||
IS-IS L1 IPv6 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-------------------------------------------------------
|
||||
2001:db8::2/128 25 - rt2 -
|
||||
2001:db8::3/128 40 - rt3 -
|
||||
2001:db8::4/128 20 - rt4 -
|
||||
2001:db8::5/128 20 - rt5 -
|
||||
2001:db8::6/128 30 - rt4 -
|
||||
- rt5 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------------
|
||||
2001:db8::1/128 0 - - -
|
||||
2001:db8::2/128 25 - rt2 implicit-null
|
||||
2001:db8::3/128 40 - rt3 implicit-null
|
||||
2001:db8::4/128 20 - rt4 implicit-null
|
||||
2001:db8::5/128 20 - rt5 implicit-null
|
||||
2001:db8::6/128 30 - rt4 16061
|
||||
- rt5 16061
|
||||
|
||||
test# test isis topology 3 root rt1 spf ipv4-only
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -132,13 +136,14 @@ rt6 TE-IS 30 rt2 - rt4(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
10.0.255.5/32 40 - rt2 -
|
||||
10.0.255.6/32 40 - rt2 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
10.0.255.5/32 40 - rt2 16050
|
||||
10.0.255.6/32 40 - rt2 16060
|
||||
|
||||
test# test isis topology 4 root rt1 spf ipv4-only
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -162,15 +167,16 @@ rt8 TE-IS 40 rt2 - rt6(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
10.0.255.5/32 30 - rt3 -
|
||||
10.0.255.6/32 40 - rt2 -
|
||||
10.0.255.7/32 40 - rt3 -
|
||||
10.0.255.8/32 50 - rt2 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
10.0.255.5/32 30 - rt3 16050
|
||||
10.0.255.6/32 40 - rt2 16060
|
||||
10.0.255.7/32 40 - rt3 16070
|
||||
10.0.255.8/32 50 - rt2 16080
|
||||
|
||||
test# test isis topology 5 root rt1 spf ipv4-only
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -196,16 +202,17 @@ rt8 TE-IS 40 rt2 - rt6(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
10.0.255.5/32 30 - rt3 -
|
||||
10.0.255.6/32 40 - rt2 -
|
||||
10.0.255.7/32 40 - rt3 -
|
||||
10.0.255.8/32 50 - rt2 -
|
||||
- rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
10.0.255.5/32 30 - rt3 16050
|
||||
10.0.255.6/32 40 - rt2 16060
|
||||
10.0.255.7/32 40 - rt3 16070
|
||||
10.0.255.8/32 50 - rt2 16080
|
||||
- rt3 16080
|
||||
|
||||
test# test isis topology 6 root rt1 spf ipv4-only
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -239,20 +246,21 @@ rt7 TE-IS 50 rt2 - rt5(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
- rt3 -
|
||||
10.0.255.5/32 50 - rt2 -
|
||||
- rt3 -
|
||||
10.0.255.6/32 40 - rt2 -
|
||||
- rt3 -
|
||||
10.0.255.7/32 60 - rt2 -
|
||||
- rt3 -
|
||||
10.0.255.8/32 50 - rt2 -
|
||||
- rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
- rt3 16040
|
||||
10.0.255.5/32 50 - rt2 16050
|
||||
- rt3 16050
|
||||
10.0.255.6/32 40 - rt2 16060
|
||||
- rt3 16060
|
||||
10.0.255.7/32 60 - rt2 16070
|
||||
- rt3 16070
|
||||
10.0.255.8/32 50 - rt2 16080
|
||||
- rt3 16080
|
||||
|
||||
test# test isis topology 7 root rt1 spf ipv4-only
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -287,19 +295,20 @@ rt12 TE-IS 50 rt4 - rt9(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------
|
||||
10.0.255.2/32 40 - rt4 -
|
||||
10.0.255.3/32 50 - rt4 -
|
||||
10.0.255.4/32 20 - rt4 -
|
||||
10.0.255.5/32 30 - rt4 -
|
||||
10.0.255.6/32 40 - rt4 -
|
||||
10.0.255.7/32 30 - rt4 -
|
||||
10.0.255.8/32 40 - rt4 -
|
||||
10.0.255.9/32 50 - rt4 -
|
||||
10.0.255.10/32 50 - rt4 -
|
||||
10.0.255.11/32 50 - rt4 -
|
||||
10.0.255.12/32 60 - rt4 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 40 - rt4 16020
|
||||
10.0.255.3/32 50 - rt4 16030
|
||||
10.0.255.4/32 20 - rt4 implicit-null
|
||||
10.0.255.5/32 30 - rt4 16050
|
||||
10.0.255.6/32 40 - rt4 16060
|
||||
10.0.255.7/32 30 - rt4 16070
|
||||
10.0.255.8/32 40 - rt4 16080
|
||||
10.0.255.9/32 50 - rt4 16090
|
||||
10.0.255.10/32 50 - rt4 16100
|
||||
10.0.255.11/32 50 - rt4 16110
|
||||
10.0.255.12/32 60 - rt4 16120
|
||||
|
||||
test# test isis topology 8 root rt1 spf ipv4-only
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -333,19 +342,20 @@ rt12 TE-IS 50 rt2 - rt9(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 30 - rt2 -
|
||||
10.0.255.4/32 20 - rt4 -
|
||||
10.0.255.5/32 30 - rt2 -
|
||||
10.0.255.6/32 40 - rt2 -
|
||||
10.0.255.7/32 30 - rt4 -
|
||||
10.0.255.8/32 40 - rt2 -
|
||||
10.0.255.9/32 50 - rt2 -
|
||||
10.0.255.10/32 40 - rt4 -
|
||||
10.0.255.11/32 50 - rt2 -
|
||||
10.0.255.12/32 60 - rt2 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 30 - rt2 16030
|
||||
10.0.255.4/32 20 - rt4 implicit-null
|
||||
10.0.255.5/32 30 - rt2 16050
|
||||
10.0.255.6/32 40 - rt2 16060
|
||||
10.0.255.7/32 30 - rt4 16070
|
||||
10.0.255.8/32 40 - rt2 16080
|
||||
10.0.255.9/32 50 - rt2 16090
|
||||
10.0.255.10/32 40 - rt4 16100
|
||||
10.0.255.11/32 50 - rt2 16110
|
||||
10.0.255.12/32 60 - rt2 16120
|
||||
|
||||
test# test isis topology 9 root rt1 spf
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -374,16 +384,17 @@ rt8 TE-IS 50 rt2 - rt4(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
10.0.255.5/32 40 - rt2 -
|
||||
10.0.255.6/32 60 - rt2 -
|
||||
10.0.255.7/32 60 - rt2 -
|
||||
10.0.255.8/32 60 - rt2 -
|
||||
10.0.255.9/32 50 - rt2 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
10.0.255.5/32 40 - rt2 16050
|
||||
10.0.255.6/32 60 - rt2 16060
|
||||
10.0.255.7/32 60 - rt2 16070
|
||||
10.0.255.8/32 60 - rt2 16080
|
||||
10.0.255.9/32 50 - rt2 16090
|
||||
|
||||
IS-IS paths to level-1 routers that speak IPv6
|
||||
Vertex Type Metric Next-Hop Interface Parent
|
||||
@ -411,16 +422,17 @@ rt8 TE-IS 50 rt2 - rt4(4)
|
||||
|
||||
IS-IS L1 IPv6 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-------------------------------------------------------
|
||||
2001:db8::2/128 20 - rt2 -
|
||||
2001:db8::3/128 20 - rt3 -
|
||||
2001:db8::4/128 30 - rt2 -
|
||||
2001:db8::5/128 40 - rt2 -
|
||||
2001:db8::6/128 60 - rt2 -
|
||||
2001:db8::7/128 60 - rt2 -
|
||||
2001:db8::8/128 60 - rt2 -
|
||||
2001:db8::9/128 50 - rt2 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------------
|
||||
2001:db8::1/128 0 - - -
|
||||
2001:db8::2/128 20 - rt2 implicit-null
|
||||
2001:db8::3/128 20 - rt3 implicit-null
|
||||
2001:db8::4/128 30 - rt2 16041
|
||||
2001:db8::5/128 40 - rt2 16051
|
||||
2001:db8::6/128 60 - rt2 16061
|
||||
2001:db8::7/128 60 - rt2 16071
|
||||
2001:db8::8/128 60 - rt2 16081
|
||||
2001:db8::9/128 50 - rt2 16091
|
||||
|
||||
test# test isis topology 10 root rt1 spf
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -444,15 +456,16 @@ rt8 TE-IS 30 rt2 - rt5(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 30 - rt3 -
|
||||
10.0.255.4/32 30 - rt4 -
|
||||
10.0.255.5/32 30 - rt2 -
|
||||
10.0.255.6/32 40 - rt3 -
|
||||
10.0.255.7/32 40 - rt4 -
|
||||
10.0.255.8/32 40 - rt2 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 30 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt4 implicit-null
|
||||
10.0.255.5/32 30 - rt2 16050
|
||||
10.0.255.6/32 40 - rt3 20060
|
||||
10.0.255.7/32 40 - rt4 16070
|
||||
10.0.255.8/32 40 - rt2 16080
|
||||
|
||||
IS-IS paths to level-1 routers that speak IPv6
|
||||
Vertex Type Metric Next-Hop Interface Parent
|
||||
@ -475,15 +488,16 @@ rt8 TE-IS 30 rt2 - rt5(4)
|
||||
|
||||
IS-IS L1 IPv6 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-------------------------------------------------------
|
||||
2001:db8::2/128 20 - rt2 -
|
||||
2001:db8::3/128 30 - rt3 -
|
||||
2001:db8::4/128 30 - rt4 -
|
||||
2001:db8::5/128 30 - rt2 -
|
||||
2001:db8::6/128 40 - rt3 -
|
||||
2001:db8::7/128 40 - rt4 -
|
||||
2001:db8::8/128 40 - rt2 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------------
|
||||
2001:db8::1/128 0 - - -
|
||||
2001:db8::2/128 20 - rt2 implicit-null
|
||||
2001:db8::3/128 30 - rt3 implicit-null
|
||||
2001:db8::4/128 30 - rt4 implicit-null
|
||||
2001:db8::5/128 30 - rt2 16051
|
||||
2001:db8::6/128 40 - rt3 20061
|
||||
2001:db8::7/128 40 - rt4 16071
|
||||
2001:db8::8/128 40 - rt2 16081
|
||||
|
||||
test# test isis topology 11 root rt1 spf
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -506,14 +520,15 @@ rt6 TE-IS 30 rt2 - rt4(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
10.0.255.5/32 30 - rt3 -
|
||||
10.0.255.6/32 40 - rt2 -
|
||||
- rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
10.0.255.5/32 30 - rt3 16050
|
||||
10.0.255.6/32 40 - rt2 16060
|
||||
- rt3 16060
|
||||
|
||||
IS-IS paths to level-1 routers that speak IPv6
|
||||
Vertex Type Metric Next-Hop Interface Parent
|
||||
@ -535,14 +550,15 @@ rt6 TE-IS 30 rt2 - rt4(4)
|
||||
|
||||
IS-IS L1 IPv6 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-------------------------------------------------------
|
||||
2001:db8::2/128 20 - rt2 -
|
||||
2001:db8::3/128 20 - rt3 -
|
||||
2001:db8::4/128 30 - rt2 -
|
||||
2001:db8::5/128 30 - rt3 -
|
||||
2001:db8::6/128 40 - rt2 -
|
||||
- rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------------
|
||||
2001:db8::1/128 0 - - -
|
||||
2001:db8::2/128 20 - rt2 implicit-null
|
||||
2001:db8::3/128 20 - rt3 implicit-null
|
||||
2001:db8::4/128 30 - rt2 16041
|
||||
2001:db8::5/128 30 - rt3 16051
|
||||
2001:db8::6/128 40 - rt2 16061
|
||||
- rt3 16061
|
||||
|
||||
test# test isis topology 12 root rt1 spf ipv4-only
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -570,17 +586,18 @@ rt10 TE-IS 50 rt2 - rt8(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
10.0.255.5/32 30 - rt3 -
|
||||
10.0.255.6/32 40 - rt2 -
|
||||
10.0.255.7/32 40 - rt3 -
|
||||
10.0.255.8/32 50 - rt2 -
|
||||
10.0.255.9/32 50 - rt3 -
|
||||
10.0.255.10/32 60 - rt2 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
10.0.255.5/32 30 - rt3 16050
|
||||
10.0.255.6/32 40 - rt2 16060
|
||||
10.0.255.7/32 40 - rt3 16070
|
||||
10.0.255.8/32 50 - rt2 16080
|
||||
10.0.255.9/32 50 - rt3 16090
|
||||
10.0.255.10/32 60 - rt2 16100
|
||||
|
||||
test# test isis topology 13 root rt1 spf ipv4-only
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -605,15 +622,16 @@ rt7 TE-IS 30 rt3 - rt5(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
- rt3 -
|
||||
10.0.255.5/32 30 - rt3 -
|
||||
10.0.255.6/32 30 - rt3 -
|
||||
10.0.255.7/32 40 - rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
- rt3 16040
|
||||
10.0.255.5/32 30 - rt3 16050
|
||||
10.0.255.6/32 30 - rt3 16060
|
||||
10.0.255.7/32 40 - rt3 16070
|
||||
|
||||
test#
|
||||
test# test isis topology 4 root rt1 reverse-spf ipv4-only
|
||||
@ -638,15 +656,16 @@ rt8 TE-IS 40 rt2 - rt6(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.2/32 20 - rt2 -
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.4/32 30 - rt2 -
|
||||
10.0.255.5/32 30 - rt3 -
|
||||
10.0.255.6/32 40 - rt2 -
|
||||
10.0.255.7/32 40 - rt3 -
|
||||
10.0.255.8/32 50 - rt2 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.2/32 20 - rt2 implicit-null
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.4/32 30 - rt2 16040
|
||||
10.0.255.5/32 30 - rt3 16050
|
||||
10.0.255.6/32 40 - rt2 16060
|
||||
10.0.255.7/32 40 - rt3 16070
|
||||
10.0.255.8/32 50 - rt2 16080
|
||||
|
||||
test# test isis topology 11 root rt1 reverse-spf
|
||||
IS-IS paths to level-1 routers that speak IP
|
||||
@ -668,11 +687,12 @@ rt6 TE-IS 30 rt3 - rt4(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.3/32 20 - rt3 -
|
||||
10.0.255.5/32 30 - rt3 -
|
||||
10.0.255.6/32 40 - rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 0 - - -
|
||||
10.0.255.3/32 20 - rt3 implicit-null
|
||||
10.0.255.5/32 30 - rt3 16050
|
||||
10.0.255.6/32 40 - rt3 16060
|
||||
|
||||
IS-IS paths to level-1 routers that speak IPv6
|
||||
Vertex Type Metric Next-Hop Interface Parent
|
||||
@ -693,11 +713,12 @@ rt6 TE-IS 30 rt3 - rt4(4)
|
||||
|
||||
IS-IS L1 IPv6 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-------------------------------------------------------
|
||||
2001:db8::3/128 20 - rt3 -
|
||||
2001:db8::5/128 30 - rt3 -
|
||||
2001:db8::6/128 40 - rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------------
|
||||
2001:db8::1/128 0 - - -
|
||||
2001:db8::3/128 20 - rt3 implicit-null
|
||||
2001:db8::5/128 30 - rt3 16051
|
||||
2001:db8::6/128 40 - rt3 16061
|
||||
|
||||
test#
|
||||
test# test isis topology 1 root rt1 ti-lfa system-id rt2
|
||||
@ -996,7 +1017,7 @@ IS-IS L1 IPv4 routing table:
|
||||
-----------------------------------------------------
|
||||
10.0.255.1/32 40 - rt6 16040
|
||||
10.0.255.2/32 55 - rt6 16040
|
||||
10.0.255.4/32 30 - rt6 -
|
||||
10.0.255.4/32 30 - rt6 16040
|
||||
|
||||
P-space (self):
|
||||
rt6
|
||||
@ -1040,7 +1061,7 @@ IS-IS L1 IPv6 routing table:
|
||||
-------------------------------------------------------
|
||||
2001:db8::1/128 40 - rt6 16041
|
||||
2001:db8::2/128 55 - rt6 16041
|
||||
2001:db8::4/128 30 - rt6 -
|
||||
2001:db8::4/128 30 - rt6 16041
|
||||
|
||||
test# test isis topology 3 root rt5 ti-lfa system-id rt4 ipv4-only
|
||||
P-space (self):
|
||||
@ -1088,10 +1109,10 @@ IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.1/32 50 - rt3 -
|
||||
- rt6 -
|
||||
10.0.255.2/32 40 - rt6 -
|
||||
10.0.255.4/32 30 - rt6 -
|
||||
10.0.255.1/32 50 - rt3 16010
|
||||
- rt6 16010
|
||||
10.0.255.2/32 40 - rt6 16020
|
||||
10.0.255.4/32 30 - rt6 16040
|
||||
|
||||
test# test isis topology 3 root rt5 ti-lfa system-id rt3 ipv4-only
|
||||
P-space (self):
|
||||
@ -1380,13 +1401,13 @@ IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.1/32 60 - rt10 -
|
||||
10.0.255.1/32 60 - rt10 16010
|
||||
10.0.255.2/32 60 - rt12 16090
|
||||
10.0.255.3/32 70 - rt12 16090
|
||||
10.0.255.4/32 50 - rt10 -
|
||||
10.0.255.4/32 50 - rt10 16040
|
||||
10.0.255.5/32 50 - rt12 16090
|
||||
10.0.255.6/32 60 - rt12 16090
|
||||
10.0.255.7/32 40 - rt10 -
|
||||
10.0.255.7/32 40 - rt10 16070
|
||||
10.0.255.8/32 40 - rt12 16090
|
||||
|
||||
test# test isis topology 7 root rt6 ti-lfa system-id rt5 ipv4-only
|
||||
@ -1463,14 +1484,14 @@ IS-IS L1 IPv4 routing table:
|
||||
10.0.255.1/32 60 - rt3 16020
|
||||
10.0.255.4/32 50 - rt3 16020
|
||||
10.0.255.5/32 40 - rt3 16020
|
||||
10.0.255.7/32 60 - rt9 -
|
||||
- rt3 -
|
||||
10.0.255.8/32 50 - rt9 -
|
||||
- rt3 -
|
||||
10.0.255.10/32 70 - rt9 -
|
||||
- rt3 -
|
||||
10.0.255.11/32 60 - rt9 -
|
||||
- rt3 -
|
||||
10.0.255.7/32 60 - rt9 16070
|
||||
- rt3 16070
|
||||
10.0.255.8/32 50 - rt9 16080
|
||||
- rt3 16080
|
||||
10.0.255.10/32 70 - rt9 16100
|
||||
- rt3 16100
|
||||
10.0.255.11/32 60 - rt9 16110
|
||||
- rt3 16110
|
||||
|
||||
test# test isis topology 8 root rt2 ti-lfa system-id rt1 ipv4-only
|
||||
P-space (self):
|
||||
@ -2322,13 +2343,13 @@ rt6 TE-IS 70 rt3 - rt5(4)
|
||||
|
||||
IS-IS L1 IPv4 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-----------------------------------------------------
|
||||
10.0.255.1/32 60 - rt1 -
|
||||
10.0.255.3/32 60 - rt3 -
|
||||
10.0.255.4/32 80 - rt3 16050
|
||||
10.0.255.5/32 70 - rt3 -
|
||||
10.0.255.6/32 80 - rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
----------------------------------------------------------
|
||||
10.0.255.1/32 60 - rt1 implicit-null
|
||||
10.0.255.3/32 60 - rt3 implicit-null
|
||||
10.0.255.4/32 80 - rt3 16050
|
||||
10.0.255.5/32 70 - rt3 16050
|
||||
10.0.255.6/32 80 - rt3 16060
|
||||
|
||||
P-space (self):
|
||||
|
||||
@ -2368,13 +2389,13 @@ rt6 TE-IS 70 rt3 - rt5(4)
|
||||
|
||||
IS-IS L1 IPv6 routing table:
|
||||
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
-------------------------------------------------------
|
||||
2001:db8::1/128 60 - rt1 -
|
||||
2001:db8::3/128 60 - rt3 -
|
||||
2001:db8::4/128 80 - rt3 16051
|
||||
2001:db8::5/128 70 - rt3 -
|
||||
2001:db8::6/128 80 - rt3 -
|
||||
Prefix Metric Interface Nexthop Label(s)
|
||||
------------------------------------------------------------
|
||||
2001:db8::1/128 60 - rt1 implicit-null
|
||||
2001:db8::3/128 60 - rt3 implicit-null
|
||||
2001:db8::4/128 80 - rt3 16051
|
||||
2001:db8::5/128 70 - rt3 16051
|
||||
2001:db8::6/128 80 - rt3 16061
|
||||
|
||||
test# test isis topology 12 root rt1 ti-lfa system-id rt3 ipv4-only
|
||||
P-space (self):
|
||||
|
Loading…
Reference in New Issue
Block a user