diff options
Diffstat (limited to 'bgpd/bgpd.c')
-rw-r--r-- | bgpd/bgpd.c | 433 |
1 files changed, 179 insertions, 254 deletions
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index b34f996b..600abf1c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -60,7 +60,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #ifdef HAVE_SNMP #include "bgpd/bgp_snmp.h" #endif /* HAVE_SNMP */ - + /* BGP process wide configuration. */ static struct bgp_master bgp_master; @@ -71,7 +71,7 @@ struct bgp_master *bm; /* BGP community-list. */ struct community_list_handler *bgp_clist; - + /* BGP global flag manipulation. */ int bgp_option_set (int flag) @@ -113,7 +113,7 @@ bgp_option_check (int flag) { return CHECK_FLAG (bm->options, flag); } - + /* BGP flag manipulation. */ int bgp_flag_set (struct bgp *bgp, int flag) @@ -134,7 +134,7 @@ bgp_flag_check (struct bgp *bgp, int flag) { return CHECK_FLAG (bgp->flags, flag); } - + /* Internal function to set BGP structure configureation flag. */ static void bgp_config_set (struct bgp *bgp, int config) @@ -153,7 +153,7 @@ bgp_config_check (struct bgp *bgp, int config) { return CHECK_FLAG (bgp->config, config); } - + /* Set BGP router identifier. */ int bgp_router_id_set (struct bgp *bgp, struct in_addr *id) @@ -240,12 +240,12 @@ bgp_cluster_id_unset (struct bgp *bgp) } return 0; } - + /* BGP timer configuration. */ int bgp_timers_set (struct bgp *bgp, u_int32_t keepalive, u_int32_t holdtime) { - bgp->default_keepalive = (keepalive < holdtime / 3 + bgp->default_keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3); bgp->default_holdtime = holdtime; @@ -260,7 +260,7 @@ bgp_timers_unset (struct bgp *bgp) return 0; } - + /* BGP confederation configuration. */ int bgp_confederation_id_set (struct bgp *bgp, as_t as) @@ -331,7 +331,7 @@ bgp_confederation_id_unset (struct bgp *bgp) bgp->confed_id = 0; bgp_config_unset (bgp, BGP_CONFIG_CONFEDERATION); - + for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) { /* We're looking for peers who's AS is not local */ @@ -364,7 +364,7 @@ bgp_confederation_peers_check (struct bgp *bgp, as_t as) for (i = 0; i < bgp->confed_peers_cnt; i++) if (bgp->confed_peers[i] == as) return 1; - + return 0; } @@ -385,11 +385,11 @@ bgp_confederation_peers_add (struct bgp *bgp, as_t as) return -1; if (bgp->confed_peers) - bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST, + bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST, bgp->confed_peers, (bgp->confed_peers_cnt + 1) * sizeof (as_t)); else - bgp->confed_peers = XMALLOC (MTYPE_BGP_CONFED_LIST, + bgp->confed_peers = XMALLOC (MTYPE_BGP_CONFED_LIST, (bgp->confed_peers_cnt + 1) * sizeof (as_t)); bgp->confed_peers[bgp->confed_peers_cnt] = as; @@ -472,7 +472,7 @@ bgp_confederation_peers_remove (struct bgp *bgp, as_t as) return 0; } - + /* Local preference configuration. */ int bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref) @@ -495,7 +495,7 @@ bgp_default_local_preference_unset (struct bgp *bgp) return 0; } - + /* If peer is RSERVER_CLIENT in at least one address family and is not member of a peer_group for that family, return 1. Used to check wether the peer is included in list bgp->rsclient. */ @@ -544,11 +544,7 @@ peer_af_flag_reset (struct peer *peer, afi_t afi, safi_t safi) 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; - } + prefix_list_unset_ref(&filter->plist[i].ref) ; if (filter->aslist[i].name) { free (filter->aslist[i].name); @@ -651,9 +647,9 @@ peer_sort (struct peer *peer) struct peer *peer1; peer1 = listnode_head (peer->group->peer); if (peer1) - return (peer1->local_as == peer1->as + return (peer1->local_as == peer1->as ? BGP_PEER_IBGP : BGP_PEER_EBGP); - } + } return BGP_PEER_INTERNAL; } @@ -692,44 +688,44 @@ peer_free (struct peer *peer) bgp_unlock(peer->bgp); /* this /ought/ to have been done already through bgp_stop earlier, - * but just to be sure.. + * but just to be sure.. */ bgp_timer_set (peer); BGP_READ_OFF (peer->t_read); BGP_WRITE_OFF (peer->t_write); BGP_EVENT_FLUSH (peer); - + if (peer->desc) XFREE (MTYPE_PEER_DESC, peer->desc); - + /* Free allocated host character. */ if (peer->host) XFREE (MTYPE_BGP_PEER_HOST, peer->host); - + /* Update source configuration. */ if (peer->update_source) sockunion_free (peer->update_source); - + if (peer->update_if) XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if); - + if (peer->clear_node_queue) work_queue_free (peer->clear_node_queue); - + bgp_sync_delete (peer); memset (peer, 0, sizeof (struct peer)); - + XFREE (MTYPE_BGP_PEER, peer); } - + /* increase reference count on a struct peer */ struct peer * peer_lock (struct peer *peer) { assert (peer && (peer->lock >= 0)); - + peer->lock++; - + return peer; } @@ -740,9 +736,9 @@ struct peer * peer_unlock (struct peer *peer) { assert (peer && (peer->lock > 0)); - + peer->lock--; - + if (peer->lock == 0) { #if 0 @@ -763,7 +759,7 @@ peer_unlock (struct peer *peer) return peer; } - + /* Allocate new peer object, implicitely locked. */ static struct peer * peer_new (struct bgp *bgp) @@ -772,12 +768,12 @@ peer_new (struct bgp *bgp) safi_t safi; struct peer *peer; struct servent *sp; - + /* bgp argument is absolutely required */ assert (bgp); if (!bgp) return NULL; - + /* Allocate new peer. */ peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer)); @@ -841,7 +837,7 @@ peer_create (union sockunion *su, struct bgp *bgp, as_t local_as, peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; else peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; - + peer = peer_lock (peer); /* bgp peer list reference */ listnode_add_sort (bgp->peer, peer); @@ -877,7 +873,7 @@ peer_create_accept (struct bgp *bgp) struct peer *peer; peer = peer_new (bgp); - + peer = peer_lock (peer); /* bgp peer list reference */ listnode_add_sort (bgp->peer, peer); @@ -997,20 +993,20 @@ peer_remote_as (struct bgp *bgp, union sockunion *su, as_t *as, /* 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_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); + peer = peer_create (su, bgp, local_as, *as, 0, 0); else - peer = peer_create (su, bgp, local_as, *as, afi, safi); + peer = peer_create (su, bgp, local_as, *as, afi, safi); } return 0; @@ -1095,7 +1091,7 @@ peer_deactivate (struct peer *peer, afi_t afi, safi_t safi) 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_RCV)) @@ -1179,7 +1175,7 @@ peer_delete (struct peer *peer) struct listnode *pn; assert (peer->status != Deleted); - + bgp = peer->bgp; if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)) @@ -1196,7 +1192,7 @@ peer_delete (struct 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. @@ -1214,9 +1210,9 @@ peer_delete (struct peer *peer) if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) bgp_md5_set (peer); } - + bgp_timer_set (peer); /* stops all timers for Deleted */ - + /* Delete from all peer list. */ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP) && (pn = listnode_lookup (bgp->peer, peer))) @@ -1224,7 +1220,7 @@ peer_delete (struct peer *peer) peer_unlock (peer); /* bgp peer list reference */ list_delete_node (bgp->peer, pn); } - + if (peer_rsclient_active (peer) && (pn = listnode_lookup (bgp->rsclient, peer))) { @@ -1262,7 +1258,7 @@ peer_delete (struct peer *peer) if (peer->su_remote) sockunion_free (peer->su_remote); peer->su_local = peer->su_remote = NULL; - + /* Free filter related memory. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) @@ -1273,13 +1269,10 @@ peer_delete (struct peer *peer) { 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); - filter->dlist[i].name = NULL; - filter->plist[i].name = NULL; + prefix_list_unset_ref(&filter->plist[i].ref) ; filter->aslist[i].name = NULL; } for (i = RMAP_IN; i < RMAP_MAX; i++) @@ -1294,16 +1287,16 @@ peer_delete (struct peer *peer) if (peer->default_rmap[afi][safi].name) free (peer->default_rmap[afi][safi].name); - + filter->usmap.name = NULL; peer->default_rmap[afi][safi].name = NULL; } - + peer_unlock (peer); /* initial reference */ return 0; } - + static int peer_group_cmp (struct peer_group *g1, struct peer_group *g2) { @@ -1369,7 +1362,7 @@ peer_group_get (struct bgp *bgp, const char *name) group->conf->afc[AFI_IP][SAFI_UNICAST] = 1; group->conf->host = XSTRDUP (MTYPE_BGP_PEER_HOST, name); group->conf->group = group; - group->conf->as = 0; + group->conf->as = 0; group->conf->ttl = 1; group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER); @@ -1383,7 +1376,7 @@ peer_group_get (struct bgp *bgp, const char *name) return 0; } -static void +static void peer_group2peer_config_copy (struct peer_group *group, struct peer *peer, afi_t afi, safi_t safi) { @@ -1521,13 +1514,8 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer, 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 (! pfilter->plist[in].ref) + prefix_list_copy_ref(&pfilter->plist[in].ref, gfilter->plist[in].ref) ; if (gfilter->aslist[in].name && ! pfilter->aslist[in].name) { if (pfilter->aslist[in].name) @@ -1558,20 +1546,9 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer, 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; - } + + prefix_list_copy_ref(&pfilter->plist[out].ref, gfilter->plist[out].ref) ; + if (gfilter->aslist[out].name) { if (pfilter->aslist[out].name) @@ -1638,7 +1615,7 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer, pfilter->usmap.name = NULL; pfilter->usmap.map = NULL; } -} +} /* Peer group's remote AS configuration. */ int @@ -1784,7 +1761,7 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, if (! peer->group) { peer->group = group; - + peer = peer_lock (peer); /* group->peer list reference */ listnode_add (group->peer, peer); } @@ -1814,7 +1791,7 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)) { struct listnode *pn; - + /* If it's not configured as RSERVER_CLIENT in any other address family, without being member of a peer_group, remove it from list bgp->rsclient.*/ @@ -1904,7 +1881,7 @@ peer_group_unbind (struct bgp *bgp, struct peer *peer, return 0; } - + /* BGP instance creation by `router bgp' commands. */ static struct bgp * bgp_create (as_t *as, const char *name) @@ -1915,7 +1892,7 @@ bgp_create (as_t *as, const char *name) if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL) return NULL; - + bgp_lock (bgp); bgp->peer_self = peer_new (bgp); bgp->peer_self->host = XSTRDUP (MTYPE_BGP_PEER_HOST, "Static announcement"); @@ -1969,7 +1946,7 @@ bgp_lookup (as_t as, const char *name) for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp)) if (bgp->as == as - && ((bgp->name == NULL && name == NULL) + && ((bgp->name == NULL && name == NULL) || (bgp->name && name && strcmp (bgp->name, name) == 0))) return bgp; return NULL; @@ -2067,7 +2044,7 @@ bgp_delete (struct bgp *bgp) /* Unset redistribution. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) + for (i = 0; i < ZEBRA_ROUTE_MAX; i++) if (i != ZEBRA_ROUTE_BGP) bgp_redistribute_unset (bgp, afi, i); @@ -2083,7 +2060,7 @@ bgp_delete (struct bgp *bgp) peer_delete(bgp->peer_self); bgp->peer_self = NULL; } - + /* Remove visibility via the master list - there may however still be * routes to be processed still referencing the struct bgp. */ @@ -2092,7 +2069,7 @@ bgp_delete (struct bgp *bgp) bgp_close (); bgp_unlock(bgp); /* initial reference */ - + return 0; } @@ -2124,7 +2101,7 @@ bgp_free (struct bgp *bgp) if (bgp->name) free (bgp->name); - + for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) { @@ -2137,7 +2114,7 @@ bgp_free (struct bgp *bgp) } XFREE (MTYPE_BGP, bgp); } - + struct peer * peer_lookup (struct bgp *bgp, union sockunion *su) { @@ -2154,7 +2131,7 @@ peer_lookup (struct bgp *bgp, union sockunion *su) else if (bm->bgp != NULL) { struct listnode *bgpnode, *nbgpnode; - + for (ALL_LIST_ELEMENTS (bm->bgp, bgpnode, nbgpnode, bgp)) for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) if (sockunion_same (&peer->su, su) @@ -2206,7 +2183,7 @@ peer_lookup_with_open (union sockunion *su, as_t remote_as, } return NULL; } - + /* If peer is configured at least one address family return 1. */ int peer_active (struct peer *peer) @@ -2232,7 +2209,7 @@ peer_active_nego (struct peer *peer) return 1; return 0; } - + /* peer_flag_change_type. */ enum peer_change_type { @@ -2428,7 +2405,7 @@ peer_flag_modify (struct peer *peer, u_int32_t flag, int set) /* No flag action is found. */ if (! found) - return BGP_ERR_INVALID_FLAG; + return BGP_ERR_INVALID_FLAG; /* Not for peer-group member. */ if (action.not_for_member && peer_group_active (peer)) @@ -2463,7 +2440,7 @@ peer_flag_modify (struct peer *peer, u_int32_t flag, int set) SET_FLAG (peer->flags, flag); else UNSET_FLAG (peer->flags, flag); - + if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { if (action.type == peer_change_reset) @@ -2526,12 +2503,12 @@ peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag, memset (&action, 0, sizeof (struct peer_flag_action)); size = sizeof peer_af_flag_action_list / sizeof (struct peer_flag_action); - + found = peer_flag_action_set (peer_af_flag_action_list, size, &action, flag); - + /* No flag action is found. */ if (! found) - return BGP_ERR_INVALID_FLAG; + return BGP_ERR_INVALID_FLAG; /* Adress family must be activated. */ if (! peer->afc[afi][safi]) @@ -2597,7 +2574,7 @@ peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag, if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { group = peer->group; - + for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) { if (! peer->af_group[afi][safi]) @@ -2648,7 +2625,7 @@ peer_af_flag_unset (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag) { return peer_af_flag_modify (peer, afi, safi, flag, 0); } - + /* EBGP multihop configuration. */ int peer_ebgp_multihop_set (struct peer *peer, int ttl) @@ -2711,14 +2688,14 @@ peer_ebgp_multihop_unset (struct peer *peer) continue; peer->ttl = 1; - + if (peer->fd >= 0) sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); } } return 0; } - + /* Neighbor description. */ int peer_description_set (struct peer *peer, char *desc) @@ -2741,7 +2718,7 @@ peer_description_unset (struct peer *peer) return 0; } - + /* Neighbor update-source. */ int peer_update_source_if_set (struct peer *peer, const char *ifname) @@ -2914,7 +2891,7 @@ peer_update_source_unset (struct peer *peer) peer->update_source = su; } else if (group->conf->update_if) - peer->update_if = + peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if); } @@ -2961,7 +2938,7 @@ peer_update_source_unset (struct peer *peer) } return 0; } - + int peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi, const char *rmap) @@ -2980,7 +2957,7 @@ peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi, if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE) || (rmap && ! peer->default_rmap[afi][safi].name) || (rmap && strcmp (rmap, peer->default_rmap[afi][safi].name) != 0)) - { + { SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE); if (rmap) @@ -3034,7 +3011,7 @@ peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi) return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)) - { + { UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE); if (peer->default_rmap[afi][safi].name) @@ -3066,7 +3043,7 @@ peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi) } return 0; } - + int peer_port_set (struct peer *peer, u_int16_t port) { @@ -3080,7 +3057,7 @@ peer_port_unset (struct peer *peer) peer->port = BGP_PORT_DEFAULT; return 0; } - + /* neighbor weight. */ int peer_weight_set (struct peer *peer, u_int16_t weight) @@ -3128,7 +3105,7 @@ peer_weight_unset (struct peer *peer) } return 0; } - + int peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime) { @@ -3198,7 +3175,7 @@ peer_timers_unset (struct peer *peer) return 0; } - + int peer_timers_connect_set (struct peer *peer, u_int32_t connect) { @@ -3233,7 +3210,7 @@ peer_timers_connect_unset (struct peer *peer) return 0; } - + int peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv) { @@ -3263,10 +3240,10 @@ peer_advertise_interval_unset (struct peer *peer) peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV; else peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; - + return 0; } - + /* neighbor interface */ int peer_interface_set (struct peer *peer, const char *str) @@ -3287,7 +3264,7 @@ peer_interface_unset (struct peer *peer) return 0; } - + /* Allow-as in. */ int peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num) @@ -3317,7 +3294,7 @@ peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num) SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN); peer_change_action (peer, afi, safi, peer_change_reset_in); } - + } return 0; } @@ -3348,7 +3325,7 @@ peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi) } return 0; } - + int peer_local_as_set (struct peer *peer, as_t as, int no_prepend) { @@ -3459,7 +3436,7 @@ peer_local_as_unset (struct peer *peer) } return 0; } - + /* Set password for authenticating with the peer. */ int peer_password_set (struct peer *peer, const char *password) @@ -3477,7 +3454,7 @@ peer_password_set (struct peer *peer, const char *password) if (peer->password) XFREE (MTYPE_PEER_PASSWORD, peer->password); - + peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, password); if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) @@ -3486,7 +3463,7 @@ peer_password_set (struct peer *peer, const char *password) bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else BGP_EVENT_ADD (peer, BGP_Stop); - + return (bgp_md5_set (peer) >= 0) ? BGP_SUCCESS : BGP_ERR_TCPSIG_FAILED; } @@ -3494,17 +3471,17 @@ peer_password_set (struct peer *peer, const char *password) { if (peer->password && strcmp (peer->password, password) == 0) continue; - + if (peer->password) XFREE (MTYPE_PEER_PASSWORD, peer->password); - + peer->password = XSTRDUP(MTYPE_PEER_PASSWORD, password); if (peer->status == Established) bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else BGP_EVENT_ADD (peer, BGP_Stop); - + if (bgp_md5_set (peer) < 0) ret = BGP_ERR_TCPSIG_FAILED; } @@ -3535,9 +3512,9 @@ peer_password_unset (struct peer *peer) if (peer->password) XFREE (MTYPE_PEER_PASSWORD, peer->password); - + peer->password = NULL; - + bgp_md5_set (peer); return 0; @@ -3555,7 +3532,7 @@ peer_password_unset (struct peer *peer) bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); else BGP_EVENT_ADD (peer, BGP_Stop); - + XFREE (MTYPE_PEER_PASSWORD, peer->password); peer->password = NULL; @@ -3564,10 +3541,10 @@ peer_password_unset (struct peer *peer) return 0; } - + /* Set distribute list to the peer. */ int -peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct, +peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct, const char *name) { struct bgp_filter *filter; @@ -3585,7 +3562,7 @@ peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct, filter = &peer->filter[afi][safi]; - if (filter->plist[direct].name) + if (filter->plist[direct].ref) return BGP_ERR_PEER_FILTER_CONFLICT; if (filter->dlist[direct].name) @@ -3698,7 +3675,7 @@ peer_distribute_update (struct access_list *access) for (direct = FILTER_IN; direct < FILTER_MAX; direct++) { if (filter->dlist[direct].name) - filter->dlist[direct].alist = + filter->dlist[direct].alist = access_list_lookup (afi, filter->dlist[direct].name); else filter->dlist[direct].alist = NULL; @@ -3715,7 +3692,7 @@ peer_distribute_update (struct access_list *access) for (direct = FILTER_IN; direct < FILTER_MAX; direct++) { if (filter->dlist[direct].name) - filter->dlist[direct].alist = + filter->dlist[direct].alist = access_list_lookup (afi, filter->dlist[direct].name); else filter->dlist[direct].alist = NULL; @@ -3724,15 +3701,16 @@ peer_distribute_update (struct access_list *access) } } } - + /* Set prefix list to the peer. */ int -peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct, +peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct, const char *name) { struct bgp_filter *filter; struct peer_group *group; struct listnode *node, *nnode; + prefix_list_ref ref ; if (! peer->afc[afi][safi]) return BGP_ERR_PEER_INACTIVE; @@ -3748,10 +3726,7 @@ peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct, if (filter->dlist[direct].name) return BGP_ERR_PEER_FILTER_CONFLICT; - if (filter->plist[direct].name) - free (filter->plist[direct].name); - filter->plist[direct].name = strdup (name); - filter->plist[direct].plist = prefix_list_lookup (afi, name); + ref = prefix_list_set_ref(&filter->plist[direct].ref, afi, name) ; if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) return 0; @@ -3764,10 +3739,7 @@ peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct, if (! peer->af_group[afi][safi]) continue; - if (filter->plist[direct].name) - free (filter->plist[direct].name); - filter->plist[direct].name = strdup (name); - filter->plist[direct].plist = prefix_list_lookup (afi, name); + prefix_list_copy_ref(&filter->plist[direct].ref, ref) ; } return 0; } @@ -3796,20 +3768,15 @@ peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct) { gfilter = &peer->group->conf->filter[afi][safi]; - if (gfilter->plist[direct].name) + if (gfilter->plist[direct].ref) { - if (filter->plist[direct].name) - free (filter->plist[direct].name); - filter->plist[direct].name = strdup (gfilter->plist[direct].name); - filter->plist[direct].plist = gfilter->plist[direct].plist; + prefix_list_copy_ref(&filter->plist[direct].ref, + gfilter->plist[direct].ref) ; return 0; } } - if (filter->plist[direct].name) - free (filter->plist[direct].name); - filter->plist[direct].name = NULL; - filter->plist[direct].plist = NULL; + prefix_list_unset_ref(&filter->plist[direct].ref) ; if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) return 0; @@ -3822,10 +3789,7 @@ peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct) if (! peer->af_group[afi][safi]) continue; - if (filter->plist[direct].name) - free (filter->plist[direct].name); - filter->plist[direct].name = NULL; - filter->plist[direct].plist = NULL; + prefix_list_unset_ref(&filter->plist[direct].ref) ; } return 0; @@ -3835,55 +3799,15 @@ peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct) static void peer_prefix_list_update (struct prefix_list *plist) { - struct listnode *mnode, *mnnode; - struct listnode *node, *nnode; - struct bgp *bgp; - struct peer *peer; - struct peer_group *group; - struct bgp_filter *filter; - afi_t afi; - safi_t safi; - int direct; - - for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp)) - { - for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) - { - for (afi = AFI_IP; afi < AFI_MAX; afi++) - for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) - { - filter = &peer->filter[afi][safi]; - - for (direct = FILTER_IN; direct < FILTER_MAX; direct++) - { - if (filter->plist[direct].name) - filter->plist[direct].plist = - prefix_list_lookup (afi, filter->plist[direct].name); - else - filter->plist[direct].plist = NULL; - } - } - } - for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group)) - { - for (afi = AFI_IP; afi < AFI_MAX; afi++) - for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) - { - filter = &group->conf->filter[afi][safi]; - - for (direct = FILTER_IN; direct < FILTER_MAX; direct++) - { - if (filter->plist[direct].name) - filter->plist[direct].plist = - prefix_list_lookup (afi, filter->plist[direct].name); - else - filter->plist[direct].plist = NULL; - } - } - } - } + /* This function used to fix up the addresses of prefix lists whenever + * a prefix list was changed. That is now done by the symbol reference + * mechanism. + * + * This function could have a use in updating a peer when a prefix list + * is changed ? + */ } - + int peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct, const char *name) @@ -4011,7 +3935,7 @@ peer_aslist_update (void) for (direct = FILTER_IN; direct < FILTER_MAX; direct++) { if (filter->aslist[direct].name) - filter->aslist[direct].aslist = + filter->aslist[direct].aslist = as_list_lookup (filter->aslist[direct].name); else filter->aslist[direct].aslist = NULL; @@ -4028,7 +3952,7 @@ peer_aslist_update (void) for (direct = FILTER_IN; direct < FILTER_MAX; direct++) { if (filter->aslist[direct].name) - filter->aslist[direct].aslist = + filter->aslist[direct].aslist = as_list_lookup (filter->aslist[direct].name); else filter->aslist[direct].aslist = NULL; @@ -4037,10 +3961,10 @@ peer_aslist_update (void) } } } - + /* Set route-map to the peer. */ int -peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct, +peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct, const char *name) { struct bgp_filter *filter; @@ -4062,7 +3986,7 @@ peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct, if (filter->map[direct].name) free (filter->map[direct].name); - + filter->map[direct].name = strdup (name); filter->map[direct].map = route_map_lookup_by_name (name); @@ -4145,10 +4069,10 @@ peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct) } return 0; } - + /* Set unsuppress-map to the peer. */ int -peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi, +peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi, const char *name) { struct bgp_filter *filter; @@ -4160,12 +4084,12 @@ peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi, if (peer_is_group_member (peer, afi, safi)) return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; - + filter = &peer->filter[afi][safi]; if (filter->usmap.name) free (filter->usmap.name); - + filter->usmap.name = strdup (name); filter->usmap.map = route_map_lookup_by_name (name); @@ -4198,7 +4122,7 @@ peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi) if (! peer->afc[afi][safi]) return BGP_ERR_PEER_INACTIVE; - + if (peer_is_group_member (peer, afi, safi)) return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER; @@ -4227,7 +4151,7 @@ peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi) } return 0; } - + int peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t max, u_char threshold, @@ -4322,7 +4246,7 @@ peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi) } return 0; } - + int peer_clear (struct peer *peer) { @@ -4387,7 +4311,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi, else prefix_type = ORF_TYPE_PREFIX_OLD; - if (filter->plist[FILTER_IN].plist) + if (filter->plist[FILTER_IN].ref) { if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND)) bgp_route_refresh_send (peer, afi, safi, @@ -4427,7 +4351,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi, } return 0; } - + /* Display peer uptime.*/ /* XXX: why does this function return char * when it takes buffer? */ char * @@ -4441,7 +4365,7 @@ peer_uptime (time_t uptime2, char *buf, size_t len) { zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len); /* XXX: should return status instead of buf... */ - snprintf (buf, len, "<error> "); + snprintf (buf, len, "<error> "); return buf; } @@ -4462,17 +4386,17 @@ peer_uptime (time_t uptime2, char *buf, size_t len) #define ONE_WEEK_SECOND 60*60*24*7 if (uptime1 < ONE_DAY_SECOND) - snprintf (buf, len, "%02d:%02d:%02d", + snprintf (buf, len, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); else if (uptime1 < ONE_WEEK_SECOND) - snprintf (buf, len, "%dd%02dh%02dm", + snprintf (buf, len, "%dd%02dh%02dm", tm->tm_yday, tm->tm_hour, tm->tm_min); else - snprintf (buf, len, "%02dw%dd%02dh", + snprintf (buf, len, "%02dw%dd%02dh", tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); return buf; } - + static void bgp_config_write_filter (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) @@ -4492,30 +4416,31 @@ bgp_config_write_filter (struct vty *vty, struct peer *peer, if (filter->dlist[in].name) if (! gfilter || ! gfilter->dlist[in].name || strcmp (filter->dlist[in].name, gfilter->dlist[in].name) != 0) - vty_out (vty, " neighbor %s distribute-list %s in%s", addr, + vty_out (vty, " neighbor %s distribute-list %s in%s", addr, filter->dlist[in].name, VTY_NEWLINE); if (filter->dlist[out].name && ! gfilter) - vty_out (vty, " neighbor %s distribute-list %s out%s", addr, + vty_out (vty, " neighbor %s distribute-list %s out%s", addr, filter->dlist[out].name, VTY_NEWLINE); /* prefix-list. */ - if (filter->plist[in].name) - if (! gfilter || ! gfilter->plist[in].name - || strcmp (filter->plist[in].name, gfilter->plist[in].name) != 0) - vty_out (vty, " neighbor %s prefix-list %s in%s", addr, - filter->plist[in].name, VTY_NEWLINE); - if (filter->plist[out].name && ! gfilter) - vty_out (vty, " neighbor %s prefix-list %s out%s", addr, - filter->plist[out].name, VTY_NEWLINE); + if ( filter->plist[in].ref && (! gfilter + || (prefix_list_ref_ident(gfilter->plist[in].ref) + != prefix_list_ref_ident(filter->plist[in].ref))) ) + vty_out (vty, " neighbor %s prefix-list %s in%s", addr, + prefix_list_ref_name(filter->plist[in].ref), VTY_NEWLINE); + + if (filter->plist[out].ref && ! gfilter) + vty_out (vty, " neighbor %s prefix-list %s out%s", addr, + prefix_list_ref_name(filter->plist[out].ref), VTY_NEWLINE); /* route-map. */ if (filter->map[RMAP_IN].name) if (! gfilter || ! gfilter->map[RMAP_IN].name || strcmp (filter->map[RMAP_IN].name, gfilter->map[RMAP_IN].name) != 0) - vty_out (vty, " neighbor %s route-map %s in%s", addr, + vty_out (vty, " neighbor %s route-map %s in%s", addr, filter->map[RMAP_IN].name, VTY_NEWLINE); if (filter->map[RMAP_OUT].name && ! gfilter) - vty_out (vty, " neighbor %s route-map %s out%s", addr, + vty_out (vty, " neighbor %s route-map %s out%s", addr, filter->map[RMAP_OUT].name, VTY_NEWLINE); if (filter->map[RMAP_IMPORT].name && ! gfilter) vty_out (vty, " neighbor %s route-map %s import%s", addr, @@ -4536,10 +4461,10 @@ bgp_config_write_filter (struct vty *vty, struct peer *peer, if (filter->aslist[in].name) if (! gfilter || ! gfilter->aslist[in].name || strcmp (filter->aslist[in].name, gfilter->aslist[in].name) != 0) - vty_out (vty, " neighbor %s filter-list %s in%s", addr, + vty_out (vty, " neighbor %s filter-list %s in%s", addr, filter->aslist[in].name, VTY_NEWLINE); if (filter->aslist[out].name && ! gfilter) - vty_out (vty, " neighbor %s filter-list %s out%s", addr, + vty_out (vty, " neighbor %s filter-list %s out%s", addr, filter->aslist[out].name, VTY_NEWLINE); } @@ -4619,7 +4544,7 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp, if (peer->ifname) vty_out (vty, " neighbor %s interface %s%s", addr, peer->ifname, VTY_NEWLINE); - + /* Passive. */ if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSIVE)) if (! peer_group_active (peer) || @@ -4656,16 +4581,16 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp, /* advertisement-interval */ if (CHECK_FLAG (peer->config, PEER_CONFIG_ROUTEADV)) vty_out (vty, " neighbor %s advertisement-interval %d%s", - addr, peer->v_routeadv, VTY_NEWLINE); + addr, peer->v_routeadv, VTY_NEWLINE); /* timers. */ if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER) && ! peer_group_active (peer)) - vty_out (vty, " neighbor %s timers %d %d%s", addr, + vty_out (vty, " neighbor %s timers %d %d%s", addr, peer->keepalive, peer->holdtime, VTY_NEWLINE); if (CHECK_FLAG (peer->config, PEER_CONFIG_CONNECT)) - vty_out (vty, " neighbor %s timers connect %d%s", addr, + vty_out (vty, " neighbor %s timers connect %d%s", addr, peer->connect, VTY_NEWLINE); /* Default weight. */ @@ -4752,7 +4677,7 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp, /* Route reflector client. */ if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REFLECTOR_CLIENT) && ! peer->af_group[afi][safi]) - vty_out (vty, " neighbor %s route-reflector-client%s", addr, + vty_out (vty, " neighbor %s route-reflector-client%s", addr, VTY_NEWLINE); /* Nexthop self. */ @@ -4774,7 +4699,7 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp, if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY) && peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)) vty_out (vty, " neighbor %s send-community both%s", addr, VTY_NEWLINE); - else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)) + else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY)) vty_out (vty, " neighbor %s send-community extended%s", addr, VTY_NEWLINE); else if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY)) @@ -4862,7 +4787,7 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp, && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) vty_out (vty, " neighbor %s attribute-unchanged%s", addr, VTY_NEWLINE); else - vty_out (vty, " neighbor %s attribute-unchanged%s%s%s%s", addr, + vty_out (vty, " neighbor %s attribute-unchanged%s%s%s%s", addr, (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) ? " as-path" : "", (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) ? @@ -4895,7 +4820,7 @@ bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi, else if (afi == AFI_IP6) { vty_out (vty, "ipv6"); - + if (safi == SAFI_MULTICAST) vty_out (vty, " multicast"); } @@ -4956,14 +4881,14 @@ bgp_config_write (struct vty *vty) /* BGP Multiple instance. */ if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE)) - { + { vty_out (vty, "bgp multiple-instance%s", VTY_NEWLINE); write++; } /* BGP Config type. */ if (bgp_option_check (BGP_OPT_CONFIG_CISCO)) - { + { vty_out (vty, "bgp config-type cisco%s", VTY_NEWLINE); write++; } @@ -4990,11 +4915,11 @@ bgp_config_write (struct vty *vty) /* BGP fast-external-failover. */ if (CHECK_FLAG (bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) - vty_out (vty, " no bgp fast-external-failover%s", VTY_NEWLINE); + vty_out (vty, " no bgp fast-external-failover%s", VTY_NEWLINE); /* BGP router ID. */ if (CHECK_FLAG (bgp->config, BGP_CONFIG_ROUTER_ID)) - vty_out (vty, " bgp router-id %s%s", inet_ntoa (bgp->router_id), + vty_out (vty, " bgp router-id %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE); /* BGP log-neighbor-changes. */ @@ -5017,7 +4942,7 @@ bgp_config_write (struct vty *vty) /* BGP client-to-client reflection. */ if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT)) vty_out (vty, " no bgp client-to-client reflection%s", VTY_NEWLINE); - + /* BGP cluster ID. */ if (CHECK_FLAG (bgp->config, BGP_CONFIG_CLUSTER_ID)) vty_out (vty, " bgp cluster-id %s%s", inet_ntoa (bgp->cluster_id), @@ -5095,7 +5020,7 @@ bgp_config_write (struct vty *vty) /* BGP timers configuration. */ if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) - vty_out (vty, " timers bgp %d %d%s", bgp->default_keepalive, + vty_out (vty, " timers bgp %d %d%s", bgp->default_keepalive, bgp->default_holdtime, VTY_NEWLINE); /* peer-group */ @@ -5113,7 +5038,7 @@ bgp_config_write (struct vty *vty) /* Distance configuration. */ bgp_config_write_distance (vty, bgp); - + /* No auto-summary */ if (bgp_option_check (BGP_OPT_CONFIG_CISCO)) vty_out (vty, " no auto-summary%s", VTY_NEWLINE); @@ -5148,7 +5073,7 @@ bgp_master_init (void) bm->start_time = time (NULL); } - + void bgp_init (void) { @@ -5203,9 +5128,9 @@ bgp_terminate (void) if (peer->status == Established) bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_PEER_UNCONFIG); - + bgp_cleanup_routes (); - + if (bm->process_main_queue) { work_queue_free (bm->process_main_queue); |