/* Remove external reachability information from a * specific area for a specific level. * Schedule an lsp regenerate if necessary. */ static void isis_redist_uninstall(struct isis_area *area, int level, struct prefix *p) { int family = p->family; struct route_table *er_table = get_ext_reach(area, family, level); struct route_node *er_node; if (!er_table) { zlog_warn("%s: External reachability table of area %s" " is not initialized.", __func__, area->area_tag); return; } er_node = route_node_lookup(er_table, p); if (!er_node) return; else route_unlock_node(er_node); if (!er_node->info) return; XFREE(MTYPE_ISIS, er_node->info); route_unlock_node(er_node); lsp_regenerate_schedule(area, level, 0); }
/* Install external reachability information into a * specific area for a specific level. * Schedule an lsp regenerate if necessary */ static void isis_redist_install(struct isis_area *area, int level, struct prefix *p, struct isis_ext_info *info) { int family = p->family; struct route_table *er_table = get_ext_reach(area, family, level); struct route_node *er_node; if (!er_table) { zlog_warn("%s: External reachability table of area %s" " is not initialized.", __func__, area->area_tag); return; } er_node = route_node_get(er_table, p); if (er_node->info) { route_unlock_node(er_node); /* Don't update/reschedule lsp generation if nothing changed. */ if (!memcmp(er_node->info, info, sizeof(*info))) return; } else { er_node->info = XMALLOC(MTYPE_ISIS, sizeof(*info)); } memcpy(er_node->info, info, sizeof(*info)); lsp_regenerate_schedule(area, level, 0); }
void isis_circuit_is_type_set (struct isis_circuit *circuit, int newtype) { if (circuit->state != C_STATE_UP) { circuit->is_type = newtype; return; } if (isis->debugs & DEBUG_EVENTS) zlog_debug ("ISIS-Evt (%s) circuit type change %s -> %s", circuit->area->area_tag, circuit_t2string (circuit->is_type), circuit_t2string (newtype)); if (circuit->is_type == newtype) return; /* No change */ if (!(newtype & circuit->area->is_type)) { zlog_err ("ISIS-Evt (%s) circuit type change - invalid level %s because" " area is %s", circuit->area->area_tag, circuit_t2string (newtype), circuit_t2string (circuit->area->is_type)); return; } if (! circuit->is_passive) { switch (circuit->is_type) { case IS_LEVEL_1: if (newtype == IS_LEVEL_2) circuit_resign_level (circuit, 1); circuit_commence_level (circuit, 2); break; case IS_LEVEL_1_AND_2: if (newtype == IS_LEVEL_1) circuit_resign_level (circuit, 2); else circuit_resign_level (circuit, 1); break; case IS_LEVEL_2: if (newtype == IS_LEVEL_1) circuit_resign_level (circuit, 2); circuit_commence_level (circuit, 1); break; default: break; } } circuit->is_type = newtype; lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); return; }
void isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype) { Log(LOG_DEBUG, "DEBUG (default/core/ISIS ): ISIS-Evt (%s) circuit type change %s -> %s\n", circuit->area->area_tag, circuit_t2string (circuit->circuit_is_type), circuit_t2string (newtype)); if (circuit->circuit_is_type == newtype) return; /* No change */ if (!(newtype & circuit->area->is_type)) { Log(LOG_ERR, "ERROR (default/core/ISIS ): ISIS-Evt (%s) circuit type change - invalid level %s because area is %s\n", circuit->area->area_tag, circuit_t2string (newtype), circuit_t2string (circuit->area->is_type)); return; } switch (circuit->circuit_is_type) { case IS_LEVEL_1: if (newtype == IS_LEVEL_2) circuit_resign_level (circuit, 1); circuit_commence_level (circuit, 2); break; case IS_LEVEL_1_AND_2: if (newtype == IS_LEVEL_1) circuit_resign_level (circuit, 2); else circuit_resign_level (circuit, 1); break; case IS_LEVEL_2: if (newtype == IS_LEVEL_1) circuit_resign_level (circuit, 2); circuit_commence_level (circuit, 1); break; default: break; } circuit->circuit_is_type = newtype; lsp_regenerate_schedule (circuit->area); return; }
void isis_event_system_type_change (struct isis_area *area, int newtype) { struct listnode *node; struct isis_circuit *circuit; Log(LOG_DEBUG, "DEBUG (default/core/ISIS ): ISIS-Evt (%s) system type change %s -> %s\n", area->area_tag, circuit_t2string (area->is_type), circuit_t2string (newtype)); if (area->is_type == newtype) return; /* No change */ switch (area->is_type) { case IS_LEVEL_1: if (area->lspdb[1] == NULL) area->lspdb[1] = lsp_db_init (); lsp_l2_generate (area); break; case IS_LEVEL_1_AND_2: if (newtype == IS_LEVEL_1) { lsp_db_destroy (area->lspdb[1]); } else { lsp_db_destroy (area->lspdb[0]); } break; case IS_LEVEL_2: if (area->lspdb[0] == NULL) area->lspdb[0] = lsp_db_init (); lsp_l1_generate (area); break; default: break; } area->is_type = newtype; for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit)) isis_event_circuit_type_change (circuit, newtype); spftree_area_init (area); lsp_regenerate_schedule (area); return; }
void isis_event_circuit_state_change (struct isis_circuit *circuit, struct isis_area *area, int up) { area->circuit_state_changes++; if (isis->debugs & DEBUG_EVENTS) zlog_debug ("ISIS-Evt (%s) circuit %s", area->area_tag, up ? "up" : "down"); /* * Regenerate LSPs this affects */ lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0); return; }
int isis_event_dis_status_change (struct thread *thread) { struct isis_circuit *circuit; circuit = THREAD_ARG (thread); /* invalid arguments */ if (!circuit || !circuit->area) return 0; if (isis->debugs & DEBUG_EVENTS) zlog_debug ("ISIS-Evt (%s) DIS status change", circuit->area->area_tag); /* LSP generation again */ lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); return 0; }
void isis_event_circuit_state_change (struct isis_circuit *circuit, int up) { struct isis_area *area; area = circuit->area; assert (area); area->circuit_state_changes++; Log(LOG_DEBUG, "DEBUG (default/core/ISIS ): ISIS-Evt (%s) circuit %s\n", circuit->area->area_tag, up ? "up" : "down"); /* * Regenerate LSPs this affects */ lsp_regenerate_schedule (area); return; }
void isis_event_adjacency_state_change (struct isis_adjacency *adj, int newstate) { /* adjacency state change event. * - the only proto-type was supported */ /* invalid arguments */ if (!adj || !adj->circuit || !adj->circuit->area) return; Log(LOG_DEBUG, "DEBUG (default/core/ISIS ): ISIS-Evt (%s) Adjacency State change\n", adj->circuit->area->area_tag); /* LSP generation again */ lsp_regenerate_schedule (adj->circuit->area); return; }
/* Router-id update message from zebra. */ static int isis_router_id_update_zebra (int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { struct isis_area *area; struct listnode *node; struct prefix router_id; zebra_router_id_update_read (zclient->ibuf, &router_id); if (isis->router_id == router_id.u.prefix4.s_addr) return 0; isis->router_id = router_id.u.prefix4.s_addr; for (ALL_LIST_ELEMENTS_RO (isis->area_list, node, area)) if (listcount (area->area_addrs) > 0) lsp_regenerate_schedule (area, area->is_type, 0); return 0; }
void isis_event_adjacency_state_change (struct isis_adjacency *adj, int newstate) { /* adjacency state change event. * - the only proto-type was supported */ /* invalid arguments */ if (!adj || !adj->circuit || !adj->circuit->area) return; if (isis->debugs & DEBUG_EVENTS) zlog_debug ("ISIS-Evt (%s) Adjacency State change", adj->circuit->area->area_tag); /* LSP generation again */ lsp_regenerate_schedule (adj->circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); return; }
static void isis_redist_unset(struct isis_area *area, int level, int family, int type) { struct isis_redist *redist = get_redist_settings(area, family, type, level); struct route_table *er_table = get_ext_reach(area, family, level); struct route_node *rn; struct isis_ext_info *info; if (!redist->redist) return; redist->redist = 0; if (!er_table) { zlog_warn("%s: External reachability table uninitialized.", __func__); return; } for (rn = route_top(er_table); rn; rn = route_next(rn)) { if (!rn->info) continue; info = rn->info; if (type == DEFAULT_ROUTE) { if (!is_default(&rn->p)) continue; } else { if (info->origin != type) continue; } XFREE(MTYPE_ISIS, rn->info); route_unlock_node(rn); } lsp_regenerate_schedule(area, level, 0); isis_redist_update_zebra_subscriptions(area->isis); }
void isis_circuit_add_addr (struct isis_circuit *circuit, struct connected *connected) { struct listnode *node; struct prefix_ipv4 *ipv4; u_char buf[BUFSIZ]; #ifdef HAVE_IPV6 struct prefix_ipv6 *ipv6; #endif /* HAVE_IPV6 */ memset (&buf, 0, BUFSIZ); if (connected->address->family == AF_INET) { u_int32_t addr = connected->address->u.prefix4.s_addr; addr = ntohl (addr); if (IPV4_NET0(addr) || IPV4_NET127(addr) || IN_CLASSD(addr) || IPV4_LINKLOCAL(addr)) return; for (ALL_LIST_ELEMENTS_RO (circuit->ip_addrs, node, ipv4)) if (prefix_same ((struct prefix *) ipv4, connected->address)) return; ipv4 = prefix_ipv4_new (); ipv4->prefixlen = connected->address->prefixlen; ipv4->prefix = connected->address->u.prefix4; listnode_add (circuit->ip_addrs, ipv4); /* Update MPLS TE Local IP address parameter */ set_circuitparams_local_ipaddr (circuit->mtc, ipv4->prefix); if (circuit->area) lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); #ifdef EXTREME_DEBUG prefix2str (connected->address, buf, BUFSIZ); zlog_debug ("Added IP address %s to circuit %d", buf, circuit->circuit_id); #endif /* EXTREME_DEBUG */ }
void isis_mpls_te_update (struct interface *ifp) { struct isis_circuit *circuit; /* Sanity Check */ if (ifp == NULL) return; /* Get circuit context from interface */ if ((circuit = circuit_scan_by_ifp(ifp)) == NULL) return; /* Update TE TLVs ... */ isis_link_params_update(circuit, ifp); /* ... and LSP */ if (IS_MPLS_TE(isisMplsTE) && circuit->area) lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); return; }
/* Call when interface TE Link parameters are modified */ void isis_link_params_update (struct isis_circuit *circuit, struct interface *ifp) { int i; struct prefix_ipv4 *addr; struct mpls_te_circuit *mtc; /* Sanity Check */ if ((circuit == NULL) || (ifp == NULL)) return; zlog_info ("MPLS-TE: Initialize circuit parameters for interface %s", ifp->name); /* Check if MPLS TE Circuit context has not been already created */ if (circuit->mtc == NULL) circuit->mtc = mpls_te_circuit_new(); mtc = circuit->mtc; /* Fulfil MTC TLV from ifp TE Link parameters */ if (HAS_LINK_PARAMS(ifp)) { mtc->status = enable; /* STD_TE metrics */ if (IS_PARAM_SET(ifp->link_params, LP_ADM_GRP)) set_circuitparams_admin_grp (mtc, ifp->link_params->admin_grp); else SUBTLV_TYPE(mtc->admin_grp) = 0; /* If not already set, register local IP addr from ip_addr list if it exists */ if (SUBTLV_TYPE(mtc->local_ipaddr) == 0) { if (circuit->ip_addrs != NULL && listcount(circuit->ip_addrs) != 0) { addr = (struct prefix_ipv4 *)listgetdata ((struct listnode *)listhead (circuit->ip_addrs)); set_circuitparams_local_ipaddr (mtc, addr->prefix); } } /* If not already set, try to determine Remote IP addr if circuit is P2P */ if ((SUBTLV_TYPE(mtc->rmt_ipaddr) == 0) && (circuit->circ_type == CIRCUIT_T_P2P)) { struct isis_adjacency *adj = circuit->u.p2p.neighbor; if (adj->ipv4_addrs != NULL && listcount(adj->ipv4_addrs) != 0) { struct in_addr *ip_addr; ip_addr = (struct in_addr *)listgetdata ((struct listnode *)listhead (adj->ipv4_addrs)); set_circuitparams_rmt_ipaddr (mtc, *ip_addr); } } if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW)) set_circuitparams_max_bw (mtc, ifp->link_params->max_bw); else SUBTLV_TYPE(mtc->max_bw) = 0; if (IS_PARAM_SET(ifp->link_params, LP_MAX_RSV_BW)) set_circuitparams_max_rsv_bw (mtc, ifp->link_params->max_rsv_bw); else SUBTLV_TYPE(mtc->max_rsv_bw) = 0; if (IS_PARAM_SET(ifp->link_params, LP_UNRSV_BW)) for (i = 0; i < MAX_CLASS_TYPE; i++) set_circuitparams_unrsv_bw (mtc, i, ifp->link_params->unrsv_bw[i]); else SUBTLV_TYPE(mtc->unrsv_bw) = 0; if (IS_PARAM_SET(ifp->link_params, LP_TE)) set_circuitparams_te_metric(mtc, ifp->link_params->te_metric); else SUBTLV_TYPE(mtc->te_metric) = 0; /* TE metric Extensions */ if (IS_PARAM_SET(ifp->link_params, LP_DELAY)) set_circuitparams_av_delay(mtc, ifp->link_params->av_delay, 0); else SUBTLV_TYPE(mtc->av_delay) = 0; if (IS_PARAM_SET(ifp->link_params, LP_MM_DELAY)) set_circuitparams_mm_delay(mtc, ifp->link_params->min_delay, ifp->link_params->max_delay, 0); else SUBTLV_TYPE(mtc->mm_delay) = 0; if (IS_PARAM_SET(ifp->link_params, LP_DELAY_VAR)) set_circuitparams_delay_var(mtc, ifp->link_params->delay_var); else SUBTLV_TYPE(mtc->delay_var) = 0; if (IS_PARAM_SET(ifp->link_params, LP_PKT_LOSS)) set_circuitparams_pkt_loss(mtc, ifp->link_params->pkt_loss, 0); else SUBTLV_TYPE(mtc->pkt_loss) = 0; if (IS_PARAM_SET(ifp->link_params, LP_RES_BW)) set_circuitparams_res_bw(mtc, ifp->link_params->res_bw); else SUBTLV_TYPE(mtc->res_bw) = 0; if (IS_PARAM_SET(ifp->link_params, LP_AVA_BW)) set_circuitparams_ava_bw(mtc, ifp->link_params->ava_bw); else SUBTLV_TYPE(mtc->ava_bw) = 0; if (IS_PARAM_SET(ifp->link_params, LP_USE_BW)) set_circuitparams_use_bw(mtc, ifp->link_params->use_bw); else SUBTLV_TYPE(mtc->use_bw) = 0; /* INTER_AS */ if (IS_PARAM_SET(ifp->link_params, LP_RMT_AS)) set_circuitparams_inter_as(mtc, ifp->link_params->rmt_ip, ifp->link_params->rmt_as); else /* reset inter-as TE params */ unset_circuitparams_inter_as (mtc); /* Compute total length of SUB TLVs */ mtc->length = subtlvs_len(mtc); } else mtc->status = disable; /* Finally Update LSP */ #if 0 if (IS_MPLS_TE(isisMplsTE) && circuit->area) lsp_regenerate_schedule (circuit->area, circuit->is_type, 0); #endif return; }