📄 bgpd.c
字号:
if (bgp->as == *as) { *as = peer->as; return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT; } } } /* Existing peer's AS number change. */ if (peer->as != *as) peer_as_change (peer, *as); } else { /* If the peer is not part of our confederation, and its not an iBGP peer then spoof the source AS */ if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION) && ! bgp_confederation_peers_check (bgp, *as) && bgp->as != *as) local_as = bgp->confed_id; else local_as = bgp->as; /* If this is IPv4 unicast configuration and "no bgp default ipv4-unicast" is specified. */ if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4) && afi == AFI_IP && safi == SAFI_UNICAST) peer = peer_create (su, bgp, local_as, *as, 0, 0); else peer = peer_create (su, bgp, local_as, *as, afi, safi); } return 0;}/* Activate the peer or peer group for specified AFI and SAFI. */intpeer_activate (struct peer *peer, afi_t afi, safi_t safi){ int active; if (peer->afc[afi][safi]) return 0; /* Activate the address family configuration. */ if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) peer->afc[afi][safi] = 1; else { active = peer_active (peer); peer->afc[afi][safi] = 1; if (peer_group_member (peer)) { peer->group->conf->afc[afi][safi] = 1; peer_group_af_config_copy (peer->group->conf, peer, afi, safi); } if (! active && peer_active (peer)) bgp_timer_set (peer); else { if (peer->status == Established) { if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV) && CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV)) { peer->afc_adv[afi][safi] = 1; bgp_capability_send (peer, afi, safi, CAPABILITY_CODE_MP, CAPABILITY_ACTION_SET); if (peer->afc_recv[afi][safi]) { peer->afc_nego[afi][safi] = 1; bgp_announce_route (peer, afi, safi); } } else { peer->last_reset = PEER_DOWN_AF_ACTIVATE; bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } } } return 0;}intpeer_deactivate (struct peer *peer, afi_t afi, safi_t safi){ struct peer_group *group; struct peer *peer1; struct listnode *nn; if (! peer->afc[afi][safi]) return 0; if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { group = peer->group; LIST_LOOP (group->peer, peer1, nn) { if (peer1->afc[afi][safi]) return BGP_ERR_PEER_GROUP_MEMBER_EXISTS; } } /* De-activate the address family configuration. */ peer->afc[afi][safi] = 0; peer_af_flag_reset (peer, afi, safi); if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (peer->status == Established) { if (CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV) && CHECK_FLAG (peer->cap, PEER_CAP_DYNAMIC_RCV)) { peer->afc_adv[afi][safi] = 0; peer->afc_nego[afi][safi] = 0; if (peer_active_nego (peer)) { bgp_capability_send (peer, afi, safi, CAPABILITY_CODE_MP, CAPABILITY_ACTION_UNSET); bgp_clear_route (peer, afi, safi); peer->synctime[afi][safi] = 0; BGP_TIMER_OFF (peer->t_routeadv[afi][safi]); peer->af_sflags[afi][safi] = 0; } else { peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE; bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } else { peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE; bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } } return 0;}voidpeer_nsf_stop (struct peer *peer){ afi_t afi; safi_t safi; UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT); UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_MODE); for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_UNICAST_MULTICAST ; safi++) peer->nsf[afi][safi] = 0; if (peer->t_gr_restart) { BGP_TIMER_OFF (peer->t_gr_restart); if (BGP_DEBUG (events, EVENTS)) zlog_info ("%s graceful restart timer stopped", peer->host); } if (peer->t_gr_stale) { BGP_TIMER_OFF (peer->t_gr_stale); if (BGP_DEBUG (events, EVENTS)) zlog_info ("%s graceful restart stalepath timer stopped", peer->host); } bgp_clear_route_all (peer);}/* Delete peer from confguration. */intpeer_delete (struct peer *peer){ int i; afi_t afi; safi_t safi; struct bgp *bgp; struct bgp_filter *filter; bgp = peer->bgp; if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)) peer_nsf_stop (peer); /* Delete peer from peer-list of group when peer is member of peer-group. */ if (peer_group_member (peer)) { listnode_delete (peer->group->peer, peer); peer->group = NULL; } /* Withdraw all information from routing table. We can not use BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is executed after peer structure is deleted. */ if (peer->status == Established) bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); else { bgp_stop (peer); bgp_fsm_change_status (peer, Idle); } /* Stop all timers. */ BGP_TIMER_OFF (peer->t_start); BGP_TIMER_OFF (peer->t_connect); BGP_TIMER_OFF (peer->t_holdtime); BGP_TIMER_OFF (peer->t_keepalive); BGP_TIMER_OFF (peer->t_asorig); BGP_TIMER_OFF (peer->t_pmax_restart); BGP_TIMER_OFF (peer->t_gr_restart); BGP_TIMER_OFF (peer->t_gr_stale); for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) BGP_TIMER_OFF (peer->t_routeadv[afi][safi]);#ifdef HAVE_TCP_SIGNATURE /* Password configuration */ if (peer->password) { if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) bgp_tcpsig_unset (bm->sock, peer); free (peer->password); }#endif /* HAVE_TCP_SIGNATURE */ /* Delete peer from peer-list of bgp, except peer of peer_self and peer_group. */ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) && peer != bgp->peer_self) listnode_delete (bgp->peer, peer); /* Buffer. */ if (peer->ibuf) stream_free (peer->ibuf); if (peer->obuf) stream_fifo_free (peer->obuf); if (peer->work) stream_free (peer->work); /* Free allocated host character. */ if (peer->host) free (peer->host); /* Local and remote addresses. */ if (peer->su_local) XFREE (MTYPE_TMP, peer->su_local); if (peer->su_remote) XFREE (MTYPE_TMP, peer->su_remote); /* Peer description string. */ if (peer->desc) XFREE (MTYPE_TMP, peer->desc); bgp_sync_delete (peer); /* Free filter related memory. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { filter = &peer->filter[afi][safi]; for (i = FILTER_IN; i < FILTER_MAX; i++) { if (filter->dlist[i].name) free (filter->dlist[i].name); if (filter->plist[i].name) free (filter->plist[i].name); if (filter->aslist[i].name) free (filter->aslist[i].name); if (filter->map[i].name) free (filter->map[i].name); } if (filter->usmap.name) free (filter->usmap.name); if (peer->default_rmap[afi][safi].name) free (peer->default_rmap[afi][safi].name); } /* Update source configuration. */ if (peer->update_source) { sockunion_free (peer->update_source); peer->update_source = NULL; } if (peer->update_if) { XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); peer->update_if = NULL; } /* Free peer structure. */ XFREE (MTYPE_BGP_PEER, peer); return 0;}intpeer_group_cmp (struct peer_group *g1, struct peer_group *g2){ return strcmp (g1->name, g2->name);}/* If peer is member of peer-group return 1. */intpeer_group_member (struct peer *peer){ if (peer->group && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) return 1; return 0;}/* Peer group cofiguration. */static struct peer_group *peer_group_new (){ return (struct peer_group *) XCALLOC (MTYPE_PEER_GROUP, sizeof (struct peer_group));}voidpeer_group_free (struct peer_group *group){ XFREE (MTYPE_PEER_GROUP, group);}struct peer_group *peer_group_lookup (struct bgp *bgp, char *name){ struct peer_group *group; struct listnode *nn; LIST_LOOP (bgp->group, group, nn) { if (strcmp (group->name, name) == 0) return group; } return NULL;}struct peer_group *peer_group_get (struct bgp *bgp, char *name){ struct peer_group *group; group = peer_group_lookup (bgp, name); if (group) return group; group = peer_group_new (); group->bgp = bgp; group->name = strdup (name); group->peer = list_new (); group->conf = peer_new (); if (! bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)) group->conf->afc[AFI_IP][SAFI_UNICAST] = 1; group->conf->host = strdup (name); group->conf->bgp = bgp; group->conf->group = group; group->conf->as = 0; group->conf->ttl = 1; group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER); group->conf->keepalive = 0; group->conf->holdtime = 0; SET_FLAG (group->conf->sflags, PEER_STATUS_GROUP); listnode_add_sort (bgp->group, group); return 0;}/* Peer group's remote AS configuration. */intpeer_group_remote_as (struct bgp *bgp, char *group_name, as_t *as){ struct peer_group *group; struct peer *peer; struct listnode *nn; group = peer_group_lookup (bgp, group_name); if (! group) return -1; if (group->conf->as == *as) return 0; /* When we setup peer-group AS number all peer group member's AS number must be updated to same number. */ peer_as_change (group->conf, *as); LIST_LOOP (group->peer, peer, nn) { if (peer->as != *as) peer_as_change (peer, *as); } return 0;}intpeer_group_delete (struct peer_group *group){ struct bgp *bgp; struct peer *peer; struct listnode *nn; struct listnode *next; bgp = group->bgp; for (nn = group->peer->head; nn; nn = next) { peer = nn->data; next = nn->next; peer_delete (peer); } free (group->name); group->name = NULL; peer_delete (group->conf); /* Delete from all peer_group list. */ listnode_delete (bgp->group, group); peer_group_free (group); return 0;}intpeer_group_remote_as_delete (struct peer_group *group){ struct peer *peer; struct listnode *nn; if (! group->conf->as) return 0; LIST_LOOP (group->peer, peer, nn) { peer->group = NULL; peer_delete (peer); } list_delete_all_node (group->peer); group->conf->as = 0; return 0;}/* Bind specified peer to peer group. */intpeer_group_bind (struct bgp *bgp, union sockunion *su, struct peer_group *group, afi_t afi, safi_t safi, as_t *as){ struct peer *peer; int first_member = 0; /* Lookup the peer. */ peer = peer_lookup (bgp, su); /* Create a new peer. */ if (! peer) { if (! group->conf->as) return BGP_ERR_PEER_GROUP_NO_REMOTE_AS; peer = peer_create (su, bgp, bgp->as, group->conf->as, 0, 0); peer->group = group; listnode_add (group->peer, peer); peer_group_global_config_copy (group->conf, peer); if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4) && afi == AFI_IP && safi == SAFI_UNICAST) return 0; return peer_activate (peer, afi, safi); } /* When the peer already belongs to peer group, check the consistency. */ if (peer_group_member (peer)) { if (strcmp (peer->group->name, group->name) != 0) return BGP_ERR_PEER_GROUP_CANT_CHANGE; return peer_activate (peer, afi, safi); } if (! group->conf->as) { if (peer_sort (group->conf) == BGP_PEER_INTERNAL) first_member = 1; else if (peer_sort (group->conf) != peer_sort (peer)) { if (as) *as = peer->as; return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT; } } peer->group = group; listnode_add (group->peer, peer); if (first_member) { /* Advertisement-interval reset */ if (peer_sort (group->conf) == BGP_PEER_IBGP) group->conf->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; else group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; /* ebgp-multihop reset */ if (peer_sort (group->conf) == BGP_PEER_IBGP) group->conf->ttl = 255; /* local-as reset */ if (peer_sort (group->conf) != BGP_PEER_EBGP) { group->conf->change_local_as = 0; UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND); } } peer_group_global_config_copy (group->conf, peer); peer_deactivate (peer, afi, safi); return peer_activate (peer, afi,safi);}/* Bind specified peer to peer group. */int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -