DEFINE_HOOK(isis_circuit_new_hook, (struct isis_circuit *circuit), (circuit));
DEFINE_HOOK(isis_circuit_del_hook, (struct isis_circuit *circuit), (circuit));
-struct isis_circuit *isis_circuit_new(struct isis *isis)
+static void isis_circuit_enable(struct isis_circuit *circuit)
+{
+ struct isis_area *area;
+ struct interface *ifp = circuit->interface;
+
+ area = isis_area_lookup(circuit->tag, ifp->vrf_id);
+ if (area)
+ isis_area_add_circuit(area, circuit);
+
+ if (if_is_operative(ifp))
+ isis_csm_state_change(IF_UP_FROM_Z, circuit, ifp);
+}
+
+static void isis_circuit_disable(struct isis_circuit *circuit)
+{
+ struct isis_area *area = circuit->area;
+ struct interface *ifp = circuit->interface;
+
+ if (if_is_operative(ifp))
+ isis_csm_state_change(IF_DOWN_FROM_Z, circuit, ifp);
+
+ if (area)
+ isis_area_del_circuit(area, circuit);
+}
+
+struct isis_circuit *isis_circuit_new(struct interface *ifp, const char *tag)
{
struct isis_circuit *circuit;
int i;
circuit = XCALLOC(MTYPE_ISIS_CIRCUIT, sizeof(struct isis_circuit));
- circuit->isis = isis;
+ circuit->tag = XSTRDUP(MTYPE_ISIS_CIRCUIT, tag);
/*
* Default values
isis_lfa_excluded_ifaces_init(circuit, ISIS_LEVEL1);
isis_lfa_excluded_ifaces_init(circuit, ISIS_LEVEL2);
- hook_call(isis_circuit_new_hook, circuit);
-
QOBJ_REG(circuit, isis_circuit);
+ isis_circuit_if_bind(circuit, ifp);
+
+ if (ifp->ifindex != IFINDEX_INTERNAL)
+ isis_circuit_enable(circuit);
+
return circuit;
}
if (!circuit)
return;
- QOBJ_UNREG(circuit);
-
- hook_call(isis_circuit_del_hook, circuit);
+ if (circuit->interface->ifindex != IFINDEX_INTERNAL)
+ isis_circuit_disable(circuit);
isis_circuit_if_unbind(circuit, circuit->interface);
+ QOBJ_UNREG(circuit);
+
circuit_mt_finish(circuit);
isis_lfa_excluded_ifaces_clear(circuit, ISIS_LEVEL1);
isis_lfa_excluded_ifaces_clear(circuit, ISIS_LEVEL2);
+ XFREE(MTYPE_ISIS_CIRCUIT, circuit->tag);
+
/* and lastly the circuit itself */
XFREE(MTYPE_ISIS_CIRCUIT, circuit);
struct isis_area *area)
{
assert(area);
+ circuit->isis = area->isis;
circuit->area = area;
/*
circuit->idx = flags_get_index(&area->flags);
+ hook_call(isis_circuit_new_hook, circuit);
+
return;
}
void isis_circuit_deconfigure(struct isis_circuit *circuit,
struct isis_area *area)
{
+ hook_call(isis_circuit_del_hook, circuit);
+
/* Free the index of SRM and SSN flags */
flags_free_index(&area->flags, circuit->idx);
circuit->idx = 0;
assert(circuit->area == area);
listnode_delete(area->circuit_list, circuit);
circuit->area = NULL;
+ circuit->isis = NULL;
return;
}
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 =
- circuit_lookup_by_ifp(ifp, area->circuit_list);
- if (circuit)
- return circuit;
- }
- }
- return circuit_lookup_by_ifp(ifp, isis->init_circ_list);
+ return (struct isis_circuit *)ifp->info;
}
DEFINE_HOOK(isis_circuit_add_addr_hook, (struct isis_circuit *circuit),
struct listnode *node, *nnode;
struct connected *conn;
- isis_circuit_if_bind(circuit, ifp);
-
if (if_is_broadcast(ifp)) {
if (fabricd || circuit->circ_type_config == CIRCUIT_T_P2P)
circuit->circ_type = CIRCUIT_T_P2P;
}
#endif /* ifdef FABRICD */
-struct isis_circuit *isis_circuit_create(struct isis_area *area,
- struct interface *ifp)
-{
- struct isis_circuit *circuit = circuit_scan_by_ifp(ifp);
-
- if (circuit && circuit->area)
- return NULL;
- circuit = isis_csm_state_change(ISIS_ENABLE, circuit, area);
- if (circuit->state != C_STATE_CONF && circuit->state != C_STATE_UP)
- return circuit;
- isis_circuit_if_bind(circuit, ifp);
-
- return circuit;
-}
-
void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
bool ipv6_router)
{
circuit->ipv6_router = ipv6_router;
circuit_update_nlpids(circuit);
- /* the area should always be there if we get here, but in the past
- * there were corner cases where the area was NULL (e.g. because the
- * circuit was deconfigured following a validation error). Do not
- * segfault if this happens again.
- */
- if (!area) {
- zlog_err("%s: NULL area for circuit %u", __func__,
- circuit->circuit_id);
- return;
- }
-
- area->ip_circuits += ip_router - old_ipr;
- area->ipv6_circuits += ipv6_router - old_ipv6r;
+ if (area) {
+ area->ip_circuits += ip_router - old_ipr;
+ area->ipv6_circuits += ipv6_router - old_ipv6r;
- if (!ip_router && !ipv6_router)
- isis_csm_state_change(ISIS_DISABLE, circuit, area);
- else
- lsp_regenerate_schedule(area, circuit->is_type, 0);
+ if (ip_router || ipv6_router)
+ lsp_regenerate_schedule(area, circuit->is_type, 0);
+ }
}
ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive)
setting = circuit_get_mt_setting(circuit, mtid);
if (setting->enabled != enabled) {
setting->enabled = enabled;
- lsp_regenerate_schedule(circuit->area, IS_LEVEL_1 | IS_LEVEL_2,
- 0);
+ if (circuit->area)
+ lsp_regenerate_schedule(circuit->area,
+ IS_LEVEL_1 | IS_LEVEL_2, 0);
}
return CMD_SUCCESS;
int isis_if_delete_hook(struct interface *ifp)
{
- struct isis_circuit *circuit;
- /* Clean up the circuit data */
- if (ifp && ifp->info) {
- circuit = ifp->info;
- isis_csm_state_change(IF_DOWN_FROM_Z, circuit, ifp);
- }
+ if (ifp->info)
+ isis_circuit_del(ifp->info);
return 0;
}
static int isis_ifp_create(struct interface *ifp)
{
- struct vrf *vrf = NULL;
+ struct isis_circuit *circuit = ifp->info;
+
+ if (circuit)
+ isis_circuit_enable(circuit);
- if (if_is_operative(ifp)) {
- vrf = vrf_lookup_by_id(ifp->vrf_id);
- if (vrf)
- isis_global_instance_create(vrf->name);
- isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp),
- ifp);
- }
hook_call(isis_if_new_hook, ifp);
return 0;
static int isis_ifp_up(struct interface *ifp)
{
- isis_csm_state_change(IF_UP_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
+ struct isis_circuit *circuit = ifp->info;
+
+ if (circuit)
+ isis_csm_state_change(IF_UP_FROM_Z, circuit, ifp);
return 0;
}
static int isis_ifp_down(struct interface *ifp)
{
- struct isis_circuit *circuit;
+ struct isis_circuit *circuit = ifp->info;
+
+ if (circuit) {
+ isis_csm_state_change(IF_DOWN_FROM_Z, circuit, ifp);
- circuit = isis_csm_state_change(IF_DOWN_FROM_Z,
- circuit_scan_by_ifp(ifp), ifp);
- if (circuit)
SET_FLAG(circuit->flags, ISIS_CIRCUIT_FLAPPED_AFTER_SPF);
+ }
return 0;
}
static int isis_ifp_destroy(struct interface *ifp)
{
- if (if_is_operative(ifp))
- zlog_warn("Zebra: got delete of %s, but interface is still up",
- ifp->name);
+ struct isis_circuit *circuit = ifp->info;
- isis_csm_state_change(IF_DOWN_FROM_Z, circuit_scan_by_ifp(ifp), ifp);
-
- /* Cannot call if_delete because we should retain the pseudo interface
- in case there is configuration info attached to it. */
- if_delete_retain(ifp);
+ if (circuit)
+ isis_circuit_disable(circuit);
return 0;
}
/*
* Configurables
*/
+ char *tag; /* area tag */
struct isis_passwd passwd; /* Circuit rx/tx password */
int is_type; /* circuit is type == level of circuit
* differentiated from circuit type (media) */
DECLARE_QOBJ_TYPE(isis_circuit);
void isis_circuit_init(void);
-struct isis_circuit *isis_circuit_new(struct isis *isis);
+struct isis_circuit *isis_circuit_new(struct interface *ifp, const char *tag);
void isis_circuit_del(struct isis_circuit *circuit);
struct isis_circuit *circuit_lookup_by_ifp(struct interface *ifp,
struct list *list);
size_t isis_circuit_pdu_size(struct isis_circuit *circuit);
void isis_circuit_stream(struct isis_circuit *circuit, struct stream **stream);
-struct isis_circuit *isis_circuit_create(struct isis_area *area,
- struct interface *ifp);
void isis_circuit_af_set(struct isis_circuit *circuit, bool ip_router,
bool ipv6_router);
ferr_r isis_circuit_passive_set(struct isis_circuit *circuit, bool passive);
void *arg)
{
enum isis_circuit_state old_state;
- struct isis *isis = NULL;
struct isis_area *area = NULL;
struct interface *ifp;
- old_state = circuit ? circuit->state : C_STATE_NA;
+ assert(circuit);
+
+ old_state = circuit->state;
if (IS_DEBUG_EVENTS)
- zlog_debug("CSM_EVENT: %s", EVENT2STR(event));
+ zlog_debug("CSM_EVENT for %s: %s", circuit->interface->name,
+ EVENT2STR(event));
switch (old_state) {
case C_STATE_NA:
- if (circuit)
- zlog_warn("Non-null circuit while state C_STATE_NA");
- assert(circuit == NULL);
switch (event) {
case ISIS_ENABLE:
area = arg;
- circuit = isis_circuit_new(area->isis);
isis_circuit_configure(circuit, area);
circuit->state = C_STATE_CONF;
break;
case IF_UP_FROM_Z:
ifp = arg;
- isis = isis_lookup_by_vrfid(ifp->vrf_id);
- if (isis == NULL) {
- if (IS_DEBUG_EVENTS)
- zlog_debug(
- " %s : ISIS routing instance not found when attempting to apply against interface %s",
- __func__, ifp->name);
- break;
- }
- circuit = isis_circuit_new(isis);
+
isis_circuit_if_add(circuit, ifp);
- listnode_add(isis->init_circ_list, circuit);
circuit->state = C_STATE_INIT;
break;
case ISIS_DISABLE:
if (IS_DEBUG_EVENTS)
- zlog_debug(
- "circuit disable event passed for a non existent circuit");
+ zlog_debug("circuit %s already disabled",
+ circuit->interface->name);
break;
case IF_DOWN_FROM_Z:
if (IS_DEBUG_EVENTS)
- zlog_debug(
- "circuit disconnect event passed for a non existent circuit");
+ zlog_debug("circuit %s already disconnected",
+ circuit->interface->name);
break;
}
break;
case C_STATE_INIT:
- assert(circuit);
switch (event) {
case ISIS_ENABLE:
- isis_circuit_configure(circuit,
- (struct isis_area *)arg);
+ area = arg;
+
+ isis_circuit_configure(circuit, area);
if (isis_circuit_up(circuit) != ISIS_OK) {
- isis_circuit_deconfigure(
- circuit, (struct isis_area *)arg);
+ isis_circuit_deconfigure(circuit, area);
break;
}
circuit->state = C_STATE_UP;
isis_event_circuit_state_change(circuit, circuit->area,
1);
- listnode_delete(circuit->isis->init_circ_list,
- circuit);
break;
case IF_UP_FROM_Z:
if (IS_DEBUG_EVENTS)
circuit->interface->name);
break;
case IF_DOWN_FROM_Z:
- isis_circuit_if_del(circuit, (struct interface *)arg);
- listnode_delete(circuit->isis->init_circ_list,
- circuit);
- isis_circuit_del(circuit);
- circuit = NULL;
+ ifp = arg;
+
+ isis_circuit_if_del(circuit, ifp);
+ circuit->state = C_STATE_NA;
break;
}
break;
case C_STATE_CONF:
- assert(circuit);
switch (event) {
case ISIS_ENABLE:
if (IS_DEBUG_EVENTS)
- zlog_debug("circuit %p is already enabled",
- circuit);
+ zlog_debug("circuit %s is already enabled",
+ circuit->interface->name);
break;
case IF_UP_FROM_Z:
- isis_circuit_if_add(circuit, (struct interface *)arg);
+ ifp = arg;
+
+ isis_circuit_if_add(circuit, ifp);
if (isis_circuit_up(circuit) != ISIS_OK) {
- isis_circuit_if_del(circuit, (struct interface *)arg);
+ isis_circuit_if_del(circuit, ifp);
flog_err(
EC_ISIS_CONFIG,
"Could not bring up %s because of invalid config.",
1);
break;
case ISIS_DISABLE:
- isis_circuit_deconfigure(circuit,
- (struct isis_area *)arg);
- isis_circuit_del(circuit);
- circuit = NULL;
+ area = arg;
+
+ isis_circuit_deconfigure(circuit, area);
+ circuit->state = C_STATE_NA;
break;
case IF_DOWN_FROM_Z:
if (IS_DEBUG_EVENTS)
- zlog_debug("circuit %p already disconnected",
- circuit);
+ zlog_debug("circuit %s already disconnected",
+ circuit->interface->name);
break;
}
break;
case C_STATE_UP:
- assert(circuit);
switch (event) {
case ISIS_ENABLE:
if (IS_DEBUG_EVENTS)
- zlog_debug("circuit %s already configured",
+ zlog_debug("circuit %s already enabled",
circuit->interface->name);
break;
case IF_UP_FROM_Z:
circuit->interface->name);
break;
case ISIS_DISABLE:
- isis = circuit->isis;
+ area = arg;
+
isis_circuit_down(circuit);
- isis_circuit_deconfigure(circuit,
- (struct isis_area *)arg);
+ isis_circuit_deconfigure(circuit, area);
circuit->state = C_STATE_INIT;
- isis_event_circuit_state_change(
- circuit, (struct isis_area *)arg, 0);
- listnode_add(isis->init_circ_list, circuit);
+ isis_event_circuit_state_change(circuit, area, 0);
break;
case IF_DOWN_FROM_Z:
+ ifp = arg;
+
isis_circuit_down(circuit);
- isis_circuit_if_del(circuit, (struct interface *)arg);
+ isis_circuit_if_del(circuit, ifp);
circuit->state = C_STATE_CONF;
isis_event_circuit_state_change(circuit, circuit->area,
0);
if (IS_DEBUG_EVENTS)
zlog_debug("CSM_STATE_CHANGE: %s -> %s ", STATE2STR(old_state),
- circuit ? STATE2STR(circuit->state)
- : STATE2STR(C_STATE_NA));
+ STATE2STR(circuit->state));
return circuit;
}
}
break;
case NB_EV_APPLY:
- area = isis_area_lookup_by_vrf(area_tag, vrf_name);
- /* 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
- * cannot rely on that so here I have to check.
- */
- if (!area) {
- flog_err(
- EC_LIB_NB_CB_CONFIG_APPLY,
- "%s: attempt to create circuit for area %s before the area has been created",
- __func__, area_tag);
- abort();
- }
ifp = nb_running_get_entry(args->dnode, NULL, true);
- circuit = isis_circuit_create(area, ifp);
- assert(circuit
- && (circuit->state == C_STATE_CONF
- || circuit->state == C_STATE_UP));
+ circuit = isis_circuit_new(ifp, area_tag);
nb_running_set_entry(args->dnode, circuit);
break;
}
return NB_OK;
circuit = nb_running_unset_entry(args->dnode);
- if (!circuit)
- return NB_ERR_INCONSISTENCY;
/* remove ldp-sync config */
isis_ldp_sync_if_remove(circuit, true);
- /* disable both AFs for this circuit. this will also update the
- * CSM state by sending an ISIS_DISABLED signal. If there is no
- * area associated to the circuit there is nothing to do
- */
- if (circuit->area)
- isis_circuit_af_set(circuit, false, false);
+ isis_circuit_del(circuit);
+
return NB_OK;
}
struct interface *ifp;
struct vrf *vrf;
const char *ifname, *vrfname;
- struct isis *isis = NULL;
switch (args->event) {
case NB_EV_VALIDATE:
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);
+ circuit = circuit_scan_by_ifp(ifp);
if (circuit && circuit->state == C_STATE_UP
&& circuit->area->is_type != IS_LEVEL_1_AND_2
&& circuit->area->is_type != circ_type) {
int lib_interface_isis_passive_modify(struct nb_cb_modify_args *args)
{
struct isis_circuit *circuit;
- struct isis_area *area;
struct interface *ifp;
bool passive = yang_dnode_get_bool(args->dnode, NULL);
return NB_OK;
circuit = nb_running_get_entry(args->dnode, NULL, true);
- if (circuit->state != C_STATE_UP) {
- circuit->is_passive = passive;
- } else {
- area = circuit->area;
- isis_csm_state_change(ISIS_DISABLE, circuit, area);
- circuit->is_passive = passive;
- isis_csm_state_change(ISIS_ENABLE, circuit, area);
- }
+ isis_circuit_passive_set(circuit, passive);
return NB_OK;
}
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->lfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->lfa_protection[0])
- circuit->area->lfa_protected_links[0]++;
- else {
- assert(circuit->area->lfa_protected_links[0] > 0);
- circuit->area->lfa_protected_links[0]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->lfa_protection[0])
+ area->lfa_protected_links[0]++;
+ else {
+ assert(area->lfa_protected_links[0] > 0);
+ area->lfa_protected_links[0]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
isis_lfa_excluded_iface_add(circuit, ISIS_LEVEL1, exclude_ifname);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
isis_lfa_excluded_iface_delete(circuit, ISIS_LEVEL1, exclude_ifname);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->rlfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->rlfa_protection[0])
- circuit->area->rlfa_protected_links[0]++;
- else {
- assert(circuit->area->rlfa_protected_links[0] > 0);
- circuit->area->rlfa_protected_links[0]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->rlfa_protection[0])
+ area->rlfa_protected_links[0]++;
+ else {
+ assert(area->rlfa_protected_links[0] > 0);
+ area->rlfa_protected_links[0]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
circuit->rlfa_max_metric[0] = yang_dnode_get_uint32(args->dnode, NULL);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
circuit->rlfa_max_metric[0] = 0;
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->tilfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->tilfa_protection[0])
- circuit->area->tilfa_protected_links[0]++;
- else {
- assert(circuit->area->tilfa_protected_links[0] > 0);
- circuit->area->tilfa_protected_links[0]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->tilfa_protection[0])
+ area->tilfa_protected_links[0]++;
+ else {
+ assert(area->tilfa_protected_links[0] > 0);
+ area->tilfa_protected_links[0]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
yang_dnode_get_bool(args->dnode, NULL);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->lfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->lfa_protection[1])
- circuit->area->lfa_protected_links[1]++;
- else {
- assert(circuit->area->lfa_protected_links[1] > 0);
- circuit->area->lfa_protected_links[1]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->lfa_protection[1])
+ area->lfa_protected_links[1]++;
+ else {
+ assert(area->lfa_protected_links[1] > 0);
+ area->lfa_protected_links[1]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
isis_lfa_excluded_iface_add(circuit, ISIS_LEVEL2, exclude_ifname);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
isis_lfa_excluded_iface_delete(circuit, ISIS_LEVEL2, exclude_ifname);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->rlfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->rlfa_protection[1])
- circuit->area->rlfa_protected_links[1]++;
- else {
- assert(circuit->area->rlfa_protected_links[1] > 0);
- circuit->area->rlfa_protected_links[1]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->rlfa_protection[1])
+ area->rlfa_protected_links[1]++;
+ else {
+ assert(area->rlfa_protected_links[1] > 0);
+ area->rlfa_protected_links[1]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
circuit->rlfa_max_metric[1] = yang_dnode_get_uint32(args->dnode, NULL);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
circuit->rlfa_max_metric[1] = 0;
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
circuit = nb_running_get_entry(args->dnode, NULL, true);
circuit->tilfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
- if (circuit->tilfa_protection[1])
- circuit->area->tilfa_protected_links[1]++;
- else {
- assert(circuit->area->tilfa_protected_links[1] > 0);
- circuit->area->tilfa_protected_links[1]--;
- }
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area) {
+ if (circuit->tilfa_protection[1])
+ area->tilfa_protected_links[1]++;
+ else {
+ assert(area->tilfa_protected_links[1] > 0);
+ area->tilfa_protected_links[1]--;
+ }
+
+ lsp_regenerate_schedule(area, area->is_type, 0);
+ }
return NB_OK;
}
yang_dnode_get_bool(args->dnode, NULL);
area = circuit->area;
- lsp_regenerate_schedule(area, area->is_type, 0);
+ if (area)
+ lsp_regenerate_schedule(area, area->is_type, 0);
return NB_OK;
}
area = isis_area_lookup(area_tag, VRF_DEFAULT);
if (!area)
- area = isis_area_create(area_tag, VRF_DEFAULT_NAME);
+ isis_area_create(area_tag, VRF_DEFAULT_NAME);
- if (!circuit || !circuit->area) {
- circuit = isis_circuit_create(area, ifp);
+ if (!circuit) {
+ circuit = isis_circuit_new(ifp, area_tag);
if (circuit->state != C_STATE_CONF
&& circuit->state != C_STATE_UP) {
return CMD_ERR_NO_MATCH;
}
- circuit = circuit_lookup_by_ifp(ifp, area->circuit_list);
+ circuit = circuit_scan_by_ifp(ifp);
if (!circuit) {
vty_out(vty, "ISIS is not enabled on circuit %s\n", ifp->name);
return CMD_ERR_NO_MATCH;
ip = false;
isis_circuit_af_set(circuit, ip, ipv6);
+
+ if (!ip && !ipv6)
+ isis_circuit_del(circuit);
+
return CMD_SUCCESS;
}
int clear_isis_neighbor_common(struct vty *, const char *id, const char *vrf_name,
bool all_vrf);
-static void isis_add(struct isis *isis)
-{
- listnode_add(im->isis, isis);
-}
-
-static void isis_delete(struct isis *isis)
-{
- listnode_delete(im->isis, isis);
-}
-
/* Link ISIS instance to VRF. */
void isis_vrf_link(struct isis *isis, struct vrf *vrf)
{
struct isis *isis;
isis = isis_lookup_by_vrfname(vrf_name);
- if (isis == NULL) {
- isis = isis_new(vrf_name);
- isis_add(isis);
- }
+ if (isis == NULL)
+ isis_new(vrf_name);
}
struct isis *isis_new(const char *vrf_name)
struct isis *isis;
isis = XCALLOC(MTYPE_ISIS, sizeof(struct isis));
+
+ isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf_name);
+
vrf = vrf_lookup_by_name(vrf_name);
- if (vrf) {
- isis->vrf_id = vrf->vrf_id;
+ if (vrf)
isis_vrf_link(isis, vrf);
- isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf->name);
- } else {
+ else
isis->vrf_id = VRF_UNKNOWN;
- isis->name = XSTRDUP(MTYPE_ISIS_NAME, vrf_name);
- }
if (IS_DEBUG_EVENTS)
zlog_debug(
isis->process_id = getpid();
isis->router_id = 0;
isis->area_list = list_new();
- isis->init_circ_list = list_new();
isis->uptime = time(NULL);
isis->snmp_notifications = 1;
dyn_cache_init(isis);
+ listnode_add(im->isis, isis);
+
return isis;
}
+void isis_finish(struct isis *isis)
+{
+ struct vrf *vrf = NULL;
+
+ listnode_delete(im->isis, isis);
+
+ vrf = vrf_lookup_by_name(isis->name);
+ if (vrf)
+ isis_vrf_unlink(isis, vrf);
+ XFREE(MTYPE_ISIS_NAME, isis->name);
+
+ isis_redist_free(isis);
+ list_delete(&isis->area_list);
+ XFREE(MTYPE_ISIS, isis);
+}
+
+void isis_area_add_circuit(struct isis_area *area, struct isis_circuit *circuit)
+{
+ isis_csm_state_change(ISIS_ENABLE, circuit, area);
+
+ area->ip_circuits += circuit->ip_router;
+ area->ipv6_circuits += circuit->ipv6_router;
+
+ area->lfa_protected_links[0] += circuit->lfa_protection[0];
+ area->rlfa_protected_links[0] += circuit->rlfa_protection[0];
+ area->tilfa_protected_links[0] += circuit->tilfa_protection[0];
+
+ area->lfa_protected_links[1] += circuit->lfa_protection[1];
+ area->rlfa_protected_links[1] += circuit->rlfa_protection[1];
+ area->tilfa_protected_links[1] += circuit->tilfa_protection[1];
+}
+
+void isis_area_del_circuit(struct isis_area *area, struct isis_circuit *circuit)
+{
+ area->ip_circuits -= circuit->ip_router;
+ area->ipv6_circuits -= circuit->ipv6_router;
+
+ area->lfa_protected_links[0] -= circuit->lfa_protection[0];
+ area->rlfa_protected_links[0] -= circuit->rlfa_protection[0];
+ area->tilfa_protected_links[0] -= circuit->tilfa_protection[0];
+
+ area->lfa_protected_links[1] -= circuit->lfa_protection[1];
+ area->rlfa_protected_links[1] -= circuit->rlfa_protection[1];
+ area->tilfa_protected_links[1] -= circuit->tilfa_protection[1];
+
+ isis_csm_state_change(ISIS_DISABLE, circuit, area);
+}
+
struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name)
{
struct isis_area *area;
struct isis *isis = NULL;
struct vrf *vrf = NULL;
+ struct interface *ifp;
+ struct isis_circuit *circuit;
+
area = XCALLOC(MTYPE_ISIS_AREA, sizeof(struct isis_area));
- if (vrf_name) {
- vrf = vrf_lookup_by_name(vrf_name);
- if (vrf) {
- isis = isis_lookup_by_vrfid(vrf->vrf_id);
- if (isis == NULL) {
- isis = isis_new(vrf_name);
- isis_add(isis);
- }
- } else {
- isis = isis_lookup_by_vrfid(VRF_UNKNOWN);
- if (isis == NULL) {
- isis = isis_new(vrf_name);
- isis_add(isis);
- }
- }
- } else {
- isis = isis_lookup_by_vrfid(VRF_DEFAULT);
- if (isis == NULL) {
- isis = isis_new(VRF_DEFAULT_NAME);
- isis_add(isis);
- }
- }
+ if (!vrf_name)
+ vrf_name = VRF_DEFAULT_NAME;
+
+ vrf = vrf_lookup_by_name(vrf_name);
+ isis = isis_lookup_by_vrfname(vrf_name);
+
+ if (isis == NULL)
+ isis = isis_new(vrf_name);
listnode_add(isis->area_list, area);
area->isis = isis;
area->bfd_signalled_down = false;
area->bfd_force_spf_refresh = false;
-
QOBJ_REG(area, isis_area);
+ if (vrf) {
+ FOR_ALL_INTERFACES (vrf, ifp) {
+ if (ifp->ifindex == IFINDEX_INTERNAL)
+ continue;
+
+ circuit = ifp->info;
+ if (circuit)
+ isis_area_add_circuit(area, circuit);
+ }
+ }
+
return area;
}
if (area->circuit_list) {
for (ALL_LIST_ELEMENTS(area->circuit_list, node, nnode,
- circuit)) {
- circuit->ip_router = 0;
- circuit->ipv6_router = 0;
- isis_csm_state_change(ISIS_DISABLE, circuit, area);
- }
+ circuit))
+ isis_area_del_circuit(area, circuit);
+
list_delete(&area->circuit_list);
}
list_delete(&area->adjacency_list);
isis = isis_lookup_by_vrfname(vrf->name);
if (isis) {
- if (isis->name && strmatch(vrf->name, VRF_DEFAULT_NAME)) {
- XFREE(MTYPE_ISIS_NAME, isis->name);
- isis->name = NULL;
- }
old_vrf_id = isis->vrf_id;
/* We have instance configured, link to VRF and make it "up". */
isis_vrf_link(isis, vrf);
isis_vrf_delete, isis_vrf_enable);
}
-void isis_finish(struct isis *isis)
-{
- struct vrf *vrf = NULL;
-
- isis_delete(isis);
- if (isis->name) {
- vrf = vrf_lookup_by_name(isis->name);
- if (vrf)
- isis_vrf_unlink(isis, vrf);
- XFREE(MTYPE_ISIS_NAME, isis->name);
- } else {
- vrf = vrf_lookup_by_id(VRF_DEFAULT);
- if (vrf)
- isis_vrf_unlink(isis, vrf);
- }
-
- isis_redist_free(isis);
- list_delete(&isis->area_list);
- list_delete(&isis->init_circ_list);
- XFREE(MTYPE_ISIS, isis);
-}
-
void isis_terminate()
{
struct isis *isis;
uint8_t sysid[ISIS_SYS_ID_LEN]; /* SystemID for this IS */
uint32_t router_id; /* Router ID from zebra */
struct list *area_list; /* list of IS-IS areas */
- struct list *init_circ_list;
uint8_t max_area_addrs; /* maximumAreaAdresses */
struct area_addr *man_area_addrs; /* manualAreaAddresses */
time_t uptime; /* when did we start */
DECLARE_HOOK(isis_area_overload_bit_update, (struct isis_area * area), (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_vrf_init(void);
struct isis *isis_new(const char *vrf_name);
+void isis_finish(struct isis *isis);
+
+void isis_area_add_circuit(struct isis_area *area,
+ struct isis_circuit *circuit);
+void isis_area_del_circuit(struct isis_area *area,
+ struct isis_circuit *circuit);
+
struct isis_area *isis_area_create(const char *, const char *);
struct isis_area *isis_area_lookup(const char *, vrf_id_t vrf_id);
struct isis_area *isis_area_lookup_by_vrf(const char *area_tag,
/* IS-IS inits. */
yang_module_load("frr-isisd");
isis = isis_new(VRF_DEFAULT_NAME);
- listnode_add(im->isis, isis);
SET_FLAG(im->options, F_ISIS_UNIT_TEST);
debug_spf_events |= DEBUG_SPF_EVENTS;
debug_lfa |= DEBUG_LFA;
circtable_test = {
- "isisCircAdminState": ["on(1)", "on(1)", "on(1)"],
- "isisCircExistState": ["active(1)", "active(1)", "active(1)"],
- "isisCircType": ["broadcast(1)", "ptToPt(2)", "staticIn(3)"],
- "isisCircExtDomain": ["false(2)", "false(2)", "false(2)"],
- "isisCircLevelType": ["level1(1)", "level1(1)", "level1and2(3)"],
- "isisCircPassiveCircuit": ["false(2)", "false(2)", "true(1)"],
- "isisCircMeshGroupEnabled": ["inactive(1)", "inactive(1)", "inactive(1)"],
- "isisCircSmallHellos": ["false(2)", "false(2)", "false(2)"],
- "isisCirc3WayEnabled": ["false(2)", "false(2)", "false(2)"],
+ "isisCircAdminState": ["on(1)", "on(1)"],
+ "isisCircExistState": ["active(1)", "active(1)"],
+ "isisCircType": ["broadcast(1)", "ptToPt(2)"],
+ "isisCircExtDomain": ["false(2)", "false(2)"],
+ "isisCircLevelType": ["level1(1)", "level1(1)"],
+ "isisCircPassiveCircuit": ["false(2)", "false(2)"],
+ "isisCircMeshGroupEnabled": ["inactive(1)", "inactive(1)"],
+ "isisCircSmallHellos": ["false(2)", "false(2)"],
+ "isisCirc3WayEnabled": ["false(2)", "false(2)"],
}
oids = []
oids.append(generate_oid(1, 1, 0))
oids.append(generate_oid(1, 2, 0))
- oids.append(generate_oid(1, 3, 0))
# check items
for item in circtable_test.keys():
circleveltable_test = {
- "isisCircLevelMetric": ["10", "10", "10", "10"],
- "isisCircLevelWideMetric": ["10", "10", "0", "0"],
- "isisCircLevelISPriority": ["64", "64", "64", "64"],
- "isisCircLevelHelloMultiplier": ["10", "10", "10", "10"],
+ "isisCircLevelMetric": ["10", "10"],
+ "isisCircLevelWideMetric": ["10", "10"],
+ "isisCircLevelISPriority": ["64", "64"],
+ "isisCircLevelHelloMultiplier": ["10", "10"],
"isisCircLevelHelloTimer": [
"3000 milliseconds",
"3000 milliseconds",
- "3000 milliseconds",
- "3000 milliseconds",
],
"isisCircLevelMinLSPRetransInt": [
"1 seconds",
"1 seconds",
- "0 seconds",
- "0 seconds",
],
}
oids = []
oids.append(generate_oid(2, 1, "area"))
oids.append(generate_oid(2, 2, "area"))
- oids.append(generate_oid(2, 3, "area"))
- oids.append(generate_oid(2, 3, "domain"))
# check items
for item in circleveltable_test.keys():
tgen.net["rt4"].cmd(
'vtysh -c "conf t" -c "interface eth-rt5" -c "ipv6 router isis 1"'
)
+ tgen.net["rt4"].cmd(
+ 'vtysh -c "conf t" -c "interface eth-rt5" -c "isis network point-to-point"'
+ )
+ tgen.net["rt4"].cmd(
+ 'vtysh -c "conf t" -c "interface eth-rt5" -c "isis hello-multiplier 3"'
+ )
tgen.net["rt6"].cmd(
'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 23999"'
)