mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 04:36:45 +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
|
||||
(level-1) or domain (level-2).
|
||||
|
||||
.. index:: show ip route isis
|
||||
.. clicmd:: show ip route isis
|
||||
.. index:: show isis route [level-1|level-2]
|
||||
.. clicmd:: show isis route [level-1|level-2]
|
||||
|
||||
Show the ISIS routing table, as determined by the most recent SPF
|
||||
calculation.
|
||||
|
@ -221,7 +221,10 @@ struct fabricd *fabricd_new(struct isis_area *area)
|
||||
rv->area = area;
|
||||
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,
|
||||
neighbor_entry_del_void);
|
||||
rv->neighbors_neighbors = hash_create(neighbor_entry_hash_key,
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "isisd/isis_dynhn.h"
|
||||
#include "isisd/isis_pdu.h"
|
||||
#include "isisd/isis_lsp.h"
|
||||
#include "isisd/isis_spf.h"
|
||||
#include "isisd/isis_events.h"
|
||||
#include "isisd/isis_mt.h"
|
||||
#include "isisd/isis_tlvs.h"
|
||||
@ -152,9 +151,6 @@ void isis_delete_adj(void *arg)
|
||||
if (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);
|
||||
|
||||
XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses);
|
||||
|
@ -49,11 +49,23 @@ void dyn_cache_init(struct isis *isis)
|
||||
{
|
||||
if (dyn_cache == NULL)
|
||||
dyn_cache = list_new();
|
||||
thread_add_timer(master, dyn_cache_cleanup, isis, 120,
|
||||
&isis->t_dync_clean);
|
||||
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
|
||||
thread_add_timer(master, dyn_cache_cleanup, isis, 120,
|
||||
&isis->t_dync_clean);
|
||||
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)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
|
@ -31,6 +31,7 @@ struct isis_dynhn {
|
||||
};
|
||||
|
||||
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_remove(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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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 */
|
||||
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) \
|
||||
_lsp_flood((lsp), (circuit), __func__, __FILE__, __LINE__)
|
||||
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
|
||||
isis_cli_init();
|
||||
#endif /* ifdef FABRICD */
|
||||
isis_spf_cmds_init();
|
||||
isis_spf_init();
|
||||
isis_redist_init();
|
||||
isis_route_map_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.
|
||||
* 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 *isis = NULL;
|
||||
@ -447,8 +447,7 @@ const char *print_sys_hostname(uint8_t *sysid)
|
||||
|
||||
/* For our system ID return our host name */
|
||||
isis = isis_lookup_by_sysid(sysid);
|
||||
|
||||
if (isis != NULL)
|
||||
if (isis && !CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
|
||||
return cmd_hostname_get();
|
||||
|
||||
dyn = dynhn_find_by_id(sysid);
|
||||
|
@ -49,7 +49,7 @@ const char *time2string(uint32_t);
|
||||
const char *nlpid2str(uint8_t nlpid);
|
||||
/* typedef struct nlpids 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);
|
||||
|
||||
/*
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "isis_pdu.h"
|
||||
#include "isis_lsp.h"
|
||||
#include "isis_spf.h"
|
||||
#include "isis_spf_private.h"
|
||||
#include "isis_route.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,
|
||||
struct prefix_ipv6 *src_p,
|
||||
uint32_t cost,
|
||||
@ -165,13 +177,25 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
|
||||
struct list *adjacencies)
|
||||
{
|
||||
struct isis_route_info *rinfo;
|
||||
struct isis_adjacency *adj;
|
||||
struct isis_vertex_adj *vadj;
|
||||
struct listnode *node;
|
||||
|
||||
rinfo = XCALLOC(MTYPE_ISIS_ROUTE_INFO, sizeof(struct isis_route_info));
|
||||
|
||||
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 */
|
||||
if (CHECK_FLAG(adj->circuit->flags,
|
||||
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 *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_verify_routes(struct isis_area *area,
|
||||
struct isis_spftree **trees);
|
||||
void isis_spftree_del(struct isis_spftree *spftree);
|
||||
void spftree_area_init(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) \
|
||||
_isis_spf_schedule((area), (level), __func__, \
|
||||
__FILE__, __LINE__)
|
||||
int _isis_spf_schedule(struct isis_area *area, int level,
|
||||
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_run_spf(struct isis_spftree *spftree);
|
||||
struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
|
||||
uint8_t *sysid,
|
||||
struct isis_spftree *spftree);
|
||||
|
@ -50,6 +50,11 @@ struct prefix_pair {
|
||||
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)}>
|
||||
*/
|
||||
@ -180,6 +185,10 @@ static void isis_vertex_del(struct 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__))
|
||||
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 tents; /* TENT */
|
||||
struct route_table *route_table;
|
||||
struct lspdb_head *lspdb; /* link-state db */
|
||||
struct list *sadj_list;
|
||||
struct isis_area *area; /* back pointer to area */
|
||||
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_monotime; /* last run as monotime for scheduling */
|
||||
time_t last_run_duration; /* last run duration in msec */
|
||||
|
||||
enum spf_type type;
|
||||
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||
uint16_t mtid;
|
||||
int family;
|
||||
int level;
|
||||
enum spf_tree_id tree_id;
|
||||
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__))
|
||||
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);
|
||||
LSP_FRAGMENT(lsp_id) = 0;
|
||||
|
||||
struct lspdb_head *lspdb = &spftree->area->lspdb[spftree->level - 1];
|
||||
struct isis_lsp *lsp = lsp_search(lspdb, lsp_id);
|
||||
struct isis_lsp *lsp = lsp_search(spftree->lspdb, lsp_id);
|
||||
|
||||
if (lsp && lsp->hdr.rem_lifetime != 0)
|
||||
return lsp;
|
||||
|
@ -210,7 +210,7 @@ int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
|
||||
uint32_t upper_bound)
|
||||
{
|
||||
struct isis_sr_db *srdb = &area->srdb;
|
||||
struct listnode *node, *nnode;
|
||||
struct listnode *node;
|
||||
struct sr_adjacency *sra;
|
||||
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 */
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
if (!circuit->ip_router)
|
||||
if (!circuit->ip_router || !adj->ipv4_address_count)
|
||||
return;
|
||||
|
||||
nexthop.ipv4 = adj->ipv4_addresses[0];
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (!circuit->ipv6_router)
|
||||
if (!circuit->ipv6_router || !adj->ipv6_address_count)
|
||||
return;
|
||||
|
||||
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 Prefix-SIDs\n")
|
||||
{
|
||||
struct listnode *node, *inode, *nnode;
|
||||
struct listnode *node, *inode;
|
||||
struct isis_area *area;
|
||||
struct isis *isis = NULL;
|
||||
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);
|
||||
if (vrf_name) {
|
||||
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,
|
||||
area)) {
|
||||
vty_out(vty, "Area %s:\n",
|
||||
@ -2084,11 +2084,11 @@ DEFUN(show_sr_node, show_sr_node_cmd,
|
||||
"Segment-Routing\n"
|
||||
"Segment-Routing node\n")
|
||||
{
|
||||
struct listnode *node, *inode, *nnode;
|
||||
struct listnode *node, *inode;
|
||||
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)) {
|
||||
vty_out(vty, "Area %s:\n",
|
||||
area->area_tag ? area->area_tag : "null");
|
||||
|
@ -311,7 +311,7 @@ DEFUN(show_isis_mpls_te_router,
|
||||
MPLS_TE_STR "Router information\n")
|
||||
{
|
||||
|
||||
struct listnode *anode, *nnode, *inode;
|
||||
struct listnode *anode, *inode;
|
||||
struct isis_area *area;
|
||||
struct isis *isis = NULL;
|
||||
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);
|
||||
if (vrf_name) {
|
||||
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,
|
||||
anode, area)) {
|
||||
if (!IS_MPLS_TE(area->mta))
|
||||
@ -483,7 +483,7 @@ DEFUN (show_isis_mpls_te_interface,
|
||||
"Interface information\n"
|
||||
"Interface name\n")
|
||||
{
|
||||
struct listnode *anode, *cnode, *nnode, *inode;
|
||||
struct listnode *anode, *cnode, *inode;
|
||||
struct isis_area *area;
|
||||
struct isis_circuit *circuit;
|
||||
struct interface *ifp;
|
||||
@ -497,7 +497,7 @@ DEFUN (show_isis_mpls_te_interface,
|
||||
|
||||
if (argc == idx_interface) {
|
||||
/* 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,
|
||||
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 = NULL;
|
||||
struct listnode *node, *nnode;
|
||||
struct isis *isis;
|
||||
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)
|
||||
return isis;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct isis *isis_lookup_by_vrfname(const char *vrfname)
|
||||
{
|
||||
struct isis *isis = NULL;
|
||||
struct listnode *node, *nnode;
|
||||
struct isis *isis;
|
||||
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)
|
||||
return isis;
|
||||
|
||||
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 listnode *node, *nnode;
|
||||
for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
|
||||
struct isis *isis;
|
||||
struct listnode *node;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
|
||||
if (!memcmp(isis->sysid, sysid, ISIS_SYS_ID_LEN))
|
||||
return isis;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -165,7 +169,7 @@ void isis_master_init(struct thread_master *master)
|
||||
|
||||
void isis_global_instance_create()
|
||||
{
|
||||
struct isis *isis = NULL;
|
||||
struct isis *isis;
|
||||
|
||||
isis = isis_lookup_by_vrfid(VRF_DEFAULT);
|
||||
if (isis == NULL) {
|
||||
@ -176,8 +180,8 @@ void isis_global_instance_create()
|
||||
|
||||
struct isis *isis_new(vrf_id_t vrf_id)
|
||||
{
|
||||
struct vrf *vrf = NULL;
|
||||
struct isis *isis = NULL;
|
||||
struct vrf *vrf;
|
||||
struct isis *isis;
|
||||
|
||||
isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
|
||||
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;
|
||||
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.
|
||||
* 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->adjacency_list = 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);
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
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 listnode *node;
|
||||
struct isis *isis = NULL;
|
||||
struct isis *isis;
|
||||
|
||||
isis = isis_lookup_by_vrfid(vrf_id);
|
||||
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[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)) {
|
||||
list_delete_node(area->area_addrs, node);
|
||||
@ -464,7 +470,7 @@ void isis_finish(struct isis *isis)
|
||||
|
||||
void isis_terminate()
|
||||
{
|
||||
struct isis *isis = NULL;
|
||||
struct isis *isis;
|
||||
struct listnode *node, *nnode;
|
||||
|
||||
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,
|
||||
const char *vrf_name, bool all_vrf)
|
||||
{
|
||||
struct listnode *anode, *cnode, *mnode, *inode;
|
||||
struct listnode *anode, *cnode, *inode;
|
||||
struct isis_area *area;
|
||||
struct isis_circuit *circuit;
|
||||
struct isis *isis = NULL;
|
||||
struct isis *isis;
|
||||
|
||||
if (!im) {
|
||||
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 (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,
|
||||
anode, area)) {
|
||||
vty_out(vty, "Area %s:\n",
|
||||
@ -677,7 +683,7 @@ int show_isis_interface_common(struct vty *vty, const char *ifname, char detail,
|
||||
detail);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
isis = isis_lookup_by_vrfname(vrf_name);
|
||||
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,
|
||||
const char *vrf_name, bool all_vrf)
|
||||
{
|
||||
struct listnode *nnode, *inode;
|
||||
struct listnode *node;
|
||||
struct isis_dynhn *dynhn;
|
||||
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||
struct isis *isis = NULL;
|
||||
struct isis *isis;
|
||||
|
||||
if (!im) {
|
||||
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 (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,
|
||||
sysid);
|
||||
}
|
||||
return 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
isis = isis_lookup_by_vrfname(vrf_name);
|
||||
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,
|
||||
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_circuit *circuit;
|
||||
struct list *adjdb;
|
||||
@ -871,8 +877,7 @@ static void isis_neighbor_common_clear(struct vty *vty, const char *id,
|
||||
int i;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
|
||||
for (ALL_LIST_ELEMENTS(area->circuit_list, cnode, cnextnode,
|
||||
circuit)) {
|
||||
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) {
|
||||
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
||||
for (i = 0; i < 2; 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,
|
||||
bool all_vrf)
|
||||
{
|
||||
struct listnode *nnode, *inode;
|
||||
struct listnode *node;
|
||||
struct isis_dynhn *dynhn;
|
||||
uint8_t sysid[ISIS_SYS_ID_LEN];
|
||||
struct isis *isis = NULL;
|
||||
struct isis *isis;
|
||||
|
||||
if (!im) {
|
||||
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 (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);
|
||||
}
|
||||
return 0;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
isis = isis_lookup_by_vrfname(vrf_name);
|
||||
if (isis != NULL)
|
||||
@ -1554,19 +1558,19 @@ DEFUN(show_hostname, show_hostname_cmd,
|
||||
"All VRFs\n"
|
||||
"IS-IS Dynamic hostname mapping\n")
|
||||
{
|
||||
struct listnode *nnode, *inode;
|
||||
struct listnode *node;
|
||||
const char *vrf_name = VRF_DEFAULT_NAME;
|
||||
bool all_vrf = false;
|
||||
int idx_vrf = 0;
|
||||
struct isis *isis = NULL;
|
||||
struct isis *isis;
|
||||
|
||||
ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
|
||||
if (vrf_name) {
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
isis = isis_lookup_by_vrfname(vrf_name);
|
||||
if (isis != NULL)
|
||||
@ -1621,8 +1625,8 @@ DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
|
||||
"All VRFs\n"
|
||||
"SPF delay IETF information\n")
|
||||
{
|
||||
struct listnode *nnode, *inode;
|
||||
struct isis *isis = NULL;
|
||||
struct listnode *node;
|
||||
struct isis *isis;
|
||||
int idx_vrf = 0;
|
||||
const char *vrf_name = VRF_DEFAULT_NAME;
|
||||
bool all_vrf = false;
|
||||
@ -1636,10 +1640,10 @@ DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
|
||||
|
||||
if (vrf_name) {
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
isis = isis_lookup_by_vrfname(vrf_name);
|
||||
if (isis != NULL)
|
||||
@ -1755,9 +1759,9 @@ DEFUN(show_isis_summary, show_isis_summary_cmd,
|
||||
"All VRFs\n"
|
||||
"summary\n")
|
||||
{
|
||||
struct listnode *inode, *nnode;
|
||||
struct listnode *node;
|
||||
int idx_vrf = 0;
|
||||
struct isis *isis = NULL;
|
||||
struct isis *isis;
|
||||
const char *vrf_name = VRF_DEFAULT_NAME;
|
||||
bool all_vrf = false;
|
||||
|
||||
@ -1768,10 +1772,10 @@ DEFUN(show_isis_summary, show_isis_summary_cmd,
|
||||
}
|
||||
if (vrf_name) {
|
||||
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);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
isis = isis_lookup_by_vrfname(vrf_name);
|
||||
if (isis != NULL)
|
||||
@ -1844,60 +1848,61 @@ struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv,
|
||||
return lsp;
|
||||
}
|
||||
|
||||
static int show_isis_database_common(struct vty *vty, const char *argv,
|
||||
int ui_level, struct isis *isis)
|
||||
void show_isis_database_lspdb(struct vty *vty, struct isis_area *area,
|
||||
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 isis_area *area;
|
||||
struct isis_lsp *lsp;
|
||||
int level, lsp_count;
|
||||
int level;
|
||||
|
||||
if (isis->area_list->count == 0)
|
||||
return CMD_SUCCESS;
|
||||
return;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
|
||||
vty_out(vty, "Area %s:\n",
|
||||
area->area_tag ? area->area_tag : "null");
|
||||
|
||||
for (level = 0; level < ISIS_LEVELS; level++) {
|
||||
if (lspdb_count(&area->lspdb[level]) > 0) {
|
||||
lsp = NULL;
|
||||
lsp = lsp_for_arg(&area->lspdb[level], argv,
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (level = 0; level < ISIS_LEVELS; level++)
|
||||
show_isis_database_lspdb(vty, area, level,
|
||||
&area->lspdb[level], argv,
|
||||
ui_level);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
/*
|
||||
* 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,
|
||||
const char *vrf_name, bool all_vrf)
|
||||
{
|
||||
struct listnode *inode, *nnode;
|
||||
struct isis *isis = NULL;
|
||||
struct listnode *node;
|
||||
struct isis *isis;
|
||||
|
||||
if (vrf_name) {
|
||||
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,
|
||||
isis);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
isis = isis_lookup_by_vrfname(vrf_name);
|
||||
if (isis != NULL)
|
||||
if (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;
|
||||
struct isis_area *area;
|
||||
struct listnode *node, *node2, *inode, *nnode;
|
||||
struct isis *isis = NULL;
|
||||
struct listnode *node, *node2, *inode;
|
||||
struct isis *isis;
|
||||
|
||||
if (!im) {
|
||||
vty_out(vty, "IS-IS Routing Process not enabled\n");
|
||||
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)) {
|
||||
/* ISIS - Area name */
|
||||
vty_out(vty, "router " PROTO_NAME " %s\n", area->area_tag);
|
||||
|
@ -76,6 +76,7 @@ struct isis_master {
|
||||
/* Various OSPF global configuration. */
|
||||
uint8_t options;
|
||||
};
|
||||
#define F_ISIS_UNIT_TEST 0x01
|
||||
|
||||
struct isis {
|
||||
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);
|
||||
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_sysid(uint8_t *sysid);
|
||||
struct isis *isis_lookup_by_sysid(const uint8_t *sysid);
|
||||
|
||||
void isis_init(void);
|
||||
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);
|
||||
int isis_area_passwd_hmac_md5_set(struct isis_area *area, int level,
|
||||
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 */
|
||||
#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_tests.h
|
||||
/isisd/test_isis_lspdb
|
||||
/isisd/test_isis_spf
|
||||
/isisd/test_isis_vertex_queue
|
||||
/lib/cli/test_cli
|
||||
/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_tlvs.h"
|
||||
|
||||
#include "test_common.h"
|
||||
|
||||
#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 void show_meminfo_at_exit(void)
|
||||
|
@ -2,15 +2,7 @@
|
||||
|
||||
#include "isisd/isis_lsp.c"
|
||||
|
||||
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;
|
||||
#include "test_common.h"
|
||||
|
||||
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"
|
||||
|
||||
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;
|
||||
#include "test_common.h"
|
||||
|
||||
static struct isis_vertex **vertices;
|
||||
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/test_fuzz_isis_tlv \
|
||||
tests/isisd/test_isis_lspdb \
|
||||
tests/isisd/test_isis_spf \
|
||||
tests/isisd/test_isis_vertex_queue \
|
||||
# end
|
||||
endif
|
||||
@ -111,6 +112,7 @@ noinst_HEADERS += \
|
||||
tests/helpers/c/tests.h \
|
||||
tests/lib/cli/common_cli.h \
|
||||
tests/lib/test_typelist.h \
|
||||
tests/isisd/test_common.h \
|
||||
# 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_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd
|
||||
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
|
||||
tests_isisd_test_isis_lspdb_CFLAGS = $(TESTS_CFLAGS)
|
||||
tests_isisd_test_isis_lspdb_CPPFLAGS = $(TESTS_CPPFLAGS)
|
||||
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_CPPFLAGS = $(TESTS_CPPFLAGS)
|
||||
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_CPPFLAGS = $(TESTS_CPPFLAGS)
|
||||
@ -327,6 +334,9 @@ EXTRA_DIST += \
|
||||
tests/isisd/test_fuzz_isis_tlv.py \
|
||||
tests/isisd/test_fuzz_isis_tlv_tests.h.gz \
|
||||
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/lib/cli/test_commands.in \
|
||||
tests/lib/cli/test_commands.py \
|
||||
|
Loading…
Reference in New Issue
Block a user