📄 bgpd.c
字号:
}/* Reset all address family specific configuration. */static voidpeer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi){ int i; struct bgp_filter *filter; char orf_name[BUFSIZ]; filter = &peer->filter[afi][safi]; /* Clear neighbor filter and route-map */ for (i = FILTER_IN; i < FILTER_MAX; i++) { if (filter->dlist[i].name) { free (filter->dlist[i].name); filter->dlist[i].name = NULL; } if (filter->plist[i].name) { free (filter->plist[i].name); filter->plist[i].name = NULL; } if (filter->aslist[i].name) { free (filter->aslist[i].name); filter->aslist[i].name = NULL; } if (filter->map[i].name) { free (filter->map[i].name); filter->map[i].name = NULL; } } /* Clear unsuppress map. */ if (filter->usmap.name) free (filter->usmap.name); filter->usmap.name = NULL; filter->usmap.map = NULL; /* Clear neighbor's all address family flags. */ peer->af_flags[afi][safi] = 0; /* Clear neighbor's all address family sflags. */ peer->af_sflags[afi][safi] = 0; /* Clear neighbor's all address family capabilities. */ peer->af_cap[afi][safi] = 0; /* Clear ORF info */ peer->orf_plist[afi][safi] = NULL; sprintf (orf_name, "%s.%d.%d", peer->host, afi, safi); prefix_bgp_orf_remove_all (orf_name); /* Set default neighbor send-community. */ if (! bgp_option_check (BGP_OPT_CONFIG_CISCO)) { SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY); SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY); } /* Clear neighbor default_originate_rmap */ if (peer->default_rmap[afi][safi].name) free (peer->default_rmap[afi][safi].name); peer->default_rmap[afi][safi].name = NULL; peer->default_rmap[afi][safi].map = NULL; /* Clear neighbor maximum-prefix */ peer->pmax[afi][safi] = 0; peer->pmax_threshold[afi][safi] = MAXIMUM_PREFIX_THRESHOLD_DEFAULT; /* Clear address family configuration */ peer->af_config[afi][safi] = 0;}void peer_group_global_config_copy (struct peer *group, struct peer *peer){ /* remote-as */ if (group->as) peer->as = group->as; /* remote-as */ if (group->change_local_as) peer->change_local_as = group->change_local_as; /* TTL */ peer->ttl = group->ttl; peer->flags = group->flags; peer->config = group->config; /* peer timers apply */ peer->holdtime = group->holdtime; peer->keepalive = group->keepalive; /* advertisement-interval reset */ if (peer_sort (peer) == BGP_PEER_IBGP) peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; else peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;#ifdef HAVE_TCP_SIGNATURE /* password apply */ if (CHECK_FLAG (group->flags, PEER_FLAG_PASSWORD)) { if (peer->password) free (peer->password); peer->password = strdup (group->password); bgp_tcpsig_set (bm->sock, peer); } else if (peer->password) { bgp_tcpsig_unset (bm->sock, peer); free (peer->password); peer->password = NULL; }#endif /* HAVE_TCP_SIGNATURE */ /* update-source apply */ if (group->update_source) { if (peer->update_source) sockunion_free (peer->update_source); if (peer->update_if) { XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); peer->update_if = NULL; } peer->update_source = sockunion_dup (group->update_source); } else if (group->update_if) { if (peer->update_if) XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); if (peer->update_source) { sockunion_free (peer->update_source); peer->update_source = NULL; } peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->update_if); }} void peer_group_af_config_copy (struct peer *group, struct peer *peer, afi_t afi, safi_t safi){ int in = FILTER_IN; int out = FILTER_OUT; struct bgp_filter *pfilter; struct bgp_filter *gfilter; pfilter = &peer->filter[afi][safi]; gfilter = &group->filter[afi][safi]; peer->af_flags[afi][safi] = group->af_flags[afi][safi]; peer->af_config[afi][safi] = group->af_config[afi][safi]; peer->weight[afi][safi] = group->weight[afi][safi]; /* maximum-prefix */ peer->pmax[afi][safi] = group->pmax[afi][safi]; peer->pmax_threshold[afi][safi] = group->pmax_threshold[afi][safi]; peer->pmax_restart[afi][safi] = group->pmax_restart[afi][safi]; /* allowas-in */ peer->allowas_in[afi][safi] = group->allowas_in[afi][safi]; /* default-originate route-map */ if (group->default_rmap[afi][safi].name) { if (peer->default_rmap[afi][safi].name) free (peer->default_rmap[afi][safi].name); peer->default_rmap[afi][safi].name = strdup (group->default_rmap[afi][safi].name); peer->default_rmap[afi][safi].map = group->default_rmap[afi][safi].map; } /* inbound filter apply */ if (gfilter->dlist[in].name && ! pfilter->dlist[in].name) { if (pfilter->dlist[in].name) free (pfilter->dlist[in].name); pfilter->dlist[in].name = strdup (gfilter->dlist[in].name); pfilter->dlist[in].alist = gfilter->dlist[in].alist; } if (gfilter->plist[in].name && ! pfilter->plist[in].name) { if (pfilter->plist[in].name) free (pfilter->plist[in].name); pfilter->plist[in].name = strdup (gfilter->plist[in].name); pfilter->plist[in].plist = gfilter->plist[in].plist; } if (gfilter->aslist[in].name && ! pfilter->aslist[in].name) { if (pfilter->aslist[in].name) free (pfilter->aslist[in].name); pfilter->aslist[in].name = strdup (gfilter->aslist[in].name); pfilter->aslist[in].aslist = gfilter->aslist[in].aslist; } if (gfilter->map[in].name && ! pfilter->map[in].name) { if (pfilter->map[in].name) free (pfilter->map[in].name); pfilter->map[in].name = strdup (gfilter->map[in].name); pfilter->map[in].map = gfilter->map[in].map; } /* outbound filter apply */ if (gfilter->dlist[out].name) { if (pfilter->dlist[out].name) free (pfilter->dlist[out].name); pfilter->dlist[out].name = strdup (gfilter->dlist[out].name); pfilter->dlist[out].alist = gfilter->dlist[out].alist; } else { if (pfilter->dlist[out].name) free (pfilter->dlist[out].name); pfilter->dlist[out].name = NULL; pfilter->dlist[out].alist = NULL; } if (gfilter->plist[out].name) { if (pfilter->plist[out].name) free (pfilter->plist[out].name); pfilter->plist[out].name = strdup (gfilter->plist[out].name); pfilter->plist[out].plist = gfilter->plist[out].plist; } else { if (pfilter->plist[out].name) free (pfilter->plist[out].name); pfilter->plist[out].name = NULL; pfilter->plist[out].plist = NULL; } if (gfilter->aslist[out].name) { if (pfilter->aslist[out].name) free (pfilter->aslist[out].name); pfilter->aslist[out].name = strdup (gfilter->aslist[out].name); pfilter->aslist[out].aslist = gfilter->aslist[out].aslist; } else { if (pfilter->aslist[out].name) free (pfilter->aslist[out].name); pfilter->aslist[out].name = NULL; pfilter->aslist[out].aslist = NULL; } if (gfilter->map[out].name) { if (pfilter->map[out].name) free (pfilter->map[out].name); pfilter->map[out].name = strdup (gfilter->map[out].name); pfilter->map[out].map = gfilter->map[out].map; } else { if (pfilter->map[out].name) free (pfilter->map[out].name); pfilter->map[out].name = NULL; pfilter->map[out].map = NULL; } if (gfilter->usmap.name) { if (pfilter->usmap.name) free (pfilter->usmap.name); pfilter->usmap.name = strdup (gfilter->usmap.name); pfilter->usmap.map = gfilter->usmap.map; } else { if (pfilter->usmap.name) free (pfilter->usmap.name); pfilter->usmap.name = NULL; pfilter->usmap.map = NULL; }} /* Check peer's AS number and determin is this peer IBGP or EBGP */intpeer_sort (struct peer *peer){ struct bgp *bgp; bgp = peer->bgp; /* Peer-group */ if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (peer->as) return (bgp->as == peer->as ? BGP_PEER_IBGP : BGP_PEER_EBGP); else { struct peer *peer1; peer1 = listnode_head (peer->group->peer); if (peer1) return (peer1->local_as == peer1->as ? BGP_PEER_IBGP : BGP_PEER_EBGP); } return BGP_PEER_INTERNAL; } /* Normal peer */ if (bgp && CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION)) { if (peer->local_as == 0) return BGP_PEER_INTERNAL; if (peer->local_as == peer->as) { if (peer->local_as == bgp->confed_id) return BGP_PEER_EBGP; else return BGP_PEER_IBGP; } if (bgp_confederation_peers_check (bgp, peer->as)) return BGP_PEER_CONFED; return BGP_PEER_EBGP; } else { return (peer->local_as == 0 ? BGP_PEER_INTERNAL : peer->local_as == peer->as ? BGP_PEER_IBGP : BGP_PEER_EBGP); }}/* Allocate new peer object. */static struct peer *peer_new (){ afi_t afi; safi_t safi; struct peer *peer; struct servent *sp; /* Allocate new peer. */ peer = XMALLOC (MTYPE_BGP_PEER, sizeof (struct peer)); memset (peer, 0, sizeof (struct peer)); /* Set default value. */ peer->fd = -1; peer->v_start = BGP_INIT_START_TIMER; peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; peer->v_asorig = BGP_DEFAULT_ASORIGINATE; peer->v_active_delay = BGP_ACTIVE_DELAY_TIMER; peer->status = Idle; peer->ostatus = Idle; peer->password = NULL; /* Set default flags. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { if (! bgp_option_check (BGP_OPT_CONFIG_CISCO)) { SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY); SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY); } peer->orf_plist[afi][safi] = NULL; } SET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN); /* Create buffers. */ peer->ibuf = stream_new (BGP_MAX_PACKET_SIZE); peer->obuf = stream_fifo_new (); peer->work = stream_new (BGP_MAX_PACKET_SIZE); bgp_sync_init (peer); /* Get service port number. */ sp = getservbyname ("bgp", "tcp"); peer->port = (sp == NULL) ? BGP_PORT_DEFAULT : ntohs (sp->s_port); return peer;}/* Create new BGP peer. */struct peer *peer_create (union sockunion *su, struct bgp *bgp, as_t local_as, as_t remote_as, afi_t afi, safi_t safi){ int active; struct peer *peer; char buf[SU_ADDRSTRLEN]; peer = peer_new (); peer->bgp = bgp; peer->su = *su; peer->local_as = local_as; peer->as = remote_as; peer->local_id = bgp->router_id; peer->v_holdtime = bgp->default_holdtime; peer->v_keepalive = bgp->default_keepalive; if (peer_sort (peer) == BGP_PEER_IBGP) peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; else peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; listnode_add_sort (bgp->peer, peer); active = peer_active (peer); if (afi && safi) peer->afc[afi][safi] = 1; /* Last read time set */ peer->readtime = time (NULL); /* Last reset time set */ peer->resettime = time (NULL); /* Default TTL set. */ peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1); /* Make peer's address string. */ sockunion2str (su, buf, SU_ADDRSTRLEN); peer->host = strdup (buf); /* set peer first create flag */ SET_FLAG (peer->sflags, PEER_STATUS_CREATE_INIT); /* Set up peer's events and timers. */ if (! active && peer_active (peer)) bgp_timer_set (peer); return peer;}/* Make accept BGP peer. Called from bgp_accept (). */struct peer *peer_create_accept (struct bgp *bgp){ struct peer *peer; peer = peer_new (); peer->bgp = bgp; listnode_add_sort (bgp->peer, peer); return peer;}/* Change peer's AS number. */voidpeer_as_change (struct peer *peer, as_t as){ int type; /* Stop peer. */ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (peer->status == Established) { peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE; bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else BGP_EVENT_ADD (peer, BGP_Stop); } type = peer_sort (peer); peer->as = as; if (bgp_config_check (peer->bgp, BGP_CONFIG_CONFEDERATION) && ! bgp_confederation_peers_check (peer->bgp, as) && peer->bgp->as != as) peer->local_as = peer->bgp->confed_id; else peer->local_as = peer->bgp->as; /* Advertisement-interval reset */ if (peer_sort (peer) == BGP_PEER_IBGP) peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; else peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; /* TTL reset */ if (peer_sort (peer) == BGP_PEER_IBGP) peer->ttl = 255; else if (type == BGP_PEER_IBGP) peer->ttl = 1; /* reflector-client reset */ if (peer_sort (peer) != BGP_PEER_IBGP) { UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_UNICAST], PEER_FLAG_REFLECTOR_CLIENT); UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MULTICAST], PEER_FLAG_REFLECTOR_CLIENT); UNSET_FLAG (peer->af_flags[AFI_IP][SAFI_MPLS_VPN], PEER_FLAG_REFLECTOR_CLIENT); UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_UNICAST], PEER_FLAG_REFLECTOR_CLIENT); UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST], PEER_FLAG_REFLECTOR_CLIENT); } /* local-as reset */ if (peer_sort (peer) != BGP_PEER_EBGP) { peer->change_local_as = 0; UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); }}/* If peer does not exist, create new one. If peer already exists, set AS number to the peer. */intpeer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as, afi_t afi, safi_t safi){ struct peer *peer; as_t local_as; peer = peer_lookup (bgp, su); if (peer) { /* When this peer is a member of peer-group. */ if (peer->group) { if (peer->group->conf->as) { /* Return peer group's AS number. */ *as = peer->group->conf->as; return BGP_ERR_PEER_GROUP_MEMBER; } if (peer_sort (peer->group->conf) == BGP_PEER_IBGP) { if (bgp->as != *as) { *as = peer->as; return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT; } } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -