/* elect DR and BDR. Refer to RFC2319 section 9.4 */ struct ospf_neighbor * ospf_dr_election_sub (struct list *routers) { struct listnode *node; struct ospf_neighbor *nbr, *max = NULL; /* Choose highest router priority. In case of tie, choose highest Router ID. */ for (node = listhead (routers); node; nextnode (node)) { nbr = getdata (node); if (max == NULL) max = nbr; else { if (max->priority < nbr->priority) max = nbr; else if (max->priority == nbr->priority) if (IPV4_ADDR_CMP (&max->router_id, &nbr->router_id) < 0) max = nbr; } } return max; }
/* Does this address belongs to me ? */ int if_check_address (struct in_addr addr) { struct listnode *node; struct interface *ifp; for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp)) { struct listnode *cnode; struct connected *connected; for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected)) { struct prefix_ipv4 *p; p = (struct prefix_ipv4 *) connected->address; if (p->family != AF_INET) continue; if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0) return 1; } } return 0; }
/******************************************************************************* 函数名称 : bgp_info_nexthop_cmp 功能描述 : bgp_info nexthop比较函数 输入参数 : 输出参数 : 返 回 值 : 1表示大于,0表示相等,-1表示小于 -------------------------------------------------------------------------------- 最近一次修改记录 : 修改作者 : 修改目的 : 新添加函数 修改日期 : 2012-8-15 *******************************************************************************/ s32 bgp_info_nexthop_cmp (struct bgp_info *bi1, struct bgp_info *bi2) { struct attr_extra *ae1, *ae2; s32 compare; ae1 = bi1->attr->extra; ae2 = bi2->attr->extra; compare = IPV4_ADDR_CMP (&bi1->attr->nexthop, &bi2->attr->nexthop); if (!compare && ae1 && ae2 && (ae1->mp_nexthop_len == ae2->mp_nexthop_len)) { switch (ae1->mp_nexthop_len) { case 4: case 12: compare = IPV4_ADDR_CMP (&ae1->mp_nexthop_global_in, &ae2->mp_nexthop_global_in); break; #ifdef HAVE_IPV6 case 16: compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global, &ae2->mp_nexthop_global); break; case 32: compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_global, &ae2->mp_nexthop_global); if (!compare) compare = IPV6_ADDR_CMP (&ae1->mp_nexthop_local, &ae2->mp_nexthop_local); break; #endif /* HAVE_IPV6 */ default: break; } } return compare; }
struct ospf_neighbor * ospf_nbr_get (struct ospf_interface *oi, struct ospf_header *ospfh, struct ip *iph, struct prefix *p) { struct route_node *rn; struct prefix key; struct ospf_neighbor *nbr; key.family = AF_INET; key.prefixlen = IPV4_MAX_BITLEN; if (oi->type == OSPF_IFTYPE_VIRTUALLINK) { key.u.prefix4 = ospfh->router_id; /* index vlink nbrs by router-id */ } else { key.u.prefix4 = iph->ip_src; } rn = route_node_get (oi->nbrs, &key); if (rn->info) { route_unlock_node (rn); nbr = rn->info; if (oi->type == OSPF_IFTYPE_NBMA && nbr->state == NSM_Attempt) { nbr->src = iph->ip_src; memcpy (&nbr->address, p, sizeof (struct prefix)); } /*add by bill 20091224. if the nbr's router id is changed, then the nbr's state is transit to ExStart, to refresh the adjacency*/ if(IPV4_ADDR_CMP(&nbr->router_id, &ospfh->router_id)) { nbr->router_id = ospfh->router_id; OSPF_NSM_EVENT_EXECUTE (nbr, NSM_AdjOK); } } else { rn->info = nbr = ospf_nbr_add (oi, ospfh, p); nbr->router_id = ospfh->router_id; } return nbr; }
/* elect DR and BDR. Refer to RFC2319 section 9.4 */ static struct ospf_neighbor *ospf_dr_election_sub(struct list *routers) { struct listnode *node; struct ospf_neighbor *nbr, *max = NULL; /* Choose highest router priority. In case of tie, choose highest Router ID. */ for (ALL_LIST_ELEMENTS_RO(routers, node, nbr)) { if (max == NULL) max = nbr; else { if (max->priority < nbr->priority) max = nbr; else if (max->priority == nbr->priority) if (IPV4_ADDR_CMP (&max->router_id, &nbr->router_id) < 0) max = nbr; } } return max; }