1. Created a structure "isis master".
2. All the changes are related to handle ISIS with different vrf.
3. A new variable added in structure "isis" to store the vrf name.
4. The display commands for isis is changed to support different VRFs.
Signed-off-by: Kaushik <kaushik@niralnetworks.com>
if (!f)
return;
- isis_run_hopcount_spf(area, isis->sysid, f->spftree);
+ isis_run_hopcount_spf(area, area->isis->sysid, f->spftree);
neighbors_neighbors_update(f);
fabricd_bump_tier_calculation_timer(f);
}
#include "isisd/fabricd.h"
#include "isisd/isis_nb.h"
-extern struct isis *isis;
-
static struct isis_adjacency *adj_alloc(const uint8_t *id)
{
struct isis_adjacency *adj;
struct listnode *anode;
struct isis_area *area;
+ struct isis *isis = NULL;
+
+ isis = isis_lookup_by_vrfid(vrf_id);
+
+ if (isis == NULL) {
+ zlog_warn(" %s : ISIS routing instance not found", __func__);
+ return -1;
+ }
if (IS_DEBUG_BFD)
zlog_debug("ISIS-BFD: Got neighbor replay request, resending neighbors.");
struct isis_area *area;
struct listnode *node;
struct isis_circuit *circuit;
+ struct isis *isis = NULL;
if (ifp->info)
return (struct isis_circuit *)ifp->info;
+ isis = isis_lookup_by_vrfid(ifp->vrf_id);
+ if (isis == NULL) {
+ zlog_warn(" %s : ISIS routing instance not found", __func__);
+ return NULL;
+ }
+
if (isis->area_list) {
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
circuit =
}
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
- circuit->circuit_id = isis_circuit_id_gen(isis, circuit->interface);
+ circuit->circuit_id = isis_circuit_id_gen(circuit->area->isis,
+ circuit->interface);
if (!circuit->circuit_id) {
flog_err(
EC_ISIS_CONFIG,
circuit->lsp_regenerate_pending[0] = 0;
circuit->lsp_regenerate_pending[1] = 0;
- _ISIS_CLEAR_FLAG(isis->circuit_ids_used, circuit->circuit_id);
+ _ISIS_CLEAR_FLAG(circuit->area->isis->circuit_ids_used,
+ circuit->circuit_id);
circuit->circuit_id = 0;
} else if (circuit->circ_type == CIRCUIT_T_P2P) {
isis_delete_adj(circuit->u.p2p.neighbor);
struct isis_area *area;
struct isis_circuit *circuit;
int i;
+ struct isis *isis = NULL;
+
+ isis = isis_lookup_by_vrfid(vrf->vrf_id);
+
+ if (isis == NULL) {
+ vty_out(vty, "ISIS routing instance not found");
+ return 0;
+ }
FOR_ALL_INTERFACES (vrf, ifp) {
/* IF name */
* need to make sure to set it in the yang model so that it
* is consistent with what FRR sees.
*/
- if (listcount(isis->area_list) == 0)
+
+ if (!im) {
+ return CMD_SUCCESS;
+ }
+
+ if (listcount(im->isis) == 0)
nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY,
"level-1-2");
ret = nb_cli_apply_changes(vty, base_xpath);
}
nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
- area = isis_area_lookup(tag);
+ area = isis_area_lookup(tag, VRF_DEFAULT);
if (area && area->circuit_list && listcount(area->circuit_list)) {
for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
circuit)) {
{
char temp_xpath[XPATH_MAXLEN];
const char *circ_type;
- struct isis_area *area;
+ struct isis_area *area = NULL;
struct interface *ifp;
/* area will be created if it is not present. make sure the yang model
* is synced with FRR and call the appropriate NB cb.
*/
- area = isis_area_lookup(tag);
+
+ if (!im) {
+ return CMD_SUCCESS;
+ }
+ ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
+ if (ifp)
+ area = isis_area_lookup(tag, ifp->vrf_id);
+
if (!area) {
snprintf(temp_xpath, XPATH_MAXLEN,
"/frr-isisd:isis/instance[area-tag='%s']", tag);
snprintf(temp_xpath, XPATH_MAXLEN,
"/frr-isisd:isis/instance[area-tag='%s']/is-type",
tag);
- nb_cli_enqueue_change(
- vty, temp_xpath, NB_OP_MODIFY,
- listcount(isis->area_list) == 0 ? "level-1-2" : NULL);
+ nb_cli_enqueue_change(vty, temp_xpath, NB_OP_MODIFY,
+ listcount(im->isis) == 0 ? "level-1-2"
+ : NULL);
nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
NULL);
nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
NB_OP_MODIFY, "true");
nb_cli_enqueue_change(
vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
- listcount(isis->area_list) == 0 ? "level-1-2"
- : "level-1");
+ listcount(im->isis) == 0 ? "level-1-2" : "level-1");
} else {
/* area exists, circuit type defaults to its area's is_type */
switch (area->is_type) {
}
/* check if the interface is a loopback and if so set it as passive */
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (ifp && if_is_loopback(ifp))
nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
NB_OP_MODIFY, "true");
{
char temp_xpath[XPATH_MAXLEN];
const char *circ_type;
- struct isis_area *area;
+ struct isis_area *area = NULL;
struct interface *ifp;
/* area will be created if it is not present. make sure the yang model
* is synced with FRR and call the appropriate NB cb.
*/
- area = isis_area_lookup(tag);
+
+ if (!im)
+ return CMD_SUCCESS;
+
+ ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
+ if (ifp)
+ area = isis_area_lookup(tag, ifp->vrf_id);
+
if (!area) {
snprintf(temp_xpath, XPATH_MAXLEN,
"/frr-isisd:isis/instance[area-tag='%s']", tag);
snprintf(temp_xpath, XPATH_MAXLEN,
"/frr-isisd:isis/instance[area-tag='%s']/is-type",
tag);
- nb_cli_enqueue_change(
- vty, temp_xpath, NB_OP_MODIFY,
- listcount(isis->area_list) == 0 ? "level-1-2" : NULL);
+ nb_cli_enqueue_change(vty, temp_xpath, NB_OP_MODIFY,
+ listcount(im->isis) == 0 ? "level-1-2"
+ : NULL);
nb_cli_enqueue_change(vty, "./frr-isisd:isis", NB_OP_CREATE,
NULL);
nb_cli_enqueue_change(vty, "./frr-isisd:isis/area-tag",
NB_OP_MODIFY, "true");
nb_cli_enqueue_change(
vty, "./frr-isisd:isis/circuit-type", NB_OP_MODIFY,
- listcount(isis->area_list) == 0 ? "level-1-2"
- : "level-1");
+ listcount(im->isis) == 0 ? "level-1-2" : "level-1");
} else {
/* area exists, circuit type defaults to its area's is_type */
switch (area->is_type) {
}
/* check if the interface is a loopback and if so set it as passive */
- ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (ifp && if_is_loopback(ifp))
nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
NB_OP_MODIFY, "true");
#include "isisd/isis_events.h"
#include "isisd/isis_errors.h"
-extern struct isis *isis;
-
static const char *const csm_statestr[] = {"C_STATE_NA", "C_STATE_INIT",
"C_STATE_CONF", "C_STATE_UP"};
isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
{
int old_state;
+ struct isis *isis = NULL;
old_state = circuit ? circuit->state : C_STATE_NA;
if (IS_DEBUG_EVENTS)
case IF_UP_FROM_Z:
circuit = isis_circuit_new();
isis_circuit_if_add(circuit, (struct interface *)arg);
+ isis = isis_lookup_by_vrfid(circuit->interface->vrf_id);
+ if (isis == NULL) {
+ zlog_warn(
+ " %s : ISIS routing instance not found",
+ __func__);
+ break;
+ }
listnode_add(isis->init_circ_list, circuit);
circuit->state = C_STATE_INIT;
break;
circuit->state = C_STATE_UP;
isis_event_circuit_state_change(circuit, circuit->area,
1);
- listnode_delete(isis->init_circ_list, circuit);
+ listnode_delete(circuit->area->isis->init_circ_list,
+ circuit);
break;
case IF_UP_FROM_Z:
assert(circuit);
break;
case IF_DOWN_FROM_Z:
isis_circuit_if_del(circuit, (struct interface *)arg);
+ isis = isis_lookup_by_vrfid(circuit->interface->vrf_id);
+ if (isis == NULL) {
+ zlog_warn(
+ "%s : ISIS routing instance not found",
+ __func__);
+ break;
+ }
+
listnode_delete(isis->init_circ_list, circuit);
isis_circuit_del(circuit);
circuit = NULL;
circuit->state = C_STATE_INIT;
isis_event_circuit_state_change(
circuit, (struct isis_area *)arg, 0);
+
+ isis = isis_lookup_by_vrfid(circuit->interface->vrf_id);
+ if (isis == NULL) {
+ zlog_warn(
+ "%s : ISIS routing instance not found",
+ __func__);
+ break;
+ }
+
listnode_add(isis->init_circ_list, circuit);
break;
case IF_DOWN_FROM_Z:
THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
circuit->lsp_regenerate_pending[level - 1] = 0;
- memcpy(id, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(id) = circuit->circuit_id;
LSP_FRAGMENT(id) = 0;
lsp_purge_pseudo(id, circuit, level);
/* there was a dr elected, purge its LSPs from the db */
lsp_purge_pseudo(old_dr, circuit, level);
}
- memcpy(circuit->u.bc.l1_desig_is, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(circuit->u.bc.l1_desig_is, circuit->area->isis->sysid,
+ ISIS_SYS_ID_LEN);
*(circuit->u.bc.l1_desig_is + ISIS_SYS_ID_LEN) =
circuit->circuit_id;
/* there was a dr elected, purge its LSPs from the db */
lsp_purge_pseudo(old_dr, circuit, level);
}
- memcpy(circuit->u.bc.l2_desig_is, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(circuit->u.bc.l2_desig_is, circuit->area->isis->sysid,
+ ISIS_SYS_ID_LEN);
*(circuit->u.bc.l2_desig_is + ISIS_SYS_ID_LEN) =
circuit->circuit_id;
struct list *dyn_cache = NULL;
static int dyn_cache_cleanup(struct thread *);
-void dyn_cache_init(void)
+void dyn_cache_init(struct isis *isis)
{
if (dyn_cache == NULL)
dyn_cache = list_new();
- thread_add_timer(master, dyn_cache_cleanup, NULL, 120,
+ thread_add_timer(master, dyn_cache_cleanup, isis, 120,
&isis->t_dync_clean);
return;
}
struct listnode *node, *nnode;
struct isis_dynhn *dyn;
time_t now = time(NULL);
+ struct isis *isis = NULL;
+
+ isis = THREAD_ARG(thread);
isis->t_dync_clean = NULL;
for (ALL_LIST_ELEMENTS(dyn_cache, node, nnode, dyn)) {
if ((now - dyn->refresh) < MAX_LSP_LIFETIME)
continue;
-
list_delete_node(dyn_cache, node);
XFREE(MTYPE_ISIS_DYNHN, dyn);
}
- thread_add_timer(master, dyn_cache_cleanup, NULL, 120,
- &isis->t_dync_clean);
+ thread_add_timer(master, dyn_cache_cleanup, isis, 120,
+ &isis->t_dync_clean);
+
return ISIS_OK;
}
* 2 0000.0000.0002 bar-gw
* * 0000.0000.0004 this-gw
*/
-void dynhn_print_all(struct vty *vty)
+void dynhn_print_all(struct vty *vty, struct isis *isis)
{
struct listnode *node;
struct isis_dynhn *dyn;
+ vty_out(vty, "vrf : %s\n", isis->name);
+ if (!isis->sysid_set)
+ return;
vty_out(vty, "Level System ID Dynamic Hostname\n");
for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) {
vty_out(vty, "%-7d", dyn->level);
int level;
};
-void dyn_cache_init(void);
+void dyn_cache_init(struct isis *isis);
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);
struct isis_dynhn *dynhn_find_by_name(const char *hostname);
-void dynhn_print_all(struct vty *vty);
+void dynhn_print_all(struct vty *vty, struct isis *isis);
#endif /* _ZEBRA_ISIS_DYNHN_H */
static void lsp_purge_add_poi(struct isis_lsp *lsp,
const uint8_t *sender)
{
+ if (lsp->area == NULL)
+ return;
+
if (!lsp->area->purge_originator)
return;
/* add purge originator identification */
if (!lsp->tlvs)
lsp->tlvs = isis_alloc_tlvs();
- isis_tlvs_set_purge_originator(lsp->tlvs, isis->sysid, sender);
+ isis_tlvs_set_purge_originator(lsp->tlvs, lsp->area->isis->sysid,
+ sender);
isis_tlvs_set_dynamic_hostname(lsp->tlvs, cmd_hostname_get());
}
stream_putw_at(lsp->pdu, 10, lsp->hdr.rem_lifetime);
}
-void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag)
+void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag,
+ struct isis *isis)
{
struct isis_dynhn *dyn = NULL;
char id[SYSID_STRLEN];
snprintf(id, sizeof(id), "%.14s", cmd_hostname_get());
else
memcpy(id, sysid_print(lsp_id), 15);
+
if (frag)
sprintf(dest, "%s.%02x-%02x", id, LSP_PSEUDO_ID(lsp_id),
LSP_FRAGMENT(lsp_id));
}
/* this function prints the lsp on show isis database */
-void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost)
+void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost,
+ struct isis *isis)
{
char LSPid[255];
char age_out[8];
char b[200];
- lspid_print(lsp->hdr.lsp_id, LSPid, dynhost, 1);
+ lspid_print(lsp->hdr.lsp_id, LSPid, dynhost, 1, isis);
vty_out(vty, "%-21s%c ", LSPid, lsp->own_lsp ? '*' : ' ');
vty_out(vty, "%5hu ", lsp->hdr.pdu_len);
vty_out(vty, "0x%08x ", lsp->hdr.seqno);
vty_out(vty, "%s\n", lsp_bits2string(lsp->hdr.lsp_bits, b, sizeof(b)));
}
-void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost)
+void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost,
+ struct isis *isis)
{
- lsp_print(lsp, vty, dynhost);
+ lsp_print(lsp, vty, dynhost, isis);
if (lsp->tlvs)
vty_multiline(vty, " ", "%s", isis_format_tlvs(lsp->tlvs));
vty_out(vty, "\n");
/* print all the lsps info in the local lspdb */
int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail,
- char dynhost)
+ char dynhost, struct isis *isis)
{
struct isis_lsp *lsp;
int lsp_count = 0;
if (detail == ISIS_UI_LEVEL_BRIEF) {
frr_each (lspdb, head, lsp) {
- lsp_print(lsp, vty, dynhost);
+ lsp_print(lsp, vty, dynhost, isis);
lsp_count++;
}
} else if (detail == ISIS_UI_LEVEL_DETAIL) {
frr_each (lspdb, head, lsp) {
- lsp_print_detail(lsp, vty, dynhost);
+ lsp_print_detail(lsp, vty, dynhost, isis);
lsp_count++;
}
}
}
/* Add Router Capability TLV. */
- if (isis->router_id != 0) {
+ if (area->isis->router_id != 0) {
struct isis_router_cap cap = {};
- cap.router_id.s_addr = isis->router_id;
+ cap.router_id.s_addr = area->isis->router_id;
/* Add SR Sub-TLVs if SR is enabled. */
if (area->srdb.enabled) {
* into LSP. TE router ID will be the same if MPLS-TE
* is not activate or MPLS-TE router-id not specified
*/
- if (isis->router_id != 0) {
- struct in_addr id = {.s_addr = isis->router_id};
+ if (area->isis->router_id != 0) {
+ struct in_addr id = {.s_addr = area->isis->router_id};
inet_ntop(AF_INET, &id, buf, sizeof(buf));
lsp_debug("ISIS (%s): Adding router ID %s as IPv4 tlv.",
area->area_tag, buf);
return ISIS_ERROR;
memset(&lspid, 0, ISIS_SYS_ID_LEN + 2);
- memcpy(&lspid, isis->sysid, ISIS_SYS_ID_LEN);
+
+ memcpy(&lspid, area->isis->sysid, ISIS_SYS_ID_LEN);
/* only builds the lsp if the area shares the level */
oldlsp = lsp_search(&area->lspdb[level - 1], lspid);
return ISIS_ERROR;
head = &area->lspdb[level - 1];
-
memset(lspid, 0, ISIS_SYS_ID_LEN + 2);
- memcpy(lspid, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(lspid, area->isis->sysid, ISIS_SYS_ID_LEN);
lsp = lsp_search(head, lspid);
all_pseudo ? "" : "not ",
func, file, line);
- memcpy(id, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(id, area->isis->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(id) = LSP_FRAGMENT(id) = 0;
now = time(NULL);
*/
uint8_t ne_id[ISIS_SYS_ID_LEN + 1];
- memcpy(ne_id, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(ne_id, area->isis->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(ne_id) = 0;
if (circuit->area->oldmetric) {
|| (circuit->u.bc.is_dr[level - 1] == 0))
return ISIS_ERROR;
- memcpy(lsp_id, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(lsp_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
LSP_FRAGMENT(lsp_id) = 0;
LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id;
|| (circuit->u.bc.is_dr[level - 1] == 0))
return ISIS_ERROR;
- memcpy(lsp_id, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(lsp_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id;
LSP_FRAGMENT(lsp_id) = 0;
if ((circuit->u.bc.is_dr[0] == 0)
|| (circuit->is_type & IS_LEVEL_1) == 0) {
- memcpy(id, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(id) = circuit->circuit_id;
LSP_FRAGMENT(id) = 0;
lsp_purge_pseudo(id, circuit, IS_LEVEL_1);
if ((circuit->u.bc.is_dr[1] == 0)
|| (circuit->is_type & IS_LEVEL_2) == 0) {
- memcpy(id, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(id) = circuit->circuit_id;
LSP_FRAGMENT(id) = 0;
lsp_purge_pseudo(id, circuit, IS_LEVEL_2);
area->area_tag, circuit_t2string(level),
circuit->interface->name);
- memcpy(lsp_id, isis->sysid, ISIS_SYS_ID_LEN);
+ memcpy(lsp_id, area->isis->sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id;
LSP_FRAGMENT(lsp_id) = 0;
now = time(NULL);
PREDECL_RBTREE_UNIQ(lspdb)
+struct isis;
/* Structure for isis_lsp, this structure will only support the fixed
* System ID (Currently 6) (atleast for now). In order to support more
* We will have to split the header into two parts, and for readability
struct isis_tlvs *tlvs, struct stream *stream,
struct isis_area *area, int level, bool confusion);
void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno);
-void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag);
-void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost);
-void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost);
+void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag,
+ struct isis *isis);
+void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost,
+ struct isis *isis);
+void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost,
+ struct isis *isis);
int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail,
- char dynhost);
+ char dynhost, struct isis *isis);
/* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set);
static __attribute__((__noreturn__)) void terminate(int i)
{
+ isis_terminate();
isis_sr_term();
isis_zebra_stop();
exit(i);
}
/* thread master */
- master = frr_init();
+ isis_master_init(frr_init());
+ master = im->master;
/*
* initializations
mt_init();
/* create the global 'isis' instance */
- isis_new(1, VRF_DEFAULT);
+ isis_global_instance_create();
isis_zebra_init(master, instance);
isis_bfd_init();
* 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(const uint8_t *sysid)
+const char *print_sys_hostname(uint8_t *sysid)
{
struct isis_dynhn *dyn;
+ struct isis *isis = NULL;
if (!sysid)
return "nullsysid";
/* For our system ID return our host name */
- if (memcmp(sysid, isis->sysid, ISIS_SYS_ID_LEN) == 0)
+ isis = isis_lookup_by_sysid(sysid);
+
+ if (isis != NULL)
return cmd_hostname_get();
dyn = dynhn_find_by_id(sysid);
const char *nlpid2str(uint8_t nlpid);
/* typedef struct nlpids nlpids; */
char *nlpid2string(struct nlpids *);
-const char *print_sys_hostname(const uint8_t *sysid);
+const char *print_sys_hostname(uint8_t *sysid);
void zlog_dump_data(void *data, int len);
/*
return NB_OK;
area_tag = yang_dnode_get_string(args->dnode, "./area-tag");
- area = isis_area_lookup(area_tag);
+ area = isis_area_lookup(area_tag, VRF_DEFAULT);
if (area)
return NB_ERR_INCONSISTENCY;
- area = isis_area_create(area_tag);
+ area = isis_area_create(area_tag, VRF_DEFAULT_NAME);
/* save area in dnode to avoid looking it up all the time */
nb_running_set_entry(args->dnode, area);
switch (args->event) {
case NB_EV_VALIDATE:
+ area = nb_running_get_entry(args->dnode, NULL, true);
+ if (area == NULL)
+ return NB_ERR_VALIDATION;
+
addr.addr_len = dotformat2buff(buff, net_title);
memcpy(addr.area_addr, buff, addr.addr_len);
if (addr.area_addr[addr.addr_len - 1] != 0) {
"nsel byte (last byte) in area address must be 0");
return NB_ERR_VALIDATION;
}
- if (isis->sysid_set) {
+ if (area->isis->sysid_set) {
/* Check that the SystemID portions match */
- if (memcmp(isis->sysid, GETSYSID((&addr)),
+ if (memcmp(area->isis->sysid, GETSYSID((&addr)),
ISIS_SYS_ID_LEN)) {
snprintf(
args->errmsg, args->errmsg_len,
area = nb_running_get_entry(args->dnode, NULL, true);
addrr = args->resource->ptr;
- if (isis->sysid_set == 0) {
+ if (area->isis->sysid_set == 0) {
/*
* First area address - get the SystemID for this router
*/
- memcpy(isis->sysid, GETSYSID(addrr), ISIS_SYS_ID_LEN);
- isis->sysid_set = 1;
+ memcpy(area->isis->sysid, GETSYSID(addrr),
+ ISIS_SYS_ID_LEN);
+ area->isis->sysid_set = 1;
} else {
/* check that we don't already have this address */
for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node,
addr.addr_len = dotformat2buff(buff, net_title);
memcpy(addr.area_addr, buff, (int)addr.addr_len);
area = nb_running_get_entry(args->dnode, NULL, true);
+
for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) {
if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len
&& !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len))
* Last area address - reset the SystemID for this router
*/
if (listcount(area->area_addrs) == 0) {
- memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
- isis->sysid_set = 0;
+ memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN);
+ area->isis->sysid_set = 0;
if (IS_DEBUG_EVENTS)
zlog_debug("Router has no SystemID");
}
*/
int lib_interface_isis_create(struct nb_cb_create_args *args)
{
- struct isis_area *area;
+ struct isis_area *area = NULL;
struct interface *ifp;
struct isis_circuit *circuit;
const char *area_tag = yang_dnode_get_string(args->dnode, "./area-tag");
break;
actual_mtu =
if_is_broadcast(ifp) ? ifp->mtu - LLC_LEN : ifp->mtu;
- area = isis_area_lookup(area_tag);
+ area = isis_area_lookup(area_tag, ifp->vrf_id);
if (area)
min_mtu = area->lsp_mtu;
else
}
break;
case NB_EV_APPLY:
- area = isis_area_lookup(area_tag);
+ ifp = nb_running_get_entry(args->dnode, NULL, true);
+ if (ifp)
+ area = isis_area_lookup(area_tag, ifp->vrf_id);
/* The area should have already be created. We are
* setting the priority of the global isis area creation
* slightly lower, so it should be executed first, but I
abort();
}
- ifp = nb_running_get_entry(args->dnode, NULL, true);
circuit = isis_circuit_create(area, ifp);
assert(circuit
&& (circuit->state == C_STATE_CONF
struct interface *ifp;
struct vrf *vrf;
const char *area_tag, *ifname, *vrfname;
+ struct isis *isis = NULL;
if (args->event == NB_EV_VALIDATE) {
/* libyang doesn't like relative paths across module boundaries
vrf = vrf_lookup_by_name(vrfname);
assert(vrf);
ifp = if_lookup_by_name(ifname, vrf->vrf_id);
+
if (!ifp)
return NB_OK;
+
+ isis = isis_lookup_by_vrfid(ifp->vrf_id);
+ if (isis == NULL)
+ return NB_ERR_VALIDATION;
+
circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
area_tag = yang_dnode_get_string(args->dnode, NULL);
if (circuit && circuit->area && circuit->area->area_tag
struct interface *ifp;
struct vrf *vrf;
const char *ifname, *vrfname;
+ struct isis *isis = NULL;
switch (args->event) {
case NB_EV_VALIDATE:
ifp = if_lookup_by_name(ifname, vrf->vrf_id);
if (!ifp)
break;
+
+ isis = isis_lookup_by_vrfid(ifp->vrf_id);
+ if (isis == NULL)
+ return NB_ERR_VALIDATION;
+
circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
if (circuit && circuit->state == C_STATE_UP
&& circuit->area->is_type != IS_LEVEL_1_AND_2
fill_fixed_hdr(pdu_type, circuit->snd_stream);
lenp = stream_get_endp(circuit->snd_stream);
+
stream_putw(circuit->snd_stream, 0); /* PDU length */
- stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
+ stream_put(circuit->snd_stream, circuit->area->isis->sysid,
+ ISIS_SYS_ID_LEN);
stream_putc(circuit->snd_stream, circuit->idx);
stream_putc(circuit->snd_stream, 9); /* code */
stream_putc(circuit->snd_stream, 16); /* len */
static int process_p2p_hello(struct iih_info *iih)
{
struct isis_threeway_adj *tw_adj = iih->tlvs->threeway_adj;
+
if (tw_adj) {
if (tw_adj->state > ISIS_THREEWAY_DOWN) {
if (IS_DEBUG_ADJ_PACKETS) {
}
if (tw_adj->neighbor_set
- && (memcmp(tw_adj->neighbor_id, isis->sysid, ISIS_SYS_ID_LEN)
- || tw_adj->neighbor_circuit_id != (uint32_t) iih->circuit->idx)) {
+ && (memcmp(tw_adj->neighbor_id,
+ iih->circuit->area->isis->sysid, ISIS_SYS_ID_LEN)
+ || tw_adj->neighbor_circuit_id
+ != (uint32_t)iih->circuit->idx)) {
if (IS_DEBUG_ADJ_PACKETS) {
zlog_debug("ISIS-Adj (%s): Rcvd P2P IIH from (%s) which lists IS/Circuit different from us as neighbor.",
? "P2P IIH"
: (level == ISIS_LEVEL1) ? "L1 LAN IIH" : "L2 LAN IIH";
-
stream_get_from(raw_pdu, circuit->rcv_stream, pdu_start,
pdu_end - pdu_start);
if (IS_DEBUG_ADJ_PACKETS) {
goto out;
}
- if (!memcmp(iih.sys_id, isis->sysid, ISIS_SYS_ID_LEN)) {
+ if (!memcmp(iih.sys_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN)) {
zlog_warn(
"ISIS-Adj (%s): Received IIH with own sysid - discard",
circuit->area->area_tag);
ack_lsp(&hdr, circuit, level);
goto out; /* FIXME: do we need a purge? */
} else {
- if (memcmp(hdr.lsp_id, isis->sysid, ISIS_SYS_ID_LEN)) {
+ if (memcmp(hdr.lsp_id, circuit->area->isis->sysid,
+ ISIS_SYS_ID_LEN)) {
/* LSP by some other system -> do 7.3.16.4 b) */
/* 7.3.16.4 b) 1) */
if (comp == LSP_NEWER) {
}
/* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a
* purge */
- if (memcmp(hdr.lsp_id, isis->sysid, ISIS_SYS_ID_LEN) == 0) {
+ if (memcmp(hdr.lsp_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN)
+ == 0) {
if (!lsp) {
/* 7.3.16.4: initiate a purge */
lsp_purge_non_exist(level, &hdr, circuit->area);
struct isis_passwd *passwd = (level == IS_LEVEL_1)
? &circuit->area->area_passwd
: &circuit->area->domain_passwd;
+
if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_RECV)) {
int auth_code = isis_tlvs_auth_is_valid(
tlvs, passwd, circuit->rcv_stream, false);
entry = entry->next) {
struct isis_lsp *lsp =
lsp_search(&circuit->area->lspdb[level - 1], entry->id);
- bool own_lsp = !memcmp(entry->id, isis->sysid, ISIS_SYS_ID_LEN);
+ bool own_lsp = !memcmp(entry->id, circuit->area->isis->sysid,
+ ISIS_SYS_ID_LEN);
if (lsp) {
/* 7.3.15.2 b) 1) is this LSP newer */
int cmp = lsp_compare(circuit->area->area_tag, lsp,
* are not 0,
* insert it and set SSN on it */
if (entry->rem_lifetime && entry->checksum
- && entry->seqno && memcmp(entry->id, isis->sysid,
- ISIS_SYS_ID_LEN)) {
+ && entry->seqno
+ && memcmp(entry->id, circuit->area->isis->sysid,
+ ISIS_SYS_ID_LEN)) {
struct isis_lsp *lsp0 = NULL;
if (LSP_FRAGMENT(entry->id)) {
}
/* either 3 or 0 */
- if (pdu_type != FS_LINK_STATE /* FS PDU doesn't contain max area addr field */
+ if (pdu_type != FS_LINK_STATE /* FS PDU doesn't contain max area addr
+ field */
&& max_area_addrs != 0
- && max_area_addrs != isis->max_area_addrs) {
+ && max_area_addrs != circuit->area->isis->max_area_addrs) {
flog_err(
EC_ISIS_PACKET,
"maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %hhu while the parameter for this IS is %u",
- max_area_addrs, isis->max_area_addrs);
+ max_area_addrs, circuit->area->isis->max_area_addrs);
circuit->max_area_addr_mismatches++;
#ifndef FABRICD
/* send northbound notification */
fill_fixed_hdr(pdu_type, circuit->snd_stream);
size_t len_pointer = stream_get_endp(circuit->snd_stream);
+
stream_putw(circuit->snd_stream, 0);
- stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
+ stream_put(circuit->snd_stream, circuit->area->isis->sysid,
+ ISIS_SYS_ID_LEN);
/* with zero circuit id - ref 9.10, 9.11 */
stream_putc(circuit->snd_stream, 0);
size_t len_pointer = stream_get_endp(circuit->snd_stream);
stream_putw(circuit->snd_stream, 0); /* length is filled in later */
- stream_put(circuit->snd_stream, isis->sysid, ISIS_SYS_ID_LEN);
+ stream_put(circuit->snd_stream, circuit->area->isis->sysid,
+ ISIS_SYS_ID_LEN);
stream_putc(circuit->snd_stream, circuit->idx);
struct isis_passwd *passwd = (level == ISIS_LEVEL1)
}
/* Handle notification about route being added */
-void isis_redist_add(int type, struct prefix *p, struct prefix_ipv6 *src_p,
- uint8_t distance, uint32_t metric)
+void isis_redist_add(struct isis *isis, int type, struct prefix *p,
+ struct prefix_ipv6 *src_p, uint8_t distance,
+ uint32_t metric)
{
int family = p->family;
struct route_table *ei_table = get_ext_info(isis, family);
}
}
-void isis_redist_delete(int type, struct prefix *p, struct prefix_ipv6 *src_p)
+void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
+ struct prefix_ipv6 *src_p)
{
int family = p->family;
struct route_table *ei_table = get_ext_info(isis, family);
* by "default-information originate always". Areas without the
* "always" setting will ignore routes with origin
* DEFAULT_ROUTE. */
- isis_redist_add(DEFAULT_ROUTE, p, NULL,
- 254, MAX_WIDE_PATH_METRIC);
+ isis_redist_add(isis, DEFAULT_ROUTE, p, NULL, 254,
+ MAX_WIDE_PATH_METRIC);
return;
}
struct route_map *map;
};
+struct isis;
struct isis_area;
struct prefix;
struct prefix_ipv6;
struct route_table *get_ext_reach(struct isis_area *area, int family,
int level);
-void isis_redist_add(int type, struct prefix *p, struct prefix_ipv6 *src_p,
- uint8_t distance, uint32_t metric);
-void isis_redist_delete(int type, struct prefix *p, struct prefix_ipv6 *src_p);
+void isis_redist_add(struct isis *isis, int type, struct prefix *p,
+ struct prefix_ipv6 *src_p, uint8_t distance,
+ uint32_t metric);
+void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
+ struct prefix_ipv6 *src_p);
int isis_redist_config_write(struct vty *vty, struct isis_area *area,
int family);
void isis_redist_init(void);
#include "table.h"
#include "spf_backoff.h"
#include "srcdest_table.h"
+#include "vrf.h"
#include "isis_constants.h"
#include "isis_common.h"
init_spt(spftree, ISIS_MT_IPV4_UNICAST, ISIS_LEVEL2,
AF_INET, SPFTREE_IPV4, true);
- if (!memcmp(sysid, isis->sysid, ISIS_SYS_ID_LEN)) {
+
+ if (!memcmp(sysid, area->isis->sysid, ISIS_SYS_ID_LEN)) {
/* If we are running locally, initialize with information from adjacencies */
struct isis_vertex *root = isis_spf_add_root(spftree, sysid);
isis_spf_preload_tent(spftree, sysid, root);
area->area_tag, level);
if (area->ip_circuits)
- retval = isis_run_spf(area, level, SPFTREE_IPV4, isis->sysid);
+ retval = isis_run_spf(area, level, SPFTREE_IPV4,
+ area->isis->sysid);
if (area->ipv6_circuits)
- retval = isis_run_spf(area, level, SPFTREE_IPV6, isis->sysid);
+ retval = isis_run_spf(area, level, SPFTREE_IPV6,
+ area->isis->sysid);
if (area->ipv6_circuits && isis_area_ipv6_dstsrc_enabled(area))
- retval = isis_run_spf(area, level, SPFTREE_DSTSRC, isis->sysid);
+ retval = isis_run_spf(area, level, SPFTREE_DSTSRC,
+ area->isis->sysid);
isis_area_verify_routes(area);
vty_out(vty, "IS-IS paths to level-%d routers %s\n",
level, tree_id_text);
isis_print_paths(vty, &area->spftree[tree_id][level - 1]->paths,
- isis->sysid);
+ area->isis->sysid);
+
vty_out(vty, "\n");
}
-DEFUN (show_isis_topology,
- show_isis_topology_cmd,
- "show " PROTO_NAME " topology"
-#ifndef FABRICD
- " [<level-1|level-2>]"
-#endif
- , SHOW_STR
- PROTO_HELP
- "IS-IS paths to Intermediate Systems\n"
-#ifndef FABRICD
- "Paths to all level-1 routers in the area\n"
- "Paths to all level-2 routers in the domain\n"
-#endif
- )
+static void show_isis_topology_common(struct vty *vty, int levels,
+ struct isis *isis)
{
- int levels;
struct listnode *node;
struct isis_area *area;
- if (argc < 4)
- levels = ISIS_LEVEL1 | ISIS_LEVEL2;
- else if (strmatch(argv[3]->text, "level-1"))
- levels = ISIS_LEVEL1;
- else
- levels = ISIS_LEVEL2;
-
if (!isis->area_list || 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",
vty_out(vty, "\n");
}
+}
+
+DEFUN(show_isis_topology, show_isis_topology_cmd,
+ "show " PROTO_NAME
+ " [vrf <NAME|all>] topology"
+#ifndef FABRICD
+ " [<level-1|level-2>]"
+#endif
+ ,
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "IS-IS paths to Intermediate Systems\n"
+#ifndef FABRICD
+ "Paths to all level-1 routers in the area\n"
+ "Paths to all level-2 routers in the domain\n"
+#endif
+)
+{
+ int levels = ISIS_LEVELS;
+ struct listnode *inode, *nnode;
+ struct isis *isis = NULL;
+ int idx = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ if (argv_find(argv, argc, "topology", &idx)) {
+ if (argc < idx + 2)
+ levels = ISIS_LEVEL1 | ISIS_LEVEL2;
+ else if (strmatch(argv[idx + 1]->arg, "level-1"))
+ levels = ISIS_LEVEL1;
+ else
+ levels = ISIS_LEVEL2;
+ }
+
+ if (!im) {
+ vty_out(vty, "IS-IS Routing Process not enabled\n");
+ return CMD_SUCCESS;
+ }
+ 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)) {
+ show_isis_topology_common(vty, levels, isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ show_isis_topology_common(vty, levels, isis);
+ }
return CMD_SUCCESS;
}
* Declaration of new show commands.
*/
DEFUN(show_sr_prefix_sids, show_sr_prefix_sids_cmd,
- "show isis segment-routing prefix-sids",
- SHOW_STR PROTO_HELP
+ "show isis [vrf <NAME|all>] segment-routing prefix-sids",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
"Segment-Routing\n"
"Segment-Routing Prefix-SIDs\n")
{
- struct listnode *node;
+ struct listnode *node, *inode, *nnode;
struct isis_area *area;
-
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
- vty_out(vty, "Area %s:\n",
- area->area_tag ? area->area_tag : "null");
-
- for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++)
- show_prefix_sids(vty, area, level);
+ struct isis *isis = NULL;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ 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(isis->area_list, node,
+ area)) {
+ vty_out(vty, "Area %s:\n",
+ area->area_tag ? area->area_tag
+ : "null");
+ for (int level = ISIS_LEVEL1;
+ level <= ISIS_LEVELS; level++)
+ show_prefix_sids(vty, area,
+ level);
+ }
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL) {
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, node,
+ area)) {
+ vty_out(vty, "Area %s:\n",
+ area->area_tag ? area->area_tag
+ : "null");
+ for (int level = ISIS_LEVEL1;
+ level <= ISIS_LEVELS; level++)
+ show_prefix_sids(vty, area, level);
+ }
+ }
}
return CMD_SUCCESS;
"Segment-Routing\n"
"Segment-Routing node\n")
{
- struct listnode *node;
+ struct listnode *node, *inode, *nnode;
struct isis_area *area;
+ struct isis *isis = NULL;
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
- vty_out(vty, "Area %s:\n",
- area->area_tag ? area->area_tag : "null");
+ for (ALL_LIST_ELEMENTS(im->isis, inode, nnode, isis)) {
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
+ vty_out(vty, "Area %s:\n",
+ area->area_tag ? area->area_tag : "null");
- for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++)
- show_node(vty, area, level);
+ for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS;
+ level++)
+ show_node(vty, area, level);
+ }
}
return CMD_SUCCESS;
/* Followings are vty command functions */
#ifndef FABRICD
-DEFUN (show_isis_mpls_te_router,
- show_isis_mpls_te_router_cmd,
- "show " PROTO_NAME " mpls-te router",
- SHOW_STR
- PROTO_HELP
- MPLS_TE_STR
- "Router information\n")
+DEFUN(show_isis_mpls_te_router,
+ show_isis_mpls_te_router_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] mpls-te router",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR "All VRFs\n"
+ MPLS_TE_STR "Router information\n")
{
- struct listnode *anode;
+ struct listnode *anode, *nnode, *inode;
struct isis_area *area;
+ struct isis *isis = NULL;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
- if (!isis) {
+ if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
return CMD_SUCCESS;
}
-
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
-
- if (!IS_MPLS_TE(area->mta))
- continue;
-
- vty_out(vty, "Area %s:\n", area->area_tag);
- if (ntohs(area->mta->router_id.s_addr) != 0)
- vty_out(vty, " MPLS-TE Router-Address: %s\n",
- inet_ntoa(area->mta->router_id));
- else
- vty_out(vty, " N/A\n");
+ 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(isis->area_list,
+ anode, area)) {
+ if (!IS_MPLS_TE(area->mta))
+ continue;
+
+ vty_out(vty, "Area %s:\n",
+ area->area_tag);
+ if (ntohs(area->mta->router_id.s_addr)
+ != 0)
+ vty_out(vty,
+ " MPLS-TE Router-Address: %s\n",
+ inet_ntoa(
+ area->mta
+ ->router_id));
+ else
+ vty_out(vty, " N/A\n");
+ }
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL) {
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
+ area)) {
+
+ if (!IS_MPLS_TE(area->mta))
+ continue;
+
+ vty_out(vty, "Area %s:\n", area->area_tag);
+ if (ntohs(area->mta->router_id.s_addr) != 0)
+ vty_out(vty,
+ " MPLS-TE Router-Address: %s\n",
+ inet_ntoa(
+ area->mta->router_id));
+ else
+ vty_out(vty, " N/A\n");
+ }
+ }
}
return CMD_SUCCESS;
"Interface information\n"
"Interface name\n")
{
- struct listnode *anode, *cnode;
+ struct listnode *anode, *cnode, *nnode, *inode;
struct isis_area *area;
struct isis_circuit *circuit;
struct interface *ifp;
int idx_interface = 4;
+ struct isis *isis = NULL;
- if (!isis) {
+ if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
return CMD_SUCCESS;
}
if (argc == idx_interface) {
/* Show All Interfaces. */
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
+ area)) {
- if (!IS_MPLS_TE(area->mta))
- continue;
+ if (!IS_MPLS_TE(area->mta))
+ continue;
- vty_out(vty, "Area %s:\n", area->area_tag);
+ vty_out(vty, "Area %s:\n", area->area_tag);
- for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode,
- circuit))
- show_ext_sub(vty, circuit->interface->name,
- circuit->ext);
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
+ cnode, circuit))
+ show_ext_sub(vty,
+ circuit->interface->name,
+ circuit->ext);
+ }
}
} else {
/* Interface name is specified. */
return CMD_SUCCESS;
}
-static void lsp_print_flooding(struct vty *vty, struct isis_lsp *lsp)
+static void lsp_print_flooding(struct vty *vty, struct isis_lsp *lsp,
+ struct isis *isis)
{
char lspid[255];
char buf[MONOTIME_STRLEN];
- lspid_print(lsp->hdr.lsp_id, lspid, true, true);
+ lspid_print(lsp->hdr.lsp_id, lspid, true, true, isis);
vty_out(vty, "Flooding information for %s\n", lspid);
if (!lsp->flooding_neighbors[TX_LSP_NORMAL]) {
struct listnode *node;
struct isis_area *area;
+ struct isis *isis = NULL;
+
+ isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+
+ if (isis == NULL) {
+ vty_out(vty, "IS-IS Routing Process not enabled\n");
+ return CMD_SUCCESS;
+ }
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
struct lspdb_head *head = &area->lspdb[ISIS_LEVEL2 - 1];
struct isis_lsp *lsp;
- vty_out(vty, "Area %s:\n", area->area_tag ?
- area->area_tag : "null");
-
+ vty_out(vty, "Area %s:\n",
+ area->area_tag ? area->area_tag : "null");
if (lspid) {
- lsp = lsp_for_arg(head, lspid);
-
+ lsp = lsp_for_arg(head, lspid, isis);
if (lsp)
- lsp_print_flooding(vty, lsp);
-
+ lsp_print_flooding(vty, lsp, isis);
continue;
}
-
frr_each (lspdb, head, lsp) {
- lsp_print_flooding(vty, lsp);
+ lsp_print_flooding(vty, lsp, isis);
vty_out(vty, "\n");
}
}
}
}
- area = isis_area_lookup(area_tag);
+ area = isis_area_lookup(area_tag, VRF_DEFAULT);
if (!area)
- area = isis_area_create(area_tag);
+ area = isis_area_create(area_tag, VRF_DEFAULT_NAME);
if (!circuit || !circuit->area) {
circuit = isis_circuit_create(area, ifp);
const char *af = argv[idx_afi]->arg;
const char *area_tag = argv[idx_word]->arg;
- area = isis_area_lookup(area_tag);
+ area = isis_area_lookup(area_tag, VRF_DEFAULT);
if (!area) {
vty_out(vty, "Can't find ISIS instance %s\n",
area_tag);
struct isis_area *area;
struct listnode *node;
struct prefix router_id;
+ struct isis *isis = NULL;
+
+ isis = isis_lookup_by_vrfid(vrf_id);
+
+ if (isis == NULL) {
+ return -1;
+ }
zebra_router_id_update_read(zclient->ibuf, &router_id);
if (isis->router_id == router_id.u.prefix4.s_addr)
static int isis_zebra_read(ZAPI_CALLBACK_ARGS)
{
struct zapi_route api;
+ struct isis *isis = NULL;
+
+ isis = isis_lookup_by_vrfid(vrf_id);
+
+ if (isis == NULL)
+ return -1;
if (zapi_route_decode(zclient->ibuf, &api) < 0)
return -1;
}
if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
- isis_redist_add(api.type, &api.prefix, &api.src_prefix,
+ isis_redist_add(isis, api.type, &api.prefix, &api.src_prefix,
api.distance, api.metric);
else
- isis_redist_delete(api.type, &api.prefix, &api.src_prefix);
+ isis_redist_delete(isis, api.type, &api.prefix,
+ &api.src_prefix);
return 0;
}
#include "prefix.h"
#include "table.h"
#include "qobj.h"
+#include "vrf.h"
#include "spf_backoff.h"
#include "lib/northbound_cli.h"
unsigned long debug_tx_queue;
unsigned long debug_sr;
-struct isis *isis = NULL;
-
DEFINE_QOBJ_TYPE(isis_area)
+/* ISIS process wide configuration. */
+static struct isis_master isis_master;
+
+/* ISIS process wide configuration pointer to export. */
+struct isis_master *im;
+
/*
* Prototypes.
*/
int isis_area_get(struct vty *, const char *);
int area_net_title(struct vty *, const char *);
int area_clear_net_title(struct vty *, const char *);
-int show_isis_interface_common(struct vty *, const char *ifname, char);
-int show_isis_neighbor_common(struct vty *, const char *id, char);
-int clear_isis_neighbor_common(struct vty *, const char *id);
+int show_isis_interface_common(struct vty *, const char *ifname, char,
+ const char *vrf_name, bool all_vrf);
+int show_isis_neighbor_common(struct vty *, const char *id, char,
+ const char *vrf_name, bool all_vrf);
+int clear_isis_neighbor_common(struct vty *, const char *id, const char *vrf_name,
+ bool all_vrf);
+
+static void isis_add(struct isis *isis)
+{
+ listnode_add(im->isis, isis);
+}
+
+static void isis_delete(struct isis *isis)
+{
+ listnode_delete(im->isis, isis);
+}
+
+/* Link ISIS instance to VRF. */
+void isis_vrf_link(struct isis *isis, struct vrf *vrf)
+{
+ isis->vrf_id = vrf->vrf_id;
+ if (vrf->info != (void *)isis)
+ vrf->info = (void *)isis;
+}
+
+/* Unlink ISIS instance to VRF. */
+void isis_vrf_unlink(struct isis *isis, struct vrf *vrf)
+{
+ if (vrf->info == (void *)isis)
+ vrf->info = NULL;
+ isis->vrf_id = VRF_UNKNOWN;
+}
+
+struct isis *isis_lookup_by_vrfid(vrf_id_t vrf_id)
+{
+ struct isis *isis = NULL;
+ struct listnode *node, *nnode;
+ for (ALL_LIST_ELEMENTS(im->isis, node, nnode, 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;
+
+ for (ALL_LIST_ELEMENTS(im->isis, node, nnode, 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 = NULL;
+ struct listnode *node, *nnode;
+ for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
+ if (!memcmp(isis->sysid, sysid, ISIS_SYS_ID_LEN))
+ return isis;
+ return NULL;
+}
+
+void isis_master_init(struct thread_master *master)
+{
+ memset(&isis_master, 0, sizeof(struct isis_master));
+ im = &isis_master;
+ im->isis = list_new();
+ im->master = master;
+}
-void isis_new(unsigned long process_id, vrf_id_t vrf_id)
+void isis_global_instance_create()
{
+ struct isis *isis = NULL;
+
+ isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+ if (isis == NULL) {
+ isis = isis_new(VRF_DEFAULT);
+ isis_add(isis);
+ }
+}
+
+struct isis *isis_new(vrf_id_t vrf_id)
+{
+ struct vrf *vrf = NULL;
+ struct isis *isis = NULL;
+
isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
+ isis->vrf_id = vrf_id;
+ vrf = vrf_lookup_by_id(vrf_id);
+
+ if (vrf) {
+ isis_vrf_link(isis, vrf);
+ isis->name = XSTRDUP(MTYPE_ISIS, vrf->name);
+ }
+
+ if (IS_DEBUG_EVENTS)
+ zlog_debug(
+ "%s: Create new isis instance with vrf_name %s vrf_id %u",
+ __func__, isis->name, isis->vrf_id);
+
/*
* Default values
*/
- isis->vrf_id = vrf_id;
isis->max_area_addrs = 3;
- isis->process_id = process_id;
+ isis->process_id = getpid();
isis->router_id = 0;
isis->area_list = list_new();
isis->init_circ_list = list_new();
isis->uptime = time(NULL);
- dyn_cache_init();
+ dyn_cache_init(isis);
+
+ return isis;
}
-struct isis_area *isis_area_create(const char *area_tag)
+struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
{
struct isis_area *area;
-
+ struct isis *isis = NULL;
+ struct vrf *vrf = NULL;
area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
/*
area_mt_init(area);
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;
return area;
}
-struct isis_area *isis_area_lookup(const char *area_tag)
+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;
+
+ isis = isis_lookup_by_vrfid(vrf_id);
+ if (isis == NULL)
+ return NULL;
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area))
if ((area->area_tag == NULL && area_tag == NULL)
{
struct isis_area *area;
- area = isis_area_lookup(area_tag);
+ area = isis_area_lookup(area_tag, VRF_DEFAULT);
if (area) {
VTY_PUSH_CONTEXT(ROUTER_NODE, area);
return CMD_SUCCESS;
}
- area = isis_area_create(area_tag);
+ area = isis_area_create(area_tag, VRF_DEFAULT_NAME);
if (IS_DEBUG_EVENTS)
zlog_debug("New IS-IS area instance %s", area->area_tag);
thread_cancel_event(master, area);
- listnode_delete(isis->area_list, area);
+ listnode_delete(area->isis->area_list, area);
free(area->area_tag);
area_mt_finish(area);
+ if (listcount(area->isis->area_list) == 0) {
+ memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN);
+ area->isis->sysid_set = 0;
+ }
+
XFREE(MTYPE_ISIS_AREA, area);
- if (listcount(isis->area_list) == 0) {
- memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
- isis->sysid_set = 0;
+}
+
+void isis_finish(struct isis *isis)
+{
+ struct vrf *vrf = NULL;
+
+ isis_delete(isis);
+ if (isis->name) {
+ vrf = vrf_lookup_by_name(isis->name);
+ if (vrf)
+ isis_vrf_unlink(isis, vrf);
+ XFREE(MTYPE_ISIS, isis->name);
+ } else {
+ vrf = vrf_lookup_by_id(VRF_DEFAULT);
+ if (vrf)
+ isis_vrf_unlink(isis, vrf);
}
+
+ XFREE(MTYPE_ISIS, isis);
+}
+
+void isis_terminate()
+{
+ struct isis *isis = NULL;
+ struct listnode *node, *nnode;
+
+ if (listcount(im->isis) == 0)
+ return;
+
+ for (ALL_LIST_ELEMENTS(im->isis, node, nnode, isis))
+ isis_finish(isis);
}
#ifdef FABRICD
uint8_t buff[255];
/* We check that we are not over the maximal number of addresses */
- if (listcount(area->area_addrs) >= isis->max_area_addrs) {
+ if (listcount(area->area_addrs) >= area->isis->max_area_addrs) {
vty_out(vty,
"Maximum of area addresses (%d) already reached \n",
- isis->max_area_addrs);
+ area->isis->max_area_addrs);
return CMD_ERR_NOTHING_TODO;
}
return CMD_WARNING_CONFIG_FAILED;
}
- if (isis->sysid_set == 0) {
+ if (area->isis->sysid_set == 0) {
/*
* First area address - get the SystemID for this router
*/
- memcpy(isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN);
- isis->sysid_set = 1;
+ memcpy(area->isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN);
+ area->isis->sysid_set = 1;
if (IS_DEBUG_EVENTS)
zlog_debug("Router has SystemID %s",
- sysid_print(isis->sysid));
+ sysid_print(area->isis->sysid));
} else {
/*
* Check that the SystemID portions match
*/
- if (memcmp(isis->sysid, GETSYSID(addr), ISIS_SYS_ID_LEN)) {
+ if (memcmp(area->isis->sysid, GETSYSID(addr),
+ ISIS_SYS_ID_LEN)) {
vty_out(vty,
"System ID must not change when defining additional area addresses\n");
XFREE(MTYPE_ISIS_AREA_ADDR, addr);
* Last area address - reset the SystemID for this router
*/
if (listcount(area->area_addrs) == 0) {
- memset(isis->sysid, 0, ISIS_SYS_ID_LEN);
- isis->sysid_set = 0;
+ memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN);
+ area->isis->sysid_set = 0;
if (IS_DEBUG_EVENTS)
zlog_debug("Router has no SystemID");
}
* 'show isis interface' command
*/
-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)
{
- struct listnode *anode, *cnode;
+ struct listnode *anode, *cnode, *mnode, *inode;
struct isis_area *area;
struct isis_circuit *circuit;
+ struct isis *isis = NULL;
- if (!isis) {
+ if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
return CMD_SUCCESS;
}
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, mnode, inode, isis)) {
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list,
+ anode, area)) {
+ vty_out(vty, "Area %s:\n",
+ area->area_tag);
+
+ if (detail == ISIS_UI_LEVEL_BRIEF)
+ vty_out(vty,
+ " Interface CircId State Type Level\n");
+
+ for (ALL_LIST_ELEMENTS_RO(
+ area->circuit_list, cnode,
+ circuit))
+ if (!ifname)
+ isis_circuit_print_vty(
+ circuit, vty,
+ detail);
+ else if (strcmp(circuit->interface->name, ifname) == 0)
+ isis_circuit_print_vty(
+ circuit, vty,
+ detail);
+ }
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL) {
+ for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode,
+ area)) {
+ vty_out(vty, "Area %s:\n", area->area_tag);
- for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
- vty_out(vty, "Area %s:\n", area->area_tag);
-
- if (detail == ISIS_UI_LEVEL_BRIEF)
- vty_out(vty,
- " Interface CircId State Type Level\n");
-
- for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit))
- if (!ifname)
- isis_circuit_print_vty(circuit, vty, detail);
- else if (strcmp(circuit->interface->name, ifname) == 0)
- isis_circuit_print_vty(circuit, vty, detail);
+ if (detail == ISIS_UI_LEVEL_BRIEF)
+ vty_out(vty,
+ " Interface CircId State Type Level\n");
+
+ for (ALL_LIST_ELEMENTS_RO(area->circuit_list,
+ cnode, circuit))
+ if (!ifname)
+ isis_circuit_print_vty(
+ circuit, vty, detail);
+ else if (
+ strcmp(circuit->interface->name,
+ ifname)
+ == 0)
+ isis_circuit_print_vty(
+ circuit, vty, detail);
+ }
+ }
}
return CMD_SUCCESS;
}
-DEFUN (show_isis_interface,
- show_isis_interface_cmd,
- "show " PROTO_NAME " interface",
- SHOW_STR
- PROTO_HELP
- "IS-IS interface\n")
+DEFUN(show_isis_interface,
+ show_isis_interface_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] interface",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "IS-IS interface\n")
{
- return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF);
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_BRIEF,
+ vrf_name, all_vrf);
}
-DEFUN (show_isis_interface_detail,
- show_isis_interface_detail_cmd,
- "show " PROTO_NAME " interface detail",
- SHOW_STR
- PROTO_HELP
- "IS-IS interface\n"
- "show detailed information\n")
+DEFUN(show_isis_interface_detail,
+ show_isis_interface_detail_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] interface detail",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "IS-IS interface\n"
+ "show detailed information\n")
{
- return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_DETAIL);
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return show_isis_interface_common(vty, NULL, ISIS_UI_LEVEL_DETAIL,
+ vrf_name, all_vrf);
}
-DEFUN (show_isis_interface_arg,
- show_isis_interface_arg_cmd,
- "show " PROTO_NAME " interface WORD",
- SHOW_STR
- PROTO_HELP
- "IS-IS interface\n"
- "IS-IS interface name\n")
+DEFUN(show_isis_interface_arg,
+ show_isis_interface_arg_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] interface WORD",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "IS-IS interface\n"
+ "IS-IS interface name\n")
{
- int idx_word = 3;
- return show_isis_interface_common(vty, argv[idx_word]->arg,
- ISIS_UI_LEVEL_DETAIL);
-}
+ int idx_word = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
-/*
- * 'show isis neighbor' command
- */
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+
+ char *ifname = argv_find(argv, argc, "WORD", &idx_word)
+ ? argv[idx_word]->arg
+ : NULL;
+ return show_isis_interface_common(vty, ifname, ISIS_UI_LEVEL_DETAIL,
+ vrf_name, all_vrf);
+}
-int show_isis_neighbor_common(struct vty *vty, const char *id, char detail)
+static void isis_neighbor_common(struct vty *vty, const char *id, char detail,
+ struct isis *isis, uint8_t *sysid)
{
struct listnode *anode, *cnode, *node;
struct isis_area *area;
struct isis_circuit *circuit;
struct list *adjdb;
struct isis_adjacency *adj;
- struct isis_dynhn *dynhn;
- uint8_t sysid[ISIS_SYS_ID_LEN];
int i;
- if (!isis) {
- vty_out(vty, "IS-IS Routing Process not enabled\n");
- return CMD_SUCCESS;
- }
-
- memset(sysid, 0, ISIS_SYS_ID_LEN);
- if (id) {
- if (sysid2buff(sysid, id) == 0) {
- dynhn = dynhn_find_by_name(id);
- if (dynhn == NULL) {
- vty_out(vty, "Invalid system id %s\n", id);
- return CMD_SUCCESS;
- }
- memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN);
- }
- }
-
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
vty_out(vty, "Area %s:\n", area->area_tag);
for (ALL_LIST_ELEMENTS_RO(
adjdb, node, adj))
if (!id
- || !memcmp(adj->sysid,
- sysid,
- ISIS_SYS_ID_LEN))
+ || !memcmp(
+ adj->sysid,
+ sysid,
+ ISIS_SYS_ID_LEN))
isis_adj_print_vty(
adj,
vty,
}
}
- return CMD_SUCCESS;
}
-
/*
- * 'clear isis neighbor' command
+ * 'show isis neighbor' command
*/
-int clear_isis_neighbor_common(struct vty *vty, const char *id)
+
+int show_isis_neighbor_common(struct vty *vty, const char *id, char detail,
+ const char *vrf_name, bool all_vrf)
{
- struct listnode *anode, *cnode, *cnextnode, *node, *nnode;
- struct isis_area *area;
- struct isis_circuit *circuit;
- struct list *adjdb;
- struct isis_adjacency *adj;
+ struct listnode *nnode, *inode;
struct isis_dynhn *dynhn;
uint8_t sysid[ISIS_SYS_ID_LEN];
- int i;
+ struct isis *isis = NULL;
- if (!isis) {
+ if (!im) {
vty_out(vty, "IS-IS Routing Process not enabled\n");
return CMD_SUCCESS;
}
}
}
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ isis_neighbor_common(vty, id, detail, isis,
+ sysid);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ isis_neighbor_common(vty, id, detail, isis, sysid);
+ }
+
+ return CMD_SUCCESS;
+}
+
+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 isis_area *area;
+ struct isis_circuit *circuit;
+ struct list *adjdb;
+ struct isis_adjacency *adj;
+ int i;
+
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
for (ALL_LIST_ELEMENTS(area->circuit_list, cnode, cnextnode,
circuit)) {
adjdb, node, nnode,
adj))
if (!id
- || !memcmp(adj->sysid,
- sysid,
- ISIS_SYS_ID_LEN))
+ || !memcmp(
+ adj->sysid,
+ sysid,
+ ISIS_SYS_ID_LEN))
isis_adj_state_change(
&adj,
ISIS_ADJ_DOWN,
}
}
}
-
- return CMD_SUCCESS;
}
-
-DEFUN (show_isis_neighbor,
- show_isis_neighbor_cmd,
- "show " PROTO_NAME " neighbor",
- SHOW_STR
- PROTO_HELP
- "IS-IS neighbor adjacencies\n")
+/*
+ * 'clear isis neighbor' command
+ */
+int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_name,
+ bool all_vrf)
{
- return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF);
-}
+ struct listnode *nnode, *inode;
+ struct isis_dynhn *dynhn;
+ uint8_t sysid[ISIS_SYS_ID_LEN];
+ struct isis *isis = NULL;
-DEFUN (show_isis_neighbor_detail,
- show_isis_neighbor_detail_cmd,
- "show " PROTO_NAME " neighbor detail",
- SHOW_STR
- PROTO_HELP
- "IS-IS neighbor adjacencies\n"
- "show detailed information\n")
-{
- return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_DETAIL);
-}
+ if (!im) {
+ vty_out(vty, "IS-IS Routing Process not enabled\n");
+ return CMD_SUCCESS;
+ }
-DEFUN (show_isis_neighbor_arg,
- show_isis_neighbor_arg_cmd,
- "show " PROTO_NAME " neighbor WORD",
- SHOW_STR
- PROTO_HELP
- "IS-IS neighbor adjacencies\n"
- "System id\n")
-{
- int idx_word = 3;
- return show_isis_neighbor_common(vty, argv[idx_word]->arg,
- ISIS_UI_LEVEL_DETAIL);
-}
+ memset(sysid, 0, ISIS_SYS_ID_LEN);
+ if (id) {
+ if (sysid2buff(sysid, id) == 0) {
+ dynhn = dynhn_find_by_name(id);
+ if (dynhn == NULL) {
+ vty_out(vty, "Invalid system id %s\n", id);
+ return CMD_SUCCESS;
+ }
+ memcpy(sysid, dynhn->id, ISIS_SYS_ID_LEN);
+ }
+ }
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ isis_neighbor_common_clear(vty, id, sysid,
+ isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ isis_neighbor_common_clear(vty, id, sysid, isis);
+ }
-DEFUN (clear_isis_neighbor,
- clear_isis_neighbor_cmd,
- "clear " PROTO_NAME " neighbor",
- CLEAR_STR
- PROTO_HELP
- "IS-IS neighbor adjacencies\n")
-{
- return clear_isis_neighbor_common(vty, NULL);
+ return CMD_SUCCESS;
}
-DEFUN (clear_isis_neighbor_arg,
- clear_isis_neighbor_arg_cmd,
- "clear " PROTO_NAME " neighbor WORD",
- CLEAR_STR
- PROTO_HELP
- "IS-IS neighbor adjacencies\n"
- "System id\n")
-{
- int idx_word = 3;
- return clear_isis_neighbor_common(vty, argv[idx_word]->arg);
+DEFUN(show_isis_neighbor,
+ show_isis_neighbor_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] neighbor",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All vrfs\n"
+ "IS-IS neighbor adjacencies\n")
+{
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_BRIEF,
+ vrf_name, all_vrf);
+}
+
+DEFUN(show_isis_neighbor_detail,
+ show_isis_neighbor_detail_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] neighbor detail",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "all vrfs\n"
+ "IS-IS neighbor adjacencies\n"
+ "show detailed information\n")
+{
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+
+ return show_isis_neighbor_common(vty, NULL, ISIS_UI_LEVEL_DETAIL,
+ vrf_name, all_vrf);
+}
+
+DEFUN(show_isis_neighbor_arg,
+ show_isis_neighbor_arg_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] neighbor WORD",
+ SHOW_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All vrfs\n"
+ "IS-IS neighbor adjacencies\n"
+ "System id\n")
+{
+ int idx_word = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ char *id = argv_find(argv, argc, "WORD", &idx_word)
+ ? argv[idx_word]->arg
+ : NULL;
+
+ return show_isis_neighbor_common(vty, id, ISIS_UI_LEVEL_DETAIL,
+ vrf_name, all_vrf);
+}
+
+DEFUN(clear_isis_neighbor,
+ clear_isis_neighbor_cmd,
+ "clear " PROTO_NAME " [vrf <NAME|all>] neighbor",
+ CLEAR_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All vrfs\n"
+ "IS-IS neighbor adjacencies\n")
+{
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return clear_isis_neighbor_common(vty, NULL, vrf_name, all_vrf);
+}
+
+DEFUN(clear_isis_neighbor_arg,
+ clear_isis_neighbor_arg_cmd,
+ "clear " PROTO_NAME " [vrf <NAME|all>] neighbor WORD",
+ CLEAR_STR
+ PROTO_HELP
+ VRF_CMD_HELP_STR
+ "All vrfs\n"
+ "IS-IS neighbor adjacencies\n"
+ "System id\n")
+{
+ int idx_word = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+
+ char *id = argv_find(argv, argc, "WORD", &idx_word)
+ ? argv[idx_word]->arg
+ : NULL;
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return clear_isis_neighbor_common(vty, id, vrf_name, all_vrf);
}
/*
return CMD_SUCCESS;
}
-DEFUN (show_hostname,
- show_hostname_cmd,
- "show " PROTO_NAME " hostname",
- SHOW_STR
- PROTO_HELP
- "IS-IS Dynamic hostname mapping\n")
+DEFUN(show_hostname, show_hostname_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] hostname",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "IS-IS Dynamic hostname mapping\n")
{
- dynhn_print_all(vty);
+ struct listnode *nnode, *inode;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+ int idx_vrf = 0;
+ struct isis *isis = NULL;
+
+ 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)) {
+ dynhn_print_all(vty, isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ dynhn_print_all(vty, isis);
+ }
return CMD_SUCCESS;
}
-DEFUN (show_isis_spf_ietf,
- show_isis_spf_ietf_cmd,
- "show " PROTO_NAME " spf-delay-ietf",
- SHOW_STR
- PROTO_HELP
- "SPF delay IETF information\n")
+static void isis_spf_ietf_common(struct vty *vty, struct isis *isis)
{
- if (!isis) {
- vty_out(vty, "ISIS is not running\n");
- return CMD_SUCCESS;
- }
-
struct listnode *node;
struct isis_area *area;
-
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
+
+ vty_out(vty, "vrf : %s\n", isis->name);
vty_out(vty, "Area %s:\n",
area->area_tag ? area->area_tag : "null");
}
}
}
+}
+
+DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] spf-delay-ietf",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "SPF delay IETF information\n")
+{
+ struct listnode *nnode, *inode;
+ struct isis *isis = NULL;
+ int idx_vrf = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)
+
+ if (!im) {
+ vty_out(vty, "ISIS is not running\n");
+ return CMD_SUCCESS;
+ }
+
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ isis_spf_ietf_common(vty, isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ isis_spf_ietf_common(vty, isis);
+ }
+
return CMD_SUCCESS;
}
-DEFUN (show_isis_summary,
- show_isis_summary_cmd,
- "show " PROTO_NAME " summary",
- SHOW_STR PROTO_HELP "summary\n")
+static void common_isis_summary(struct vty *vty, struct isis *isis)
{
struct listnode *node, *node2;
struct isis_area *area;
int level;
- if (isis == NULL) {
- vty_out(vty, PROTO_NAME " is not running\n");
- return CMD_SUCCESS;
- }
-
+ vty_out(vty, "vrf : %s\n", isis->name);
vty_out(vty, "Process Id : %ld\n", isis->process_id);
if (isis->sysid_set)
vty_out(vty, "System Id : %s\n",
}
}
}
+}
+
+DEFUN(show_isis_summary, show_isis_summary_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] summary",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "summary\n")
+{
+ struct listnode *inode, *nnode;
+ int idx_vrf = 0;
+ struct isis *isis = NULL;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
+
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf)
+ if (!im) {
+ vty_out(vty, PROTO_NAME " is not running\n");
+ return CMD_SUCCESS;
+ }
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ common_isis_summary(vty, isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ common_isis_summary(vty, isis);
+ }
+
vty_out(vty, "\n");
return CMD_SUCCESS;
}
-struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv)
+struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv,
+ struct isis *isis)
{
char sysid[255] = {0};
uint8_t number[3];
return lsp;
}
-/*
- * This function supports following display options:
- * [ show isis database [detail] ]
- * [ show isis database <sysid> [detail] ]
- * [ show isis database <hostname> [detail] ]
- * [ show isis database <sysid>.<pseudo-id> [detail] ]
- * [ show isis database <hostname>.<pseudo-id> [detail] ]
- * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
- * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
- * [ show isis database detail <sysid> ]
- * [ show isis database detail <hostname> ]
- * [ show isis database detail <sysid>.<pseudo-id> ]
- * [ show isis database detail <hostname>.<pseudo-id> ]
- * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
- * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
- */
-static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
+static int show_isis_database_common(struct vty *vty, const char *argv,
+ int ui_level, struct isis *isis)
{
struct listnode *node;
struct isis_area *area;
for (level = 0; level < ISIS_LEVELS; level++) {
if (lspdb_count(&area->lspdb[level]) > 0) {
- lsp = lsp_for_arg(&area->lspdb[level], argv);
+ lsp = NULL;
+ lsp = lsp_for_arg(&area->lspdb[level], argv,
+ isis);
if (lsp != NULL || argv == NULL) {
vty_out(vty,
if (ui_level == ISIS_UI_LEVEL_DETAIL)
lsp_print_detail(
lsp, vty,
- area->dynhostname);
+ area->dynhostname,
+ isis);
else
lsp_print(lsp, vty,
- area->dynhostname);
+ area->dynhostname,
+ isis);
} else if (argv == NULL) {
lsp_count = lsp_print_all(
vty, &area->lspdb[level],
- ui_level, area->dynhostname);
+ ui_level, area->dynhostname,
+ isis);
vty_out(vty, " %u LSPs\n\n",
lsp_count);
}
}
}
+ return CMD_SUCCESS;
+}
+/*
+ * This function supports following display options:
+ * [ show isis database [detail] ]
+ * [ show isis database <sysid> [detail] ]
+ * [ show isis database <hostname> [detail] ]
+ * [ show isis database <sysid>.<pseudo-id> [detail] ]
+ * [ show isis database <hostname>.<pseudo-id> [detail] ]
+ * [ show isis database <sysid>.<pseudo-id>-<fragment-number> [detail] ]
+ * [ show isis database <hostname>.<pseudo-id>-<fragment-number> [detail] ]
+ * [ show isis database detail <sysid> ]
+ * [ show isis database detail <hostname> ]
+ * [ show isis database detail <sysid>.<pseudo-id> ]
+ * [ show isis database detail <hostname>.<pseudo-id> ]
+ * [ show isis database detail <sysid>.<pseudo-id>-<fragment-number> ]
+ * [ show isis database detail <hostname>.<pseudo-id>-<fragment-number> ]
+ */
+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;
+
+ if (vrf_name) {
+ if (all_vrf) {
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
+ show_isis_database_common(vty, argv, ui_level,
+ isis);
+ }
+ return 0;
+ }
+ isis = isis_lookup_by_vrfname(vrf_name);
+ if (isis != NULL)
+ show_isis_database_common(vty, argv, ui_level, isis);
+ }
return CMD_SUCCESS;
}
-DEFUN (show_database,
- show_database_cmd,
- "show " PROTO_NAME " database [detail] [WORD]",
- SHOW_STR
- PROTO_HELP
- "Link state database\n"
- "Detailed information\n"
- "LSP ID\n")
+DEFUN(show_database, show_database_cmd,
+ "show " PROTO_NAME " [vrf <NAME|all>] database [detail] [WORD]",
+ SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
+ "All VRFs\n"
+ "Link state database\n"
+ "Detailed information\n"
+ "LSP ID\n")
{
int idx = 0;
+ int idx_vrf = 0;
+ const char *vrf_name = VRF_DEFAULT_NAME;
+ bool all_vrf = false;
int uilevel = argv_find(argv, argc, "detail", &idx)
? ISIS_UI_LEVEL_DETAIL
: ISIS_UI_LEVEL_BRIEF;
char *id = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg : NULL;
- return show_isis_database(vty, id, uilevel);
+ ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+ return show_isis_database(vty, id, uilevel, vrf_name, all_vrf);
}
#ifdef FABRICD
int idx_word = 3;
area_tag = argv[idx_word]->arg;
- area = isis_area_lookup(area_tag);
+ area = isis_area_lookup(area_tag, VRF_DEFAULT);
if (area == NULL) {
zlog_warn("%s: could not find area with area-tag %s",
__func__, area_tag);
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;
+
+ if (!im) {
+ vty_out(vty, "IS-IS Routing Process not enabled\n");
+ return CMD_SUCCESS;
+ }
- if (isis != NULL) {
- struct isis_area *area;
- struct listnode *node, *node2;
+ for (ALL_LIST_ELEMENTS(im->isis, nnode, inode, isis)) {
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
/* ISIS - Area name */
extern void isis_cli_init(void);
#endif
+#define ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf) \
+ if (argv_find(argv, argc, "vrf", &idx_vrf)) { \
+ vrf_name = argv[idx_vrf + 1]->arg; \
+ all_vrf = strmatch(vrf_name, "all"); \
+ }
+
extern struct zebra_privs_t isisd_privs;
/* uncomment if you are a developer in bug hunt */
struct fabricd;
+struct isis_master {
+ /* ISIS instance. */
+ struct list *isis;
+ /* ISIS thread master. */
+ struct thread_master *master;
+ /* Various OSPF global configuration. */
+ uint8_t options;
+};
+
struct isis {
vrf_id_t vrf_id;
+ char *name;
unsigned long process_id;
int sysid_set;
uint8_t sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */
struct route_table *ext_info[REDIST_PROTOCOL_COUNT];
};
-extern struct isis *isis;
+extern struct isis_master *im;
enum spf_tree_id {
SPFTREE_IPV4 = 0,
};
DECLARE_QOBJ_TYPE(isis_area)
+void isis_terminate(void);
+void isis_finish(struct isis *isis);
+void isis_master_init(struct thread_master *master);
+void isis_vrf_link(struct isis *isis, struct vrf *vrf);
+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);
+
void isis_init(void);
-void isis_new(unsigned long process_id, vrf_id_t vrf_id);
-struct isis_area *isis_area_create(const char *);
-struct isis_area *isis_area_lookup(const char *);
+struct isis *isis_new(vrf_id_t vrf_id);
+struct isis_area *isis_area_create(const char *, const char *);
+struct isis_area *isis_area_lookup(const char *, vrf_id_t vrf_id);
int isis_area_get(struct vty *vty, const char *area_tag);
void isis_area_destroy(struct isis_area *area);
void print_debug(struct vty *, int, int);
-struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv);
+struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv,
+ struct isis *isis);
void isis_area_invalidate_routes(struct isis_area *area, int levels);
void isis_area_verify_routes(struct isis_area *area);
int main(int argc, char **argv)
{
+ struct isis *isis = NULL;
isis = calloc(sizeof(*isis), 1);
test_lsp_build_list_nonzero_ht();
return 0;