isisd : Transformational changes to support different VRFs.

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>
This commit is contained in:
Kaushik 2020-07-13 05:37:59 -07:00
parent 40ce7a4203
commit eab88f3655
26 changed files with 1122 additions and 429 deletions

View File

@ -475,7 +475,7 @@ void fabricd_run_spf(struct isis_area *area)
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);
}

View File

@ -50,8 +50,6 @@
#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;

View File

@ -195,6 +195,14 @@ static int isis_bfd_nbr_replay(ZAPI_CALLBACK_ARGS)
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.");

View File

@ -224,10 +224,17 @@ struct isis_circuit *circuit_scan_by_ifp(struct interface *ifp)
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 =
@ -618,7 +625,8 @@ int isis_circuit_up(struct isis_circuit *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,
@ -802,7 +810,8 @@ void isis_circuit_down(struct isis_circuit *circuit)
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);
@ -1011,6 +1020,14 @@ static int isis_interface_config_write(struct vty *vty)
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 */

View File

@ -62,7 +62,12 @@ DEFPY_YANG_NOSH(router_isis, router_isis_cmd, "router isis WORD$tag",
* 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);
@ -90,7 +95,7 @@ DEFPY_YANG(no_router_isis, no_router_isis_cmd, "no router isis WORD$tag",
}
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)) {
@ -134,13 +139,20 @@ DEFPY_YANG(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag",
{
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);
@ -148,9 +160,9 @@ DEFPY_YANG(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$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",
@ -159,8 +171,7 @@ DEFPY_YANG(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$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) {
@ -188,7 +199,6 @@ DEFPY_YANG(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag",
}
/* 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");
@ -204,13 +214,20 @@ DEFPY_YANG(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag",
{
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);
@ -218,9 +235,9 @@ DEFPY_YANG(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$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",
@ -229,8 +246,7 @@ DEFPY_YANG(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$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) {
@ -258,7 +274,6 @@ DEFPY_YANG(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag",
}
/* 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");

View File

@ -48,8 +48,6 @@
#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"};
@ -66,6 +64,7 @@ struct isis_circuit *
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)
@ -86,6 +85,13 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
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;
@ -111,7 +117,8 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
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);
@ -122,6 +129,14 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
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;
@ -174,6 +189,15 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
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:

View File

@ -225,7 +225,7 @@ int isis_dr_resign(struct isis_circuit *circuit, int level)
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);
@ -278,7 +278,8 @@ int isis_dr_commence(struct isis_circuit *circuit, int 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;
@ -299,7 +300,8 @@ int isis_dr_commence(struct isis_circuit *circuit, int level)
/* 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;

View File

@ -45,11 +45,11 @@ extern struct host host;
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;
}
@ -59,19 +59,22 @@ static int dyn_cache_cleanup(struct thread *thread)
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;
}
@ -132,11 +135,14 @@ void isis_dynhn_remove(const uint8_t *id)
* 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);

View File

@ -30,11 +30,11 @@ struct isis_dynhn {
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 */

View File

@ -338,13 +338,17 @@ void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno)
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());
}
@ -591,7 +595,8 @@ static void lsp_set_time(struct isis_lsp *lsp)
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];
@ -607,6 +612,7 @@ void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag)
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));
@ -638,13 +644,14 @@ static const char *lsp_bits2string(uint8_t lsp_bits, char *buf, size_t buf_size)
}
/* 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);
@ -658,9 +665,10 @@ void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost)
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");
@ -668,19 +676,19 @@ void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost)
/* 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++;
}
}
@ -913,10 +921,10 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
}
/* 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) {
@ -954,8 +962,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
* 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);
@ -1210,7 +1218,8 @@ int lsp_generate(struct isis_area *area, int level)
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);
@ -1281,9 +1290,8 @@ static int lsp_regenerate(struct isis_area *area, int level)
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);
@ -1404,7 +1412,7 @@ int _lsp_regenerate_schedule(struct isis_area *area, int level,
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);
@ -1525,7 +1533,7 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
*/
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) {
@ -1603,7 +1611,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
|| (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;
@ -1663,7 +1671,7 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level)
|| (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;
@ -1720,7 +1728,7 @@ static int lsp_l1_refresh_pseudo(struct thread *thread)
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);
@ -1742,7 +1750,7 @@ static int lsp_l2_refresh_pseudo(struct thread *thread)
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);
@ -1770,7 +1778,7 @@ int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level)
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);

View File

@ -29,6 +29,7 @@
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
@ -115,11 +116,14 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
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);

View File

@ -101,6 +101,7 @@ void sigusr1(void);
static __attribute__((__noreturn__)) void terminate(int i)
{
isis_terminate();
isis_sr_term();
isis_zebra_stop();
exit(i);
@ -233,7 +234,8 @@ int main(int argc, char **argv, char **envp)
}
/* thread master */
master = frr_init();
isis_master_init(frr_init());
master = im->master;
/*
* initializations
@ -259,7 +261,7 @@ int main(int argc, char **argv, char **envp)
mt_init();
/* create the global 'isis' instance */
isis_new(1, VRF_DEFAULT);
isis_global_instance_create();
isis_zebra_init(master, instance);
isis_bfd_init();

View File

@ -437,15 +437,18 @@ 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(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);

View File

