/* Check area border router status. */ void ospf_check_abr_status (struct ospf *ospf) { struct ospf_area *area; listnode node; int bb_configured = 0; int bb_act_attached = 0; int areas_configured = 0; int areas_act_attached = 0; u_char new_flags = ospf->flags; if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_check_abr_status(): Start"); for (node = listhead (ospf->areas); node; nextnode (node)) { area = getdata (node); if (listcount (area->oiflist)) { areas_configured++; if (OSPF_IS_AREA_BACKBONE (area)) bb_configured = 1; } if (ospf_area_actively_attached (area)) { areas_act_attached++; if (OSPF_IS_AREA_BACKBONE (area)) bb_act_attached = 1; } } if (IS_DEBUG_OSPF_EVENT) { zlog_info ("ospf_check_abr_status(): looked through areas"); zlog_info ("ospf_check_abr_status(): bb_configured: %d", bb_configured); zlog_info ("ospf_check_abr_status(): bb_act_attached: %d", bb_act_attached); zlog_info ("ospf_check_abr_status(): areas_configured: %d", areas_configured); zlog_info ("ospf_check_abr_status(): areas_act_attached: %d", areas_act_attached); } switch (ospf->abr_type) { case OSPF_ABR_SHORTCUT: case OSPF_ABR_STAND: if (areas_act_attached > 1) SET_FLAG (new_flags, OSPF_FLAG_ABR); else UNSET_FLAG (new_flags, OSPF_FLAG_ABR); break; case OSPF_ABR_IBM: if ((areas_act_attached > 1) && bb_configured) SET_FLAG (new_flags, OSPF_FLAG_ABR); else UNSET_FLAG (new_flags, OSPF_FLAG_ABR); break; case OSPF_ABR_CISCO: if ((areas_configured > 1) && bb_act_attached) SET_FLAG (new_flags, OSPF_FLAG_ABR); else UNSET_FLAG (new_flags, OSPF_FLAG_ABR); break; default: break; } if (new_flags != ospf->flags) { ospf_spf_calculate_schedule (ospf); if (IS_DEBUG_OSPF_EVENT) zlog_info ("ospf_check_abr_status(): new router flags: %x",new_flags); ospf->flags = new_flags; OSPF_TIMER_ON (ospf->t_router_lsa_update, ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY); } }
static void isis_zebra_route_add_ipv4 (struct prefix *prefix, struct isis_route_info *route_info) { u_char message, flags; int psize; struct stream *stream; struct isis_nexthop *nexthop; struct listnode *node; if (CHECK_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED)) return; if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_ISIS], VRF_DEFAULT)) { message = 0; flags = 0; SET_FLAG (message, ZAPI_MESSAGE_NEXTHOP); SET_FLAG (message, ZAPI_MESSAGE_METRIC); #if 0 SET_FLAG (message, ZAPI_MESSAGE_DISTANCE); #endif stream = zclient->obuf; stream_reset (stream); zclient_create_header (stream, ZEBRA_IPV4_ROUTE_ADD, VRF_DEFAULT); /* type */ stream_putc (stream, ZEBRA_ROUTE_ISIS); /* flags */ stream_putc (stream, flags); /* message */ stream_putc (stream, message); /* SAFI */ stream_putw (stream, SAFI_UNICAST); /* prefix information */ psize = PSIZE (prefix->prefixlen); stream_putc (stream, prefix->prefixlen); stream_write (stream, (u_char *) & prefix->u.prefix4, psize); stream_putc (stream, listcount (route_info->nexthops)); /* Nexthop, ifindex, distance and metric information */ for (ALL_LIST_ELEMENTS_RO (route_info->nexthops, node, nexthop)) { /* FIXME: can it be ? */ if (nexthop->ip.s_addr != INADDR_ANY) { stream_putc (stream, ZEBRA_NEXTHOP_IPV4); stream_put_in_addr (stream, &nexthop->ip); } else { stream_putc (stream, ZEBRA_NEXTHOP_IFINDEX); stream_putl (stream, nexthop->ifindex); } } #if 0 if (CHECK_FLAG (message, ZAPI_MESSAGE_DISTANCE)) stream_putc (stream, route_info->depth); #endif if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) stream_putl (stream, route_info->cost); stream_putw_at (stream, 0, stream_get_endp (stream)); zclient_send_message(zclient); SET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED); UNSET_FLAG (route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC); }
/* Send ECMP routes to zebra. */ static void ripng_zebra_ipv6_send (struct route_node *rp, u_char cmd) { static struct in6_addr **nexthops = NULL; static unsigned int *ifindexes = NULL; static unsigned int nexthops_len = 0; struct list *list = (struct list *)rp->info; struct zapi_ipv6 api; struct listnode *listnode = NULL; struct ripng_info *rinfo = NULL; int count = 0; if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIPNG], VRF_DEFAULT)) { api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_RIPNG; api.flags = 0; api.message = 0; api.safi = SAFI_UNICAST; if (nexthops_len < listcount (list)) { nexthops_len = listcount (list); nexthops = XREALLOC (MTYPE_TMP, nexthops, nexthops_len * sizeof (struct in6_addr *)); ifindexes = XREALLOC (MTYPE_TMP, ifindexes, nexthops_len * sizeof (unsigned int)); } SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX); for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo)) { nexthops[count] = &rinfo->nexthop; ifindexes[count] = rinfo->ifindex; count++; if (cmd == ZEBRA_IPV6_ROUTE_ADD) SET_FLAG (rinfo->flags, RIPNG_RTF_FIB); else UNSET_FLAG (rinfo->flags, RIPNG_RTF_FIB); } api.nexthop = nexthops; api.nexthop_num = count; api.ifindex = ifindexes; api.ifindex_num = count; rinfo = listgetdata (listhead (list)); SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = rinfo->metric; zapi_ipv6_route (cmd, zclient, (struct prefix_ipv6 *)&rp->p, &api); if (IS_RIPNG_DEBUG_ZEBRA) { if (ripng->ecmp) zlog_debug ("%s: %s/%d nexthops %d", (cmd == ZEBRA_IPV6_ROUTE_ADD) ? \ "Install into zebra" : "Delete from zebra", inet6_ntoa (rp->p.u.prefix6), rp->p.prefixlen, count); else zlog_debug ("%s: %s/%d", (cmd == ZEBRA_IPV6_ROUTE_ADD) ? \ "Install into zebra" : "Delete from zebra", inet6_ntoa (rp->p.u.prefix6), rp->p.prefixlen); } }
if (listnode_lookup (parent->children, vertex) == NULL) listnode_add (parent->children, vertex); } if (parent && parent->Adj_N && listcount(parent->Adj_N) > 0) { for (ALL_LIST_ELEMENTS_RO (parent->Adj_N, node, parent_adj)) listnode_add (vertex->Adj_N, parent_adj); } else if (adj) { listnode_add (vertex->Adj_N, adj); } #ifdef EXTREME_DEBUG zlog_debug ("ISIS-Spf: add to TENT %s %s %s depth %d dist %d adjcount %d", print_sys_hostname (vertex->N.id), vtype2string (vertex->type), vid2string (vertex, buff), vertex->depth, vertex->d_N, listcount(vertex->Adj_N)); #endif /* EXTREME_DEBUG */ if (list_isempty (spftree->tents)) { listnode_add (spftree->tents, vertex); return vertex; } /* XXX: This cant use the standard ALL_LIST_ELEMENTS macro */ for (node = listhead (spftree->tents); node; node = listnextnode (node)) { v = listgetdata (node); if (v->d_N > vertex->d_N) { list_add_node_prev (spftree->tents, node, vertex);
unsigned int number_of_listeners (void) { return listcount(sm->listen_sockets); }
static void bgp_dump_routes_index_table(struct bgp *bgp) { struct peer *peer; struct listnode *node; uint16_t peerno = 0; struct stream *obuf; obuf = bgp_dump_obuf; stream_reset (obuf); /* MRT header */ bgp_dump_header (obuf, MSG_TABLE_DUMP_V2, TABLE_DUMP_V2_PEER_INDEX_TABLE); /* Collector BGP ID */ stream_put_in_addr (obuf, &bgp->router_id); /* View name */ if(bgp->name) { stream_putw (obuf, strlen(bgp->name)); stream_put(obuf, bgp->name, strlen(bgp->name)); } else { stream_putw(obuf, 0); } /* Peer count */ stream_putw (obuf, listcount(bgp->peer)); /* Walk down all peers */ for(ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer)) { /* Peer's type */ if (sockunion_family(&peer->su) == AF_INET) { stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP); } #ifdef HAVE_IPV6 else if (sockunion_family(&peer->su) == AF_INET6) { stream_putc (obuf, TABLE_DUMP_V2_PEER_INDEX_TABLE_AS4+TABLE_DUMP_V2_PEER_INDEX_TABLE_IP6); } #endif /* HAVE_IPV6 */ /* Peer's BGP ID */ stream_put_in_addr (obuf, &peer->remote_id); /* Peer's IP address */ if (sockunion_family(&peer->su) == AF_INET) { stream_put_in_addr (obuf, &peer->su.sin.sin_addr); } #ifdef HAVE_IPV6 else if (sockunion_family(&peer->su) == AF_INET6) { stream_write (obuf, (u_char *)&peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN); } #endif /* HAVE_IPV6 */ /* Peer's AS number. */ /* Note that, as this is an AS4 compliant quagga, the RIB is always AS4 */ stream_putl (obuf, peer->as); /* Store the peer number for this peer */ peer->table_dump_index = peerno; peerno++; } bgp_dump_set_size(obuf, MSG_TABLE_DUMP_V2); fwrite (STREAM_DATA (obuf), stream_get_endp (obuf), 1, bgp_dump_routes.fp); fflush (bgp_dump_routes.fp); }
int area_net_title (struct isis_area *area, const u_char *net_title) { struct area_addr *addr; struct area_addr *addrp; struct listnode *node; u_char buff[255]; if (!area) { Log(LOG_WARNING, "WARN ( %s/core/ISIS ): Can't find ISIS instance\n", config.name); return TRUE; } /* We check that we are not over the maximal number of addresses */ if (listcount (area->area_addrs) >= isis->max_area_addrs) { Log(LOG_WARNING, "WARN ( %s/core/ISIS ): Maximum of area addresses (%d) already reached\n", config.name, isis->max_area_addrs); return TRUE; } addr = calloc(1, sizeof (struct area_addr)); addr->addr_len = dotformat2buff (buff, net_title); memcpy (addr->area_addr, buff, addr->addr_len); if (addr->addr_len < 8 || addr->addr_len > 20) { Log(LOG_WARNING, "WARN ( %s/core/ISIS ): area address must be at least 8..20 octets long (%d)\n", config.name, addr->addr_len); free(addr); return TRUE; } if (isis->sysid_set == 0) { /* * First area address - get the SystemID for this router */ memcpy (isis->sysid, GETSYSID (addr, ISIS_SYS_ID_LEN), ISIS_SYS_ID_LEN); isis->sysid_set = 1; Log(LOG_DEBUG, "DEBUG ( %s/core/ISIS ): Router has SystemID %s\n", config.name, sysid_print (isis->sysid)); } else { /* * Check that the SystemID portions match */ if (memcmp (isis->sysid, GETSYSID (addr, ISIS_SYS_ID_LEN), ISIS_SYS_ID_LEN)) { Log(LOG_WARNING, "WARN ( %s/core/ISIS ): System ID must not change when defining additional area addresses\n", config.name); free(addr); return TRUE; } /* now we see that we don't already have this address */ for (ALL_LIST_ELEMENTS_RO (area->area_addrs, node, addrp)) { if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) != (addr->addr_len)) continue; if (!memcmp (addrp->area_addr, addr->area_addr, addr->addr_len)) { free(addr); return FALSE; /* silent fail */ } } } /* * Forget the systemID part of the address */ addr->addr_len -= (ISIS_SYS_ID_LEN + 1); isis_listnode_add (area->area_addrs, addr); /* Only now we can safely generate our LSPs for this area */ if (listcount (area->area_addrs) > 0) { lsp_l1_generate (area); lsp_l2_generate (area); } return FALSE; }
int isis_dr_elect (struct isis_circuit *circuit, int level) { struct list *adjdb; struct listnode *node; struct isis_adjacency *adj, *adj_dr = NULL; struct list *list = list_new (); u_char own_prio; int biggest_prio = -1; int cmp_res, retval = ISIS_OK; own_prio = circuit->priority[level - 1]; adjdb = circuit->u.bc.adjdb[level - 1]; if (!adjdb) { zlog_warn ("isis_dr_elect() adjdb == NULL"); list_delete (list); return ISIS_WARNING; } isis_adj_build_up_list (adjdb, list); /* * Loop the adjacencies and find the one with the biggest priority */ for (ALL_LIST_ELEMENTS_RO (list, node, adj)) { /* clear flag for show output */ adj->dis_record[level - 1].dis = ISIS_IS_NOT_DIS; adj->dis_record[level - 1].last_dis_change = time (NULL); if (adj->prio[level - 1] > biggest_prio) { biggest_prio = adj->prio[level - 1]; adj_dr = adj; } else if (adj->prio[level - 1] == biggest_prio) { /* * Comparison of MACs breaks a tie */ if (adj_dr) { cmp_res = memcmp (adj_dr->snpa, adj->snpa, ETH_ALEN); if (cmp_res < 0) { adj_dr = adj; } if (cmp_res == 0) zlog_warn ("isis_dr_elect(): multiple adjacencies with same SNPA"); } else { adj_dr = adj; } } } if (!adj_dr) { /* * Could not find the DR - means we are alone. Resign if we were DR. */ if (circuit->u.bc.is_dr[level - 1]) retval = isis_dr_resign (circuit, level); list_delete (list); return retval; } /* * Now we have the DR adjacency, compare it to self */ if (adj_dr->prio[level - 1] < own_prio || (adj_dr->prio[level - 1] == own_prio && memcmp (adj_dr->snpa, circuit->u.bc.snpa, ETH_ALEN) < 0)) { adj_dr->dis_record[level - 1].dis = ISIS_IS_NOT_DIS; adj_dr->dis_record[level - 1].last_dis_change = time (NULL); /* rotate the history log */ for (ALL_LIST_ELEMENTS_RO (list, node, adj)) isis_check_dr_change (adj, level); /* We are the DR, commence DR */ if (circuit->u.bc.is_dr[level - 1] == 0 && listcount (list) > 0) retval = isis_dr_commence (circuit, level); }
/* 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; }