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
|
Show topology IS-IS paths to Intermediate Systems, globally, in area
|
||||||
(level-1) or domain (level-2).
|
(level-1) or domain (level-2).
|
||||||
|
|
||||||
.. index:: 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] [backup]
|
.. clicmd:: show isis route [level-1|level-2] [prefix-sid|backup]
|
||||||
|
|
||||||
Show the ISIS routing table, as determined by the most recent SPF
|
Show the ISIS routing table, as determined by the most recent SPF
|
||||||
calculation.
|
calculation.
|
||||||
|
@ -180,23 +180,6 @@ bool isis_lfa_excise_node_check(const struct isis_spftree *spftree,
|
|||||||
return false;
|
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 {
|
struct tilfa_find_pnode_prefix_sid_args {
|
||||||
uint32_t sid_index;
|
uint32_t sid_index;
|
||||||
};
|
};
|
||||||
@ -313,7 +296,7 @@ tilfa_compute_label_stack(struct lspdb_head *lspdb,
|
|||||||
|
|
||||||
switch (sid->type) {
|
switch (sid->type) {
|
||||||
case TILFA_SID_PREFIX:
|
case TILFA_SID_PREFIX:
|
||||||
srgb = tilfa_find_srgb(lspdb, sadj->id);
|
srgb = isis_sr_find_srgb(lspdb, sadj->id);
|
||||||
if (!srgb) {
|
if (!srgb) {
|
||||||
zlog_warn("%s: SRGB not found for node %s",
|
zlog_warn("%s: SRGB not found for node %s",
|
||||||
__func__,
|
__func__,
|
||||||
@ -704,7 +687,7 @@ int isis_lfa_check(struct isis_spftree *spftree_pc, struct isis_vertex *vertex)
|
|||||||
struct route_table *route_table;
|
struct route_table *route_table;
|
||||||
|
|
||||||
route_table = spftree_pc->lfa.old.spftree->route_table_backup;
|
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)
|
if (IS_DEBUG_TILFA)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"ISIS-TI-LFA: %s %s already covered by node protection",
|
"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->family = family;
|
||||||
nexthop->ifindex = ifindex;
|
nexthop->ifindex = ifindex;
|
||||||
nexthop->ip = *ip;
|
nexthop->ip = *ip;
|
||||||
isis_sr_nexthop_reset(&nexthop->sr);
|
|
||||||
|
|
||||||
return nexthop;
|
return nexthop;
|
||||||
}
|
}
|
||||||
@ -117,7 +116,7 @@ static struct isis_nexthop *nexthoplookup(struct list *nexthops, int family,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void adjinfo2nexthop(int family, struct list *nexthops,
|
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 mpls_label_stack *label_stack)
|
||||||
{
|
{
|
||||||
struct isis_nexthop *nh;
|
struct isis_nexthop *nh;
|
||||||
@ -134,6 +133,8 @@ void adjinfo2nexthop(int family, struct list *nexthops,
|
|||||||
AF_INET, &ip,
|
AF_INET, &ip,
|
||||||
adj->circuit->interface->ifindex);
|
adj->circuit->interface->ifindex);
|
||||||
memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid));
|
memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid));
|
||||||
|
if (sr)
|
||||||
|
nh->sr = *sr;
|
||||||
nh->label_stack = label_stack;
|
nh->label_stack = label_stack;
|
||||||
listnode_add(nexthops, nh);
|
listnode_add(nexthops, nh);
|
||||||
break;
|
break;
|
||||||
@ -150,6 +151,8 @@ void adjinfo2nexthop(int family, struct list *nexthops,
|
|||||||
AF_INET6, &ip,
|
AF_INET6, &ip,
|
||||||
adj->circuit->interface->ifindex);
|
adj->circuit->interface->ifindex);
|
||||||
memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid));
|
memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid));
|
||||||
|
if (sr)
|
||||||
|
nh->sr = *sr;
|
||||||
nh->label_stack = label_stack;
|
nh->label_stack = label_stack;
|
||||||
listnode_add(nexthops, nh);
|
listnode_add(nexthops, nh);
|
||||||
break;
|
break;
|
||||||
@ -165,22 +168,22 @@ void adjinfo2nexthop(int family, struct list *nexthops,
|
|||||||
|
|
||||||
static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo,
|
static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo,
|
||||||
const uint8_t *sysid,
|
const uint8_t *sysid,
|
||||||
|
struct isis_sr_psid_info *sr,
|
||||||
struct mpls_label_stack *label_stack)
|
struct mpls_label_stack *label_stack)
|
||||||
{
|
{
|
||||||
struct isis_nexthop *nh;
|
struct isis_nexthop *nh;
|
||||||
|
|
||||||
nh = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop));
|
nh = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop));
|
||||||
memcpy(nh->sysid, sysid, sizeof(nh->sysid));
|
memcpy(nh->sysid, sysid, sizeof(nh->sysid));
|
||||||
isis_sr_nexthop_reset(&nh->sr);
|
nh->sr = *sr;
|
||||||
nh->label_stack = label_stack;
|
nh->label_stack = label_stack;
|
||||||
listnode_add(rinfo->nexthops, nh);
|
listnode_add(rinfo->nexthops, nh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
static struct isis_route_info *
|
||||||
struct prefix_ipv6 *src_p,
|
isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p,
|
||||||
uint32_t cost,
|
uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr,
|
||||||
uint32_t depth,
|
struct list *adjacencies)
|
||||||
struct list *adjacencies)
|
|
||||||
{
|
{
|
||||||
struct isis_route_info *rinfo;
|
struct isis_route_info *rinfo;
|
||||||
struct isis_vertex_adj *vadj;
|
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)) {
|
for (ALL_LIST_ELEMENTS_RO(adjacencies, node, vadj)) {
|
||||||
struct isis_spf_adj *sadj = vadj->sadj;
|
struct isis_spf_adj *sadj = vadj->sadj;
|
||||||
struct isis_adjacency *adj = sadj->adj;
|
struct isis_adjacency *adj = sadj->adj;
|
||||||
|
struct isis_sr_psid_info *sr = &vadj->sr;
|
||||||
struct mpls_label_stack *label_stack = vadj->label_stack;
|
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.
|
* environment.
|
||||||
*/
|
*/
|
||||||
if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) {
|
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);
|
label_stack);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -227,12 +231,13 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
|||||||
prefix->family);
|
prefix->family);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
adjinfo2nexthop(prefix->family, rinfo->nexthops, adj,
|
adjinfo2nexthop(prefix->family, rinfo->nexthops, adj, sr,
|
||||||
label_stack);
|
label_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
rinfo->cost = cost;
|
rinfo->cost = cost;
|
||||||
rinfo->depth = depth;
|
rinfo->depth = depth;
|
||||||
|
rinfo->sr = *sr;
|
||||||
|
|
||||||
return rinfo;
|
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);
|
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,
|
static int isis_route_info_same(struct isis_route_info *new,
|
||||||
struct isis_route_info *old, char *buf,
|
struct isis_route_info *old, char *buf,
|
||||||
size_t buf_size)
|
size_t buf_size)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct isis_nexthop *nexthop;
|
struct isis_nexthop *new_nh, *old_nh;
|
||||||
|
|
||||||
if (new->cost != old->cost) {
|
if (new->cost != old->cost) {
|
||||||
if (buf)
|
if (buf)
|
||||||
@ -275,6 +296,12 @@ static int isis_route_info_same(struct isis_route_info *new,
|
|||||||
return 0;
|
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 (new->nexthops->count != old->nexthops->count) {
|
||||||
if (buf)
|
if (buf)
|
||||||
snprintf(buf, buf_size, "nhops num (old: %u, new: %u)",
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, nexthop)) {
|
for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, new_nh)) {
|
||||||
if (!nexthoplookup(old->nexthops, nexthop->family, &nexthop->ip,
|
old_nh = nexthoplookup(old->nexthops, new_nh->family,
|
||||||
nexthop->ifindex)) {
|
&new_nh->ip, new_nh->ifindex);
|
||||||
|
if (!old_nh) {
|
||||||
if (buf)
|
if (buf)
|
||||||
snprintf(buf, buf_size,
|
snprintf(buf, buf_size,
|
||||||
"new nhop"); /* TODO: print nhop */
|
"new nhop"); /* TODO: print nhop */
|
||||||
return 0;
|
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 */
|
/* 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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct isis_route_info *isis_route_create(struct prefix *prefix,
|
struct isis_route_info *
|
||||||
struct prefix_ipv6 *src_p,
|
isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p,
|
||||||
uint32_t cost,
|
uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr,
|
||||||
uint32_t depth,
|
struct list *adjacencies, struct isis_area *area,
|
||||||
struct list *adjacencies,
|
struct route_table *table)
|
||||||
struct isis_area *area,
|
|
||||||
struct route_table *table)
|
|
||||||
{
|
{
|
||||||
struct route_node *route_node;
|
struct route_node *route_node;
|
||||||
struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL;
|
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)
|
if (!table)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
rinfo_new = isis_route_info_new(prefix, src_p, cost,
|
rinfo_new = isis_route_info_new(prefix, src_p, cost, depth, sr,
|
||||||
depth, adjacencies);
|
adjacencies);
|
||||||
route_node = srcdest_rnode_get(table, prefix, src_p);
|
route_node = srcdest_rnode_get(table, prefix, src_p);
|
||||||
|
|
||||||
rinfo_old = route_node->info;
|
rinfo_old = route_node->info;
|
||||||
@ -351,6 +382,7 @@ struct isis_route_info *isis_route_create(struct prefix *prefix,
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"ISIS-Rte (%s): route changed: %pFX, change: %s",
|
"ISIS-Rte (%s): route changed: %pFX, change: %s",
|
||||||
area->area_tag, prefix, change_buf);
|
area->area_tag, prefix, change_buf);
|
||||||
|
rinfo_new->sr_previous = rinfo_old->sr;
|
||||||
isis_route_info_delete(rinfo_old);
|
isis_route_info_delete(rinfo_old);
|
||||||
route_info = rinfo_new;
|
route_info = rinfo_new;
|
||||||
UNSET_FLAG(route_info->flag,
|
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))
|
if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
|
||||||
return;
|
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);
|
hook_call(isis_route_update_hook, area, prefix, route_info);
|
||||||
|
|
||||||
SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
|
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))
|
if (!CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
|
||||||
return;
|
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);
|
hook_call(isis_route_update_hook, area, prefix, route_info);
|
||||||
|
|
||||||
UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
|
UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
|
||||||
|
@ -32,7 +32,7 @@ struct isis_nexthop {
|
|||||||
int family;
|
int family;
|
||||||
union g_addr ip;
|
union g_addr ip;
|
||||||
uint8_t sysid[ISIS_SYS_ID_LEN];
|
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||||
struct sr_nexthop_info sr;
|
struct isis_sr_psid_info sr;
|
||||||
struct mpls_label_stack *label_stack;
|
struct mpls_label_stack *label_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,6 +43,8 @@ struct isis_route_info {
|
|||||||
uint8_t flag;
|
uint8_t flag;
|
||||||
uint32_t cost;
|
uint32_t cost;
|
||||||
uint32_t depth;
|
uint32_t depth;
|
||||||
|
struct isis_sr_psid_info sr;
|
||||||
|
struct isis_sr_psid_info sr_previous;
|
||||||
struct list *nexthops;
|
struct list *nexthops;
|
||||||
struct isis_route_info *backup;
|
struct isis_route_info *backup;
|
||||||
};
|
};
|
||||||
@ -54,15 +56,13 @@ DECLARE_HOOK(isis_route_update_hook,
|
|||||||
|
|
||||||
void isis_nexthop_delete(struct isis_nexthop *nexthop);
|
void isis_nexthop_delete(struct isis_nexthop *nexthop);
|
||||||
void adjinfo2nexthop(int family, struct list *nexthops,
|
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 mpls_label_stack *label_stack);
|
||||||
struct isis_route_info *isis_route_create(struct prefix *prefix,
|
struct isis_route_info *
|
||||||
struct prefix_ipv6 *src_p,
|
isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p,
|
||||||
uint32_t cost,
|
uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr,
|
||||||
uint32_t depth,
|
struct list *adjacencies, struct isis_area *area,
|
||||||
struct list *adjacencies,
|
struct route_table *table);
|
||||||
struct isis_area *area,
|
|
||||||
struct route_table *table);
|
|
||||||
|
|
||||||
/* Walk the given table and install new routes to zebra and remove old ones.
|
/* Walk the given table and install new routes to zebra and remove old ones.
|
||||||
* route status is tracked using ISIS_ROUTE_FLAG_ACTIVE */
|
* 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)) {
|
if (VTYPE_IP(vertex->type)) {
|
||||||
srcdest2str(&vertex->N.ip.dest,
|
srcdest2str(&vertex->N.ip.p.dest, &vertex->N.ip.p.src, buff,
|
||||||
&vertex->N.ip.src,
|
size);
|
||||||
buff, size);
|
|
||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,13 +214,33 @@ static struct isis_vertex *isis_vertex_new(struct isis_spftree *spftree,
|
|||||||
return vertex;
|
return vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct isis_vertex_adj *isis_vertex_adj_add(struct isis_vertex *vertex,
|
static struct isis_vertex_adj *isis_vertex_adj_add(struct isis_spftree *spftree,
|
||||||
struct isis_spf_adj *sadj)
|
struct isis_vertex *vertex,
|
||||||
|
struct isis_spf_adj *sadj,
|
||||||
|
struct isis_prefix_sid *psid)
|
||||||
{
|
{
|
||||||
struct isis_vertex_adj *vadj;
|
struct isis_vertex_adj *vadj;
|
||||||
|
|
||||||
vadj = XCALLOC(MTYPE_ISIS_VERTEX_ADJ, sizeof(*vadj));
|
vadj = XCALLOC(MTYPE_ISIS_VERTEX_ADJ, sizeof(*vadj));
|
||||||
vadj->sadj = sadj;
|
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);
|
listnode_add(vertex->Adj_N, vadj);
|
||||||
|
|
||||||
return 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
|
* 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,
|
static struct isis_vertex *
|
||||||
enum vertextype vtype, void *id,
|
isis_spf_add2tent(struct isis_spftree *spftree, enum vertextype vtype, void *id,
|
||||||
uint32_t cost, int depth,
|
uint32_t cost, int depth, struct isis_spf_adj *sadj,
|
||||||
struct isis_spf_adj *sadj,
|
struct isis_prefix_sid *psid, struct isis_vertex *parent)
|
||||||
struct isis_vertex *parent)
|
|
||||||
{
|
{
|
||||||
struct isis_vertex *vertex;
|
struct isis_vertex *vertex;
|
||||||
struct listnode *node;
|
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 = isis_vertex_new(spftree, id, vtype);
|
||||||
vertex->d_N = cost;
|
vertex->d_N = cost;
|
||||||
vertex->depth = depth;
|
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) {
|
if (parent) {
|
||||||
listnode_add(vertex->parents, 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;
|
struct isis_vertex_adj *parent_vadj;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, 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) {
|
} else if (sadj) {
|
||||||
isis_vertex_adj_add(vertex, sadj);
|
isis_vertex_adj_add(spftree, vertex, sadj, psid);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EXTREME_DEBUG
|
#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,
|
static void isis_spf_add_local(struct isis_spftree *spftree,
|
||||||
enum vertextype vtype, void *id,
|
enum vertextype vtype, void *id,
|
||||||
struct isis_spf_adj *sadj, uint32_t cost,
|
struct isis_spf_adj *sadj, uint32_t cost,
|
||||||
|
struct isis_prefix_sid *psid,
|
||||||
struct isis_vertex *parent)
|
struct isis_vertex *parent)
|
||||||
{
|
{
|
||||||
struct isis_vertex *vertex;
|
struct isis_vertex *vertex;
|
||||||
@ -538,7 +568,8 @@ static void isis_spf_add_local(struct isis_spftree *spftree,
|
|||||||
/* C.2.5 c) */
|
/* C.2.5 c) */
|
||||||
if (vertex->d_N == cost) {
|
if (vertex->d_N == cost) {
|
||||||
if (sadj)
|
if (sadj)
|
||||||
isis_vertex_adj_add(vertex, sadj);
|
isis_vertex_adj_add(spftree, vertex, sadj,
|
||||||
|
psid);
|
||||||
/* d) */
|
/* d) */
|
||||||
if (!CHECK_FLAG(spftree->flags,
|
if (!CHECK_FLAG(spftree->flags,
|
||||||
F_SPFTREE_NO_ADJACENCIES)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
|
static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
|
||||||
void *id, uint32_t dist, uint16_t depth,
|
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;
|
struct isis_vertex *vertex;
|
||||||
#ifdef EXTREME_DEBUG
|
#ifdef EXTREME_DEBUG
|
||||||
@ -628,8 +659,9 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
|
|||||||
parent_vadj))
|
parent_vadj))
|
||||||
if (!isis_vertex_adj_exists(spftree, vertex,
|
if (!isis_vertex_adj_exists(spftree, vertex,
|
||||||
parent_vadj->sadj))
|
parent_vadj->sadj))
|
||||||
isis_vertex_adj_add(vertex,
|
isis_vertex_adj_add(spftree, vertex,
|
||||||
parent_vadj->sadj);
|
parent_vadj->sadj,
|
||||||
|
psid);
|
||||||
if (CHECK_FLAG(spftree->flags,
|
if (CHECK_FLAG(spftree->flags,
|
||||||
F_SPFTREE_HOPCOUNT_METRIC))
|
F_SPFTREE_HOPCOUNT_METRIC))
|
||||||
vertex_update_firsthops(vertex, parent);
|
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"));
|
(parent ? print_sys_hostname(parent->N.id) : "null"));
|
||||||
#endif /* EXTREME_DEBUG */
|
#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;
|
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];
|
static const uint8_t null_sysid[ISIS_SYS_ID_LEN];
|
||||||
struct isis_mt_router_info *mt_router_info = NULL;
|
struct isis_mt_router_info *mt_router_info = NULL;
|
||||||
struct prefix_pair ip_info;
|
struct prefix_pair ip_info;
|
||||||
|
bool has_valid_psid;
|
||||||
|
|
||||||
if (isis_lfa_excise_node_check(spftree, lsp->hdr.lsp_id)) {
|
if (isis_lfa_excise_node_check(spftree, lsp->hdr.lsp_id)) {
|
||||||
if (IS_DEBUG_TILFA)
|
if (IS_DEBUG_TILFA)
|
||||||
@ -739,7 +772,7 @@ lspfragloop:
|
|||||||
LSP_PSEUDO_ID(r->id)
|
LSP_PSEUDO_ID(r->id)
|
||||||
? VTYPE_PSEUDO_IS
|
? VTYPE_PSEUDO_IS
|
||||||
: VTYPE_NONPSEUDO_IS,
|
: VTYPE_NONPSEUDO_IS,
|
||||||
(void *)r->id, dist, depth + 1,
|
(void *)r->id, dist, depth + 1, NULL,
|
||||||
parent);
|
parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -773,7 +806,8 @@ lspfragloop:
|
|||||||
process_N(spftree,
|
process_N(spftree,
|
||||||
LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS
|
LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS
|
||||||
: VTYPE_NONPSEUDO_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.u.prefix4 = r->prefix.prefix;
|
||||||
ip_info.dest.prefixlen = r->prefix.prefixlen;
|
ip_info.dest.prefixlen = r->prefix.prefixlen;
|
||||||
process_N(spftree, vtype, &ip_info,
|
process_N(spftree, vtype, &ip_info,
|
||||||
dist, depth + 1, parent);
|
dist, depth + 1, NULL, parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -823,8 +857,34 @@ lspfragloop:
|
|||||||
dist = cost + r->metric;
|
dist = cost + r->metric;
|
||||||
ip_info.dest.u.prefix4 = r->prefix.prefix;
|
ip_info.dest.u.prefix4 = r->prefix.prefix;
|
||||||
ip_info.dest.prefixlen = r->prefix.prefixlen;
|
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;
|
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 isis_vertex *parent = args->parent;
|
||||||
struct prefix_pair ip_info;
|
struct prefix_pair ip_info;
|
||||||
enum vertextype vtype;
|
enum vertextype vtype;
|
||||||
|
bool has_valid_psid = false;
|
||||||
|
|
||||||
if (external)
|
if (external)
|
||||||
return LSP_ITER_CONTINUE;
|
return LSP_ITER_CONTINUE;
|
||||||
@ -936,7 +1023,30 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix,
|
|||||||
else
|
else
|
||||||
vtype = VTYPE_IP6REACH_INTERNAL;
|
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;
|
return LSP_ITER_CONTINUE;
|
||||||
}
|
}
|
||||||
@ -985,7 +1095,8 @@ static void isis_spf_preload_tent(struct isis_spftree *spftree,
|
|||||||
F_ISIS_SPF_ADJ_OLDMETRIC)
|
F_ISIS_SPF_ADJ_OLDMETRIC)
|
||||||
? VTYPE_NONPSEUDO_IS
|
? VTYPE_NONPSEUDO_IS
|
||||||
: VTYPE_NONPSEUDO_TE_IS,
|
: VTYPE_NONPSEUDO_TE_IS,
|
||||||
sadj->id, sadj, metric, parent);
|
sadj->id, sadj, metric, NULL,
|
||||||
|
parent);
|
||||||
} else if (sadj->lan.lsp_pseudo) {
|
} else if (sadj->lan.lsp_pseudo) {
|
||||||
isis_spf_process_lsp(spftree, sadj->lan.lsp_pseudo,
|
isis_spf_process_lsp(spftree, sadj->lan.lsp_pseudo,
|
||||||
metric, 0, spftree->sysid, parent);
|
metric, 0, spftree->sysid, parent);
|
||||||
@ -1291,8 +1402,9 @@ static void spf_path_process(struct isis_spftree *spftree,
|
|||||||
} else
|
} else
|
||||||
route_table = spftree->route_table;
|
route_table = spftree->route_table;
|
||||||
|
|
||||||
isis_route_create(&vertex->N.ip.dest, &vertex->N.ip.src,
|
isis_route_create(&vertex->N.ip.p.dest,
|
||||||
vertex->d_N, vertex->depth,
|
&vertex->N.ip.p.src, vertex->d_N,
|
||||||
|
vertex->depth, &vertex->N.ip.sr,
|
||||||
vertex->Adj_N, area, route_table);
|
vertex->Adj_N, area, route_table);
|
||||||
} else if (IS_DEBUG_SPF_EVENTS)
|
} else if (IS_DEBUG_SPF_EVENTS)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -1532,8 +1644,6 @@ static int isis_run_spf_cb(struct thread *thread)
|
|||||||
|
|
||||||
isis_area_verify_routes(area);
|
isis_area_verify_routes(area);
|
||||||
|
|
||||||
isis_area_verify_sr(area);
|
|
||||||
|
|
||||||
/* walk all circuits and reset any spf specific flags */
|
/* walk all circuits and reset any spf specific flags */
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct isis_circuit *circuit;
|
struct isis_circuit *circuit;
|
||||||
@ -1824,12 +1934,126 @@ DEFUN(show_isis_topology, show_isis_topology_cmd,
|
|||||||
return CMD_SUCCESS;
|
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,
|
void isis_print_routes(struct vty *vty, struct isis_spftree *spftree,
|
||||||
bool backup)
|
bool prefix_sid, bool backup)
|
||||||
{
|
{
|
||||||
struct route_table *route_table;
|
struct route_table *route_table;
|
||||||
struct ttable *tt;
|
struct ttable *tt;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
|
bool no_adjacencies = false;
|
||||||
const char *tree_id_text = NULL;
|
const char *tree_id_text = NULL;
|
||||||
|
|
||||||
if (!spftree)
|
if (!spftree)
|
||||||
@ -1855,82 +2079,28 @@ void isis_print_routes(struct vty *vty, struct isis_spftree *spftree,
|
|||||||
|
|
||||||
/* Prepare table. */
|
/* Prepare table. */
|
||||||
tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
|
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.cell.rpad = 2;
|
||||||
tt->style.corner = '+';
|
tt->style.corner = '+';
|
||||||
ttable_restyle(tt);
|
ttable_restyle(tt);
|
||||||
ttable_rowseps(tt, 0, BOTTOM, true, '-');
|
ttable_rowseps(tt, 0, BOTTOM, true, '-');
|
||||||
|
|
||||||
|
if (CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES))
|
||||||
|
no_adjacencies = true;
|
||||||
|
|
||||||
route_table =
|
route_table =
|
||||||
(backup) ? spftree->route_table_backup : spftree->route_table;
|
(backup) ? spftree->route_table_backup : spftree->route_table;
|
||||||
for (rn = route_top(route_table); rn; rn = route_next(rn)) {
|
for (rn = route_top(route_table); rn; rn = route_next(rn)) {
|
||||||
struct isis_route_info *rinfo;
|
struct isis_route_info *rinfo;
|
||||||
struct isis_nexthop *nexthop;
|
|
||||||
struct listnode *node;
|
|
||||||
bool first = true;
|
|
||||||
char buf_prefix[BUFSIZ];
|
|
||||||
|
|
||||||
rinfo = rn->info;
|
rinfo = rn->info;
|
||||||
if (!rinfo)
|
if (!rinfo)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
(void)prefix2str(&rn->p, buf_prefix, sizeof(buf_prefix));
|
isis_print_route(tt, &rn->p, rinfo, prefix_sid, no_adjacencies);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dump the generated table. */
|
/* 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,
|
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 listnode *node;
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
@ -1965,19 +2136,19 @@ static void show_isis_route_common(struct vty *vty, int levels,
|
|||||||
isis_print_routes(
|
isis_print_routes(
|
||||||
vty,
|
vty,
|
||||||
area->spftree[SPFTREE_IPV4][level - 1],
|
area->spftree[SPFTREE_IPV4][level - 1],
|
||||||
backup);
|
prefix_sid, backup);
|
||||||
}
|
}
|
||||||
if (area->ipv6_circuits > 0) {
|
if (area->ipv6_circuits > 0) {
|
||||||
isis_print_routes(
|
isis_print_routes(
|
||||||
vty,
|
vty,
|
||||||
area->spftree[SPFTREE_IPV6][level - 1],
|
area->spftree[SPFTREE_IPV6][level - 1],
|
||||||
backup);
|
prefix_sid, backup);
|
||||||
}
|
}
|
||||||
if (isis_area_ipv6_dstsrc_enabled(area)) {
|
if (isis_area_ipv6_dstsrc_enabled(area)) {
|
||||||
isis_print_routes(vty,
|
isis_print_routes(vty,
|
||||||
area->spftree[SPFTREE_DSTSRC]
|
area->spftree[SPFTREE_DSTSRC]
|
||||||
[level - 1],
|
[level - 1],
|
||||||
backup);
|
prefix_sid, backup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1989,13 +2160,14 @@ DEFUN(show_isis_route, show_isis_route_cmd,
|
|||||||
#ifndef FABRICD
|
#ifndef FABRICD
|
||||||
" [<level-1|level-2>]"
|
" [<level-1|level-2>]"
|
||||||
#endif
|
#endif
|
||||||
" [backup]",
|
" [<prefix-sid|backup>]",
|
||||||
SHOW_STR PROTO_HELP VRF_FULL_CMD_HELP_STR
|
SHOW_STR PROTO_HELP VRF_FULL_CMD_HELP_STR
|
||||||
"IS-IS routing table\n"
|
"IS-IS routing table\n"
|
||||||
#ifndef FABRICD
|
#ifndef FABRICD
|
||||||
"level-1 routes\n"
|
"level-1 routes\n"
|
||||||
"level-2 routes\n"
|
"level-2 routes\n"
|
||||||
#endif
|
#endif
|
||||||
|
"Show Prefix-SID information\n"
|
||||||
"Show backup routes\n")
|
"Show backup routes\n")
|
||||||
{
|
{
|
||||||
int levels;
|
int levels;
|
||||||
@ -2003,6 +2175,7 @@ DEFUN(show_isis_route, show_isis_route_cmd,
|
|||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
const char *vrf_name = VRF_DEFAULT_NAME;
|
const char *vrf_name = VRF_DEFAULT_NAME;
|
||||||
bool all_vrf = false;
|
bool all_vrf = false;
|
||||||
|
bool prefix_sid = false;
|
||||||
bool backup = false;
|
bool backup = false;
|
||||||
int idx = 0;
|
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);
|
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))
|
if (argv_find(argv, argc, "backup", &idx))
|
||||||
backup = true;
|
backup = true;
|
||||||
|
|
||||||
@ -2026,12 +2201,13 @@ DEFUN(show_isis_route, show_isis_route_cmd,
|
|||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||||
show_isis_route_common(vty, levels, isis,
|
show_isis_route_common(vty, levels, isis,
|
||||||
backup);
|
prefix_sid, backup);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
isis = isis_lookup_by_vrfname(vrf_name);
|
isis = isis_lookup_by_vrfname(vrf_name);
|
||||||
if (isis != NULL)
|
if (isis != NULL)
|
||||||
show_isis_route_common(vty, levels, isis, backup);
|
show_isis_route_common(vty, levels, isis, prefix_sid,
|
||||||
|
backup);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
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);
|
const char *func, const char *file, int line);
|
||||||
void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree);
|
void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree);
|
||||||
void isis_print_routes(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_init(void);
|
||||||
void isis_spf_print(struct isis_spftree *spftree, struct vty *vty);
|
void isis_spf_print(struct isis_spftree *spftree, struct vty *vty);
|
||||||
void isis_run_spf(struct isis_spftree *spftree);
|
void isis_run_spf(struct isis_spftree *spftree);
|
||||||
|
@ -52,6 +52,7 @@ struct prefix_pair {
|
|||||||
|
|
||||||
struct isis_vertex_adj {
|
struct isis_vertex_adj {
|
||||||
struct isis_spf_adj *sadj;
|
struct isis_spf_adj *sadj;
|
||||||
|
struct isis_sr_psid_info sr;
|
||||||
struct mpls_label_stack *label_stack;
|
struct mpls_label_stack *label_stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,7 +63,10 @@ struct isis_vertex {
|
|||||||
enum vertextype type;
|
enum vertextype type;
|
||||||
union {
|
union {
|
||||||
uint8_t id[ISIS_SYS_ID_LEN + 1];
|
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;
|
} N;
|
||||||
uint32_t d_N; /* d(N) Distance from this IS */
|
uint32_t d_N; /* d(N) Distance from this IS */
|
||||||
uint16_t depth; /* The depth in the imaginary tree */
|
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)) {
|
if (VTYPE_IP(vertex->type)) {
|
||||||
uint32_t key;
|
uint32_t key;
|
||||||
|
|
||||||
key = prefix_hash_key(&vertex->N.ip.dest);
|
key = prefix_hash_key(&vertex->N.ip.p.dest);
|
||||||
key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key);
|
key = jhash_1word(prefix_hash_key(&vertex->N.ip.p.src), key);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,11 +112,12 @@ static bool isis_vertex_queue_hash_cmp(const void *a, const void *b)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (VTYPE_IP(va->type)) {
|
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 false;
|
||||||
|
|
||||||
return prefix_cmp((const struct prefix *)&va->N.ip.src,
|
return prefix_cmp((const struct prefix *)&va->N.ip.p.src,
|
||||||
(const struct prefix *)&vb->N.ip.src) == 0;
|
(const struct prefix *)&vb->N.ip.p.src)
|
||||||
|
== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 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)) {
|
if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) {
|
||||||
memcpy(vertex->N.id, id, ISIS_SYS_ID_LEN + 1);
|
memcpy(vertex->N.id, id, ISIS_SYS_ID_LEN + 1);
|
||||||
} else if (VTYPE_IP(vtype)) {
|
} 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 {
|
} else {
|
||||||
flog_err(EC_LIB_DEVELOPMENT, "Unknown Vertex Type");
|
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
|
#define SRLB_UPPER_BOUND 15999
|
||||||
|
|
||||||
/* Segment Routing Data Base (SRDB) RB-Tree structure */
|
/* 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)
|
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 */
|
/* Segment Routing Local Block allocation */
|
||||||
struct sr_local_block {
|
struct sr_local_block {
|
||||||
bool active;
|
bool active;
|
||||||
@ -106,85 +120,6 @@ struct sr_adjacency {
|
|||||||
struct isis_adjacency *adj;
|
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. */
|
/* SID type. NOTE: these values must be in sync with the YANG module. */
|
||||||
enum sr_sid_value_type {
|
enum sr_sid_value_type {
|
||||||
SR_SID_VALUE_TYPE_INDEX = 0,
|
SR_SID_VALUE_TYPE_INDEX = 0,
|
||||||
@ -235,12 +170,6 @@ struct isis_sr_db {
|
|||||||
/* List of local Adjacency-SIDs. */
|
/* List of local Adjacency-SIDs. */
|
||||||
struct list *adj_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 */
|
/* Management of SRLB & SRGB allocation */
|
||||||
struct sr_local_block srlb;
|
struct sr_local_block srlb;
|
||||||
bool srgb_active;
|
bool srgb_active;
|
||||||
@ -267,6 +196,14 @@ struct isis_sr_db {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Prototypes. */
|
/* 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,
|
extern int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound,
|
||||||
uint32_t upper_bound);
|
uint32_t upper_bound);
|
||||||
extern int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_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,
|
extern void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg,
|
||||||
bool external,
|
bool external,
|
||||||
struct isis_prefix_sid *psid);
|
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,
|
extern void sr_adj_sid_add_single(struct isis_adjacency *adj, int family,
|
||||||
bool backup, struct list *nexthops);
|
bool backup, struct list *nexthops);
|
||||||
extern struct sr_adjacency *isis_sr_adj_sid_find(struct isis_adjacency *adj,
|
extern struct sr_adjacency *isis_sr_adj_sid_find(struct isis_adjacency *adj,
|
||||||
int family,
|
int family,
|
||||||
enum sr_adj_type type);
|
enum sr_adj_type type);
|
||||||
extern void isis_area_delete_backup_adj_sids(struct isis_area *area, int level);
|
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 int isis_sr_start(struct isis_area *area);
|
||||||
extern void isis_sr_stop(struct isis_area *area);
|
extern void isis_sr_stop(struct isis_area *area);
|
||||||
extern void isis_sr_area_init(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(
|
sbuf_push(
|
||||||
buf, indent,
|
buf, indent,
|
||||||
" Segment Routing: I:%s V:%s, Global Block Base: %u Range: %u\n",
|
" Segment Routing: I:%s V:%s, Global Block Base: %u Range: %u\n",
|
||||||
IS_SR_IPV4(router_cap->srgb) ? "1" : "0",
|
IS_SR_IPV4(&router_cap->srgb) ? "1" : "0",
|
||||||
IS_SR_IPV6(router_cap->srgb) ? "1" : "0",
|
IS_SR_IPV6(&router_cap->srgb) ? "1" : "0",
|
||||||
router_cap->srgb.lower_bound,
|
router_cap->srgb.lower_bound,
|
||||||
router_cap->srgb.range_size);
|
router_cap->srgb.range_size);
|
||||||
|
|
||||||
|
@ -138,8 +138,8 @@ struct isis_threeway_adj {
|
|||||||
/* Segment Routing subTLV's as per RFC8667 */
|
/* Segment Routing subTLV's as per RFC8667 */
|
||||||
#define ISIS_SUBTLV_SRGB_FLAG_I 0x80
|
#define ISIS_SUBTLV_SRGB_FLAG_I 0x80
|
||||||
#define ISIS_SUBTLV_SRGB_FLAG_V 0x40
|
#define ISIS_SUBTLV_SRGB_FLAG_V 0x40
|
||||||
#define IS_SR_IPV4(srgb) (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_I)
|
#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_IPV6(srgb) ((srgb)->flags & ISIS_SUBTLV_SRGB_FLAG_V)
|
||||||
#define SUBTLV_SR_BLOCK_SIZE 6
|
#define SUBTLV_SR_BLOCK_SIZE 6
|
||||||
#define SUBTLV_RANGE_INDEX_SIZE 10
|
#define SUBTLV_RANGE_INDEX_SIZE 10
|
||||||
#define SUBTLV_RANGE_LABEL_SIZE 9
|
#define SUBTLV_RANGE_LABEL_SIZE 9
|
||||||
|
@ -155,16 +155,14 @@ static int isis_zebra_link_params(ZAPI_CALLBACK_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum isis_zebra_nexthop_type {
|
enum isis_zebra_nexthop_type {
|
||||||
ISIS_ROUTE_NEXTHOP_MAIN = 0,
|
ISIS_NEXTHOP_MAIN = 0,
|
||||||
ISIS_ROUTE_NEXTHOP_BACKUP,
|
ISIS_NEXTHOP_BACKUP,
|
||||||
ISIS_MPLS_NEXTHOP_MAIN,
|
|
||||||
ISIS_MPLS_NEXTHOP_BACKUP,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops,
|
static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops,
|
||||||
struct zapi_nexthop zapi_nexthops[],
|
struct zapi_nexthop zapi_nexthops[],
|
||||||
enum isis_zebra_nexthop_type type,
|
enum isis_zebra_nexthop_type type,
|
||||||
uint8_t backup_nhs)
|
bool mpls_lsp, uint8_t backup_nhs)
|
||||||
{
|
{
|
||||||
struct isis_nexthop *nexthop;
|
struct isis_nexthop *nexthop;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
@ -210,23 +208,18 @@ static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops,
|
|||||||
|
|
||||||
/* Add MPLS label(s). */
|
/* Add MPLS label(s). */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ISIS_ROUTE_NEXTHOP_MAIN:
|
case ISIS_NEXTHOP_MAIN:
|
||||||
case ISIS_ROUTE_NEXTHOP_BACKUP:
|
if (nexthop->sr.present) {
|
||||||
/*
|
|
||||||
* SR/TI-LFA labels are installed using separate
|
|
||||||
* messages.
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
case ISIS_MPLS_NEXTHOP_MAIN:
|
|
||||||
if (nexthop->sr.label != MPLS_INVALID_LABEL) {
|
|
||||||
api_nh->label_num = 1;
|
api_nh->label_num = 1;
|
||||||
api_nh->labels[0] = nexthop->sr.label;
|
api_nh->labels[0] = nexthop->sr.label;
|
||||||
} else {
|
} else if (mpls_lsp)
|
||||||
api_nh->label_num = 1;
|
/*
|
||||||
api_nh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
|
* Do not use non-SR enabled nexthops to prevent
|
||||||
}
|
* broken LSPs from being formed.
|
||||||
|
*/
|
||||||
|
continue;
|
||||||
break;
|
break;
|
||||||
case ISIS_MPLS_NEXTHOP_BACKUP:
|
case ISIS_NEXTHOP_BACKUP:
|
||||||
if (nexthop->label_stack) {
|
if (nexthop->label_stack) {
|
||||||
api_nh->label_num =
|
api_nh->label_num =
|
||||||
nexthop->label_stack->num_labels;
|
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,
|
nexthop->label_stack->label,
|
||||||
sizeof(mpls_label_t)
|
sizeof(mpls_label_t)
|
||||||
* api_nh->label_num);
|
* 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->label_num = 1;
|
||||||
api_nh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
|
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;
|
struct zapi_route api;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
if (zclient->sock < 0)
|
if (zclient->sock < 0 || list_isempty(route_info->nexthops))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memset(&api, 0, sizeof(api));
|
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) {
|
if (route_info->backup) {
|
||||||
count = isis_zebra_add_nexthops(
|
count = isis_zebra_add_nexthops(
|
||||||
isis, route_info->backup->nexthops, api.backup_nexthops,
|
isis, route_info->backup->nexthops, api.backup_nexthops,
|
||||||
ISIS_ROUTE_NEXTHOP_BACKUP, 0);
|
ISIS_NEXTHOP_BACKUP, false, 0);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
SET_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS);
|
SET_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS);
|
||||||
api.backup_nexthop_num = count;
|
api.backup_nexthop_num = count;
|
||||||
@ -295,7 +292,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix,
|
|||||||
|
|
||||||
/* Add primary nexthops. */
|
/* Add primary nexthops. */
|
||||||
count = isis_zebra_add_nexthops(isis, route_info->nexthops,
|
count = isis_zebra_add_nexthops(isis, route_info->nexthops,
|
||||||
api.nexthops, ISIS_ROUTE_NEXTHOP_MAIN,
|
api.nexthops, ISIS_NEXTHOP_MAIN, false,
|
||||||
count);
|
count);
|
||||||
if (!count)
|
if (!count)
|
||||||
return;
|
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_labels zl;
|
||||||
struct zapi_nexthop *znh;
|
|
||||||
struct interface *ifp;
|
|
||||||
struct isis_route_info *rinfo;
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
sr_debug("ISIS-Sr (%s): update label %u for prefix %pFX",
|
||||||
|
area->area_tag, psid->label, prefix);
|
||||||
|
|
||||||
/* Prepare message. */
|
/* Prepare message. */
|
||||||
memset(&zl, 0, sizeof(zl));
|
memset(&zl, 0, sizeof(zl));
|
||||||
zl.type = ZEBRA_LSP_ISIS_SR;
|
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);
|
ifp = if_lookup_by_name("lo", VRF_DEFAULT);
|
||||||
if (!ifp) {
|
if (!ifp) {
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"%s: couldn't install Prefix-SID %pFX: loopback interface not found",
|
"%s: couldn't install Prefix-SID %pFX: loopback interface not found",
|
||||||
__func__, &srp->prefix);
|
__func__, prefix);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,21 +366,12 @@ static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
|
|||||||
znh->ifindex = ifp->ifindex;
|
znh->ifindex = ifp->ifindex;
|
||||||
znh->label_num = 1;
|
znh->label_num = 1;
|
||||||
znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
|
znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
|
||||||
break;
|
} else {
|
||||||
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;
|
|
||||||
|
|
||||||
/* Add backup nexthops first. */
|
/* Add backup nexthops first. */
|
||||||
if (rinfo->backup) {
|
if (rinfo->backup) {
|
||||||
count = isis_zebra_add_nexthops(
|
count = isis_zebra_add_nexthops(
|
||||||
isis, rinfo->backup->nexthops,
|
area->isis, rinfo->backup->nexthops,
|
||||||
zl.backup_nexthops, ISIS_MPLS_NEXTHOP_BACKUP,
|
zl.backup_nexthops, ISIS_NEXTHOP_BACKUP, true,
|
||||||
0);
|
0);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
|
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. */
|
/* Add primary nexthops. */
|
||||||
count = isis_zebra_add_nexthops(isis, rinfo->nexthops,
|
count = isis_zebra_add_nexthops(area->isis, rinfo->nexthops,
|
||||||
zl.nexthops,
|
zl.nexthops, ISIS_NEXTHOP_MAIN,
|
||||||
ISIS_MPLS_NEXTHOP_MAIN, count);
|
true, count);
|
||||||
if (!count)
|
if (!count)
|
||||||
return;
|
return;
|
||||||
zl.nexthop_num = count;
|
zl.nexthop_num = count;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send message to zebra. */
|
/* 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;
|
struct zapi_labels zl;
|
||||||
|
|
||||||
|
sr_debug("ISIS-Sr (%s): delete label %u for prefix %pFX",
|
||||||
|
area->area_tag, psid->label, prefix);
|
||||||
|
|
||||||
/* Prepare message. */
|
/* Prepare message. */
|
||||||
memset(&zl, 0, sizeof(zl));
|
memset(&zl, 0, sizeof(zl));
|
||||||
zl.type = ZEBRA_LSP_ISIS_SR;
|
zl.type = ZEBRA_LSP_ISIS_SR;
|
||||||
zl.local_label = srp->input_label;
|
zl.local_label = psid->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send message to zebra. */
|
/* Send message to zebra. */
|
||||||
(void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
|
(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.
|
* 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,
|
count = isis_zebra_add_nexthops(isis, sra->backup_nexthops,
|
||||||
zl.backup_nexthops,
|
zl.backup_nexthops,
|
||||||
ISIS_MPLS_NEXTHOP_BACKUP, 0);
|
ISIS_NEXTHOP_BACKUP, true, 0);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
|
SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
|
||||||
zl.backup_nexthop_num = count;
|
zl.backup_nexthop_num = count;
|
||||||
|
@ -37,7 +37,6 @@ void isis_zebra_init(struct thread_master *master, int instance);
|
|||||||
void isis_zebra_stop(void);
|
void isis_zebra_stop(void);
|
||||||
|
|
||||||
struct isis_route_info;
|
struct isis_route_info;
|
||||||
struct sr_prefix;
|
|
||||||
struct sr_adjacency;
|
struct sr_adjacency;
|
||||||
|
|
||||||
void isis_zebra_route_add_route(struct isis *isis,
|
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 *prefix,
|
||||||
struct prefix_ipv6 *src_p,
|
struct prefix_ipv6 *src_p,
|
||||||
struct isis_route_info *route_info);
|
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);
|
void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra);
|
||||||
int isis_distribute_list_update(int routetype);
|
int isis_distribute_list_update(int routetype);
|
||||||
void isis_zebra_redistribute_set(afi_t afi, int type);
|
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. */
|
/* Print the SPT and the corresponding routing table. */
|
||||||
isis_print_spftree(vty, spftree);
|
isis_print_spftree(vty, spftree);
|
||||||
isis_print_routes(vty, spftree, false);
|
isis_print_routes(vty, spftree, false, false);
|
||||||
|
|
||||||
/* Cleanup SPF tree. */
|
/* Cleanup SPF tree. */
|
||||||
isis_spftree_del(spftree);
|
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. */
|
/* Print the post-convergence SPT and the correspoding routing table. */
|
||||||
isis_print_spftree(vty, spftree_pc);
|
isis_print_spftree(vty, spftree_pc);
|
||||||
isis_print_routes(vty, spftree_self, true);
|
isis_print_routes(vty, spftree_self, false, true);
|
||||||
|
|
||||||
/* Cleanup everything. */
|
/* Cleanup everything. */
|
||||||
isis_spftree_del(spftree_self);
|
isis_spftree_del(spftree_self);
|
||||||
|
@ -18,14 +18,15 @@ rt6 TE-IS 30 rt2 - rt4(4)
|
|||||||
|
|
||||||
IS-IS L1 IPv4 routing table:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
10.0.255.5/32 30 - rt3 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.6/32 40 - rt2 -
|
10.0.255.5/32 30 - rt3 16050
|
||||||
- rt3 -
|
10.0.255.6/32 40 - rt2 16060
|
||||||
|
- rt3 16060
|
||||||
|
|
||||||
IS-IS paths to level-1 routers that speak IPv6
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
Vertex Type Metric Next-Hop Interface Parent
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
@ -46,14 +47,15 @@ rt6 TE-IS 30 rt2 - rt4(4)
|
|||||||
|
|
||||||
IS-IS L1 IPv6 routing table:
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-------------------------------------------------------
|
------------------------------------------------------------
|
||||||
2001:db8::2/128 20 - rt2 -
|
2001:db8::1/128 0 - - -
|
||||||
2001:db8::3/128 20 - rt3 -
|
2001:db8::2/128 20 - rt2 implicit-null
|
||||||
2001:db8::4/128 30 - rt2 -
|
2001:db8::3/128 20 - rt3 implicit-null
|
||||||
2001:db8::5/128 30 - rt3 -
|
2001:db8::4/128 30 - rt2 16041
|
||||||
2001:db8::6/128 40 - rt2 -
|
2001:db8::5/128 30 - rt3 16051
|
||||||
- rt3 -
|
2001:db8::6/128 40 - rt2 16061
|
||||||
|
- rt3 16061
|
||||||
|
|
||||||
test# test isis topology 2 root rt1 spf
|
test# test isis topology 2 root rt1 spf
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 25 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 40 - rt3 -
|
10.0.255.2/32 25 - rt2 implicit-null
|
||||||
10.0.255.4/32 20 - rt4 -
|
10.0.255.3/32 40 - rt3 implicit-null
|
||||||
10.0.255.5/32 20 - rt5 -
|
10.0.255.4/32 20 - rt4 implicit-null
|
||||||
10.0.255.6/32 30 - rt4 -
|
10.0.255.5/32 20 - rt5 implicit-null
|
||||||
- rt5 -
|
10.0.255.6/32 30 - rt4 16060
|
||||||
|
- rt5 16060
|
||||||
|
|
||||||
IS-IS paths to level-1 routers that speak IPv6
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
Vertex Type Metric Next-Hop Interface Parent
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
@ -105,14 +108,15 @@ rt3 TE-IS 30 rt3 - rt1(4)
|
|||||||
|
|
||||||
IS-IS L1 IPv6 routing table:
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-------------------------------------------------------
|
------------------------------------------------------------
|
||||||
2001:db8::2/128 25 - rt2 -
|
2001:db8::1/128 0 - - -
|
||||||
2001:db8::3/128 40 - rt3 -
|
2001:db8::2/128 25 - rt2 implicit-null
|
||||||
2001:db8::4/128 20 - rt4 -
|
2001:db8::3/128 40 - rt3 implicit-null
|
||||||
2001:db8::5/128 20 - rt5 -
|
2001:db8::4/128 20 - rt4 implicit-null
|
||||||
2001:db8::6/128 30 - rt4 -
|
2001:db8::5/128 20 - rt5 implicit-null
|
||||||
- rt5 -
|
2001:db8::6/128 30 - rt4 16061
|
||||||
|
- rt5 16061
|
||||||
|
|
||||||
test# test isis topology 3 root rt1 spf ipv4-only
|
test# test isis topology 3 root rt1 spf ipv4-only
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
10.0.255.5/32 40 - rt2 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.6/32 40 - rt2 -
|
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
|
test# test isis topology 4 root rt1 spf ipv4-only
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
10.0.255.5/32 30 - rt3 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.6/32 40 - rt2 -
|
10.0.255.5/32 30 - rt3 16050
|
||||||
10.0.255.7/32 40 - rt3 -
|
10.0.255.6/32 40 - rt2 16060
|
||||||
10.0.255.8/32 50 - rt2 -
|
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
|
test# test isis topology 5 root rt1 spf ipv4-only
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
10.0.255.5/32 30 - rt3 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.6/32 40 - rt2 -
|
10.0.255.5/32 30 - rt3 16050
|
||||||
10.0.255.7/32 40 - rt3 -
|
10.0.255.6/32 40 - rt2 16060
|
||||||
10.0.255.8/32 50 - rt2 -
|
10.0.255.7/32 40 - rt3 16070
|
||||||
- rt3 -
|
10.0.255.8/32 50 - rt2 16080
|
||||||
|
- rt3 16080
|
||||||
|
|
||||||
test# test isis topology 6 root rt1 spf ipv4-only
|
test# test isis topology 6 root rt1 spf ipv4-only
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
- rt3 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.5/32 50 - rt2 -
|
- rt3 16040
|
||||||
- rt3 -
|
10.0.255.5/32 50 - rt2 16050
|
||||||
10.0.255.6/32 40 - rt2 -
|
- rt3 16050
|
||||||
- rt3 -
|
10.0.255.6/32 40 - rt2 16060
|
||||||
10.0.255.7/32 60 - rt2 -
|
- rt3 16060
|
||||||
- rt3 -
|
10.0.255.7/32 60 - rt2 16070
|
||||||
10.0.255.8/32 50 - rt2 -
|
- rt3 16070
|
||||||
- rt3 -
|
10.0.255.8/32 50 - rt2 16080
|
||||||
|
- rt3 16080
|
||||||
|
|
||||||
test# test isis topology 7 root rt1 spf ipv4-only
|
test# test isis topology 7 root rt1 spf ipv4-only
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
10.0.255.2/32 40 - rt4 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 50 - rt4 -
|
10.0.255.2/32 40 - rt4 16020
|
||||||
10.0.255.4/32 20 - rt4 -
|
10.0.255.3/32 50 - rt4 16030
|
||||||
10.0.255.5/32 30 - rt4 -
|
10.0.255.4/32 20 - rt4 implicit-null
|
||||||
10.0.255.6/32 40 - rt4 -
|
10.0.255.5/32 30 - rt4 16050
|
||||||
10.0.255.7/32 30 - rt4 -
|
10.0.255.6/32 40 - rt4 16060
|
||||||
10.0.255.8/32 40 - rt4 -
|
10.0.255.7/32 30 - rt4 16070
|
||||||
10.0.255.9/32 50 - rt4 -
|
10.0.255.8/32 40 - rt4 16080
|
||||||
10.0.255.10/32 50 - rt4 -
|
10.0.255.9/32 50 - rt4 16090
|
||||||
10.0.255.11/32 50 - rt4 -
|
10.0.255.10/32 50 - rt4 16100
|
||||||
10.0.255.12/32 60 - rt4 -
|
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
|
test# test isis topology 8 root rt1 spf ipv4-only
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 30 - rt2 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 20 - rt4 -
|
10.0.255.3/32 30 - rt2 16030
|
||||||
10.0.255.5/32 30 - rt2 -
|
10.0.255.4/32 20 - rt4 implicit-null
|
||||||
10.0.255.6/32 40 - rt2 -
|
10.0.255.5/32 30 - rt2 16050
|
||||||
10.0.255.7/32 30 - rt4 -
|
10.0.255.6/32 40 - rt2 16060
|
||||||
10.0.255.8/32 40 - rt2 -
|
10.0.255.7/32 30 - rt4 16070
|
||||||
10.0.255.9/32 50 - rt2 -
|
10.0.255.8/32 40 - rt2 16080
|
||||||
10.0.255.10/32 40 - rt4 -
|
10.0.255.9/32 50 - rt2 16090
|
||||||
10.0.255.11/32 50 - rt2 -
|
10.0.255.10/32 40 - rt4 16100
|
||||||
10.0.255.12/32 60 - rt2 -
|
10.0.255.11/32 50 - rt2 16110
|
||||||
|
10.0.255.12/32 60 - rt2 16120
|
||||||
|
|
||||||
test# test isis topology 9 root rt1 spf
|
test# test isis topology 9 root rt1 spf
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
10.0.255.5/32 40 - rt2 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.6/32 60 - rt2 -
|
10.0.255.5/32 40 - rt2 16050
|
||||||
10.0.255.7/32 60 - rt2 -
|
10.0.255.6/32 60 - rt2 16060
|
||||||
10.0.255.8/32 60 - rt2 -
|
10.0.255.7/32 60 - rt2 16070
|
||||||
10.0.255.9/32 50 - rt2 -
|
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
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
Vertex Type Metric Next-Hop Interface Parent
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
@ -411,16 +422,17 @@ rt8 TE-IS 50 rt2 - rt4(4)
|
|||||||
|
|
||||||
IS-IS L1 IPv6 routing table:
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-------------------------------------------------------
|
------------------------------------------------------------
|
||||||
2001:db8::2/128 20 - rt2 -
|
2001:db8::1/128 0 - - -
|
||||||
2001:db8::3/128 20 - rt3 -
|
2001:db8::2/128 20 - rt2 implicit-null
|
||||||
2001:db8::4/128 30 - rt2 -
|
2001:db8::3/128 20 - rt3 implicit-null
|
||||||
2001:db8::5/128 40 - rt2 -
|
2001:db8::4/128 30 - rt2 16041
|
||||||
2001:db8::6/128 60 - rt2 -
|
2001:db8::5/128 40 - rt2 16051
|
||||||
2001:db8::7/128 60 - rt2 -
|
2001:db8::6/128 60 - rt2 16061
|
||||||
2001:db8::8/128 60 - rt2 -
|
2001:db8::7/128 60 - rt2 16071
|
||||||
2001:db8::9/128 50 - rt2 -
|
2001:db8::8/128 60 - rt2 16081
|
||||||
|
2001:db8::9/128 50 - rt2 16091
|
||||||
|
|
||||||
test# test isis topology 10 root rt1 spf
|
test# test isis topology 10 root rt1 spf
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 30 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt4 -
|
10.0.255.3/32 30 - rt3 implicit-null
|
||||||
10.0.255.5/32 30 - rt2 -
|
10.0.255.4/32 30 - rt4 implicit-null
|
||||||
10.0.255.6/32 40 - rt3 -
|
10.0.255.5/32 30 - rt2 16050
|
||||||
10.0.255.7/32 40 - rt4 -
|
10.0.255.6/32 40 - rt3 20060
|
||||||
10.0.255.8/32 40 - rt2 -
|
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
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
Vertex Type Metric Next-Hop Interface Parent
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
@ -475,15 +488,16 @@ rt8 TE-IS 30 rt2 - rt5(4)
|
|||||||
|
|
||||||
IS-IS L1 IPv6 routing table:
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-------------------------------------------------------
|
------------------------------------------------------------
|
||||||
2001:db8::2/128 20 - rt2 -
|
2001:db8::1/128 0 - - -
|
||||||
2001:db8::3/128 30 - rt3 -
|
2001:db8::2/128 20 - rt2 implicit-null
|
||||||
2001:db8::4/128 30 - rt4 -
|
2001:db8::3/128 30 - rt3 implicit-null
|
||||||
2001:db8::5/128 30 - rt2 -
|
2001:db8::4/128 30 - rt4 implicit-null
|
||||||
2001:db8::6/128 40 - rt3 -
|
2001:db8::5/128 30 - rt2 16051
|
||||||
2001:db8::7/128 40 - rt4 -
|
2001:db8::6/128 40 - rt3 20061
|
||||||
2001:db8::8/128 40 - rt2 -
|
2001:db8::7/128 40 - rt4 16071
|
||||||
|
2001:db8::8/128 40 - rt2 16081
|
||||||
|
|
||||||
test# test isis topology 11 root rt1 spf
|
test# test isis topology 11 root rt1 spf
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
10.0.255.5/32 30 - rt3 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.6/32 40 - rt2 -
|
10.0.255.5/32 30 - rt3 16050
|
||||||
- rt3 -
|
10.0.255.6/32 40 - rt2 16060
|
||||||
|
- rt3 16060
|
||||||
|
|
||||||
IS-IS paths to level-1 routers that speak IPv6
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
Vertex Type Metric Next-Hop Interface Parent
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
@ -535,14 +550,15 @@ rt6 TE-IS 30 rt2 - rt4(4)
|
|||||||
|
|
||||||
IS-IS L1 IPv6 routing table:
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-------------------------------------------------------
|
------------------------------------------------------------
|
||||||
2001:db8::2/128 20 - rt2 -
|
2001:db8::1/128 0 - - -
|
||||||
2001:db8::3/128 20 - rt3 -
|
2001:db8::2/128 20 - rt2 implicit-null
|
||||||
2001:db8::4/128 30 - rt2 -
|
2001:db8::3/128 20 - rt3 implicit-null
|
||||||
2001:db8::5/128 30 - rt3 -
|
2001:db8::4/128 30 - rt2 16041
|
||||||
2001:db8::6/128 40 - rt2 -
|
2001:db8::5/128 30 - rt3 16051
|
||||||
- rt3 -
|
2001:db8::6/128 40 - rt2 16061
|
||||||
|
- rt3 16061
|
||||||
|
|
||||||
test# test isis topology 12 root rt1 spf ipv4-only
|
test# test isis topology 12 root rt1 spf ipv4-only
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
10.0.255.5/32 30 - rt3 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.6/32 40 - rt2 -
|
10.0.255.5/32 30 - rt3 16050
|
||||||
10.0.255.7/32 40 - rt3 -
|
10.0.255.6/32 40 - rt2 16060
|
||||||
10.0.255.8/32 50 - rt2 -
|
10.0.255.7/32 40 - rt3 16070
|
||||||
10.0.255.9/32 50 - rt3 -
|
10.0.255.8/32 50 - rt2 16080
|
||||||
10.0.255.10/32 60 - rt2 -
|
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
|
test# test isis topology 13 root rt1 spf ipv4-only
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
- rt3 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.5/32 30 - rt3 -
|
- rt3 16040
|
||||||
10.0.255.6/32 30 - rt3 -
|
10.0.255.5/32 30 - rt3 16050
|
||||||
10.0.255.7/32 40 - rt3 -
|
10.0.255.6/32 30 - rt3 16060
|
||||||
|
10.0.255.7/32 40 - rt3 16070
|
||||||
|
|
||||||
test#
|
test#
|
||||||
test# test isis topology 4 root rt1 reverse-spf ipv4-only
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.2/32 20 - rt2 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.2/32 20 - rt2 implicit-null
|
||||||
10.0.255.4/32 30 - rt2 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
10.0.255.5/32 30 - rt3 -
|
10.0.255.4/32 30 - rt2 16040
|
||||||
10.0.255.6/32 40 - rt2 -
|
10.0.255.5/32 30 - rt3 16050
|
||||||
10.0.255.7/32 40 - rt3 -
|
10.0.255.6/32 40 - rt2 16060
|
||||||
10.0.255.8/32 50 - rt2 -
|
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
|
test# test isis topology 11 root rt1 reverse-spf
|
||||||
IS-IS paths to level-1 routers that speak IP
|
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:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.3/32 20 - rt3 -
|
10.0.255.1/32 0 - - -
|
||||||
10.0.255.5/32 30 - rt3 -
|
10.0.255.3/32 20 - rt3 implicit-null
|
||||||
10.0.255.6/32 40 - rt3 -
|
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
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
Vertex Type Metric Next-Hop Interface Parent
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
@ -693,11 +713,12 @@ rt6 TE-IS 30 rt3 - rt4(4)
|
|||||||
|
|
||||||
IS-IS L1 IPv6 routing table:
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-------------------------------------------------------
|
------------------------------------------------------------
|
||||||
2001:db8::3/128 20 - rt3 -
|
2001:db8::1/128 0 - - -
|
||||||
2001:db8::5/128 30 - rt3 -
|
2001:db8::3/128 20 - rt3 implicit-null
|
||||||
2001:db8::6/128 40 - rt3 -
|
2001:db8::5/128 30 - rt3 16051
|
||||||
|
2001:db8::6/128 40 - rt3 16061
|
||||||
|
|
||||||
test#
|
test#
|
||||||
test# test isis topology 1 root rt1 ti-lfa system-id rt2
|
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.1/32 40 - rt6 16040
|
||||||
10.0.255.2/32 55 - 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):
|
P-space (self):
|
||||||
rt6
|
rt6
|
||||||
@ -1040,7 +1061,7 @@ IS-IS L1 IPv6 routing table:
|
|||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
2001:db8::1/128 40 - rt6 16041
|
2001:db8::1/128 40 - rt6 16041
|
||||||
2001:db8::2/128 55 - 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
|
test# test isis topology 3 root rt5 ti-lfa system-id rt4 ipv4-only
|
||||||
P-space (self):
|
P-space (self):
|
||||||
@ -1088,10 +1109,10 @@ IS-IS L1 IPv4 routing table:
|
|||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
10.0.255.1/32 50 - rt3 -
|
10.0.255.1/32 50 - rt3 16010
|
||||||
- rt6 -
|
- rt6 16010
|
||||||
10.0.255.2/32 40 - rt6 -
|
10.0.255.2/32 40 - rt6 16020
|
||||||
10.0.255.4/32 30 - rt6 -
|
10.0.255.4/32 30 - rt6 16040
|
||||||
|
|
||||||
test# test isis topology 3 root rt5 ti-lfa system-id rt3 ipv4-only
|
test# test isis topology 3 root rt5 ti-lfa system-id rt3 ipv4-only
|
||||||
P-space (self):
|
P-space (self):
|
||||||
@ -1380,13 +1401,13 @@ IS-IS L1 IPv4 routing table:
|
|||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
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.2/32 60 - rt12 16090
|
||||||
10.0.255.3/32 70 - 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.5/32 50 - rt12 16090
|
||||||
10.0.255.6/32 60 - 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
|
10.0.255.8/32 40 - rt12 16090
|
||||||
|
|
||||||
test# test isis topology 7 root rt6 ti-lfa system-id rt5 ipv4-only
|
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.1/32 60 - rt3 16020
|
||||||
10.0.255.4/32 50 - rt3 16020
|
10.0.255.4/32 50 - rt3 16020
|
||||||
10.0.255.5/32 40 - rt3 16020
|
10.0.255.5/32 40 - rt3 16020
|
||||||
10.0.255.7/32 60 - rt9 -
|
10.0.255.7/32 60 - rt9 16070
|
||||||
- rt3 -
|
- rt3 16070
|
||||||
10.0.255.8/32 50 - rt9 -
|
10.0.255.8/32 50 - rt9 16080
|
||||||
- rt3 -
|
- rt3 16080
|
||||||
10.0.255.10/32 70 - rt9 -
|
10.0.255.10/32 70 - rt9 16100
|
||||||
- rt3 -
|
- rt3 16100
|
||||||
10.0.255.11/32 60 - rt9 -
|
10.0.255.11/32 60 - rt9 16110
|
||||||
- rt3 -
|
- rt3 16110
|
||||||
|
|
||||||
test# test isis topology 8 root rt2 ti-lfa system-id rt1 ipv4-only
|
test# test isis topology 8 root rt2 ti-lfa system-id rt1 ipv4-only
|
||||||
P-space (self):
|
P-space (self):
|
||||||
@ -2322,13 +2343,13 @@ rt6 TE-IS 70 rt3 - rt5(4)
|
|||||||
|
|
||||||
IS-IS L1 IPv4 routing table:
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-----------------------------------------------------
|
----------------------------------------------------------
|
||||||
10.0.255.1/32 60 - rt1 -
|
10.0.255.1/32 60 - rt1 implicit-null
|
||||||
10.0.255.3/32 60 - rt3 -
|
10.0.255.3/32 60 - rt3 implicit-null
|
||||||
10.0.255.4/32 80 - rt3 16050
|
10.0.255.4/32 80 - rt3 16050
|
||||||
10.0.255.5/32 70 - rt3 -
|
10.0.255.5/32 70 - rt3 16050
|
||||||
10.0.255.6/32 80 - rt3 -
|
10.0.255.6/32 80 - rt3 16060
|
||||||
|
|
||||||
P-space (self):
|
P-space (self):
|
||||||
|
|
||||||
@ -2368,13 +2389,13 @@ rt6 TE-IS 70 rt3 - rt5(4)
|
|||||||
|
|
||||||
IS-IS L1 IPv6 routing table:
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
Prefix Metric Interface Nexthop Label(s)
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
-------------------------------------------------------
|
------------------------------------------------------------
|
||||||
2001:db8::1/128 60 - rt1 -
|
2001:db8::1/128 60 - rt1 implicit-null
|
||||||
2001:db8::3/128 60 - rt3 -
|
2001:db8::3/128 60 - rt3 implicit-null
|
||||||
2001:db8::4/128 80 - rt3 16051
|
2001:db8::4/128 80 - rt3 16051
|
||||||
2001:db8::5/128 70 - rt3 -
|
2001:db8::5/128 70 - rt3 16051
|
||||||
2001:db8::6/128 80 - rt3 -
|
2001:db8::6/128 80 - rt3 16061
|
||||||
|
|
||||||
test# test isis topology 12 root rt1 ti-lfa system-id rt3 ipv4-only
|
test# test isis topology 12 root rt1 ti-lfa system-id rt3 ipv4-only
|
||||||
P-space (self):
|
P-space (self):
|
||||||
|
Loading…
Reference in New Issue
Block a user