mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 13:33:15 +00:00
Merge pull request #6999 from opensourcerouting/isisd-modular-spf
isisd: make the SPF code more modular + reverse SPF + unit tests
This commit is contained in:
commit
4a097aaf88
@ -418,8 +418,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 ip route isis
|
.. index:: show isis route [level-1|level-2]
|
||||||
.. clicmd:: show ip route isis
|
.. clicmd:: show isis route [level-1|level-2]
|
||||||
|
|
||||||
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.
|
||||||
|
@ -221,7 +221,10 @@ struct fabricd *fabricd_new(struct isis_area *area)
|
|||||||
rv->area = area;
|
rv->area = area;
|
||||||
rv->initial_sync_state = FABRICD_SYNC_PENDING;
|
rv->initial_sync_state = FABRICD_SYNC_PENDING;
|
||||||
|
|
||||||
rv->spftree = isis_spftree_new(area);
|
rv->spftree =
|
||||||
|
isis_spftree_new(area, &area->lspdb[IS_LEVEL_2 - 1],
|
||||||
|
area->isis->sysid, ISIS_LEVEL2, SPFTREE_IPV4,
|
||||||
|
SPF_TYPE_FORWARD, F_SPFTREE_HOPCOUNT_METRIC);
|
||||||
rv->neighbors = skiplist_new(0, neighbor_entry_list_cmp,
|
rv->neighbors = skiplist_new(0, neighbor_entry_list_cmp,
|
||||||
neighbor_entry_del_void);
|
neighbor_entry_del_void);
|
||||||
rv->neighbors_neighbors = hash_create(neighbor_entry_hash_key,
|
rv->neighbors_neighbors = hash_create(neighbor_entry_hash_key,
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
#include "isisd/isis_dynhn.h"
|
#include "isisd/isis_dynhn.h"
|
||||||
#include "isisd/isis_pdu.h"
|
#include "isisd/isis_pdu.h"
|
||||||
#include "isisd/isis_lsp.h"
|
#include "isisd/isis_lsp.h"
|
||||||
#include "isisd/isis_spf.h"
|
|
||||||
#include "isisd/isis_events.h"
|
#include "isisd/isis_events.h"
|
||||||
#include "isisd/isis_mt.h"
|
#include "isisd/isis_mt.h"
|
||||||
#include "isisd/isis_tlvs.h"
|
#include "isisd/isis_tlvs.h"
|
||||||
@ -152,9 +151,6 @@ void isis_delete_adj(void *arg)
|
|||||||
if (adj->adj_state != ISIS_ADJ_DOWN)
|
if (adj->adj_state != ISIS_ADJ_DOWN)
|
||||||
adj->adj_state = ISIS_ADJ_DOWN;
|
adj->adj_state = ISIS_ADJ_DOWN;
|
||||||
|
|
||||||
/* remove from SPF trees */
|
|
||||||
spftree_area_adj_del(adj->circuit->area, adj);
|
|
||||||
|
|
||||||
hook_call(isis_adj_state_change_hook, adj);
|
hook_call(isis_adj_state_change_hook, adj);
|
||||||
|
|
||||||
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses);
|
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses);
|
||||||
|
@ -49,11 +49,23 @@ void dyn_cache_init(struct isis *isis)
|
|||||||
{
|
{
|
||||||
if (dyn_cache == NULL)
|
if (dyn_cache == NULL)
|
||||||
dyn_cache = list_new();
|
dyn_cache = list_new();
|
||||||
thread_add_timer(master, dyn_cache_cleanup, isis, 120,
|
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
|
||||||
&isis->t_dync_clean);
|
thread_add_timer(master, dyn_cache_cleanup, isis, 120,
|
||||||
|
&isis->t_dync_clean);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dyn_cache_cleanup_all(void)
|
||||||
|
{
|
||||||
|
struct listnode *node, *nnode;
|
||||||
|
struct isis_dynhn *dyn;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS(dyn_cache, node, nnode, dyn)) {
|
||||||
|
list_delete_node(dyn_cache, node);
|
||||||
|
XFREE(MTYPE_ISIS_DYNHN, dyn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int dyn_cache_cleanup(struct thread *thread)
|
static int dyn_cache_cleanup(struct thread *thread)
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
@ -31,6 +31,7 @@ struct isis_dynhn {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void dyn_cache_init(struct isis *isis);
|
void dyn_cache_init(struct isis *isis);
|
||||||
|
void dyn_cache_cleanup_all(void);
|
||||||
void isis_dynhn_insert(const uint8_t *id, const char *hostname, int level);
|
void isis_dynhn_insert(const uint8_t *id, const char *hostname, int level);
|
||||||
void isis_dynhn_remove(const uint8_t *id);
|
void isis_dynhn_remove(const uint8_t *id);
|
||||||
struct isis_dynhn *dynhn_find_by_id(const uint8_t *id);
|
struct isis_dynhn *dynhn_find_by_id(const uint8_t *id);
|
||||||
|
154
isisd/isis_lsp.c
154
isisd/isis_lsp.c
@ -2046,6 +2046,160 @@ static int lsp_handle_adj_state_change(struct isis_adjacency *adj)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate over all IP reachability TLVs in a LSP (all fragments) of the given
|
||||||
|
* address-family and MT-ID.
|
||||||
|
*/
|
||||||
|
int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid,
|
||||||
|
lsp_ip_reach_iter_cb cb, void *arg)
|
||||||
|
{
|
||||||
|
bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id);
|
||||||
|
struct isis_lsp *frag;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0)
|
||||||
|
return LSP_ITER_CONTINUE;
|
||||||
|
|
||||||
|
/* Parse main LSP. */
|
||||||
|
if (lsp->tlvs) {
|
||||||
|
if (!fabricd && !pseudo_lsp && family == AF_INET
|
||||||
|
&& mtid == ISIS_MT_IPV4_UNICAST) {
|
||||||
|
struct isis_item_list *reachs[] = {
|
||||||
|
&lsp->tlvs->oldstyle_ip_reach,
|
||||||
|
&lsp->tlvs->oldstyle_ip_reach_ext};
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < array_size(reachs); i++) {
|
||||||
|
struct isis_oldstyle_ip_reach *r;
|
||||||
|
|
||||||
|
for (r = (struct isis_oldstyle_ip_reach *)
|
||||||
|
reachs[i]
|
||||||
|
->head;
|
||||||
|
r; r = r->next) {
|
||||||
|
bool external = i ? true : false;
|
||||||
|
|
||||||
|
if ((*cb)((struct prefix *)&r->prefix,
|
||||||
|
r->metric, external, NULL,
|
||||||
|
arg)
|
||||||
|
== LSP_ITER_STOP)
|
||||||
|
return LSP_ITER_STOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pseudo_lsp && family == AF_INET) {
|
||||||
|
struct isis_item_list *ipv4_reachs;
|
||||||
|
|
||||||
|
if (mtid == ISIS_MT_IPV4_UNICAST)
|
||||||
|
ipv4_reachs = &lsp->tlvs->extended_ip_reach;
|
||||||
|
else
|
||||||
|
ipv4_reachs = isis_lookup_mt_items(
|
||||||
|
&lsp->tlvs->mt_ip_reach, mtid);
|
||||||
|
|
||||||
|
struct isis_extended_ip_reach *r;
|
||||||
|
for (r = ipv4_reachs ? (struct isis_extended_ip_reach *)
|
||||||
|
ipv4_reachs->head
|
||||||
|
: NULL;
|
||||||
|
r; r = r->next) {
|
||||||
|
if ((*cb)((struct prefix *)&r->prefix,
|
||||||
|
r->metric, false, r->subtlvs, arg)
|
||||||
|
== LSP_ITER_STOP)
|
||||||
|
return LSP_ITER_STOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pseudo_lsp && family == AF_INET6) {
|
||||||
|
struct isis_item_list *ipv6_reachs;
|
||||||
|
struct isis_ipv6_reach *r;
|
||||||
|
|
||||||
|
if (mtid == ISIS_MT_IPV4_UNICAST)
|
||||||
|
ipv6_reachs = &lsp->tlvs->ipv6_reach;
|
||||||
|
else
|
||||||
|
ipv6_reachs = isis_lookup_mt_items(
|
||||||
|
&lsp->tlvs->mt_ipv6_reach, mtid);
|
||||||
|
|
||||||
|
for (r = ipv6_reachs ? (struct isis_ipv6_reach *)
|
||||||
|
ipv6_reachs->head
|
||||||
|
: NULL;
|
||||||
|
r; r = r->next) {
|
||||||
|
if ((*cb)((struct prefix *)&r->prefix,
|
||||||
|
r->metric, r->external, r->subtlvs,
|
||||||
|
arg)
|
||||||
|
== LSP_ITER_STOP)
|
||||||
|
return LSP_ITER_STOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse LSP fragments. */
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) {
|
||||||
|
if (!frag->tlvs)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
isis_lsp_iterate_ip_reach(frag, family, mtid, cb, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LSP_ITER_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate over all IS reachability TLVs in a LSP (all fragments) of the given
|
||||||
|
* MT-ID.
|
||||||
|
*/
|
||||||
|
int isis_lsp_iterate_is_reach(struct isis_lsp *lsp, uint16_t mtid,
|
||||||
|
lsp_is_reach_iter_cb cb, void *arg)
|
||||||
|
{
|
||||||
|
bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id);
|
||||||
|
struct isis_lsp *frag;
|
||||||
|
struct listnode *node;
|
||||||
|
struct isis_item *head;
|
||||||
|
struct isis_item_list *te_neighs;
|
||||||
|
|
||||||
|
if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0)
|
||||||
|
return LSP_ITER_CONTINUE;
|
||||||
|
|
||||||
|
/* Parse main LSP. */
|
||||||
|
if (lsp->tlvs) {
|
||||||
|
if (pseudo_lsp || mtid == ISIS_MT_IPV4_UNICAST) {
|
||||||
|
head = lsp->tlvs->oldstyle_reach.head;
|
||||||
|
for (struct isis_oldstyle_reach *reach =
|
||||||
|
(struct isis_oldstyle_reach *)head;
|
||||||
|
reach; reach = reach->next) {
|
||||||
|
if ((*cb)(reach->id, reach->metric, true, NULL,
|
||||||
|
arg)
|
||||||
|
== LSP_ITER_STOP)
|
||||||
|
return LSP_ITER_STOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pseudo_lsp || mtid == ISIS_MT_IPV4_UNICAST)
|
||||||
|
te_neighs = &lsp->tlvs->extended_reach;
|
||||||
|
else
|
||||||
|
te_neighs =
|
||||||
|
isis_get_mt_items(&lsp->tlvs->mt_reach, mtid);
|
||||||
|
if (te_neighs) {
|
||||||
|
head = te_neighs->head;
|
||||||
|
for (struct isis_extended_reach *reach =
|
||||||
|
(struct isis_extended_reach *)head;
|
||||||
|
reach; reach = reach->next) {
|
||||||
|
if ((*cb)(reach->id, reach->metric, false,
|
||||||
|
reach->subtlvs, arg)
|
||||||
|
== LSP_ITER_STOP)
|
||||||
|
return LSP_ITER_STOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse LSP fragments. */
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) {
|
||||||
|
if (!frag->tlvs)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
isis_lsp_iterate_is_reach(frag, mtid, cb, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return LSP_ITER_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
void lsp_init(void)
|
void lsp_init(void)
|
||||||
{
|
{
|
||||||
hook_register(isis_adj_state_change_hook,
|
hook_register(isis_adj_state_change_hook,
|
||||||
|
@ -127,6 +127,26 @@ int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail,
|
|||||||
/* sets SRMflags for all active circuits of an lsp */
|
/* sets SRMflags for all active circuits of an lsp */
|
||||||
void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set);
|
void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set);
|
||||||
|
|
||||||
|
#define LSP_ITER_CONTINUE 0
|
||||||
|
#define LSP_ITER_STOP -1
|
||||||
|
|
||||||
|
/* Callback used by isis_lsp_iterate_ip_reach() function. */
|
||||||
|
struct isis_subtlvs;
|
||||||
|
typedef int (*lsp_ip_reach_iter_cb)(const struct prefix *prefix,
|
||||||
|
uint32_t metric, bool external,
|
||||||
|
struct isis_subtlvs *subtlvs, void *arg);
|
||||||
|
|
||||||
|
/* Callback used by isis_lsp_iterate_is_reach() function. */
|
||||||
|
typedef int (*lsp_is_reach_iter_cb)(const uint8_t *id, uint32_t metric,
|
||||||
|
bool oldmetric,
|
||||||
|
struct isis_ext_subtlvs *subtlvs,
|
||||||
|
void *arg);
|
||||||
|
|
||||||
|
int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid,
|
||||||
|
lsp_ip_reach_iter_cb cb, void *arg);
|
||||||
|
int isis_lsp_iterate_is_reach(struct isis_lsp *lsp, uint16_t mtid,
|
||||||
|
lsp_is_reach_iter_cb cb, void *arg);
|
||||||
|
|
||||||
#define lsp_flood(lsp, circuit) \
|
#define lsp_flood(lsp, circuit) \
|
||||||
_lsp_flood((lsp), (circuit), __func__, __FILE__, __LINE__)
|
_lsp_flood((lsp), (circuit), __func__, __FILE__, __LINE__)
|
||||||
void _lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit,
|
void _lsp_flood(struct isis_lsp *lsp, struct isis_circuit *circuit,
|
||||||
|
@ -252,7 +252,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
#ifndef FABRICD
|
#ifndef FABRICD
|
||||||
isis_cli_init();
|
isis_cli_init();
|
||||||
#endif /* ifdef FABRICD */
|
#endif /* ifdef FABRICD */
|
||||||
isis_spf_cmds_init();
|
isis_spf_init();
|
||||||
isis_redist_init();
|
isis_redist_init();
|
||||||
isis_route_map_init();
|
isis_route_map_init();
|
||||||
isis_mpls_te_init();
|
isis_mpls_te_init();
|
||||||
|
@ -437,7 +437,7 @@ struct in_addr newprefix2inaddr(uint8_t *prefix_start, uint8_t prefix_masklen)
|
|||||||
* Returns the dynamic hostname associated with the passed system ID.
|
* Returns the dynamic hostname associated with the passed system ID.
|
||||||
* If no dynamic hostname found then returns formatted system ID.
|
* If no dynamic hostname found then returns formatted system ID.
|
||||||
*/
|
*/
|
||||||
const char *print_sys_hostname(uint8_t *sysid)
|
const char *print_sys_hostname(const uint8_t *sysid)
|
||||||
{
|
{
|
||||||
struct isis_dynhn *dyn;
|
struct isis_dynhn *dyn;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis = NULL;
|
||||||
@ -447,8 +447,7 @@ const char *print_sys_hostname(uint8_t *sysid)
|
|||||||
|
|
||||||
/* For our system ID return our host name */
|
/* For our system ID return our host name */
|
||||||
isis = isis_lookup_by_sysid(sysid);
|
isis = isis_lookup_by_sysid(sysid);
|
||||||
|
if (isis && !CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
|
||||||
if (isis != NULL)
|
|
||||||
return cmd_hostname_get();
|
return cmd_hostname_get();
|
||||||
|
|
||||||
dyn = dynhn_find_by_id(sysid);
|
dyn = dynhn_find_by_id(sysid);
|
||||||
|
@ -49,7 +49,7 @@ const char *time2string(uint32_t);
|
|||||||
const char *nlpid2str(uint8_t nlpid);
|
const char *nlpid2str(uint8_t nlpid);
|
||||||
/* typedef struct nlpids nlpids; */
|
/* typedef struct nlpids nlpids; */
|
||||||
char *nlpid2string(struct nlpids *);
|
char *nlpid2string(struct nlpids *);
|
||||||
const char *print_sys_hostname(uint8_t *sysid);
|
const char *print_sys_hostname(const uint8_t *sysid);
|
||||||
void zlog_dump_data(void *data, int len);
|
void zlog_dump_data(void *data, int len);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "isis_pdu.h"
|
#include "isis_pdu.h"
|
||||||
#include "isis_lsp.h"
|
#include "isis_lsp.h"
|
||||||
#include "isis_spf.h"
|
#include "isis_spf.h"
|
||||||
|
#include "isis_spf_private.h"
|
||||||
#include "isis_route.h"
|
#include "isis_route.h"
|
||||||
#include "isis_zebra.h"
|
#include "isis_zebra.h"
|
||||||
|
|
||||||
@ -158,6 +159,17 @@ static void adjinfo2nexthop(int family, struct list *nexthops,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo,
|
||||||
|
const uint8_t *sysid)
|
||||||
|
{
|
||||||
|
struct isis_nexthop *nh;
|
||||||
|
|
||||||
|
nh = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop));
|
||||||
|
memcpy(nh->sysid, sysid, sizeof(nh->sysid));
|
||||||
|
isis_sr_nexthop_reset(&nh->sr);
|
||||||
|
listnode_add(rinfo->nexthops, nh);
|
||||||
|
}
|
||||||
|
|
||||||
static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
||||||
struct prefix_ipv6 *src_p,
|
struct prefix_ipv6 *src_p,
|
||||||
uint32_t cost,
|
uint32_t cost,
|
||||||
@ -165,13 +177,25 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
|||||||
struct list *adjacencies)
|
struct list *adjacencies)
|
||||||
{
|
{
|
||||||
struct isis_route_info *rinfo;
|
struct isis_route_info *rinfo;
|
||||||
struct isis_adjacency *adj;
|
struct isis_vertex_adj *vadj;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
|
|
||||||
rinfo = XCALLOC(MTYPE_ISIS_ROUTE_INFO, sizeof(struct isis_route_info));
|
rinfo = XCALLOC(MTYPE_ISIS_ROUTE_INFO, sizeof(struct isis_route_info));
|
||||||
|
|
||||||
rinfo->nexthops = list_new();
|
rinfo->nexthops = list_new();
|
||||||
for (ALL_LIST_ELEMENTS_RO(adjacencies, node, adj)) {
|
for (ALL_LIST_ELEMENTS_RO(adjacencies, node, vadj)) {
|
||||||
|
struct isis_spf_adj *sadj = vadj->sadj;
|
||||||
|
struct isis_adjacency *adj = sadj->adj;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create dummy nexthops when running SPF on a testing
|
||||||
|
* environment.
|
||||||
|
*/
|
||||||
|
if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) {
|
||||||
|
isis_route_add_dummy_nexthops(rinfo, sadj->id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* check for force resync this route */
|
/* check for force resync this route */
|
||||||
if (CHECK_FLAG(adj->circuit->flags,
|
if (CHECK_FLAG(adj->circuit->flags,
|
||||||
ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
|
ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
|
||||||
|
1103
isisd/isis_spf.c
1103
isisd/isis_spf.c
File diff suppressed because it is too large
Load Diff
@ -26,21 +26,46 @@
|
|||||||
|
|
||||||
struct isis_spftree;
|
struct isis_spftree;
|
||||||
|
|
||||||
struct isis_spftree *isis_spftree_new(struct isis_area *area);
|
enum spf_type {
|
||||||
|
SPF_TYPE_FORWARD = 1,
|
||||||
|
SPF_TYPE_REVERSE,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct isis_spf_adj {
|
||||||
|
uint8_t id[ISIS_SYS_ID_LEN + 1];
|
||||||
|
struct isis_adjacency *adj;
|
||||||
|
uint32_t metric;
|
||||||
|
struct isis_ext_subtlvs *subtlvs;
|
||||||
|
struct {
|
||||||
|
uint8_t desig_is_id[ISIS_SYS_ID_LEN + 1];
|
||||||
|
struct isis_lsp *lsp_pseudo;
|
||||||
|
} lan;
|
||||||
|
uint8_t flags;
|
||||||
|
#define F_ISIS_SPF_ADJ_BROADCAST 0x01
|
||||||
|
#define F_ISIS_SPF_ADJ_OLDMETRIC 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
struct isis_spftree *isis_spftree_new(struct isis_area *area,
|
||||||
|
struct lspdb_head *lspdb,
|
||||||
|
const uint8_t *sysid, int level,
|
||||||
|
enum spf_tree_id tree_id,
|
||||||
|
enum spf_type type, uint8_t flags);
|
||||||
void isis_spf_invalidate_routes(struct isis_spftree *tree);
|
void isis_spf_invalidate_routes(struct isis_spftree *tree);
|
||||||
void isis_spf_verify_routes(struct isis_area *area,
|
void isis_spf_verify_routes(struct isis_area *area,
|
||||||
struct isis_spftree **trees);
|
struct isis_spftree **trees);
|
||||||
void isis_spftree_del(struct isis_spftree *spftree);
|
void isis_spftree_del(struct isis_spftree *spftree);
|
||||||
void spftree_area_init(struct isis_area *area);
|
void spftree_area_init(struct isis_area *area);
|
||||||
void spftree_area_del(struct isis_area *area);
|
void spftree_area_del(struct isis_area *area);
|
||||||
void spftree_area_adj_del(struct isis_area *area, struct isis_adjacency *adj);
|
|
||||||
#define isis_spf_schedule(area, level) \
|
#define isis_spf_schedule(area, level) \
|
||||||
_isis_spf_schedule((area), (level), __func__, \
|
_isis_spf_schedule((area), (level), __func__, \
|
||||||
__FILE__, __LINE__)
|
__FILE__, __LINE__)
|
||||||
int _isis_spf_schedule(struct isis_area *area, int level,
|
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_spf_cmds_init(void);
|
void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree);
|
||||||
|
void isis_print_routes(struct vty *vty, struct isis_spftree *spftree);
|
||||||
|
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);
|
||||||
struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
|
struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
|
||||||
uint8_t *sysid,
|
uint8_t *sysid,
|
||||||
struct isis_spftree *spftree);
|
struct isis_spftree *spftree);
|
||||||
|
@ -50,6 +50,11 @@ struct prefix_pair {
|
|||||||
struct prefix_ipv6 src;
|
struct prefix_ipv6 src;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct isis_vertex_adj {
|
||||||
|
struct isis_spf_adj *sadj;
|
||||||
|
struct mpls_label_stack *label_stack;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Triple <N, d(N), {Adj(N)}>
|
* Triple <N, d(N), {Adj(N)}>
|
||||||
*/
|
*/
|
||||||
@ -180,6 +185,10 @@ static void isis_vertex_del(struct isis_vertex *vertex)
|
|||||||
XFREE(MTYPE_ISIS_VERTEX, vertex);
|
XFREE(MTYPE_ISIS_VERTEX, vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isis_vertex_adj_exists(const struct isis_spftree *spftree,
|
||||||
|
const struct isis_vertex *vertex,
|
||||||
|
const struct isis_spf_adj *sadj);
|
||||||
|
|
||||||
__attribute__((__unused__))
|
__attribute__((__unused__))
|
||||||
static void isis_vertex_queue_clear(struct isis_vertex_queue *queue)
|
static void isis_vertex_queue_clear(struct isis_vertex_queue *queue)
|
||||||
{
|
{
|
||||||
@ -297,18 +306,26 @@ struct isis_spftree {
|
|||||||
struct isis_vertex_queue paths; /* the SPT */
|
struct isis_vertex_queue paths; /* the SPT */
|
||||||
struct isis_vertex_queue tents; /* TENT */
|
struct isis_vertex_queue tents; /* TENT */
|
||||||
struct route_table *route_table;
|
struct route_table *route_table;
|
||||||
|
struct lspdb_head *lspdb; /* link-state db */
|
||||||
|
struct list *sadj_list;
|
||||||
struct isis_area *area; /* back pointer to area */
|
struct isis_area *area; /* back pointer to area */
|
||||||
unsigned int runcount; /* number of runs since uptime */
|
unsigned int runcount; /* number of runs since uptime */
|
||||||
time_t last_run_timestamp; /* last run timestamp as wall time for display */
|
time_t last_run_timestamp; /* last run timestamp as wall time for display */
|
||||||
time_t last_run_monotime; /* last run as monotime for scheduling */
|
time_t last_run_monotime; /* last run as monotime for scheduling */
|
||||||
time_t last_run_duration; /* last run duration in msec */
|
time_t last_run_duration; /* last run duration in msec */
|
||||||
|
|
||||||
|
enum spf_type type;
|
||||||
|
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||||
uint16_t mtid;
|
uint16_t mtid;
|
||||||
int family;
|
int family;
|
||||||
int level;
|
int level;
|
||||||
enum spf_tree_id tree_id;
|
enum spf_tree_id tree_id;
|
||||||
bool hopcount_metric;
|
bool hopcount_metric;
|
||||||
|
uint8_t flags;
|
||||||
};
|
};
|
||||||
|
#define F_SPFTREE_HOPCOUNT_METRIC 0x01
|
||||||
|
#define F_SPFTREE_NO_ROUTES 0x02
|
||||||
|
#define F_SPFTREE_NO_ADJACENCIES 0x04
|
||||||
|
|
||||||
__attribute__((__unused__))
|
__attribute__((__unused__))
|
||||||
static void isis_vertex_id_init(struct isis_vertex *vertex, const void *id,
|
static void isis_vertex_id_init(struct isis_vertex *vertex, const void *id,
|
||||||
@ -347,8 +364,7 @@ static struct isis_lsp *lsp_for_vertex(struct isis_spftree *spftree,
|
|||||||
memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
|
memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
|
||||||
LSP_FRAGMENT(lsp_id) = 0;
|
LSP_FRAGMENT(lsp_id) = 0;
|
||||||
|
|
||||||
struct lspdb_head *lspdb = &spftree->area->lspdb[spftree->level - 1];
|
struct isis_lsp *lsp = lsp_search(spftree->lspdb, lsp_id);
|
||||||
struct isis_lsp *lsp = lsp_search(lspdb, lsp_id);
|
|
||||||
|
|
||||||
if (lsp && lsp->hdr.rem_lifetime != 0)
|
if (lsp && lsp->hdr.rem_lifetime != 0)
|
||||||
return lsp;
|
return lsp;
|
||||||
|
@ -210,7 +210,7 @@ int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
|
|||||||
uint32_t upper_bound)
|
uint32_t upper_bound)
|
||||||
{
|
{
|
||||||
struct isis_sr_db *srdb = &area->srdb;
|
struct isis_sr_db *srdb = &area->srdb;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node;
|
||||||
struct sr_adjacency *sra;
|
struct sr_adjacency *sra;
|
||||||
|
|
||||||
sr_debug("ISIS-Sr (%s): Update SRLB with new range [%u/%u]",
|
sr_debug("ISIS-Sr (%s): Update SRLB with new range [%u/%u]",
|
||||||
@ -236,7 +236,7 @@ int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Reinstall local Adjacency-SIDs with new labels. */
|
/* Reinstall local Adjacency-SIDs with new labels. */
|
||||||
for (ALL_LIST_ELEMENTS(area->srdb.adj_sids, node, nnode, sra))
|
for (ALL_LIST_ELEMENTS_RO(area->srdb.adj_sids, node, sra))
|
||||||
sr_adj_sid_update(sra, &srdb->srlb);
|
sr_adj_sid_update(sra, &srdb->srlb);
|
||||||
|
|
||||||
/* Update and Flood LSP */
|
/* Update and Flood LSP */
|
||||||
@ -1521,13 +1521,13 @@ static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family,
|
|||||||
/* Determine nexthop IP address */
|
/* Determine nexthop IP address */
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
if (!circuit->ip_router)
|
if (!circuit->ip_router || !adj->ipv4_address_count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nexthop.ipv4 = adj->ipv4_addresses[0];
|
nexthop.ipv4 = adj->ipv4_addresses[0];
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
if (!circuit->ipv6_router)
|
if (!circuit->ipv6_router || !adj->ipv6_address_count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nexthop.ipv6 = adj->ipv6_addresses[0];
|
nexthop.ipv6 = adj->ipv6_addresses[0];
|
||||||
@ -1986,7 +1986,7 @@ DEFUN(show_sr_prefix_sids, show_sr_prefix_sids_cmd,
|
|||||||
"Segment-Routing\n"
|
"Segment-Routing\n"
|
||||||
"Segment-Routing Prefix-SIDs\n")
|
"Segment-Routing Prefix-SIDs\n")
|
||||||
{
|
{
|
||||||
struct listnode *node, *inode, *nnode;
|
struct listnode *node, *inode;
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis = NULL;
|
||||||
const char *vrf_name = VRF_DEFAULT_NAME;
|
const char *vrf_name = VRF_DEFAULT_NAME;
|
||||||
@ -1996,7 +1996,7 @@ DEFUN(show_sr_prefix_sids, show_sr_prefix_sids_cmd,
|
|||||||
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
||||||
if (vrf_name) {
|
if (vrf_name) {
|
||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node,
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node,
|
||||||
area)) {
|
area)) {
|
||||||
vty_out(vty, "Area %s:\n",
|
vty_out(vty, "Area %s:\n",
|
||||||
@ -2084,11 +2084,11 @@ DEFUN(show_sr_node, show_sr_node_cmd,
|
|||||||
"Segment-Routing\n"
|
"Segment-Routing\n"
|
||||||
"Segment-Routing node\n")
|
"Segment-Routing node\n")
|
||||||
{
|
{
|
||||||
struct listnode *node, *inode, *nnode;
|
struct listnode *node, *inode;
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, inode, nnode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
||||||
vty_out(vty, "Area %s:\n",
|
vty_out(vty, "Area %s:\n",
|
||||||
area->area_tag ? area->area_tag : "null");
|
area->area_tag ? area->area_tag : "null");
|
||||||
|
@ -311,7 +311,7 @@ DEFUN(show_isis_mpls_te_router,
|
|||||||
MPLS_TE_STR "Router information\n")
|
MPLS_TE_STR "Router information\n")
|
||||||
{
|
{
|
||||||
|
|
||||||
struct listnode *anode, *nnode, *inode;
|
struct listnode *anode, *inode;
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis = NULL;
|
||||||
const char *vrf_name = VRF_DEFAULT_NAME;
|
const char *vrf_name = VRF_DEFAULT_NAME;
|
||||||
@ -325,7 +325,7 @@ DEFUN(show_isis_mpls_te_router,
|
|||||||
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
||||||
if (vrf_name) {
|
if (vrf_name) {
|
||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list,
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list,
|
||||||
anode, area)) {
|
anode, area)) {
|
||||||
if (!IS_MPLS_TE(area->mta))
|
if (!IS_MPLS_TE(area->mta))
|
||||||
@ -483,7 +483,7 @@ DEFUN (show_isis_mpls_te_interface,
|
|||||||
"Interface information\n"
|
"Interface information\n"
|
||||||
"Interface name\n")
|
"Interface name\n")
|
||||||
{
|
{
|
||||||
struct listnode *anode, *cnode, *nnode, *inode;
|
struct listnode *anode, *cnode, *inode;
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct isis_circuit *circuit;
|
struct isis_circuit *circuit;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
@ -497,7 +497,7 @@ DEFUN (show_isis_mpls_te_interface,
|
|||||||
|
|
||||||
if (argc == idx_interface) {
|
if (argc == idx_interface) {
|
||||||
/* Show All Interfaces. */
|
/* Show All Interfaces. */
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
|
||||||
area)) {
|
area)) {
|
||||||
|
|
||||||
|
248
isisd/isisd.c
248
isisd/isisd.c
@ -125,33 +125,37 @@ void isis_vrf_unlink(struct isis *isis, struct vrf *vrf)
|
|||||||
|
|
||||||
struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id)
|
struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||||
if (isis->vrf_id == vrf_id)
|
if (isis->vrf_id == vrf_id)
|
||||||
return isis;
|
return isis;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct isis *isis_lookup_by_vrfname(const char *vrfname)
|
struct isis *isis_lookup_by_vrfname(const char *vrfname)
|
||||||
{
|
{
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||||
if (isis->name && vrfname && strcmp(isis->name, vrfname) == 0)
|
if (isis->name && vrfname && strcmp(isis->name, vrfname) == 0)
|
||||||
return isis;
|
return isis;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct isis *isis_lookup_by_sysid(uint8_t *sysid)
|
struct isis *isis_lookup_by_sysid(const uint8_t *sysid)
|
||||||
{
|
{
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node;
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||||
if (!memcmp(isis->sysid, sysid, ISIS_SYS_ID_LEN))
|
if (!memcmp(isis->sysid, sysid, ISIS_SYS_ID_LEN))
|
||||||
return isis;
|
return isis;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +169,7 @@ void isis_master_init(struct thread_master *master)
|
|||||||
|
|
||||||
void isis_global_instance_create()
|
void isis_global_instance_create()
|
||||||
{
|
{
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
|
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
|
||||||
if (isis == NULL) {
|
if (isis == NULL) {
|
||||||
@ -176,8 +180,8 @@ void isis_global_instance_create()
|
|||||||
|
|
||||||
struct isis *isis_new(vrf_id_t vrf_id)
|
struct isis *isis_new(vrf_id_t vrf_id)
|
||||||
{
|
{
|
||||||
struct vrf *vrf = NULL;
|
struct vrf *vrf;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
|
isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
|
||||||
isis->vrf_id = vrf_id;
|
isis->vrf_id = vrf_id;
|
||||||
@ -214,6 +218,27 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
|
|||||||
struct vrf *vrf = NULL;
|
struct vrf *vrf = NULL;
|
||||||
area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
|
area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
|
||||||
|
|
||||||
|
if (vrf_name) {
|
||||||
|
vrf = vrf_lookup_by_name(vrf_name);
|
||||||
|
if (vrf) {
|
||||||
|
isis = isis_lookup_by_vrfid(vrf->vrf_id);
|
||||||
|
if (isis == NULL) {
|
||||||
|
isis = isis_new(vrf->vrf_id);
|
||||||
|
isis_add(isis);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
|
||||||
|
if (isis == NULL) {
|
||||||
|
isis = isis_new(VRF_DEFAULT);
|
||||||
|
isis_add(isis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listnode_add(isis->area_list, area);
|
||||||
|
area->isis = isis;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fabricd runs only as level-2.
|
* Fabricd runs only as level-2.
|
||||||
* For IS-IS, the default is level-1-2
|
* For IS-IS, the default is level-1-2
|
||||||
@ -237,7 +262,8 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
|
|||||||
area->circuit_list = list_new();
|
area->circuit_list = list_new();
|
||||||
area->adjacency_list = list_new();
|
area->adjacency_list = list_new();
|
||||||
area->area_addrs = list_new();
|
area->area_addrs = list_new();
|
||||||
thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
|
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
|
||||||
|
thread_add_timer(master, lsp_tick, area, 1, &area->t_tick);
|
||||||
flags_initialize(&area->flags);
|
flags_initialize(&area->flags);
|
||||||
|
|
||||||
isis_sr_area_init(area);
|
isis_sr_area_init(area);
|
||||||
@ -293,27 +319,6 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
|
|||||||
|
|
||||||
area->area_tag = strdup(area_tag);
|
area->area_tag = strdup(area_tag);
|
||||||
|
|
||||||
if (vrf_name) {
|
|
||||||
vrf = vrf_lookup_by_name(vrf_name);
|
|
||||||
if (vrf) {
|
|
||||||
isis = isis_lookup_by_vrfid(vrf->vrf_id);
|
|
||||||
if (isis == NULL) {
|
|
||||||
isis = isis_new(vrf->vrf_id);
|
|
||||||
isis_add(isis);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
|
|
||||||
if (isis == NULL) {
|
|
||||||
isis = isis_new(VRF_DEFAULT);
|
|
||||||
isis_add(isis);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listnode_add(isis->area_list, area);
|
|
||||||
area->isis = isis;
|
|
||||||
|
|
||||||
if (fabricd)
|
if (fabricd)
|
||||||
area->fabricd = fabricd_new(area);
|
area->fabricd = fabricd_new(area);
|
||||||
|
|
||||||
@ -335,7 +340,7 @@ struct isis_area *isis_area_lookup(const char *area_tag, vrf_id_t vrf_id)
|
|||||||
{
|
{
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
isis = isis_lookup_by_vrfid(vrf_id);
|
isis = isis_lookup_by_vrfid(vrf_id);
|
||||||
if (isis == NULL)
|
if (isis == NULL)
|
||||||
@ -414,7 +419,8 @@ void isis_area_destroy(struct isis_area *area)
|
|||||||
spf_backoff_free(area->spf_delay_ietf[0]);
|
spf_backoff_free(area->spf_delay_ietf[0]);
|
||||||
spf_backoff_free(area->spf_delay_ietf[1]);
|
spf_backoff_free(area->spf_delay_ietf[1]);
|
||||||
|
|
||||||
isis_redist_area_finish(area);
|
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
|
||||||
|
isis_redist_area_finish(area);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(area->area_addrs, node, nnode, addr)) {
|
for (ALL_LIST_ELEMENTS(area->area_addrs, node, nnode, addr)) {
|
||||||
list_delete_node(area->area_addrs, node);
|
list_delete_node(area->area_addrs, node);
|
||||||
@ -464,7 +470,7 @@ void isis_finish(struct isis *isis)
|
|||||||
|
|
||||||
void isis_terminate()
|
void isis_terminate()
|
||||||
{
|
{
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
|
|
||||||
if (listcount(im->isis) == 0)
|
if (listcount(im->isis) == 0)
|
||||||
@ -643,10 +649,10 @@ int area_clear_net_title(struct vty *vty, const char *net_title)
|
|||||||
int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
|
int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
|
||||||
const char *vrf_name, bool all_vrf)
|
const char *vrf_name, bool all_vrf)
|
||||||
{
|
{
|
||||||
struct listnode *anode, *cnode, *mnode, *inode;
|
struct listnode *anode, *cnode, *inode;
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct isis_circuit *circuit;
|
struct isis_circuit *circuit;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
if (!im) {
|
if (!im) {
|
||||||
vty_out(vty, "IS-IS Routing Process not enabled\n");
|
vty_out(vty, "IS-IS Routing Process not enabled\n");
|
||||||
@ -654,7 +660,7 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
|
|||||||
}
|
}
|
||||||
if (vrf_name) {
|
if (vrf_name) {
|
||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, mnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list,
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list,
|
||||||
anode, area)) {
|
anode, area)) {
|
||||||
vty_out(vty, "Area %s:\n",
|
vty_out(vty, "Area %s:\n",
|
||||||
@ -677,7 +683,7 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
|
|||||||
detail);
|
detail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
isis = isis_lookup_by_vrfname(vrf_name);
|
isis = isis_lookup_by_vrfname(vrf_name);
|
||||||
if (isis != NULL) {
|
if (isis != NULL) {
|
||||||
@ -822,10 +828,10 @@ static void isis_neighbor_common(struct vty *vty, const char *id, char detail,
|
|||||||
int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
|
int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
|
||||||
const char *vrf_name, bool all_vrf)
|
const char *vrf_name, bool all_vrf)
|
||||||
{
|
{
|
||||||
struct listnode *nnode, *inode;
|
struct listnode *node;
|
||||||
struct isis_dynhn *dynhn;
|
struct isis_dynhn *dynhn;
|
||||||
uint8_t sysid[ISIS_SYS_ID_LEN];
|
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
if (!im) {
|
if (!im) {
|
||||||
vty_out(vty, "IS-IS Routing Process not enabled\n");
|
vty_out(vty, "IS-IS Routing Process not enabled\n");
|
||||||
@ -846,11 +852,11 @@ int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
|
|||||||
|
|
||||||
if (vrf_name) {
|
if (vrf_name) {
|
||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) {
|
||||||
isis_neighbor_common(vty, id, detail, isis,
|
isis_neighbor_common(vty, id, detail, isis,
|
||||||
sysid);
|
sysid);
|
||||||
}
|
}
|
||||||
return 0;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
isis = isis_lookup_by_vrfname(vrf_name);
|
isis = isis_lookup_by_vrfname(vrf_name);
|
||||||
if (isis != NULL)
|
if (isis != NULL)
|
||||||
@ -863,7 +869,7 @@ int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
|
|||||||
static void isis_neighbor_common_clear(struct vty *vty, const char *id,
|
static void isis_neighbor_common_clear(struct vty *vty, const char *id,
|
||||||
uint8_t *sysid, struct isis *isis)
|
uint8_t *sysid, struct isis *isis)
|
||||||
{
|
{
|
||||||
struct listnode *anode, *cnode, *cnextnode, *node, *nnode;
|
struct listnode *anode, *cnode, *node, *nnode;
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct isis_circuit *circuit;
|
struct isis_circuit *circuit;
|
||||||
struct list *adjdb;
|
struct list *adjdb;
|
||||||
@ -871,8 +877,7 @@ static void isis_neighbor_common_clear(struct vty *vty, const char *id,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
|
||||||
for (ALL_LIST_ELEMENTS(area->circuit_list, cnode, cnextnode,
|
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
|
||||||
circuit)) {
|
|
||||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
adjdb = circuit->u.bc.adjdb[i];
|
adjdb = circuit->u.bc.adjdb[i];
|
||||||
@ -910,10 +915,10 @@ static void isis_neighbor_common_clear(struct vty *vty, const char *id,
|
|||||||
int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_name,
|
int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_name,
|
||||||
bool all_vrf)
|
bool all_vrf)
|
||||||
{
|
{
|
||||||
struct listnode *nnode, *inode;
|
struct listnode *node;
|
||||||
struct isis_dynhn *dynhn;
|
struct isis_dynhn *dynhn;
|
||||||
uint8_t sysid[ISIS_SYS_ID_LEN];
|
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
if (!im) {
|
if (!im) {
|
||||||
vty_out(vty, "IS-IS Routing Process not enabled\n");
|
vty_out(vty, "IS-IS Routing Process not enabled\n");
|
||||||
@ -933,11 +938,10 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_
|
|||||||
}
|
}
|
||||||
if (vrf_name) {
|
if (vrf_name) {
|
||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||||
isis_neighbor_common_clear(vty, id, sysid,
|
isis_neighbor_common_clear(vty, id, sysid,
|
||||||
isis);
|
isis);
|
||||||
}
|
return CMD_SUCCESS;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
isis = isis_lookup_by_vrfname(vrf_name);
|
isis = isis_lookup_by_vrfname(vrf_name);
|
||||||
if (isis != NULL)
|
if (isis != NULL)
|
||||||
@ -1554,19 +1558,19 @@ DEFUN(show_hostname, show_hostname_cmd,
|
|||||||
"All VRFs\n"
|
"All VRFs\n"
|
||||||
"IS-IS Dynamic hostname mapping\n")
|
"IS-IS Dynamic hostname mapping\n")
|
||||||
{
|
{
|
||||||
struct listnode *nnode, *inode;
|
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;
|
||||||
int idx_vrf = 0;
|
int idx_vrf = 0;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
||||||
if (vrf_name) {
|
if (vrf_name) {
|
||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||||
dynhn_print_all(vty, isis);
|
dynhn_print_all(vty, isis);
|
||||||
}
|
|
||||||
return 0;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
isis = isis_lookup_by_vrfname(vrf_name);
|
isis = isis_lookup_by_vrfname(vrf_name);
|
||||||
if (isis != NULL)
|
if (isis != NULL)
|
||||||
@ -1621,8 +1625,8 @@ DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
|
|||||||
"All VRFs\n"
|
"All VRFs\n"
|
||||||
"SPF delay IETF information\n")
|
"SPF delay IETF information\n")
|
||||||
{
|
{
|
||||||
struct listnode *nnode, *inode;
|
struct listnode *node;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
int idx_vrf = 0;
|
int idx_vrf = 0;
|
||||||
const char *vrf_name = VRF_DEFAULT_NAME;
|
const char *vrf_name = VRF_DEFAULT_NAME;
|
||||||
bool all_vrf = false;
|
bool all_vrf = false;
|
||||||
@ -1636,10 +1640,10 @@ DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
|
|||||||
|
|
||||||
if (vrf_name) {
|
if (vrf_name) {
|
||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||||
isis_spf_ietf_common(vty, isis);
|
isis_spf_ietf_common(vty, isis);
|
||||||
}
|
|
||||||
return 0;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
isis = isis_lookup_by_vrfname(vrf_name);
|
isis = isis_lookup_by_vrfname(vrf_name);
|
||||||
if (isis != NULL)
|
if (isis != NULL)
|
||||||
@ -1755,9 +1759,9 @@ DEFUN(show_isis_summary, show_isis_summary_cmd,
|
|||||||
"All VRFs\n"
|
"All VRFs\n"
|
||||||
"summary\n")
|
"summary\n")
|
||||||
{
|
{
|
||||||
struct listnode *inode, *nnode;
|
struct listnode *node;
|
||||||
int idx_vrf = 0;
|
int idx_vrf = 0;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
const char *vrf_name = VRF_DEFAULT_NAME;
|
const char *vrf_name = VRF_DEFAULT_NAME;
|
||||||
bool all_vrf = false;
|
bool all_vrf = false;
|
||||||
|
|
||||||
@ -1768,10 +1772,10 @@ DEFUN(show_isis_summary, show_isis_summary_cmd,
|
|||||||
}
|
}
|
||||||
if (vrf_name) {
|
if (vrf_name) {
|
||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||||
common_isis_summary(vty, isis);
|
common_isis_summary(vty, isis);
|
||||||
}
|
|
||||||
return 0;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
isis = isis_lookup_by_vrfname(vrf_name);
|
isis = isis_lookup_by_vrfname(vrf_name);
|
||||||
if (isis != NULL)
|
if (isis != NULL)
|
||||||
@ -1844,60 +1848,61 @@ struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv,
|
|||||||
return lsp;
|
return lsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int show_isis_database_common(struct vty *vty, const char *argv,
|
void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
|
||||||
int ui_level, struct isis *isis)
|
int level, struct lspdb_head *lspdb,
|
||||||
|
const char *argv, int ui_level)
|
||||||
|
{
|
||||||
|
struct isis_lsp *lsp;
|
||||||
|
int lsp_count;
|
||||||
|
|
||||||
|
if (lspdb_count(lspdb) > 0) {
|
||||||
|
lsp = lsp_for_arg(lspdb, argv, area->isis);
|
||||||
|
|
||||||
|
if (lsp != NULL || argv == NULL) {
|
||||||
|
vty_out(vty, "IS-IS Level-%d link-state database:\n",
|
||||||
|
level + 1);
|
||||||
|
|
||||||
|
/* print the title in all cases */
|
||||||
|
vty_out(vty,
|
||||||
|
"LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lsp) {
|
||||||
|
if (ui_level == ISIS_UI_LEVEL_DETAIL)
|
||||||
|
lsp_print_detail(lsp, vty, area->dynhostname,
|
||||||
|
area->isis);
|
||||||
|
else
|
||||||
|
lsp_print(lsp, vty, area->dynhostname,
|
||||||
|
area->isis);
|
||||||
|
} else if (argv == NULL) {
|
||||||
|
lsp_count =
|
||||||
|
lsp_print_all(vty, lspdb, ui_level,
|
||||||
|
area->dynhostname, area->isis);
|
||||||
|
|
||||||
|
vty_out(vty, " %u LSPs\n\n", lsp_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void show_isis_database_common(struct vty *vty, const char *argv,
|
||||||
|
int ui_level, struct isis *isis)
|
||||||
{
|
{
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct isis_lsp *lsp;
|
int level;
|
||||||
int level, lsp_count;
|
|
||||||
|
|
||||||
if (isis->area_list->count == 0)
|
if (isis->area_list->count == 0)
|
||||||
return CMD_SUCCESS;
|
return;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
||||||
vty_out(vty, "Area %s:\n",
|
vty_out(vty, "Area %s:\n",
|
||||||
area->area_tag ? area->area_tag : "null");
|
area->area_tag ? area->area_tag : "null");
|
||||||
|
|
||||||
for (level = 0; level < ISIS_LEVELS; level++) {
|
for (level = 0; level < ISIS_LEVELS; level++)
|
||||||
if (lspdb_count(&area->lspdb[level]) > 0) {
|
show_isis_database_lspdb(vty, area, level,
|
||||||
lsp = NULL;
|
&area->lspdb[level], argv,
|
||||||
lsp = lsp_for_arg(&area->lspdb[level], argv,
|
ui_level);
|
||||||
isis);
|
|
||||||
|
|
||||||
if (lsp != NULL || argv == NULL) {
|
|
||||||
vty_out(vty,
|
|
||||||
"IS-IS Level-%d link-state database:\n",
|
|
||||||
level + 1);
|
|
||||||
|
|
||||||
/* print the title in all cases */
|
|
||||||
vty_out(vty,
|
|
||||||
"LSP ID PduLen SeqNumber Chksum Holdtime ATT/P/OL\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lsp) {
|
|
||||||
if (ui_level == ISIS_UI_LEVEL_DETAIL)
|
|
||||||
lsp_print_detail(
|
|
||||||
lsp, vty,
|
|
||||||
area->dynhostname,
|
|
||||||
isis);
|
|
||||||
else
|
|
||||||
lsp_print(lsp, vty,
|
|
||||||
area->dynhostname,
|
|
||||||
isis);
|
|
||||||
} else if (argv == NULL) {
|
|
||||||
lsp_count = lsp_print_all(
|
|
||||||
vty, &area->lspdb[level],
|
|
||||||
ui_level, area->dynhostname,
|
|
||||||
isis);
|
|
||||||
|
|
||||||
vty_out(vty, " %u LSPs\n\n",
|
|
||||||
lsp_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return CMD_SUCCESS;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* This function supports following display options:
|
* This function supports following display options:
|
||||||
@ -1918,19 +1923,19 @@ static int show_isis_database_common(struct vty *vty, const char *argv,
|
|||||||
static int show_isis_database(struct vty *vty, const char *argv, int ui_level,
|
static int show_isis_database(struct vty *vty, const char *argv, int ui_level,
|
||||||
const char *vrf_name, bool all_vrf)
|
const char *vrf_name, bool all_vrf)
|
||||||
{
|
{
|
||||||
struct listnode *inode, *nnode;
|
struct listnode *node;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
if (vrf_name) {
|
if (vrf_name) {
|
||||||
if (all_vrf) {
|
if (all_vrf) {
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||||
show_isis_database_common(vty, argv, ui_level,
|
show_isis_database_common(vty, argv, ui_level,
|
||||||
isis);
|
isis);
|
||||||
}
|
|
||||||
return 0;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
isis = isis_lookup_by_vrfname(vrf_name);
|
isis = isis_lookup_by_vrfname(vrf_name);
|
||||||
if (isis != NULL)
|
if (isis)
|
||||||
show_isis_database_common(vty, argv, ui_level, isis);
|
show_isis_database_common(vty, argv, ui_level, isis);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2352,16 +2357,15 @@ static int isis_config_write(struct vty *vty)
|
|||||||
{
|
{
|
||||||
int write = 0;
|
int write = 0;
|
||||||
struct isis_area *area;
|
struct isis_area *area;
|
||||||
struct listnode *node, *node2, *inode, *nnode;
|
struct listnode *node, *node2, *inode;
|
||||||
struct isis *isis = NULL;
|
struct isis *isis;
|
||||||
|
|
||||||
if (!im) {
|
if (!im) {
|
||||||
vty_out(vty, "IS-IS Routing Process not enabled\n");
|
vty_out(vty, "IS-IS Routing Process not enabled\n");
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
|
for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
||||||
/* ISIS - Area name */
|
/* ISIS - Area name */
|
||||||
vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag);
|
vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag);
|
||||||
|
@ -76,6 +76,7 @@ struct isis_master {
|
|||||||
/* Various OSPF global configuration. */
|
/* Various OSPF global configuration. */
|
||||||
uint8_t options;
|
uint8_t options;
|
||||||
};
|
};
|
||||||
|
#define F_ISIS_UNIT_TEST 0x01
|
||||||
|
|
||||||
struct isis {
|
struct isis {
|
||||||
vrf_id_t vrf_id;
|
vrf_id_t vrf_id;
|
||||||
@ -215,7 +216,7 @@ void isis_vrf_unlink(struct isis *isis, struct vrf *vrf);
|
|||||||
void isis_global_instance_create(void);
|
void isis_global_instance_create(void);
|
||||||
struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id);
|
struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id);
|
||||||
struct isis *isis_lookup_by_vrfname(const char *vrfname);
|
struct isis *isis_lookup_by_vrfname(const char *vrfname);
|
||||||
struct isis *isis_lookup_by_sysid(uint8_t *sysid);
|
struct isis *isis_lookup_by_sysid(const uint8_t *sysid);
|
||||||
|
|
||||||
void isis_init(void);
|
void isis_init(void);
|
||||||
struct isis *isis_new(vrf_id_t vrf_id);
|
struct isis *isis_new(vrf_id_t vrf_id);
|
||||||
@ -247,6 +248,9 @@ int isis_area_passwd_cleartext_set(struct isis_area *area, int level,
|
|||||||
const char *passwd, uint8_t snp_auth);
|
const char *passwd, uint8_t snp_auth);
|
||||||
int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
|
int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
|
||||||
const char *passwd, uint8_t snp_auth);
|
const char *passwd, uint8_t snp_auth);
|
||||||
|
void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
|
||||||
|
int level, struct lspdb_head *lspdb,
|
||||||
|
const char *argv, int ui_level);
|
||||||
|
|
||||||
/* YANG paths */
|
/* YANG paths */
|
||||||
#define ISIS_INSTANCE "/frr-isisd:isis/instance"
|
#define ISIS_INSTANCE "/frr-isisd:isis/instance"
|
||||||
|
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -13,6 +13,7 @@
|
|||||||
/isisd/test_fuzz_isis_tlv
|
/isisd/test_fuzz_isis_tlv
|
||||||
/isisd/test_fuzz_isis_tlv_tests.h
|
/isisd/test_fuzz_isis_tlv_tests.h
|
||||||
/isisd/test_isis_lspdb
|
/isisd/test_isis_lspdb
|
||||||
|
/isisd/test_isis_spf
|
||||||
/isisd/test_isis_vertex_queue
|
/isisd/test_isis_vertex_queue
|
||||||
/lib/cli/test_cli
|
/lib/cli/test_cli
|
||||||
/lib/cli/test_cli_clippy.c
|
/lib/cli/test_cli_clippy.c
|
||||||
|
331
tests/isisd/test_common.c
Normal file
331
tests/isisd/test_common.c
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 NetDEF, Inc.
|
||||||
|
* Renato Westphal
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; see the file COPYING; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zebra.h>
|
||||||
|
|
||||||
|
#include "isisd/isisd.h"
|
||||||
|
#include "isisd/isis_dynhn.h"
|
||||||
|
#include "isisd/isis_mt.h"
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
struct thread_master *master;
|
||||||
|
struct zebra_privs_t isisd_privs;
|
||||||
|
|
||||||
|
int isis_sock_init(struct isis_circuit *circuit)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct isis_test_node *
|
||||||
|
test_topology_find_node(const struct isis_topology *topology,
|
||||||
|
const char *hostname, uint8_t pseudonode_id)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; topology->nodes[i].hostname[0]; i++)
|
||||||
|
if (strmatch(hostname, topology->nodes[i].hostname)
|
||||||
|
&& pseudonode_id == topology->nodes[i].pseudonode_id)
|
||||||
|
return &topology->nodes[i];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct isis_topology *
|
||||||
|
test_topology_find(struct isis_topology *test_topologies, uint16_t number)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; test_topologies[i].number; i++)
|
||||||
|
if (test_topologies[i].number == number)
|
||||||
|
return &test_topologies[i];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct isis_test_node *
|
||||||
|
test_find_adjacency(const struct isis_test_node *tnode, const char *hostname)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; tnode->adjacencies[i].hostname[0]; i++) {
|
||||||
|
const struct isis_test_adj *tadj;
|
||||||
|
|
||||||
|
tadj = &tnode->adjacencies[i];
|
||||||
|
if (strmatch(hostname, tadj->hostname))
|
||||||
|
return tnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct isis_lsp *lsp_add(struct lspdb_head *lspdb,
|
||||||
|
struct isis_area *area, int level,
|
||||||
|
const uint8_t *sysid, uint8_t pseudonode_id)
|
||||||
|
{
|
||||||
|
struct isis_lsp *lsp;
|
||||||
|
uint8_t lspid[ISIS_SYS_ID_LEN + 2];
|
||||||
|
|
||||||
|
memcpy(lspid, sysid, ISIS_SYS_ID_LEN);
|
||||||
|
LSP_PSEUDO_ID(lspid) = pseudonode_id;
|
||||||
|
LSP_FRAGMENT(lspid) = 0;
|
||||||
|
|
||||||
|
lsp = lsp_new(area, lspid, 6000, 1, 0, 0, NULL, level);
|
||||||
|
lsp->tlvs = isis_alloc_tlvs();
|
||||||
|
lspdb_add(lspdb, lsp);
|
||||||
|
|
||||||
|
return lsp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lsp_add_ip_reach(struct isis_lsp *lsp,
|
||||||
|
const struct isis_test_node *tnode,
|
||||||
|
const char *prefix_str, uint32_t *next_sid_index)
|
||||||
|
{
|
||||||
|
struct prefix prefix;
|
||||||
|
struct sr_prefix_cfg pcfg = {};
|
||||||
|
struct sr_prefix_cfg *pcfg_p = NULL;
|
||||||
|
|
||||||
|
if (str2prefix(prefix_str, &prefix) != 1) {
|
||||||
|
zlog_debug("%s: invalid network: %s", __func__, prefix_str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
|
||||||
|
pcfg_p = &pcfg;
|
||||||
|
|
||||||
|
pcfg.sid = *next_sid_index;
|
||||||
|
*next_sid_index = *next_sid_index + 1;
|
||||||
|
pcfg.sid_type = SR_SID_VALUE_TYPE_INDEX;
|
||||||
|
pcfg.last_hop_behavior = SR_LAST_HOP_BEHAVIOR_PHP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefix.family == AF_INET)
|
||||||
|
isis_tlvs_add_extended_ip_reach(lsp->tlvs,
|
||||||
|
(struct prefix_ipv4 *)&prefix,
|
||||||
|
10, false, pcfg_p);
|
||||||
|
else
|
||||||
|
isis_tlvs_add_ipv6_reach(lsp->tlvs, ISIS_MT_IPV6_UNICAST,
|
||||||
|
(struct prefix_ipv6 *)&prefix, 10,
|
||||||
|
false, pcfg_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lsp_add_reach(struct isis_lsp *lsp,
|
||||||
|
const struct isis_test_node *tnode,
|
||||||
|
const uint8_t *ne_id, uint8_t pseudonode_id,
|
||||||
|
uint32_t metric, int family, mpls_label_t *next_label)
|
||||||
|
{
|
||||||
|
uint8_t nodeid[ISIS_SYS_ID_LEN + 1];
|
||||||
|
uint16_t mtid;
|
||||||
|
struct isis_ext_subtlvs *ext = NULL;
|
||||||
|
|
||||||
|
memcpy(nodeid, ne_id, ISIS_SYS_ID_LEN);
|
||||||
|
LSP_PSEUDO_ID(nodeid) = pseudonode_id;
|
||||||
|
|
||||||
|
if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
|
||||||
|
struct isis_adj_sid *adj_sid;
|
||||||
|
|
||||||
|
adj_sid = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*adj_sid));
|
||||||
|
adj_sid->family = family;
|
||||||
|
SET_FLAG(adj_sid->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG);
|
||||||
|
SET_FLAG(adj_sid->flags, EXT_SUBTLV_LINK_ADJ_SID_LFLG);
|
||||||
|
if (family == AF_INET6)
|
||||||
|
SET_FLAG(adj_sid->flags, EXT_SUBTLV_LINK_ADJ_SID_FFLG);
|
||||||
|
adj_sid->weight = 0;
|
||||||
|
adj_sid->sid = *next_label;
|
||||||
|
*next_label = *next_label + 1;
|
||||||
|
|
||||||
|
ext = isis_alloc_ext_subtlvs();
|
||||||
|
isis_tlvs_add_adj_sid(ext, adj_sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
mtid = (family == AF_INET) ? ISIS_MT_IPV4_UNICAST
|
||||||
|
: ISIS_MT_IPV6_UNICAST;
|
||||||
|
|
||||||
|
isis_tlvs_add_extended_reach(lsp->tlvs, mtid, nodeid, metric, ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lsp_add_router_capability(struct isis_lsp *lsp,
|
||||||
|
const struct isis_test_node *tnode)
|
||||||
|
{
|
||||||
|
struct isis_router_cap cap = {};
|
||||||
|
|
||||||
|
if (!tnode->router_id)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (inet_pton(AF_INET, tnode->router_id, &cap.router_id) != 1) {
|
||||||
|
zlog_debug("%s: invalid router-id: %s", __func__,
|
||||||
|
tnode->router_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CHECK_FLAG(tnode->flags, F_ISIS_TEST_NODE_SR)) {
|
||||||
|
cap.srgb.flags =
|
||||||
|
ISIS_SUBTLV_SRGB_FLAG_I | ISIS_SUBTLV_SRGB_FLAG_V;
|
||||||
|
cap.srgb.lower_bound = tnode->srgb.lower_bound
|
||||||
|
? tnode->srgb.lower_bound
|
||||||
|
: SRGB_DFTL_LOWER_BOUND;
|
||||||
|
cap.srgb.range_size = tnode->srgb.range_size
|
||||||
|
? tnode->srgb.range_size
|
||||||
|
: SRGB_DFTL_RANGE_SIZE;
|
||||||
|
cap.algo[0] = SR_ALGORITHM_SPF;
|
||||||
|
cap.algo[1] = SR_ALGORITHM_UNSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
isis_tlvs_set_router_capability(lsp->tlvs, &cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lsp_add_mt_router_info(struct isis_lsp *lsp,
|
||||||
|
const struct isis_test_node *tnode)
|
||||||
|
{
|
||||||
|
if (tnode->protocols.ipv4)
|
||||||
|
isis_tlvs_add_mt_router_info(lsp->tlvs, ISIS_MT_IPV4_UNICAST, 0,
|
||||||
|
false);
|
||||||
|
if (tnode->protocols.ipv6)
|
||||||
|
isis_tlvs_add_mt_router_info(lsp->tlvs, ISIS_MT_IPV6_UNICAST, 0,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lsp_add_protocols_supported(struct isis_lsp *lsp,
|
||||||
|
const struct isis_test_node *tnode)
|
||||||
|
{
|
||||||
|
struct nlpids nlpids = {};
|
||||||
|
|
||||||
|
if (!tnode->protocols.ipv4 && !tnode->protocols.ipv6)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tnode->protocols.ipv4) {
|
||||||
|
nlpids.nlpids[nlpids.count] = NLPID_IP;
|
||||||
|
nlpids.count++;
|
||||||
|
}
|
||||||
|
if (tnode->protocols.ipv6) {
|
||||||
|
nlpids.nlpids[nlpids.count] = NLPID_IPV6;
|
||||||
|
nlpids.count++;
|
||||||
|
}
|
||||||
|
isis_tlvs_set_protocols_supported(lsp->tlvs, &nlpids);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int topology_load_node_level(const struct isis_topology *topology,
|
||||||
|
const struct isis_test_node *tnode,
|
||||||
|
size_t tnode_index, struct isis_area *area,
|
||||||
|
struct lspdb_head *lspdb, int level)
|
||||||
|
{
|
||||||
|
struct isis_lsp *lsp;
|
||||||
|
uint32_t next_sid_index = (tnode_index + 1) * 10;
|
||||||
|
mpls_label_t next_label = 16;
|
||||||
|
|
||||||
|
lsp = lsp_add(lspdb, area, level, tnode->sysid, tnode->pseudonode_id);
|
||||||
|
lsp_add_mt_router_info(lsp, tnode);
|
||||||
|
lsp_add_protocols_supported(lsp, tnode);
|
||||||
|
lsp_add_router_capability(lsp, tnode);
|
||||||
|
|
||||||
|
/* Add IP Reachability Information. */
|
||||||
|
for (size_t i = 0; tnode->networks[i]; i++) {
|
||||||
|
if (i > MAX_NETWORKS) {
|
||||||
|
zlog_debug(
|
||||||
|
"%s: node has too many networks (maximum is %u)",
|
||||||
|
__func__, MAX_NETWORKS);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
lsp_add_ip_reach(lsp, tnode, tnode->networks[i],
|
||||||
|
&next_sid_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add IS Reachability Information. */
|
||||||
|
for (size_t i = 0; tnode->adjacencies[i].hostname[0]; i++) {
|
||||||
|
const struct isis_test_adj *tadj;
|
||||||
|
const struct isis_test_node *tadj_node;
|
||||||
|
|
||||||
|
if (i > MAX_ADJACENCIES) {
|
||||||
|
zlog_debug(
|
||||||
|
"%s: node has too many adjacencies (maximum is %u)",
|
||||||
|
__func__, MAX_ADJACENCIES);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
tadj = &tnode->adjacencies[i];
|
||||||
|
tadj_node = test_topology_find_node(topology, tadj->hostname,
|
||||||
|
tadj->pseudonode_id);
|
||||||
|
if (!tadj_node) {
|
||||||
|
zlog_debug(
|
||||||
|
"%s: node \"%s\" has an adjacency with non-existing node \"%s\"",
|
||||||
|
__func__, tnode->hostname, tadj->hostname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!test_find_adjacency(tadj_node, tnode->hostname)) {
|
||||||
|
zlog_debug(
|
||||||
|
"%s: node \"%s\" has an one-way adjacency with node \"%s\"",
|
||||||
|
__func__, tnode->hostname, tadj->hostname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tnode->pseudonode_id || tadj_node->pseudonode_id
|
||||||
|
|| (tnode->protocols.ipv4 && tadj_node->protocols.ipv4))
|
||||||
|
lsp_add_reach(lsp, tnode, tadj_node->sysid,
|
||||||
|
tadj_node->pseudonode_id, tadj->metric,
|
||||||
|
AF_INET, &next_label);
|
||||||
|
if (tadj_node->pseudonode_id
|
||||||
|
|| (tnode->protocols.ipv6 && tadj_node->protocols.ipv6))
|
||||||
|
lsp_add_reach(lsp, tnode, tadj_node->sysid,
|
||||||
|
tadj_node->pseudonode_id, tadj->metric,
|
||||||
|
AF_INET6, &next_label);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int topology_load_node(const struct isis_topology *topology,
|
||||||
|
const struct isis_test_node *tnode,
|
||||||
|
size_t tnode_index, struct isis_area *area,
|
||||||
|
struct lspdb_head lspdb[])
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
isis_dynhn_insert(tnode->sysid, tnode->hostname, tnode->level);
|
||||||
|
|
||||||
|
for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
|
||||||
|
if ((tnode->level & level) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = topology_load_node_level(topology, tnode, tnode_index,
|
||||||
|
area, &lspdb[level - 1], level);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_topology_load(const struct isis_topology *topology,
|
||||||
|
struct isis_area *area, struct lspdb_head lspdb[])
|
||||||
|
{
|
||||||
|
for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++)
|
||||||
|
lsp_db_init(&lspdb[level - 1]);
|
||||||
|
|
||||||
|
for (size_t i = 0; topology->nodes[i].hostname[0]; i++) {
|
||||||
|
const struct isis_test_node *tnode = &topology->nodes[i];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (i > MAX_NODES) {
|
||||||
|
zlog_debug(
|
||||||
|
"%s: topology has too many nodes (maximum is %u)",
|
||||||
|
__func__, MAX_NODES);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = topology_load_node(topology, tnode, i, area, lspdb);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
82
tests/isisd/test_common.h
Normal file
82
tests/isisd/test_common.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 NetDEF, Inc.
|
||||||
|
* Renato Westphal
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; see the file COPYING; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _COMMON_ISIS_H
|
||||||
|
#define _COMMON_ISIS_H
|
||||||
|
|
||||||
|
#include "isisd/isisd.h"
|
||||||
|
#include "isisd/isis_spf.h"
|
||||||
|
#include "isisd/isis_spf_private.h"
|
||||||
|
|
||||||
|
#define MAX_HOSTNAME 16
|
||||||
|
#define MAX_NETWORKS 8
|
||||||
|
#define MAX_ADJACENCIES 8
|
||||||
|
#define MAX_NODES 12
|
||||||
|
|
||||||
|
#define SRGB_DFTL_LOWER_BOUND 16000
|
||||||
|
#define SRGB_DFTL_RANGE_SIZE 8000
|
||||||
|
|
||||||
|
struct isis_test_adj {
|
||||||
|
char hostname[MAX_HOSTNAME];
|
||||||
|
uint8_t pseudonode_id;
|
||||||
|
uint32_t metric;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct isis_test_node {
|
||||||
|
char hostname[MAX_HOSTNAME];
|
||||||
|
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||||
|
uint8_t pseudonode_id;
|
||||||
|
int level;
|
||||||
|
struct {
|
||||||
|
bool ipv4;
|
||||||
|
bool ipv6;
|
||||||
|
} protocols;
|
||||||
|
const char *router_id;
|
||||||
|
struct {
|
||||||
|
uint32_t lower_bound;
|
||||||
|
uint32_t range_size;
|
||||||
|
} srgb;
|
||||||
|
const char *networks[MAX_NETWORKS + 1];
|
||||||
|
struct isis_test_adj adjacencies[MAX_ADJACENCIES + 1];
|
||||||
|
uint8_t flags;
|
||||||
|
};
|
||||||
|
#define F_ISIS_TEST_NODE_SR 0x01
|
||||||
|
|
||||||
|
struct isis_topology {
|
||||||
|
uint16_t number;
|
||||||
|
struct isis_test_node nodes[MAX_NODES + 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Prototypes. */
|
||||||
|
extern int isis_sock_init(struct isis_circuit *circuit);
|
||||||
|
extern const struct isis_test_node *
|
||||||
|
test_topology_find_node(const struct isis_topology *topology,
|
||||||
|
const char *hostname, uint8_t pseudonode_id);
|
||||||
|
extern const struct isis_topology *
|
||||||
|
test_topology_find(struct isis_topology *test_topologies, uint16_t number);
|
||||||
|
extern int test_topology_load(const struct isis_topology *topology,
|
||||||
|
struct isis_area *area,
|
||||||
|
struct lspdb_head lspdb[]);
|
||||||
|
|
||||||
|
/* Global variables. */
|
||||||
|
extern struct thread_master *master;
|
||||||
|
extern struct zebra_privs_t isisd_privs;
|
||||||
|
extern struct isis_topology test_topologies[];
|
||||||
|
|
||||||
|
#endif /* _COMMON_ISIS_H */
|
@ -14,17 +14,10 @@
|
|||||||
#include "isisd/isis_circuit.h"
|
#include "isisd/isis_circuit.h"
|
||||||
#include "isisd/isis_tlvs.h"
|
#include "isisd/isis_tlvs.h"
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
#define TEST_STREAM_SIZE 1500
|
#define TEST_STREAM_SIZE 1500
|
||||||
|
|
||||||
struct thread_master *master;
|
|
||||||
int isis_sock_init(struct isis_circuit *circuit);
|
|
||||||
int isis_sock_init(struct isis_circuit *circuit)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct zebra_privs_t isisd_privs;
|
|
||||||
|
|
||||||
static bool atexit_registered;
|
static bool atexit_registered;
|
||||||
|
|
||||||
static void show_meminfo_at_exit(void)
|
static void show_meminfo_at_exit(void)
|
||||||
|
@ -2,15 +2,7 @@
|
|||||||
|
|
||||||
#include "isisd/isis_lsp.c"
|
#include "isisd/isis_lsp.c"
|
||||||
|
|
||||||
struct thread_master *master;
|
#include "test_common.h"
|
||||||
|
|
||||||
int isis_sock_init(struct isis_circuit *circuit);
|
|
||||||
int isis_sock_init(struct isis_circuit *circuit)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct zebra_privs_t isisd_privs;
|
|
||||||
|
|
||||||
static void test_lsp_build_list_nonzero_ht(void)
|
static void test_lsp_build_list_nonzero_ht(void)
|
||||||
{
|
{
|
||||||
|
313
tests/isisd/test_isis_spf.c
Normal file
313
tests/isisd/test_isis_spf.c
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 NetDEF, Inc.
|
||||||
|
* Renato Westphal
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; see the file COPYING; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zebra.h>
|
||||||
|
|
||||||
|
#include <lib/version.h>
|
||||||
|
#include "getopt.h"
|
||||||
|
#include "thread.h"
|
||||||
|
#include "vty.h"
|
||||||
|
#include "command.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "vrf.h"
|
||||||
|
#include "yang.h"
|
||||||
|
|
||||||
|
#include "isisd/isisd.h"
|
||||||
|
#include "isisd/isis_dynhn.h"
|
||||||
|
#include "isisd/isis_misc.h"
|
||||||
|
#include "isisd/isis_spf.h"
|
||||||
|
#include "isisd/isis_spf_private.h"
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
enum test_type {
|
||||||
|
TEST_SPF = 1,
|
||||||
|
TEST_REVERSE_SPF,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define F_DISPLAY_LSPDB 0x01
|
||||||
|
#define F_IPV4_ONLY 0x02
|
||||||
|
#define F_IPV6_ONLY 0x04
|
||||||
|
#define F_LEVEL1_ONLY 0x08
|
||||||
|
#define F_LEVEL2_ONLY 0x10
|
||||||
|
|
||||||
|
static struct isis *isis;
|
||||||
|
|
||||||
|
static void test_run_spf(struct vty *vty, const struct isis_topology *topology,
|
||||||
|
const struct isis_test_node *root,
|
||||||
|
struct isis_area *area, struct lspdb_head *lspdb,
|
||||||
|
int level, int tree, bool reverse)
|
||||||
|
{
|
||||||
|
struct isis_spftree *spftree;
|
||||||
|
enum spf_type spf_type;
|
||||||
|
|
||||||
|
/* Run SPF. */
|
||||||
|
spf_type = reverse ? SPF_TYPE_REVERSE : SPF_TYPE_FORWARD;
|
||||||
|
spftree = isis_spftree_new(area, lspdb, root->sysid, level, tree,
|
||||||
|
spf_type, F_SPFTREE_NO_ADJACENCIES);
|
||||||
|
isis_run_spf(spftree);
|
||||||
|
|
||||||
|
/* Print the SPT and the corresponding routing table. */
|
||||||
|
isis_print_spftree(vty, spftree);
|
||||||
|
isis_print_routes(vty, spftree);
|
||||||
|
|
||||||
|
/* Cleanup SPF tree. */
|
||||||
|
isis_spftree_del(spftree);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_run(struct vty *vty, const struct isis_topology *topology,
|
||||||
|
const struct isis_test_node *root, enum test_type test_type,
|
||||||
|
uint8_t flags)
|
||||||
|
{
|
||||||
|
struct isis_area *area;
|
||||||
|
|
||||||
|
/* Init topology. */
|
||||||
|
memcpy(isis->sysid, root->sysid, sizeof(isis->sysid));
|
||||||
|
area = isis_area_create("1", NULL);
|
||||||
|
area->is_type = IS_LEVEL_1_AND_2;
|
||||||
|
area->srdb.enabled = true;
|
||||||
|
if (test_topology_load(topology, area, area->lspdb) != 0) {
|
||||||
|
vty_out(vty, "%% Failed to load topology\n");
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
|
||||||
|
if (level == IS_LEVEL_1 && CHECK_FLAG(flags, F_LEVEL2_ONLY))
|
||||||
|
continue;
|
||||||
|
if (level == IS_LEVEL_2 && CHECK_FLAG(flags, F_LEVEL1_ONLY))
|
||||||
|
continue;
|
||||||
|
if ((root->level & level) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Print the LDPDB. */
|
||||||
|
if (CHECK_FLAG(flags, F_DISPLAY_LSPDB))
|
||||||
|
show_isis_database_lspdb(vty, area, level - 1,
|
||||||
|
&area->lspdb[level - 1], NULL,
|
||||||
|
ISIS_UI_LEVEL_DETAIL);
|
||||||
|
|
||||||
|
for (int tree = SPFTREE_IPV4; tree <= SPFTREE_IPV6; tree++) {
|
||||||
|
if (tree == SPFTREE_IPV4
|
||||||
|
&& CHECK_FLAG(flags, F_IPV6_ONLY))
|
||||||
|
continue;
|
||||||
|
if (tree == SPFTREE_IPV6
|
||||||
|
&& CHECK_FLAG(flags, F_IPV4_ONLY))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (test_type) {
|
||||||
|
case TEST_SPF:
|
||||||
|
test_run_spf(vty, topology, root, area,
|
||||||
|
&area->lspdb[level - 1], level,
|
||||||
|
tree, false);
|
||||||
|
break;
|
||||||
|
case TEST_REVERSE_SPF:
|
||||||
|
test_run_spf(vty, topology, root, area,
|
||||||
|
&area->lspdb[level - 1], level,
|
||||||
|
tree, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cleanup IS-IS area. */
|
||||||
|
isis_area_destroy(area);
|
||||||
|
|
||||||
|
/* Cleanup hostnames. */
|
||||||
|
dyn_cache_cleanup_all();
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN(test_isis, test_isis_cmd,
|
||||||
|
"test isis topology (1-13) root HOSTNAME\
|
||||||
|
<\
|
||||||
|
spf\
|
||||||
|
|reverse-spf\
|
||||||
|
>\
|
||||||
|
[display-lspdb] [<ipv4-only|ipv6-only>] [<level-1-only|level-2-only>]",
|
||||||
|
"Test command\n"
|
||||||
|
"IS-IS routing protocol\n"
|
||||||
|
"Test topology\n"
|
||||||
|
"Test topology number\n"
|
||||||
|
"SPF root\n"
|
||||||
|
"SPF root hostname\n"
|
||||||
|
"Normal Shortest Path First\n"
|
||||||
|
"Reverse Shortest Path First\n"
|
||||||
|
"Display the LSPDB\n"
|
||||||
|
"Do IPv4 processing only\n"
|
||||||
|
"Do IPv6 processing only\n"
|
||||||
|
"Skip L2 LSPs\n"
|
||||||
|
"Skip L1 LSPs\n")
|
||||||
|
{
|
||||||
|
uint16_t topology_number;
|
||||||
|
const struct isis_topology *topology;
|
||||||
|
const struct isis_test_node *root;
|
||||||
|
enum test_type test_type;
|
||||||
|
uint8_t flags = 0;
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
/* Load topology. */
|
||||||
|
argv_find(argv, argc, "topology", &idx);
|
||||||
|
topology_number = atoi(argv[idx + 1]->arg);
|
||||||
|
topology = test_topology_find(test_topologies, topology_number);
|
||||||
|
if (!topology) {
|
||||||
|
vty_out(vty, "%% Topology \"%s\" not found\n",
|
||||||
|
argv[idx + 1]->arg);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find root node. */
|
||||||
|
argv_find(argv, argc, "root", &idx);
|
||||||
|
root = test_topology_find_node(topology, argv[idx + 1]->arg, 0);
|
||||||
|
if (!root) {
|
||||||
|
vty_out(vty, "%% Node \"%s\" not found\n", argv[idx + 1]->arg);
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse test information. */
|
||||||
|
if (argv_find(argv, argc, "spf", &idx))
|
||||||
|
test_type = TEST_SPF;
|
||||||
|
else if (argv_find(argv, argc, "reverse-spf", &idx))
|
||||||
|
test_type = TEST_REVERSE_SPF;
|
||||||
|
else
|
||||||
|
return CMD_WARNING;
|
||||||
|
|
||||||
|
/* Parse control flags. */
|
||||||
|
if (argv_find(argv, argc, "display-lspdb", &idx))
|
||||||
|
SET_FLAG(flags, F_DISPLAY_LSPDB);
|
||||||
|
if (argv_find(argv, argc, "ipv4-only", &idx))
|
||||||
|
SET_FLAG(flags, F_IPV4_ONLY);
|
||||||
|
else if (argv_find(argv, argc, "ipv6-only", &idx))
|
||||||
|
SET_FLAG(flags, F_IPV6_ONLY);
|
||||||
|
if (argv_find(argv, argc, "level-1-only", &idx))
|
||||||
|
SET_FLAG(flags, F_LEVEL1_ONLY);
|
||||||
|
else if (argv_find(argv, argc, "level-2-only", &idx))
|
||||||
|
SET_FLAG(flags, F_LEVEL2_ONLY);
|
||||||
|
|
||||||
|
return test_run(vty, topology, root, test_type, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void vty_do_exit(int isexit)
|
||||||
|
{
|
||||||
|
printf("\nend.\n");
|
||||||
|
|
||||||
|
isis_finish(isis);
|
||||||
|
cmd_terminate();
|
||||||
|
vty_terminate();
|
||||||
|
yang_terminate();
|
||||||
|
thread_master_free(master);
|
||||||
|
|
||||||
|
log_memstats(stderr, "test-isis-spf");
|
||||||
|
if (!isexit)
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct option longopts[] = {{"help", no_argument, NULL, 'h'},
|
||||||
|
{"debug", no_argument, NULL, 'd'},
|
||||||
|
{0}};
|
||||||
|
|
||||||
|
/* Help information display. */
|
||||||
|
static void usage(char *progname, int status)
|
||||||
|
{
|
||||||
|
if (status != 0)
|
||||||
|
fprintf(stderr, "Try `%s --help' for more information.\n",
|
||||||
|
progname);
|
||||||
|
else {
|
||||||
|
printf("Usage : %s [OPTION...]\n\
|
||||||
|
isisd SPF test program.\n\n\
|
||||||
|
-u, --debug Enable debugging\n\
|
||||||
|
-h, --help Display this help and exit\n\
|
||||||
|
\n\
|
||||||
|
Report bugs to %s\n",
|
||||||
|
progname, FRR_BUG_ADDRESS);
|
||||||
|
}
|
||||||
|
exit(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
char *progname;
|
||||||
|
struct thread thread;
|
||||||
|
bool debug = false;
|
||||||
|
|
||||||
|
/* Set umask before anything for security */
|
||||||
|
umask(0027);
|
||||||
|
|
||||||
|
/* get program name */
|
||||||
|
progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
opt = getopt_long(argc, argv, "hd", longopts, 0);
|
||||||
|
|
||||||
|
if (opt == EOF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (opt) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
debug = true;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
usage(progname, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(progname, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* master init. */
|
||||||
|
master = thread_master_create(NULL);
|
||||||
|
isis_master_init(master);
|
||||||
|
|
||||||
|
/* Library inits. */
|
||||||
|
cmd_init(1);
|
||||||
|
cmd_hostname_set("test");
|
||||||
|
vty_init(master, false);
|
||||||
|
yang_init(true);
|
||||||
|
if (debug)
|
||||||
|
zlog_aux_init("NONE: ", LOG_DEBUG);
|
||||||
|
else
|
||||||
|
zlog_aux_init("NONE: ", ZLOG_DISABLED);
|
||||||
|
|
||||||
|
/* IS-IS inits. */
|
||||||
|
yang_module_load("frr-isisd");
|
||||||
|
isis = isis_new(VRF_DEFAULT);
|
||||||
|
listnode_add(im->isis, isis);
|
||||||
|
SET_FLAG(im->options, F_ISIS_UNIT_TEST);
|
||||||
|
debug_spf_events |= DEBUG_SPF_EVENTS;
|
||||||
|
debug_events |= DEBUG_EVENTS;
|
||||||
|
debug_rte_events |= DEBUG_RTE_EVENTS;
|
||||||
|
|
||||||
|
/* Install test command. */
|
||||||
|
install_element(VIEW_NODE, &test_isis_cmd);
|
||||||
|
|
||||||
|
/* Read input from .in file. */
|
||||||
|
vty_stdio(vty_do_exit);
|
||||||
|
|
||||||
|
/* Fetch next active thread. */
|
||||||
|
while (thread_fetch(master, &thread))
|
||||||
|
thread_call(&thread);
|
||||||
|
|
||||||
|
/* Not reached. */
|
||||||
|
exit(0);
|
||||||
|
}
|
16
tests/isisd/test_isis_spf.in
Normal file
16
tests/isisd/test_isis_spf.in
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
test isis topology 1 root rt1 spf
|
||||||
|
test isis topology 2 root rt1 spf
|
||||||
|
test isis topology 3 root rt1 spf ipv4-only
|
||||||
|
test isis topology 4 root rt1 spf ipv4-only
|
||||||
|
test isis topology 5 root rt1 spf ipv4-only
|
||||||
|
test isis topology 6 root rt1 spf ipv4-only
|
||||||
|
test isis topology 7 root rt1 spf ipv4-only
|
||||||
|
test isis topology 8 root rt1 spf ipv4-only
|
||||||
|
test isis topology 9 root rt1 spf
|
||||||
|
test isis topology 10 root rt1 spf
|
||||||
|
test isis topology 11 root rt1 spf
|
||||||
|
test isis topology 12 root rt1 spf ipv4-only
|
||||||
|
test isis topology 13 root rt1 spf ipv4-only
|
||||||
|
|
||||||
|
test isis topology 4 root rt1 reverse-spf ipv4-only
|
||||||
|
test isis topology 11 root rt1 reverse-spf
|
4
tests/isisd/test_isis_spf.py
Normal file
4
tests/isisd/test_isis_spf.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import frrtest
|
||||||
|
|
||||||
|
class TestIsisSPF(frrtest.TestRefOut):
|
||||||
|
program = './test_isis_spf'
|
703
tests/isisd/test_isis_spf.refout
Normal file
703
tests/isisd/test_isis_spf.refout
Normal file
@ -0,0 +1,703 @@
|
|||||||
|
test# test isis topology 1 root rt1 spf
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt3 - rt5(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
|
||||||
|
rt3 -
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
10.0.255.5/32 30 - rt3 -
|
||||||
|
10.0.255.6/32 40 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
|
||||||
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
2001:db8::1/128 IP6 internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
|
||||||
|
2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt3 - rt5(4)
|
||||||
|
2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
|
||||||
|
2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
|
||||||
|
2001:db8::6/128 IP6 internal 40 rt2 - rt6(4)
|
||||||
|
rt3 -
|
||||||
|
|
||||||
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-------------------------------------------------------
|
||||||
|
2001:db8::2/128 20 - rt2 -
|
||||||
|
2001:db8::3/128 20 - rt3 -
|
||||||
|
2001:db8::4/128 30 - rt2 -
|
||||||
|
2001:db8::5/128 30 - rt3 -
|
||||||
|
2001:db8::6/128 40 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
|
||||||
|
test# test isis topology 2 root rt1 spf
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt4 TE-IS 10 rt4 - rt1(4)
|
||||||
|
rt5 TE-IS 10 rt5 - rt1(4)
|
||||||
|
rt2 TE-IS 15 rt2 - rt1(4)
|
||||||
|
rt1
|
||||||
|
rt6 TE-IS 20 rt4 - rt4(4)
|
||||||
|
rt5 - rt5(4)
|
||||||
|
10.0.255.4/32 IP TE 20 rt4 - rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 20 rt5 - rt5(4)
|
||||||
|
10.0.255.2/32 IP TE 25 rt2 - rt2(4)
|
||||||
|
rt3 TE-IS 30 rt3 - rt1(4)
|
||||||
|
10.0.255.6/32 IP TE 30 rt4 - rt6(4)
|
||||||
|
rt5 -
|
||||||
|
10.0.255.3/32 IP TE 40 rt3 - rt3(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 25 - rt2 -
|
||||||
|
10.0.255.3/32 40 - rt3 -
|
||||||
|
10.0.255.4/32 20 - rt4 -
|
||||||
|
10.0.255.5/32 20 - rt5 -
|
||||||
|
10.0.255.6/32 30 - rt4 -
|
||||||
|
- rt5 -
|
||||||
|
|
||||||
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
2001:db8::1/128 IP6 internal 0 rt1(4)
|
||||||
|
rt4 TE-IS 10 rt4 - rt1(4)
|
||||||
|
rt5 TE-IS 10 rt5 - rt1(4)
|
||||||
|
rt2 TE-IS 15 rt2 - rt1(4)
|
||||||
|
rt1
|
||||||
|
rt6 TE-IS 20 rt4 - rt4(4)
|
||||||
|
rt5 - rt5(4)
|
||||||
|
2001:db8::4/128 IP6 internal 20 rt4 - rt4(4)
|
||||||
|
2001:db8::5/128 IP6 internal 20 rt5 - rt5(4)
|
||||||
|
2001:db8::2/128 IP6 internal 25 rt2 - rt2(4)
|
||||||
|
rt3 TE-IS 30 rt3 - rt1(4)
|
||||||
|
2001:db8::6/128 IP6 internal 30 rt4 - rt6(4)
|
||||||
|
rt5 -
|
||||||
|
2001:db8::3/128 IP6 internal 40 rt3 - rt3(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-------------------------------------------------------
|
||||||
|
2001:db8::2/128 25 - rt2 -
|
||||||
|
2001:db8::3/128 40 - rt3 -
|
||||||
|
2001:db8::4/128 20 - rt4 -
|
||||||
|
2001:db8::5/128 20 - rt5 -
|
||||||
|
2001:db8::6/128 30 - rt4 -
|
||||||
|
- rt5 -
|
||||||
|
|
||||||
|
test# test isis topology 3 root rt1 spf ipv4-only
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt5 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 40 rt2 - rt5(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
10.0.255.5/32 40 - rt2 -
|
||||||
|
10.0.255.6/32 40 - rt2 -
|
||||||
|
|
||||||
|
test# test isis topology 4 root rt1 spf ipv4-only
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt7 TE-IS 30 rt3 - rt5(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
|
||||||
|
rt8 TE-IS 40 rt2 - rt6(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
|
||||||
|
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
|
||||||
|
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
10.0.255.5/32 30 - rt3 -
|
||||||
|
10.0.255.6/32 40 - rt2 -
|
||||||
|
10.0.255.7/32 40 - rt3 -
|
||||||
|
10.0.255.8/32 50 - rt2 -
|
||||||
|
|
||||||
|
test# test isis topology 5 root rt1 spf ipv4-only
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt7 TE-IS 30 rt3 - rt5(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
|
||||||
|
rt8 TE-IS 40 rt2 - rt6(4)
|
||||||
|
rt3 - rt7(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
|
||||||
|
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
|
||||||
|
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
|
||||||
|
rt3 -
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
10.0.255.5/32 30 - rt3 -
|
||||||
|
10.0.255.6/32 40 - rt2 -
|
||||||
|
10.0.255.7/32 40 - rt3 -
|
||||||
|
10.0.255.8/32 50 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
|
||||||
|
test# test isis topology 6 root rt1 spf ipv4-only
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt3 - rt3(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt3 -
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
rt3 -
|
||||||
|
rt5 TE-IS 40 rt2 - rt6(4)
|
||||||
|
rt3 -
|
||||||
|
rt8 TE-IS 40 rt2 - rt6(4)
|
||||||
|
rt3 -
|
||||||
|
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
|
||||||
|
rt3 -
|
||||||
|
rt7 TE-IS 50 rt2 - rt5(4)
|
||||||
|
rt3 - rt8(4)
|
||||||
|
10.0.255.5/32 IP TE 50 rt2 - rt5(4)
|
||||||
|
rt3 -
|
||||||
|
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
|
||||||
|
rt3 -
|
||||||
|
10.0.255.7/32 IP TE 60 rt2 - rt7(4)
|
||||||
|
rt3 -
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
10.0.255.5/32 50 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
10.0.255.6/32 40 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
10.0.255.7/32 60 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
10.0.255.8/32 50 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
|
||||||
|
test# test isis topology 7 root rt1 spf ipv4-only
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt4 TE-IS 10 rt4 - rt1(4)
|
||||||
|
rt5 TE-IS 20 rt4 - rt4(4)
|
||||||
|
rt7 TE-IS 20 rt4 - rt4(4)
|
||||||
|
10.0.255.4/32 IP TE 20 rt4 - rt4(4)
|
||||||
|
rt2 TE-IS 30 rt4 - rt5(4)
|
||||||
|
rt6 TE-IS 30 rt4 - rt5(4)
|
||||||
|
rt8 TE-IS 30 rt4 - rt5(4)
|
||||||
|
rt7(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt4 - rt5(4)
|
||||||
|
10.0.255.7/32 IP TE 30 rt4 - rt7(4)
|
||||||
|
rt10 TE-IS 40 rt4 - rt7(4)
|
||||||
|
rt3 TE-IS 40 rt4 - rt2(4)
|
||||||
|
rt6(4)
|
||||||
|
rt9 TE-IS 40 rt4 - rt8(4)
|
||||||
|
rt11 TE-IS 40 rt4 - rt8(4)
|
||||||
|
10.0.255.2/32 IP TE 40 rt4 - rt2(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt4 - rt6(4)
|
||||||
|
10.0.255.8/32 IP TE 40 rt4 - rt8(4)
|
||||||
|
rt12 TE-IS 50 rt4 - rt9(4)
|
||||||
|
rt11(4)
|
||||||
|
10.0.255.10/32 IP TE 50 rt4 - rt10(4)
|
||||||
|
10.0.255.3/32 IP TE 50 rt4 - rt3(4)
|
||||||
|
10.0.255.9/32 IP TE 50 rt4 - rt9(4)
|
||||||
|
10.0.255.11/32 IP TE 50 rt4 - rt11(4)
|
||||||
|
10.0.255.12/32 IP TE 60 rt4 - rt12(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
------------------------------------------------------
|
||||||
|
10.0.255.2/32 40 - rt4 -
|
||||||
|
10.0.255.3/32 50 - rt4 -
|
||||||
|
10.0.255.4/32 20 - rt4 -
|
||||||
|
10.0.255.5/32 30 - rt4 -
|
||||||
|
10.0.255.6/32 40 - rt4 -
|
||||||
|
10.0.255.7/32 30 - rt4 -
|
||||||
|
10.0.255.8/32 40 - rt4 -
|
||||||
|
10.0.255.9/32 50 - rt4 -
|
||||||
|
10.0.255.10/32 50 - rt4 -
|
||||||
|
10.0.255.11/32 50 - rt4 -
|
||||||
|
10.0.255.12/32 60 - rt4 -
|
||||||
|
|
||||||
|
test# test isis topology 8 root rt1 spf ipv4-only
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt4 TE-IS 10 rt4 - rt1(4)
|
||||||
|
rt3 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt5 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt7 TE-IS 20 rt4 - rt4(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.4/32 IP TE 20 rt4 - rt4(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt3(4)
|
||||||
|
rt5(4)
|
||||||
|
rt8 TE-IS 30 rt2 - rt5(4)
|
||||||
|
rt10 TE-IS 30 rt4 - rt7(4)
|
||||||
|
10.0.255.3/32 IP TE 30 rt2 - rt3(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt2 - rt5(4)
|
||||||
|
10.0.255.7/32 IP TE 30 rt4 - rt7(4)
|
||||||
|
rt9 TE-IS 40 rt2 - rt8(4)
|
||||||
|
rt11 TE-IS 40 rt2 - rt8(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
|
||||||
|
10.0.255.8/32 IP TE 40 rt2 - rt8(4)
|
||||||
|
10.0.255.10/32 IP TE 40 rt4 - rt10(4)
|
||||||
|
rt12 TE-IS 50 rt2 - rt9(4)
|
||||||
|
rt11(4)
|
||||||
|
10.0.255.9/32 IP TE 50 rt2 - rt9(4)
|
||||||
|
10.0.255.11/32 IP TE 50 rt2 - rt11(4)
|
||||||
|
10.0.255.12/32 IP TE 60 rt2 - rt12(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
------------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 30 - rt2 -
|
||||||
|
10.0.255.4/32 20 - rt4 -
|
||||||
|
10.0.255.5/32 30 - rt2 -
|
||||||
|
10.0.255.6/32 40 - rt2 -
|
||||||
|
10.0.255.7/32 30 - rt4 -
|
||||||
|
10.0.255.8/32 40 - rt2 -
|
||||||
|
10.0.255.9/32 50 - rt2 -
|
||||||
|
10.0.255.10/32 40 - rt4 -
|
||||||
|
10.0.255.11/32 50 - rt2 -
|
||||||
|
10.0.255.12/32 60 - rt2 -
|
||||||
|
|
||||||
|
test# test isis topology 9 root rt1 spf
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt5 TE-IS 30 rt2 - rt4(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
rt9 TE-IS 40 rt2 - rt5(4)
|
||||||
|
10.0.255.5/32 IP TE 40 rt2 - rt5(4)
|
||||||
|
rt6 TE-IS 50 rt2 - rt4(4)
|
||||||
|
rt9(4)
|
||||||
|
rt7 TE-IS 50 rt2 - rt4(4)
|
||||||
|
rt9(4)
|
||||||
|
rt8 TE-IS 50 rt2 - rt4(4)
|
||||||
|
rt9(4)
|
||||||
|
10.0.255.9/32 IP TE 50 rt2 - rt9(4)
|
||||||
|
10.0.255.6/32 IP TE 60 rt2 - rt6(4)
|
||||||
|
10.0.255.7/32 IP TE 60 rt2 - rt7(4)
|
||||||
|
10.0.255.8/32 IP TE 60 rt2 - rt8(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
10.0.255.5/32 40 - rt2 -
|
||||||
|
10.0.255.6/32 60 - rt2 -
|
||||||
|
10.0.255.7/32 60 - rt2 -
|
||||||
|
10.0.255.8/32 60 - rt2 -
|
||||||
|
10.0.255.9/32 50 - rt2 -
|
||||||
|
|
||||||
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
2001:db8::1/128 IP6 internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
|
||||||
|
2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
|
||||||
|
rt5 TE-IS 30 rt2 - rt4(4)
|
||||||
|
2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
|
||||||
|
rt9 TE-IS 40 rt2 - rt5(4)
|
||||||
|
2001:db8::5/128 IP6 internal 40 rt2 - rt5(4)
|
||||||
|
rt6 TE-IS 50 rt2 - rt4(4)
|
||||||
|
rt9(4)
|
||||||
|
rt7 TE-IS 50 rt2 - rt4(4)
|
||||||
|
rt9(4)
|
||||||
|
rt8 TE-IS 50 rt2 - rt4(4)
|
||||||
|
rt9(4)
|
||||||
|
2001:db8::9/128 IP6 internal 50 rt2 - rt9(4)
|
||||||
|
2001:db8::6/128 IP6 internal 60 rt2 - rt6(4)
|
||||||
|
2001:db8::7/128 IP6 internal 60 rt2 - rt7(4)
|
||||||
|
2001:db8::8/128 IP6 internal 60 rt2 - rt8(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-------------------------------------------------------
|
||||||
|
2001:db8::2/128 20 - rt2 -
|
||||||
|
2001:db8::3/128 20 - rt3 -
|
||||||
|
2001:db8::4/128 30 - rt2 -
|
||||||
|
2001:db8::5/128 40 - rt2 -
|
||||||
|
2001:db8::6/128 60 - rt2 -
|
||||||
|
2001:db8::7/128 60 - rt2 -
|
||||||
|
2001:db8::8/128 60 - rt2 -
|
||||||
|
2001:db8::9/128 50 - rt2 -
|
||||||
|
|
||||||
|
test# test isis topology 10 root rt1 spf
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 20 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt4 - rt1(4)
|
||||||
|
rt5 TE-IS 20 rt2 - rt2(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
rt6 TE-IS 30 rt3 - rt3(4)
|
||||||
|
rt7 TE-IS 30 rt4 - rt4(4)
|
||||||
|
rt8 TE-IS 30 rt2 - rt5(4)
|
||||||
|
10.0.255.3/32 IP TE 30 rt3 - rt3(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt4 - rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt2 - rt5(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt3 - rt6(4)
|
||||||
|
10.0.255.7/32 IP TE 40 rt4 - rt7(4)
|
||||||
|
10.0.255.8/32 IP TE 40 rt2 - rt8(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 30 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt4 -
|
||||||
|
10.0.255.5/32 30 - rt2 -
|
||||||
|
10.0.255.6/32 40 - rt3 -
|
||||||
|
10.0.255.7/32 40 - rt4 -
|
||||||
|
10.0.255.8/32 40 - rt2 -
|
||||||
|
|
||||||
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
2001:db8::1/128 IP6 internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 20 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt4 - rt1(4)
|
||||||
|
rt5 TE-IS 20 rt2 - rt2(4)
|
||||||
|
2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
|
||||||
|
rt6 TE-IS 30 rt3 - rt3(4)
|
||||||
|
rt7 TE-IS 30 rt4 - rt4(4)
|
||||||
|
rt8 TE-IS 30 rt2 - rt5(4)
|
||||||
|
2001:db8::3/128 IP6 internal 30 rt3 - rt3(4)
|
||||||
|
2001:db8::4/128 IP6 internal 30 rt4 - rt4(4)
|
||||||
|
2001:db8::5/128 IP6 internal 30 rt2 - rt5(4)
|
||||||
|
2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
|
||||||
|
2001:db8::7/128 IP6 internal 40 rt4 - rt7(4)
|
||||||
|
2001:db8::8/128 IP6 internal 40 rt2 - rt8(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-------------------------------------------------------
|
||||||
|
2001:db8::2/128 20 - rt2 -
|
||||||
|
2001:db8::3/128 30 - rt3 -
|
||||||
|
2001:db8::4/128 30 - rt4 -
|
||||||
|
2001:db8::5/128 30 - rt2 -
|
||||||
|
2001:db8::6/128 40 - rt3 -
|
||||||
|
2001:db8::7/128 40 - rt4 -
|
||||||
|
2001:db8::8/128 40 - rt2 -
|
||||||
|
|
||||||
|
test# test isis topology 11 root rt1 spf
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt2 pseudo_TE-IS 20 rt3 - rt3(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt3 - rt5(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
|
||||||
|
rt3 -
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
10.0.255.5/32 30 - rt3 -
|
||||||
|
10.0.255.6/32 40 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
|
||||||
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
2001:db8::1/128 IP6 internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt2 pseudo_TE-IS 20 rt3 - rt3(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
2001:db8::2/128 IP6 internal 20 rt2 - rt2(4)
|
||||||
|
2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt3 - rt5(4)
|
||||||
|
2001:db8::4/128 IP6 internal 30 rt2 - rt4(4)
|
||||||
|
2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
|
||||||
|
2001:db8::6/128 IP6 internal 40 rt2 - rt6(4)
|
||||||
|
rt3 -
|
||||||
|
|
||||||
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-------------------------------------------------------
|
||||||
|
2001:db8::2/128 20 - rt2 -
|
||||||
|
2001:db8::3/128 20 - rt3 -
|
||||||
|
2001:db8::4/128 30 - rt2 -
|
||||||
|
2001:db8::5/128 30 - rt3 -
|
||||||
|
2001:db8::6/128 40 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
|
||||||
|
test# test isis topology 12 root rt1 spf ipv4-only
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt7 TE-IS 30 rt3 - rt5(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
|
||||||
|
rt8 TE-IS 40 rt2 - rt6(4)
|
||||||
|
rt9 TE-IS 40 rt3 - rt7(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
|
||||||
|
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
|
||||||
|
rt10 TE-IS 50 rt2 - rt8(4)
|
||||||
|
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
|
||||||
|
10.0.255.9/32 IP TE 50 rt3 - rt9(4)
|
||||||
|
10.0.255.10/32 IP TE 60 rt2 - rt10(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
------------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
10.0.255.5/32 30 - rt3 -
|
||||||
|
10.0.255.6/32 40 - rt2 -
|
||||||
|
10.0.255.7/32 40 - rt3 -
|
||||||
|
10.0.255.8/32 50 - rt2 -
|
||||||
|
10.0.255.9/32 50 - rt3 -
|
||||||
|
10.0.255.10/32 60 - rt2 -
|
||||||
|
|
||||||
|
test# test isis topology 13 root rt1 spf ipv4-only
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt3 - rt3(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 20 rt3 - rt3(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt7 TE-IS 30 rt3 - rt5(4)
|
||||||
|
rt6(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
rt3 -
|
||||||
|
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
|
||||||
|
10.0.255.6/32 IP TE 30 rt3 - rt6(4)
|
||||||
|
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
- rt3 -
|
||||||
|
10.0.255.5/32 30 - rt3 -
|
||||||
|
10.0.255.6/32 30 - rt3 -
|
||||||
|
10.0.255.7/32 40 - rt3 -
|
||||||
|
|
||||||
|
test#
|
||||||
|
test# test isis topology 4 root rt1 reverse-spf ipv4-only
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt2 - rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt4 TE-IS 20 rt2 - rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2 - rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt2 - rt4(4)
|
||||||
|
rt7 TE-IS 30 rt3 - rt5(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt2 - rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
|
||||||
|
rt8 TE-IS 40 rt2 - rt6(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt2 - rt6(4)
|
||||||
|
10.0.255.7/32 IP TE 40 rt3 - rt7(4)
|
||||||
|
10.0.255.8/32 IP TE 50 rt2 - rt8(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.2/32 20 - rt2 -
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.4/32 30 - rt2 -
|
||||||
|
10.0.255.5/32 30 - rt3 -
|
||||||
|
10.0.255.6/32 40 - rt2 -
|
||||||
|
10.0.255.7/32 40 - rt3 -
|
||||||
|
10.0.255.8/32 50 - rt2 -
|
||||||
|
|
||||||
|
test# test isis topology 11 root rt1 reverse-spf
|
||||||
|
IS-IS paths to level-1 routers that speak IP
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
10.0.255.1/32 IP internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt2 pseudo_TE-IS 20 rt3 - rt3(4)
|
||||||
|
rt4 TE-IS 20 rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
10.0.255.2/32 IP TE 20 rt2(4)
|
||||||
|
10.0.255.3/32 IP TE 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt3 - rt4(4)
|
||||||
|
rt5(4)
|
||||||
|
10.0.255.4/32 IP TE 30 rt4(4)
|
||||||
|
10.0.255.5/32 IP TE 30 rt3 - rt5(4)
|
||||||
|
10.0.255.6/32 IP TE 40 rt3 - rt6(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv4 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-----------------------------------------------------
|
||||||
|
10.0.255.3/32 20 - rt3 -
|
||||||
|
10.0.255.5/32 30 - rt3 -
|
||||||
|
10.0.255.6/32 40 - rt3 -
|
||||||
|
|
||||||
|
IS-IS paths to level-1 routers that speak IPv6
|
||||||
|
Vertex Type Metric Next-Hop Interface Parent
|
||||||
|
rt1
|
||||||
|
2001:db8::1/128 IP6 internal 0 rt1(4)
|
||||||
|
rt2 TE-IS 10 rt1(4)
|
||||||
|
rt3 TE-IS 10 rt3 - rt1(4)
|
||||||
|
rt2 pseudo_TE-IS 20 rt3 - rt3(4)
|
||||||
|
rt4 TE-IS 20 rt2(4)
|
||||||
|
rt5 TE-IS 20 rt3 - rt3(4)
|
||||||
|
2001:db8::2/128 IP6 internal 20 rt2(4)
|
||||||
|
2001:db8::3/128 IP6 internal 20 rt3 - rt3(4)
|
||||||
|
rt6 TE-IS 30 rt3 - rt4(4)
|
||||||
|
rt5(4)
|
||||||
|
2001:db8::4/128 IP6 internal 30 rt4(4)
|
||||||
|
2001:db8::5/128 IP6 internal 30 rt3 - rt5(4)
|
||||||
|
2001:db8::6/128 IP6 internal 40 rt3 - rt6(4)
|
||||||
|
|
||||||
|
IS-IS L1 IPv6 routing table:
|
||||||
|
|
||||||
|
Prefix Metric Interface Nexthop Label(s)
|
||||||
|
-------------------------------------------------------
|
||||||
|
2001:db8::3/128 20 - rt3 -
|
||||||
|
2001:db8::5/128 30 - rt3 -
|
||||||
|
2001:db8::6/128 40 - rt3 -
|
||||||
|
|
||||||
|
test#
|
||||||
|
end.
|
@ -2,14 +2,7 @@
|
|||||||
|
|
||||||
#include "isisd/isis_spf.c"
|
#include "isisd/isis_spf.c"
|
||||||
|
|
||||||
struct thread_master *master;
|
#include "test_common.h"
|
||||||
int isis_sock_init(struct isis_circuit *circuit);
|
|
||||||
int isis_sock_init(struct isis_circuit *circuit)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct zebra_privs_t isisd_privs;
|
|
||||||
|
|
||||||
static struct isis_vertex **vertices;
|
static struct isis_vertex **vertices;
|
||||||
static size_t vertex_count;
|
static size_t vertex_count;
|
||||||
|
3307
tests/isisd/test_topologies.c
Normal file
3307
tests/isisd/test_topologies.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@ else
|
|||||||
TESTS_ISISD = \
|
TESTS_ISISD = \
|
||||||
tests/isisd/test_fuzz_isis_tlv \
|
tests/isisd/test_fuzz_isis_tlv \
|
||||||
tests/isisd/test_isis_lspdb \
|
tests/isisd/test_isis_lspdb \
|
||||||
|
tests/isisd/test_isis_spf \
|
||||||
tests/isisd/test_isis_vertex_queue \
|
tests/isisd/test_isis_vertex_queue \
|
||||||
# end
|
# end
|
||||||
endif
|
endif
|
||||||
@ -111,6 +112,7 @@ noinst_HEADERS += \
|
|||||||
tests/helpers/c/tests.h \
|
tests/helpers/c/tests.h \
|
||||||
tests/lib/cli/common_cli.h \
|
tests/lib/cli/common_cli.h \
|
||||||
tests/lib/test_typelist.h \
|
tests/lib/test_typelist.h \
|
||||||
|
tests/isisd/test_common.h \
|
||||||
# end
|
# end
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -168,16 +170,21 @@ tests_bgpd_test_peer_attr_SOURCES = tests/bgpd/test_peer_attr.c
|
|||||||
tests_isisd_test_fuzz_isis_tlv_CFLAGS = $(TESTS_CFLAGS) -I$(top_builddir)/tests/isisd
|
tests_isisd_test_fuzz_isis_tlv_CFLAGS = $(TESTS_CFLAGS) -I$(top_builddir)/tests/isisd
|
||||||
tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd
|
tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd
|
||||||
tests_isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
|
tests_isisd_test_fuzz_isis_tlv_LDADD = $(ISISD_TEST_LDADD)
|
||||||
tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c
|
tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv.c tests/isisd/test_common.c
|
||||||
nodist_tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv_tests.h
|
nodist_tests_isisd_test_fuzz_isis_tlv_SOURCES = tests/isisd/test_fuzz_isis_tlv_tests.h
|
||||||
tests_isisd_test_isis_lspdb_CFLAGS = $(TESTS_CFLAGS)
|
tests_isisd_test_isis_lspdb_CFLAGS = $(TESTS_CFLAGS)
|
||||||
tests_isisd_test_isis_lspdb_CPPFLAGS = $(TESTS_CPPFLAGS)
|
tests_isisd_test_isis_lspdb_CPPFLAGS = $(TESTS_CPPFLAGS)
|
||||||
tests_isisd_test_isis_lspdb_LDADD = $(ISISD_TEST_LDADD)
|
tests_isisd_test_isis_lspdb_LDADD = $(ISISD_TEST_LDADD)
|
||||||
tests_isisd_test_isis_lspdb_SOURCES = tests/isisd/test_isis_lspdb.c
|
tests_isisd_test_isis_lspdb_SOURCES = tests/isisd/test_isis_lspdb.c tests/isisd/test_common.c
|
||||||
|
tests_isisd_test_isis_spf_CFLAGS = $(TESTS_CFLAGS)
|
||||||
|
tests_isisd_test_isis_spf_CPPFLAGS = $(TESTS_CPPFLAGS)
|
||||||
|
tests_isisd_test_isis_spf_LDADD = $(ISISD_TEST_LDADD)
|
||||||
|
tests_isisd_test_isis_spf_SOURCES = tests/isisd/test_isis_spf.c tests/isisd/test_common.c tests/isisd/test_topologies.c
|
||||||
|
nodist_tests_isisd_test_isis_spf_SOURCES = yang/frr-isisd.yang.c
|
||||||
tests_isisd_test_isis_vertex_queue_CFLAGS = $(TESTS_CFLAGS)
|
tests_isisd_test_isis_vertex_queue_CFLAGS = $(TESTS_CFLAGS)
|
||||||
tests_isisd_test_isis_vertex_queue_CPPFLAGS = $(TESTS_CPPFLAGS)
|
tests_isisd_test_isis_vertex_queue_CPPFLAGS = $(TESTS_CPPFLAGS)
|
||||||
tests_isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD)
|
tests_isisd_test_isis_vertex_queue_LDADD = $(ISISD_TEST_LDADD)
|
||||||
tests_isisd_test_isis_vertex_queue_SOURCES = tests/isisd/test_isis_vertex_queue.c
|
tests_isisd_test_isis_vertex_queue_SOURCES = tests/isisd/test_isis_vertex_queue.c tests/isisd/test_common.c
|
||||||
|
|
||||||
tests_lib_cxxcompat_CFLAGS = $(TESTS_CFLAGS) $(CXX_COMPAT_CFLAGS) $(WERROR)
|
tests_lib_cxxcompat_CFLAGS = $(TESTS_CFLAGS) $(CXX_COMPAT_CFLAGS) $(WERROR)
|
||||||
tests_lib_cxxcompat_CPPFLAGS = $(TESTS_CPPFLAGS)
|
tests_lib_cxxcompat_CPPFLAGS = $(TESTS_CPPFLAGS)
|
||||||
@ -327,6 +334,9 @@ EXTRA_DIST += \
|
|||||||
tests/isisd/test_fuzz_isis_tlv.py \
|
tests/isisd/test_fuzz_isis_tlv.py \
|
||||||
tests/isisd/test_fuzz_isis_tlv_tests.h.gz \
|
tests/isisd/test_fuzz_isis_tlv_tests.h.gz \
|
||||||
tests/isisd/test_isis_lspdb.py \
|
tests/isisd/test_isis_lspdb.py \
|
||||||
|
tests/isisd/test_isis_spf.py \
|
||||||
|
tests/isisd/test_isis_spf.in \
|
||||||
|
tests/isisd/test_isis_spf.refout \
|
||||||
tests/isisd/test_isis_vertex_queue.py \
|
tests/isisd/test_isis_vertex_queue.py \
|
||||||
tests/lib/cli/test_commands.in \
|
tests/lib/cli/test_commands.in \
|
||||||
tests/lib/cli/test_commands.py \
|
tests/lib/cli/test_commands.py \
|
||||||
|
Loading…
Reference in New Issue
Block a user