📄 bgpd.c
字号:
/* 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 configured at least one address family return 1. */intpeer_group_active (struct peer *peer){ if (peer->af_group[AFI_IP][SAFI_UNICAST] || peer->af_group[AFI_IP][SAFI_MULTICAST] || peer->af_group[AFI_IP][SAFI_MPLS_VPN] || peer->af_group[AFI_IP6][SAFI_UNICAST] || peer->af_group[AFI_IP6][SAFI_MULTICAST]) 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); UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT); group->conf->keepalive = 0; group->conf->holdtime = 0; group->conf->connect = 0; SET_FLAG (group->conf->sflags, PEER_STATUS_GROUP); listnode_add_sort (bgp->group, group); return 0;}void peer_group2peer_config_copy (struct peer_group *group, struct peer *peer, afi_t afi, safi_t safi){ int in = FILTER_IN; int out = FILTER_OUT; struct peer *conf; struct bgp_filter *pfilter; struct bgp_filter *gfilter; conf = group->conf; pfilter = &peer->filter[afi][safi]; gfilter = &conf->filter[afi][safi]; /* remote-as */ if (conf->as) peer->as = conf->as; /* remote-as */ if (conf->change_local_as) peer->change_local_as = conf->change_local_as; /* TTL */ peer->ttl = conf->ttl; /* Weight */ peer->weight = conf->weight; /* peer flags apply */ peer->flags = conf->flags; /* peer af_flags apply */ peer->af_flags[afi][safi] = conf->af_flags[afi][safi]; /* peer config apply */ peer->config = conf->config; /* peer timers apply */ peer->holdtime = conf->holdtime; peer->keepalive = conf->keepalive; peer->connect = conf->connect; if (CHECK_FLAG (conf->config, PEER_CONFIG_CONNECT)) peer->v_connect = conf->connect; else peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; /* 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; /* maximum-prefix */ peer->pmax[afi][safi] = conf->pmax[afi][safi]; peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi]; /* allowas-in */ peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi]; /* default-originate route-map */ if (conf->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 (conf->default_rmap[afi][safi].name); peer->default_rmap[afi][safi].map = conf->default_rmap[afi][safi].map; } /* update-source apply */ if (conf->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 (conf->update_source); } else if (conf->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, conf->update_if); } /* 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; }} /* 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; bgp = group->bgp; LIST_LOOP (group->peer, peer, nn) { peer->group = NULL; peer_delete (peer); } list_delete (group->peer); free (group->name); group->name = NULL; group->conf->group = 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; /* Check peer group's address family. */ if (! group->conf->afc[afi][safi]) return BGP_ERR_PEER_GROUP_AF_UNCONFIGURED; /* 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, afi, safi); peer->group = group; peer->af_group[afi][safi] = 1; listnode_add (group->peer, peer); peer_group2peer_config_copy (group, peer, afi, safi); return 0; } /* When the peer already belongs to peer group, check the consistency. */ if (peer->af_group[afi][safi]) { if (strcmp (peer->group->name, group->name) != 0) return BGP_ERR_PEER_GROUP_CANT_CHANGE; return 0; } /* Check current peer group configuration. */ if (peer_group_active (peer) && strcmp (peer->group->name, group->name) != 0) return BGP_ERR_PEER_GROUP_MISMATCH; if (! group->conf->as) { if (peer_sort (group->conf) != BGP_PEER_INTERNAL && peer_sort (group->conf) != peer_sort (peer)) { if (as) *as = peer->as; return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT; } if (peer_sort (group->conf) == BGP_PEER_INTERNAL) first_member = 1; } peer->af_group[afi][safi] = 1; peer->afc[afi][safi] = 1; if (! peer->group) { 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_group2peer_config_copy (group, peer, afi, safi); if (peer->status == Established) { peer->last_reset = PEER_DOWN_RMAP_BIND; bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else BGP_EVENT_ADD (peer, BGP_Stop); return 0;}intpeer_group_unbind (struct bgp *bgp, struct peer *peer, struct peer_group *group, afi_t afi, safi_t safi){ if (! peer->af_group[afi][safi]) return 0; if (group != peer->group) return BGP_ERR_PEER_GROUP_MISMATCH; peer->af_group[afi][safi] = 0; peer->afc[afi][safi] = 0; peer_af_flag_reset (peer, afi, safi); if (! peer_group_active (peer)) { listnode_delete (group->peer, peer); peer->group = NULL; if (group->conf->as) { peer_delete (peer); return 0; } peer_global_config_reset (peer); } if (peer->status == Established)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -