📄 bgp_util.c
字号:
voidbgp_disable_rte_by_igp(rte) struct rt_entry *rte;{ struct rpcb *bnp; struct rt_entry *brte; struct bgpcblist *bgpcb, *bgpcb_head; extern byte bgpyes; if (!bgpyes) return; switch(rte->rt_proto.rtp_type) { case RTPROTO_RIP: case RTPROTO_IF:#ifdef notyet case RTPROTO_OSPF:#endif bgpcb_head = make_bgpcb_list(); for (bgpcb = bgpcb_head; bgpcb; bgpcb = bgpcb->next) { bnp = bgpcb->bnp; /* * XXX: bnp might be closed or even freed during the loop, * so the validity check is necessary. */ if (!bgp_rpcb_isvalid(bnp)) continue; brte = bnp->rp_adj_ribs_in; while(brte) { if (brte->rt_gwsrc_type == rte->rt_proto.rtp_type && /* sanity? */ brte->rt_gwsrc_entry == rte && (brte->rt_flags & (RTF_UP|RTF_INSTALLED)) == (RTF_UP|RTF_INSTALLED)) { struct rt_entry crte; IFLOG(LOG_BGPROUTE) syslog(LOG_DEBUG, "<%s>: BGP route(%s/%d) was disabled", __FUNCTION__, ip6str(&brte->rt_ripinfo.rip6_dest, 0), brte->rt_ripinfo.rip6_plen); bgp_disable_rte(brte); /* flush gateway information */ brte->rt_gwsrc_type = RTPROTO_NONE; brte->rt_gwsrc_entry = NULL; memset(&brte->rt_gw, 0, sizeof(struct in6_addr)); brte->rt_gwif = NULL; /* withdraw this route */ crte = *brte; crte.rt_next = crte.rt_prev = &crte; propagate(&crte); /* XXX: propagate might invalidate bnp */ if (!bgp_rpcb_isvalid(bnp)) { syslog(LOG_NOTICE, "<%s>: rpcb %p was " "invalidated during a " "propagation", __FUNCTION__, bnp); break; } } if ((brte = brte->rt_next) == bnp->rp_adj_ribs_in) break; } } free_bgpcb_list(bgpcb_head); break; default: fatalx("<bgp_disable_rte_by_igp>: rt_proto.rtp_type corrupted"); /* NOTREACHED */ }}struct rpcb *find_epeer_by_rpcb(bnp) struct rpcb *bnp;{ struct rpcb *ebnp = NULL; if (bnp == NULL) return(NULL); if (bnp->rp_state == BGPSTATE_ESTABLISHED) return(bnp); if (bnp->rp_mode & BGPO_IGP) { /* IBGP */ ebnp = find_epeer_by_id(bnp->rp_id); if (ebnp == NULL) ebnp = find_epeer_by_addr(&bnp->rp_gaddr); if (ebnp == NULL) /* last resort */ ebnp = find_epeer_by_addr(&bnp->rp_laddr); } else { /* EBGP */ ebnp = find_epeer_by_as(bnp->rp_as); } return(ebnp);}struct rpcb *find_epeer_by_addr(addr) struct in6_addr *addr;{ struct rpcb *bnp; struct in6_addr lladdr; extern struct rpcb *bgb; if (IN6_IS_ADDR_UNSPECIFIED(addr)) return(NULL); bnp = bgb; while(bnp) { lladdr = bnp->rp_laddr; if (bnp->rp_ife) SET_IN6_LINKLOCAL_IFINDEX(&lladdr, bnp->rp_ife->ifi_ifn->if_index); if (bnp->rp_state == BGPSTATE_ESTABLISHED && (IN6_ARE_ADDR_EQUAL(&bnp->rp_gaddr, addr) || (!IN6_IS_ADDR_UNSPECIFIED(&lladdr) && IN6_ARE_ADDR_EQUAL(&lladdr, addr)))) return(bnp); if ((bnp = bnp->rp_next) == bgb) break; } return NULL;}/* * find_peer_by_as() */struct rpcb *find_peer_by_as(u_int16_t asnum) { struct rpcb *bnp; extern struct rpcb *bgb; bnp = bgb; while(bnp) { if (bnp->rp_as == asnum) return bnp; if ((bnp = bnp->rp_next) == bgb) break; } return NULL;}/* * find_epeer_by_as() * DESCRIPTION: find ESTABLISHED peer by ASnumber */struct rpcb *find_epeer_by_as(u_int16_t asnum) { struct rpcb *bnp; extern struct rpcb *bgb; bnp = bgb; while(bnp) { if (bnp->rp_as == asnum && bnp->rp_state == BGPSTATE_ESTABLISHED) return bnp; if ((bnp = bnp->rp_next) == bgb) break; } return NULL;}/* * find_ppeer_by_as() * DESCRIPTION: find PASSIVEly connected peer by ASnumber */struct rpcb *find_ppeer_by_as(u_int16_t asnum) { struct rpcb *bnp; extern struct rpcb *bgb; bnp = bgb; while(bnp) { if ((bnp->rp_as == asnum) && (bnp->rp_mode & BGPO_PASSIVE)) return bnp; if ((bnp = bnp->rp_next) == bgb) break; } return NULL;}/* * find_epeer_by_id() * RETURN VALUES: a Pointer: found * NULL : not found */struct rpcb *find_epeer_by_id(u_int32_t id) { struct rpcb *bnp; extern struct rpcb *bgb; if (id == 0) return NULL; bnp = bgb; while(bnp) { if (bnp->rp_id == id && bnp->rp_state == BGPSTATE_ESTABLISHED) return bnp; if ((bnp = bnp->rp_next) == bgb) break; } return NULL;}/* * find_ppeer_by_id() */struct rpcb *find_ppeer_by_id(u_int32_t id) { struct rpcb *bnp; extern struct rpcb *bgb; bnp = bgb; while(bnp) { if (bnp->rp_id == id && (bnp->rp_mode & BGPO_PASSIVE)) return bnp; if ((bnp = bnp->rp_next) == bgb) break; } return NULL;}struct rpcb *find_active_peer(key) struct rpcb *key;{ struct rpcb *bnp; extern struct rpcb *bgb; /* * If state of the KEY rpcb is unspecified(because of, for example, * not fully connected yet), there is no rpcb that matches it. */ if (key->rp_id == 0 && key->rp_as == 0) return(NULL); bnp = bgb; while(bnp) { if ((key->rp_mode & BGPO_IGP) && (bnp->rp_mode & BGPO_IGP) && bnp->rp_state >= BGPSTATE_CONNECT && ((bnp->rp_id && bnp->rp_id == key->rp_id) || IN6_ARE_ADDR_EQUAL(&key->rp_gaddr, &bnp->rp_gaddr) || (!IN6_IS_ADDR_UNSPECIFIED(&key->rp_laddr) && IN6_ARE_ADDR_EQUAL(&key->rp_laddr, &bnp->rp_laddr)))) return(bnp); if (!(key->rp_mode & BGPO_IGP) && !(bnp->rp_mode & BGPO_IGP) && bnp->rp_as == key->rp_as && bnp->rp_state >= BGPSTATE_CONNECT) return(bnp); if ((bnp = bnp->rp_next) == bgb) break; } return(NULL);}/* search for an actively opened peer */struct rpcb *find_aopen_peer(key) struct rpcb *key;{ struct rpcb *bnp = NULL; if ((key->rp_mode & BGPO_PASSIVE) == 0) return(key); if ((bnp = find_apeer_by_addr(&key->rp_gaddr)) == NULL) bnp = find_apeer_by_addr(&key->rp_laddr); if (bnp == NULL) { /* * This case could occur when receiving a connection * request from an unkown router. * We can't call bgp_peerstr here, since it causes an * infinite loop. */#if 0 /* disabled since this would be noisy */ syslog(LOG_DEBUG, "<%s>: can't find an actively opened peer for %x", __FUNCTION__, key);#endif } return(bnp);}struct rpcb *find_idle_peer(key) struct rpcb *key;{ struct rpcb *bnp; extern struct rpcb *bgb; /* * If state of the KEY rpcb is unspecified(because of, for example, * not fully connected yet), there is no rpcb that matches it. */ if (key->rp_id == 0 && key->rp_as == 0) return(NULL); bnp = bgb; while(bnp) { if ((key->rp_mode & BGPO_IGP) && (bnp->rp_mode & BGPO_IGP) && bnp->rp_state == BGPSTATE_IDLE && ((bnp->rp_id && bnp->rp_id == key->rp_id) || IN6_ARE_ADDR_EQUAL(&key->rp_gaddr, &bnp->rp_gaddr) || (!IN6_IS_ADDR_UNSPECIFIED(&key->rp_laddr) && IN6_ARE_ADDR_EQUAL(&key->rp_laddr, &bnp->rp_laddr)))) return(bnp); if (!(key->rp_mode & BGPO_IGP) && !(bnp->rp_mode & BGPO_IGP) && bnp->rp_as == key->rp_as && bnp->rp_state == BGPSTATE_IDLE) return(bnp); if ((bnp = bnp->rp_next) == bgb) break; } return(NULL);}/* * find_apeer_by_addr() * DESCRIPTION: in the case of LinkLocal-address, * we need I/F information. (e.g. LLADDRHACK) */struct rpcb *find_apeer_by_addr(struct in6_addr *addr){ struct rpcb *bnp; struct in6_addr llhackaddr; extern struct rpcb *bgb; if (IN6_IS_ADDR_UNSPECIFIED(addr)) return NULL; bnp = bgb; while(bnp) { llhackaddr = bnp->rp_laddr; if (!IN6_IS_ADDR_UNSPECIFIED(&llhackaddr)) { if (bnp->rp_ife) SET_IN6_LINKLOCAL_IFINDEX(&llhackaddr, bnp->rp_ife->ifi_ifn->if_index); else if (IN6_IS_ADDR_LINKLOCAL(&bnp->rp_addr.sin6_addr) && bnp->rp_addr.sin6_scope_id) { SET_IN6_LINKLOCAL_IFINDEX(&llhackaddr, bnp->rp_addr.sin6_scope_id); } } if (!(bnp->rp_mode & BGPO_PASSIVE) && (IN6_ARE_ADDR_EQUAL(&bnp->rp_gaddr, addr) || (!IN6_IS_ADDR_UNSPECIFIED(&llhackaddr) && IN6_ARE_ADDR_EQUAL(&llhackaddr, addr)))) return bnp; if ((bnp = bnp->rp_next) == bgb) break; } return NULL;}/* * Check if a given pointer is actually in the peer list and if * the connection to the peer is ESTABLISHUED. * We need this function since we sometimes encounter a situation where * the connection associated with the pointer is closed or even the pointer * is freed during some operations such as update or withdrawing. * This means that we must not the content of BNP, the argument. * We can only refer the address of the pointer. */intbgp_rpcb_isvalid(bnp) struct rpcb *bnp;{ extern struct rpcb *bgb; struct rpcb *b; b = bgb; while(b) { if (b == bnp && b->rp_state == BGPSTATE_ESTABLISHED) return(1); if ((b = b->rp_next) == bgb) break; } return(0);}/* * ibgpconfig() * * Route Reflector [rfc1966]. */voidibgpconfig(){ struct rpcb *ibnp, *bnp;#if 0 struct ifinfo *ife; struct ripif *ripif;#endif extern byte IamRR;#if 0 extern byte ripyes;#endif extern u_int32_t clusterId, bgpIdentifier; extern struct rpcb *bgb;#if 0 extern struct ifinfo *ifentry; extern struct ripif *ripifs;#endif if (IamRR) if (clusterId == 0) clusterId = bgpIdentifier; /* ad-hoc */ /* * 1) A Route from a Non-Client peer * * Reflect to all other Clients. */ if (IamRR) { ibnp = bgb; while (ibnp) { if (ibnp->rp_mode & BGPO_RRCLIENT) { bnp = bgb; while (bnp) { if ( (bnp->rp_mode & BGPO_IGP) && !(bnp->rp_mode & BGPO_RRCLIENT) && ibnp != bnp ) { struct rtproto *rtp; MALLOC(rtp, struct rtproto); rtp->rtp_type = RTPROTO_BGP; rtp->rtp_bgp = bnp; if (ibnp->rp_adj_ribs_out) insque(rtp, ibnp->rp_adj_ribs_out); else { rtp->rtp_next = rtp; rtp->rtp_prev = rtp; ibnp->rp_adj_ribs_out = rtp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -