Skip to content

Commit

Permalink
isisd : Transformational changes to support different VRFs.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
KaushikNiral committed Aug 14, 2020
1 parent 40ce7a4 commit eab88f3
Show file tree
Hide file tree
Showing 26 changed files with 1,116 additions and 423 deletions.
2 changes: 1 addition & 1 deletion isisd/fabricd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
2 changes: 0 additions & 2 deletions isisd/isis_adjacency.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions isisd/isis_bfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down
21 changes: 19 additions & 2 deletions isisd/isis_circuit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand Down
51 changes: 33 additions & 18 deletions isisd/isis_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -134,23 +139,30 @@ 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);
nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, 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",
Expand All @@ -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) {
Expand Down Expand Up @@ -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");
Expand All @@ -204,23 +214,30 @@ 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);
nb_cli_enqueue_change(vty, temp_xpath, NB_OP_CREATE, 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",
Expand All @@ -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) {
Expand Down Expand Up @@ -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");
Expand Down
30 changes: 27 additions & 3 deletions isisd/isis_csm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"};

Expand All @@ -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)
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
8 changes: 5 additions & 3 deletions isisd/isis_dr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down
18 changes: 12 additions & 6 deletions isisd/isis_dynhn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions isisd/isis_dynhn.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Loading

0 comments on commit eab88f3

Please sign in to comment.