mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-03 22:19:21 +00:00
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:
parent
40ce7a4203
commit
eab88f3655
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.");
|
||||
|
@ -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 */
|
||||
|
@ -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");
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
876
isisd/isisd.c
876
isisd/isisd.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user