@ -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(const uint8_t *sysid);
const char *print_sys_hostname(uint8_t *sysid);
void zlog_dump_data(void *data, int len);
/*

View File

@ -58,11 +58,11 @@ int isis_instance_create(struct nb_cb_create_args *args)
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);
@ -113,6 +113,10 @@ int isis_instance_area_address_create(struct nb_cb_create_args *args)
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) {
@ -121,9 +125,9 @@ int isis_instance_area_address_create(struct nb_cb_create_args *args)
"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,
@ -145,12 +149,13 @@ int isis_instance_area_address_create(struct nb_cb_create_args *args)
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,
@ -200,6 +205,7 @@ int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args)
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))
@ -214,8 +220,8 @@ int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args)
* 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");
}
@ -1822,7 +1828,7 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_mo
*/
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");
@ -1842,7 +1848,7 @@ int lib_interface_isis_create(struct nb_cb_create_args *args)
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
@ -1860,7 +1866,9 @@ int lib_interface_isis_create(struct nb_cb_create_args *args)
}
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
@ -1874,7 +1882,6 @@ int lib_interface_isis_create(struct nb_cb_create_args *args)
abort();
}
ifp = nb_running_get_entry(args->dnode, NULL, true);
circuit = isis_circuit_create(area, ifp);
assert(circuit
&& (circuit->state == C_STATE_CONF
@ -1915,6 +1922,7 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
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
@ -1926,8 +1934,14 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
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
@ -1952,6 +1966,7 @@ int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args)
struct interface *ifp;
struct vrf *vrf;
const char *ifname, *vrfname;
struct isis *isis = NULL;
switch (args->event) {
case NB_EV_VALIDATE:
@ -1966,6 +1981,11 @@ int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args)
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

View File

@ -74,8 +74,10 @@ static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit,
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 */
@ -128,6 +130,7 @@ struct iih_info {
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) {
@ -140,8 +143,10 @@ static int process_p2p_hello(struct iih_info *iih)
}
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.",
@ -561,7 +566,6 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
? "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) {
@ -724,7 +728,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
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);
@ -1040,7 +1044,8 @@ dontcheckadj:
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) {
@ -1134,7 +1139,8 @@ dontcheckadj:
}
/* 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);
@ -1370,6 +1376,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
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);
@ -1420,7 +1427,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
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,
@ -1459,8 +1467,9 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
* 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)) {
@ -1667,13 +1676,14 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
}
/* 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 */
@ -2052,8 +2062,10 @@ int send_csnp(struct isis_circuit *circuit, int level)
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);
@ -2230,7 +2242,8 @@ static int send_psnp(int level, struct isis_circuit *circuit)
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)

View File

@ -218,8 +218,9 @@ static void isis_redist_ensure_default(struct isis *isis, int family)
}
/* 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);
@ -270,7 +271,8 @@ void isis_redist_add(int type, struct prefix *p, struct prefix_ipv6 *src_p,
}
}
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);
@ -292,8 +294,8 @@ void isis_redist_delete(int type, struct prefix *p, struct prefix_ipv6 *src_p)
* 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;
}

View File

@ -40,6 +40,7 @@ struct isis_redist {
struct route_map *map;
};
struct isis;
struct isis_area;
struct prefix;
struct prefix_ipv6;
@ -47,9 +48,11 @@ struct vty;
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);

View File

@ -35,6 +35,7 @@
#include "table.h"
#include "spf_backoff.h"
#include "srcdest_table.h"
#include "vrf.h"
#include "isis_constants.h"
#include "isis_common.h"
@ -1083,7 +1084,8 @@ struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
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);
@ -1209,11 +1211,14 @@ static int isis_run_spf_cb(struct thread *thread)
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);
@ -1405,38 +1410,19 @@ static void isis_print_spftree(struct vty *vty, int level,
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",
@ -1469,6 +1455,58 @@ DEFUN (show_isis_topology,
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;
}

View File

@ -1980,20 +1980,48 @@ static void show_prefix_sids(struct vty *vty, struct isis_area *area, int level)
* 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;
struct isis *isis = NULL;
const char *vrf_name = VRF_DEFAULT_NAME;
bool all_vrf = false;
int idx_vrf = 0;
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);
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;
@ -2056,15 +2084,19 @@ DEFUN(show_sr_node, show_sr_node_cmd,
"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;

View File

@ -302,34 +302,68 @@ int isis_mpls_te_update(struct interface *ifp)
/* 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;
}
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;
for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) {
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;
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");
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;
@ -449,30 +483,35 @@ DEFUN (show_isis_mpls_te_interface,
"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. */

View File

@ -112,12 +112,13 @@ DEFUN (no_triggered_csnp,
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]) {
@ -170,25 +171,29 @@ DEFUN (show_lsp_flooding,
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");
}
}
@ -222,9 +227,9 @@ DEFUN (ip_router_isis,
}
}
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);
@ -276,7 +281,7 @@ DEFUN (no_ip_router_isis,
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);

View File

@ -62,6 +62,13 @@ static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
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)
@ -407,6 +414,12 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra)
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;
@ -428,10 +441,11 @@ static int isis_zebra_read(ZAPI_CALLBACK_ARGS)
}
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;
}

File diff suppressed because it is too large Load Diff

View File

@ -55,6 +55,12 @@ static const bool fabricd = false;
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 */
@ -62,8 +68,18 @@ extern struct zebra_privs_t isisd_privs;
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 */
@ -79,7 +95,7 @@ struct isis {
struct route_table *ext_info[REDIST_PROTOCOL_COUNT];
};
extern struct isis *isis;
extern struct isis_master *im;
enum spf_tree_id {
SPFTREE_IPV4 = 0,
@ -191,14 +207,25 @@ struct isis_area {
};
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);

View File

@ -82,6 +82,7 @@ static void test_lsp_build_list_nonzero_ht(void)
int main(int argc, char **argv)
{
struct isis *isis = NULL;
isis = calloc(sizeof(*isis), 1);
test_lsp_build_list_nonzero_ht();
return 0;