frr/bgpd/bgpd.c

5165 lines
134 KiB
C
Raw Normal View History

2002-12-13 21:15:29 +01:00
/* BGP-4, BGP-4+ daemon program
Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
This file is part of GNU Zebra.
GNU Zebra is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
GNU Zebra is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Zebra; see the file COPYING. If not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include <zebra.h>
#include "prefix.h"
#include "thread.h"
#include "buffer.h"
#include "stream.h"
#include "command.h"
#include "sockunion.h"
#include "network.h"
#include "memory.h"
#include "filter.h"
#include "routemap.h"
#include "str.h"
#include "log.h"
#include "plist.h"
#include "linklist.h"
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
#include "workqueue.h"
2002-12-13 21:15:29 +01:00
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_aspath.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_dump.h"
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_regex.h"
#include "bgpd/bgp_clist.h"
#include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_packet.h"
#include "bgpd/bgp_zebra.h"
#include "bgpd/bgp_open.h"
#include "bgpd/bgp_filter.h"
#include "bgpd/bgp_nexthop.h"
#include "bgpd/bgp_damp.h"
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_advertise.h"
#include "bgpd/bgp_network.h"
#include "bgpd/bgp_vty.h"
#ifdef HAVE_SNMP
#include "bgpd/bgp_snmp.h"
#endif /* HAVE_SNMP */
/* BGP process wide configuration. */
static struct bgp_master bgp_master;
2004-10-03 20:18:34 +02:00
extern struct in_addr router_id_zebra;
2002-12-13 21:15:29 +01:00
/* BGP process wide configuration pointer to export. */
struct bgp_master *bm;
/* BGP community-list. */
struct community_list_handler *bgp_clist;
/* BGP global flag manipulation. */
int
bgp_option_set (int flag)
{
switch (flag)
{
case BGP_OPT_NO_FIB:
case BGP_OPT_MULTIPLE_INSTANCE:
case BGP_OPT_CONFIG_CISCO:
SET_FLAG (bm->options, flag);
break;
default:
return BGP_ERR_INVALID_FLAG;
}
return 0;
}
int
bgp_option_unset (int flag)
{
switch (flag)
{
case BGP_OPT_MULTIPLE_INSTANCE:
if (listcount (bm->bgp) > 1)
return BGP_ERR_MULTIPLE_INSTANCE_USED;
/* Fall through. */
case BGP_OPT_NO_FIB:
case BGP_OPT_CONFIG_CISCO:
UNSET_FLAG (bm->options, flag);
break;
default:
return BGP_ERR_INVALID_FLAG;
}
return 0;
}
int
bgp_option_check (int flag)
{
return CHECK_FLAG (bm->options, flag);
}
/* BGP flag manipulation. */
int
bgp_flag_set (struct bgp *bgp, int flag)
{
SET_FLAG (bgp->flags, flag);
return 0;
}
int
bgp_flag_unset (struct bgp *bgp, int flag)
{
UNSET_FLAG (bgp->flags, flag);
return 0;
}
int
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)
{
SET_FLAG (bgp->config, config);
}
static void
bgp_config_unset (struct bgp *bgp, int config)
{
UNSET_FLAG (bgp->config, config);
}
static int
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)
{
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (bgp_config_check (bgp, BGP_CONFIG_ROUTER_ID)
&& IPV4_ADDR_SAME (&bgp->router_id, id))
return 0;
IPV4_ADDR_COPY (&bgp->router_id, id);
bgp_config_set (bgp, BGP_CONFIG_ROUTER_ID);
/* Set all peer's local identifier with this value. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
IPV4_ADDR_COPY (&peer->local_id, id);
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_RID_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
}
return 0;
}
/* BGP's cluster-id control. */
int
bgp_cluster_id_set (struct bgp *bgp, struct in_addr *cluster_id)
{
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID)
&& IPV4_ADDR_SAME (&bgp->cluster_id, cluster_id))
return 0;
IPV4_ADDR_COPY (&bgp->cluster_id, cluster_id);
bgp_config_set (bgp, BGP_CONFIG_CLUSTER_ID);
/* Clear all IBGP peer. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (peer_sort (peer) != BGP_PEER_IBGP)
continue;
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_CLID_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
}
return 0;
}
int
bgp_cluster_id_unset (struct bgp *bgp)
{
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! bgp_config_check (bgp, BGP_CONFIG_CLUSTER_ID))
return 0;
bgp->cluster_id.s_addr = 0;
bgp_config_unset (bgp, BGP_CONFIG_CLUSTER_ID);
/* Clear all IBGP peer. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (peer_sort (peer) != BGP_PEER_IBGP)
continue;
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_CLID_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
}
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
? keepalive : holdtime / 3);
bgp->default_holdtime = holdtime;
return 0;
}
int
bgp_timers_unset (struct bgp *bgp)
{
bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
return 0;
}
/* BGP confederation configuration. */
int
bgp_confederation_id_set (struct bgp *bgp, as_t as)
{
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
int already_confed;
if (as == 0)
return BGP_ERR_INVALID_AS;
/* Remember - were we doing confederation before? */
already_confed = bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION);
bgp->confed_id = as;
bgp_config_set (bgp, BGP_CONFIG_CONFEDERATION);
/* If we were doing confederation already, this is just an external
AS change. Just Reset EBGP sessions, not CONFED sessions. If we
were not doing confederation before, reset all EBGP sessions. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
/* We're looking for peers who's AS is not local or part of our
confederation. */
if (already_confed)
{
if (peer_sort (peer) == BGP_PEER_EBGP)
{
peer->local_as = as;
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
}
else
{
/* Not doign confederation before, so reset every non-local
session */
if (peer_sort (peer) != BGP_PEER_IBGP)
{
/* Reset the local_as to be our EBGP one */
if (peer_sort (peer) == BGP_PEER_EBGP)
peer->local_as = as;
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
}
}
return 0;
}
int
bgp_confederation_id_unset (struct bgp *bgp)
{
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
bgp->confed_id = 0;
bgp_config_unset (bgp, BGP_CONFIG_CONFEDERATION);
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
/* We're looking for peers who's AS is not local */
if (peer_sort (peer) != BGP_PEER_IBGP)
{
peer->local_as = bgp->as;
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
}
return 0;
}
/* Is an AS part of the confed or not? */
int
bgp_confederation_peers_check (struct bgp *bgp, as_t as)
{
int i;
if (! bgp)
return 0;
for (i = 0; i < bgp->confed_peers_cnt; i++)
if (bgp->confed_peers[i] == as)
return 1;
return 0;
}
/* Add an AS to the confederation set. */
int
bgp_confederation_peers_add (struct bgp *bgp, as_t as)
{
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! bgp)
return BGP_ERR_INVALID_BGP;
if (bgp->as == as)
return BGP_ERR_INVALID_AS;
if (bgp_confederation_peers_check (bgp, as))
return -1;
if (bgp->confed_peers)
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_cnt + 1) * sizeof (as_t));
bgp->confed_peers[bgp->confed_peers_cnt] = as;
bgp->confed_peers_cnt++;
if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
{
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (peer->as == as)
{
peer->local_as = bgp->as;
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
}
}
return 0;
}
/* Delete an AS from the confederation set. */
int
bgp_confederation_peers_remove (struct bgp *bgp, as_t as)
{
int i;
int j;
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! bgp)
return -1;
if (! bgp_confederation_peers_check (bgp, as))
return -1;
for (i = 0; i < bgp->confed_peers_cnt; i++)
if (bgp->confed_peers[i] == as)
for(j = i + 1; j < bgp->confed_peers_cnt; j++)
bgp->confed_peers[j - 1] = bgp->confed_peers[j];
bgp->confed_peers_cnt--;
if (bgp->confed_peers_cnt == 0)
{
if (bgp->confed_peers)
XFREE (MTYPE_BGP_CONFED_LIST, bgp->confed_peers);
bgp->confed_peers = NULL;
}
else
bgp->confed_peers = XREALLOC (MTYPE_BGP_CONFED_LIST,
bgp->confed_peers,
bgp->confed_peers_cnt * sizeof (as_t));
/* Now reset any peer who's remote AS has just been removed from the
CONFED */
if (bgp_config_check (bgp, BGP_CONFIG_CONFEDERATION))
{
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (peer->as == as)
{
peer->local_as = bgp->confed_id;
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_CONFED_PEER_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
}
}
return 0;
}
/* Local preference configuration. */
int
bgp_default_local_preference_set (struct bgp *bgp, u_int32_t local_pref)
{
if (! bgp)
return -1;
bgp->default_local_pref = local_pref;
return 0;
}
int
bgp_default_local_preference_unset (struct bgp *bgp)
{
if (! bgp)
return -1;
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
return 0;
}
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
/* 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. */
int
peer_rsclient_active (struct peer *peer)
{
int i;
int j;
for (i=AFI_IP; i < AFI_MAX; i++)
for (j=SAFI_UNICAST; j < SAFI_MAX; j++)
if (CHECK_FLAG(peer->af_flags[i][j], PEER_FLAG_RSERVER_CLIENT)
&& ! peer->af_group[i][j])
return 1;
return 0;
}
/* Peer comparison function for sorting. */
2002-12-13 21:15:29 +01:00
static int
peer_cmp (struct peer *p1, struct peer *p2)
{
return sockunion_cmp (&p1->su, &p2->su);
2002-12-13 21:15:29 +01:00
}
int
peer_af_flag_check (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
{
return CHECK_FLAG (peer->af_flags[afi][safi], flag);
}
/* Reset all address family specific configuration. */
static void
peer_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;
}
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
}
for (i = RMAP_IN; i < RMAP_MAX; i++)
{
2002-12-13 21:15:29 +01:00
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;
2002-12-13 21:15:29 +01:00
}
/* peer global config reset */
static void
2002-12-13 21:15:29 +01:00
peer_global_config_reset (struct peer *peer)
{
peer->weight = 0;
peer->change_local_as = 0;
peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1);
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;
}
if (peer_sort (peer) == BGP_PEER_IBGP)
peer->v_routeadv = BGP_DEFAULT_IBGP_ROUTEADV;
else
peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
peer->flags = 0;
peer->config = 0;
peer->holdtime = 0;
peer->keepalive = 0;
peer->connect = 0;
peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
}
/* Check peer's AS number and determin is this peer IBGP or EBGP */
int
peer_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);
}
}
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
static inline void
peer_free (struct peer *peer)
{
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
assert (peer->status == Deleted);
/* this /ought/ to have been done already through bgp_stop earlier,
* 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);
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
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);
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
bgp_sync_delete (peer);
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
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));
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
assert (peer->status != Deleted);
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
peer->lock++;
return peer;
}
/* decrease reference count on a struct peer
* struct peer is freed and NULL returned if last reference
*/
struct peer *
peer_unlock (struct peer *peer)
{
assert (peer && (peer->lock > 0));
peer->lock--;
if (peer->lock == 0)
{
#if 0
zlog_debug ("unlocked and freeing");
zlog_backtrace (LOG_DEBUG);
#endif
peer_free (peer);
return NULL;
}
#if 0
if (peer->lock == 1)
{
zlog_debug ("unlocked to 1");
zlog_backtrace (LOG_DEBUG);
}
#endif
return peer;
}
/* Allocate new peer object, implicitely locked. */
2002-12-13 21:15:29 +01:00
static struct peer *
peer_new (struct bgp *bgp)
2002-12-13 21:15:29 +01:00
{
afi_t afi;
safi_t safi;
struct peer *peer;
struct servent *sp;
/* bgp argument is absolutely required */
assert (bgp);
if (!bgp)
return NULL;
2002-12-13 21:15:29 +01:00
/* Allocate new peer. */
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer));
2002-12-13 21:15:29 +01:00
/* Set default value. */
peer->fd = -1;
2002-12-13 21:15:29 +01:00
peer->v_start = BGP_INIT_START_TIMER;
peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
peer->v_asorig = BGP_DEFAULT_ASORIGINATE;
peer->status = Idle;
peer->ostatus = Idle;
peer->weight = 0;
[bgpd] TCP-MD5: password vty configuration and initial Linux support 2008-07-21 Paul Jakma <paul.jakma@sun.com> * bgp_packet.c: (bgp_open_receive) fix warning in a zlog call * bgp_vty.c: (bgp_vty_return) add return code * bgpd.c: (bgp_master_init) setup the socket list. * bgp_network.c: Remove the dual IPv4/6 socket thing for now, which was implemented by Michael, until such time as its clear its required for Linux (see sockopt comments). IPv6 support, including IPv4 sessions on AF_INET6 sockets, therefore is broken, and the '-l 0.0.0.0' arguments would need to be given to bgpd to make things work here. 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Tomohiko Kusuda <kusuda@inetcore.com> Leigh Brown <leigh@solinno.co.uk> * bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5 sockopt and bgpd. (bgp_md5_set_socket) Helper for bgp_connect (bgp_md5_set) setup TCP-MD5SIG for the given peer. (bgp_connect) call out to bgp_md5_set_socket for the outgoing connect socket. (bgp_socket) save references to the listen sockets, needed if TCP-MD5SIG is applied later or changed. * bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password' commands. * bgpd.c: (peer_{new,delete) manage TCP-MD5 password (peer_group2peer_config_copy) inherit TCP-MD5 password (peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5 passwords: applying checks, stopping peers, and trying to return errors to UI, etc. (bgp_config_write_peer) save password. Fix missing newline in writeout of neighbor ... port. 2008-07-21 Paul Jakma <paul.jakma@sun.com> * sockunion.c: ifdef out various places that converted v4mapped sockets to pure v4. Doesn't seem necessary at all, presumably a workaround for now historical inet_ntop bugs (?) 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> * sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
peer->password = NULL;
peer->bgp = bgp;
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
peer = peer_lock (peer); /* initial reference */
2002-12-13 21:15:29 +01:00
/* 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. */
static struct peer *
2002-12-13 21:15:29 +01:00
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 (bgp);
2002-12-13 21:15:29 +01:00
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;
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
peer = peer_lock (peer); /* bgp peer list reference */
2002-12-13 21:15:29 +01:00
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);
2002-12-13 21:15:29 +01:00
/* 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 = XSTRDUP (MTYPE_BGP_PEER_HOST, buf);
2002-12-13 21:15:29 +01:00
/* 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 (bgp);
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
peer = peer_lock (peer); /* bgp peer list reference */
listnode_add_sort (bgp->peer, peer);
return peer;
}
2002-12-13 21:15:29 +01:00
/* Change peer's AS number. */
static void
2002-12-13 21:15:29 +01:00
peer_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);
}
2002-12-13 21:15:29 +01:00
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;
2002-12-13 21:15:29 +01:00
/* 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. */
int
peer_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
{
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. */
int
peer_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 (! active && peer_active (peer))
bgp_timer_set (peer);
else
{
if (peer->status == Established)
{
if (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);
}
2002-12-13 21:15:29 +01:00
}
}
}
return 0;
}
int
peer_deactivate (struct peer *peer, afi_t afi, safi_t safi)
{
struct peer_group *group;
struct peer *peer1;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1))
2002-12-13 21:15:29 +01:00
{
if (peer1->af_group[afi][safi])
return BGP_ERR_PEER_GROUP_MEMBER_EXISTS;
}
}
else
{
if (peer->af_group[afi][safi])
return BGP_ERR_PEER_BELONGS_TO_GROUP;
}
if (! peer->afc[afi][safi])
return 0;
/* 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_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->pcount[afi][safi] = 0;
}
else
{
peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
}
else
{
peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
}
}
return 0;
}
void
peer_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_debug ("%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_debug ("%s graceful restart stalepath timer stopped", peer->host);
}
bgp_clear_route_all (peer);
}
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
/* Delete peer from confguration.
*
* The peer is moved to a dead-end "Deleted" neighbour-state, to allow
* it to "cool off" and refcounts to hit 0, at which state it is freed.
*
* This function /should/ take care to be idempotent, to guard against
* it being called multiple times through stray events that come in
* that happen to result in this function being called again. That
* said, getting here for a "Deleted" peer is a bug in the neighbour
* FSM.
*/
2002-12-13 21:15:29 +01:00
int
peer_delete (struct peer *peer)
{
int i;
afi_t afi;
safi_t safi;
struct bgp *bgp;
struct bgp_filter *filter;
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
assert (peer->status != Deleted);
2002-12-13 21:15:29 +01:00
bgp = peer->bgp;
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
peer_nsf_stop (peer);
2002-12-13 21:15:29 +01:00
/* If this peer belongs to peer group. Clearn up the
relationship. */
if (peer->group)
{
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
struct listnode *pn;
if ((pn = listnode_lookup (peer->group->peer, peer)))
{
peer = peer_unlock (peer); /* group->peer list reference */
list_delete_node (peer->group->peer, pn);
}
2002-12-13 21:15:29 +01:00
peer->group = NULL;
}
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
2002-12-13 21:15:29 +01:00
/* Withdraw all information from routing table. We can not use
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
* BGP_EVENT_ADD (peer, BGP_Stop) at here. Because the event is
* executed after peer structure is deleted.
*/
peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
2002-12-13 21:15:29 +01:00
bgp_stop (peer);
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
bgp_fsm_change_status (peer, Deleted);
[bgpd] TCP-MD5: password vty configuration and initial Linux support 2008-07-21 Paul Jakma <paul.jakma@sun.com> * bgp_packet.c: (bgp_open_receive) fix warning in a zlog call * bgp_vty.c: (bgp_vty_return) add return code * bgpd.c: (bgp_master_init) setup the socket list. * bgp_network.c: Remove the dual IPv4/6 socket thing for now, which was implemented by Michael, until such time as its clear its required for Linux (see sockopt comments). IPv6 support, including IPv4 sessions on AF_INET6 sockets, therefore is broken, and the '-l 0.0.0.0' arguments would need to be given to bgpd to make things work here. 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Tomohiko Kusuda <kusuda@inetcore.com> Leigh Brown <leigh@solinno.co.uk> * bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5 sockopt and bgpd. (bgp_md5_set_socket) Helper for bgp_connect (bgp_md5_set) setup TCP-MD5SIG for the given peer. (bgp_connect) call out to bgp_md5_set_socket for the outgoing connect socket. (bgp_socket) save references to the listen sockets, needed if TCP-MD5SIG is applied later or changed. * bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password' commands. * bgpd.c: (peer_{new,delete) manage TCP-MD5 password (peer_group2peer_config_copy) inherit TCP-MD5 password (peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5 passwords: applying checks, stopping peers, and trying to return errors to UI, etc. (bgp_config_write_peer) save password. Fix missing newline in writeout of neighbor ... port. 2008-07-21 Paul Jakma <paul.jakma@sun.com> * sockunion.c: ifdef out various places that converted v4mapped sockets to pure v4. Doesn't seem necessary at all, presumably a workaround for now historical inet_ntop bugs (?) 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> * sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
/* Password configuration */
if (peer->password)
{
XFREE (MTYPE_PEER_PASSWORD, peer->password);
peer->password = NULL;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
bgp_md5_set (peer);
}
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
bgp_timer_set (peer); /* stops all timers for Deleted */
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
2002-12-13 21:15:29 +01:00
/* Delete from all peer list. */
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
{
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
struct listnode *pn;
if ((pn = listnode_lookup (bgp->peer, peer)))
{
peer_unlock (peer); /* bgp peer list reference */
list_delete_node (bgp->peer, pn);
}
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
if (peer_rsclient_active (peer)
&& (pn = listnode_lookup (bgp->rsclient, peer)))
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
{
peer_unlock (peer); /* rsclient list reference */
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
list_delete_node (bgp->rsclient, pn);
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
}
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
}
/* Free RIB for any family in which peer is RSERVER_CLIENT, and is not
member of a peer_group. */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
if (peer->rib[afi][safi] && ! peer->af_group[afi][safi])
bgp_table_finish (&peer->rib[afi][safi]);
2002-12-13 21:15:29 +01:00
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
/* Buffers. */
2002-12-13 21:15:29 +01:00
if (peer->ibuf)
stream_free (peer->ibuf);
if (peer->obuf)
stream_fifo_free (peer->obuf);
if (peer->work)
stream_free (peer->work);
peer->obuf = NULL;
peer->work = peer->ibuf = NULL;
2002-12-13 21:15:29 +01:00
/* Local and remote addresses. */
if (peer->su_local)
sockunion_free (peer->su_local);
2002-12-13 21:15:29 +01:00
if (peer->su_remote)
sockunion_free (peer->su_remote);
peer->su_local = peer->su_remote = NULL;
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
2002-12-13 21:15:29 +01:00
/* 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);
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
filter->dlist[i].name = NULL;
filter->plist[i].name = NULL;
filter->aslist[i].name = NULL;
}
for (i = RMAP_IN; i < RMAP_MAX; i++)
{
2002-12-13 21:15:29 +01:00
if (filter->map[i].name)
free (filter->map[i].name);
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
filter->map[i].name = NULL;
2002-12-13 21:15:29 +01:00
}
if (filter->usmap.name)
free (filter->usmap.name);
if (peer->default_rmap[afi][safi].name)
free (peer->default_rmap[afi][safi].name);
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
filter->usmap.name = NULL;
peer->default_rmap[afi][safi].name = NULL;
2002-12-13 21:15:29 +01:00
}
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
peer_unlock (peer); /* initial reference */
2002-12-13 21:15:29 +01:00
return 0;
}
static int
2002-12-13 21:15:29 +01:00
peer_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. */
static int
2002-12-13 21:15:29 +01:00
peer_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));
}
static void
2002-12-13 21:15:29 +01:00
peer_group_free (struct peer_group *group)
{
XFREE (MTYPE_PEER_GROUP, group);
}
struct peer_group *
peer_group_lookup (struct bgp *bgp, const char *name)
2002-12-13 21:15:29 +01:00
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
2002-12-13 21:15:29 +01:00
{
if (strcmp (group->name, name) == 0)
return group;
}
return NULL;
}
struct peer_group *
peer_group_get (struct bgp *bgp, const char *name)
2002-12-13 21:15:29 +01:00
{
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 (bgp);
2002-12-13 21:15:29 +01:00
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->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;
}
static void
2002-12-13 21:15:29 +01:00
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;
[bgpd] TCP-MD5: password vty configuration and initial Linux support 2008-07-21 Paul Jakma <paul.jakma@sun.com> * bgp_packet.c: (bgp_open_receive) fix warning in a zlog call * bgp_vty.c: (bgp_vty_return) add return code * bgpd.c: (bgp_master_init) setup the socket list. * bgp_network.c: Remove the dual IPv4/6 socket thing for now, which was implemented by Michael, until such time as its clear its required for Linux (see sockopt comments). IPv6 support, including IPv4 sessions on AF_INET6 sockets, therefore is broken, and the '-l 0.0.0.0' arguments would need to be given to bgpd to make things work here. 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Tomohiko Kusuda <kusuda@inetcore.com> Leigh Brown <leigh@solinno.co.uk> * bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5 sockopt and bgpd. (bgp_md5_set_socket) Helper for bgp_connect (bgp_md5_set) setup TCP-MD5SIG for the given peer. (bgp_connect) call out to bgp_md5_set_socket for the outgoing connect socket. (bgp_socket) save references to the listen sockets, needed if TCP-MD5SIG is applied later or changed. * bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password' commands. * bgpd.c: (peer_{new,delete) manage TCP-MD5 password (peer_group2peer_config_copy) inherit TCP-MD5 password (peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5 passwords: applying checks, stopping peers, and trying to return errors to UI, etc. (bgp_config_write_peer) save password. Fix missing newline in writeout of neighbor ... port. 2008-07-21 Paul Jakma <paul.jakma@sun.com> * sockunion.c: ifdef out various places that converted v4mapped sockets to pure v4. Doesn't seem necessary at all, presumably a workaround for now historical inet_ntop bugs (?) 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> * sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
/* password apply */
if (peer->password)
XFREE (MTYPE_PEER_PASSWORD, peer->password);
if (conf->password)
peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, conf->password);
else
peer->password = NULL;
bgp_md5_set (peer);
2002-12-13 21:15:29 +01:00
/* maximum-prefix */
peer->pmax[afi][safi] = conf->pmax[afi][safi];
peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
peer->pmax_restart[afi][safi] = conf->pmax_restart[afi][safi];
2002-12-13 21:15:29 +01:00
/* allowas-in */
peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi];
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
/* route-server-client */
if (CHECK_FLAG(conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
{
/* Make peer's RIB point to group's RIB. */
peer->rib[afi][safi] = group->conf->rib[afi][safi];
/* Import policy. */
if (pfilter->map[RMAP_IMPORT].name)
free (pfilter->map[RMAP_IMPORT].name);
if (gfilter->map[RMAP_IMPORT].name)
{
pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
}
else
{
pfilter->map[RMAP_IMPORT].name = NULL;
pfilter->map[RMAP_IMPORT].map = NULL;
}
/* Export policy. */
if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
{
pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
}
}
2002-12-13 21:15:29 +01:00
/* 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;
}
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if (gfilter->map[RMAP_IN].name && ! pfilter->map[RMAP_IN].name)
2002-12-13 21:15:29 +01:00
{
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if (pfilter->map[RMAP_IN].name)
free (pfilter->map[RMAP_IN].name);
pfilter->map[RMAP_IN].name = strdup (gfilter->map[RMAP_IN].name);
pfilter->map[RMAP_IN].map = gfilter->map[RMAP_IN].map;
2002-12-13 21:15:29 +01:00
}
/* 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;
}
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if (gfilter->map[RMAP_OUT].name)
{
if (pfilter->map[RMAP_OUT].name)
free (pfilter->map[RMAP_OUT].name);
pfilter->map[RMAP_OUT].name = strdup (gfilter->map[RMAP_OUT].name);
pfilter->map[RMAP_OUT].map = gfilter->map[RMAP_OUT].map;
}
else
{
if (pfilter->map[RMAP_OUT].name)
free (pfilter->map[RMAP_OUT].name);
pfilter->map[RMAP_OUT].name = NULL;
pfilter->map[RMAP_OUT].map = NULL;
}
/* RS-client's import/export route-maps. */
if (gfilter->map[RMAP_IMPORT].name)
2002-12-13 21:15:29 +01:00
{
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if (pfilter->map[RMAP_IMPORT].name)
free (pfilter->map[RMAP_IMPORT].name);
pfilter->map[RMAP_IMPORT].name = strdup (gfilter->map[RMAP_IMPORT].name);
pfilter->map[RMAP_IMPORT].map = gfilter->map[RMAP_IMPORT].map;
2002-12-13 21:15:29 +01:00
}
else
{
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if (pfilter->map[RMAP_IMPORT].name)
free (pfilter->map[RMAP_IMPORT].name);
pfilter->map[RMAP_IMPORT].name = NULL;
pfilter->map[RMAP_IMPORT].map = NULL;
}
if (gfilter->map[RMAP_EXPORT].name && ! pfilter->map[RMAP_EXPORT].name)
{
if (pfilter->map[RMAP_EXPORT].name)
free (pfilter->map[RMAP_EXPORT].name);
pfilter->map[RMAP_EXPORT].name = strdup (gfilter->map[RMAP_EXPORT].name);
pfilter->map[RMAP_EXPORT].map = gfilter->map[RMAP_EXPORT].map;
2002-12-13 21:15:29 +01:00
}
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. */
int
peer_group_remote_as (struct bgp *bgp, const char *group_name, as_t *as)
2002-12-13 21:15:29 +01:00
{
struct peer_group *group;
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
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);
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (peer->as != *as)
peer_as_change (peer, *as);
}
return 0;
}
int
peer_group_delete (struct peer_group *group)
{
struct bgp *bgp;
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
bgp = group->bgp;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
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;
}
int
peer_group_remote_as_delete (struct peer_group *group)
{
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! group->conf->as)
return 0;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
peer->group = NULL;
peer_delete (peer);
}
list_delete_all_node (group->peer);
group->conf->as = 0;
return 0;
}
/* Bind specified peer to peer group. */
int
peer_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;
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
peer = peer_lock (peer); /* group->peer list reference */
2002-12-13 21:15:29 +01:00
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;
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
peer = peer_lock (peer); /* group->peer list reference */
2002-12-13 21:15:29 +01:00
listnode_add (group->peer, peer);
}
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
else
assert (group && peer->group == group);
2002-12-13 21:15:29 +01:00
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);
}
}
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
{
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
struct listnode *pn;
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
/* 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.*/
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
if (! peer_rsclient_active (peer)
&& (pn = listnode_lookup (bgp->rsclient, peer)))
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
{
peer_unlock (peer); /* peer rsclient reference */
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
list_delete_node (bgp->rsclient, pn);
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
}
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
bgp_table_finish (&peer->rib[afi][safi]);
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
/* Import policy. */
if (peer->filter[afi][safi].map[RMAP_IMPORT].name)
{
free (peer->filter[afi][safi].map[RMAP_IMPORT].name);
peer->filter[afi][safi].map[RMAP_IMPORT].name = NULL;
peer->filter[afi][safi].map[RMAP_IMPORT].map = NULL;
}
/* Export policy. */
if (! CHECK_FLAG(group->conf->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
&& peer->filter[afi][safi].map[RMAP_EXPORT].name)
{
free (peer->filter[afi][safi].map[RMAP_EXPORT].name);
peer->filter[afi][safi].map[RMAP_EXPORT].name = NULL;
peer->filter[afi][safi].map[RMAP_EXPORT].map = NULL;
}
}
2002-12-13 21:15:29 +01:00
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);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
}
int
peer_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);
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if (peer->rib[afi][safi])
peer->rib[afi][safi] = NULL;
2002-12-13 21:15:29 +01:00
if (! peer_group_active (peer))
{
[bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma <paul.jakma@sun.com> * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers.
2006-09-14 04:58:49 +02:00
assert (listnode_lookup (group->peer, peer));
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
peer_unlock (peer); /* peer group list reference */
2002-12-13 21:15:29 +01:00
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)
{
peer->last_reset = PEER_DOWN_RMAP_UNBIND;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
}
/* BGP instance creation by `router bgp' commands. */
static struct bgp *
bgp_create (as_t *as, const char *name)
2002-12-13 21:15:29 +01:00
{
struct bgp *bgp;
afi_t afi;
safi_t safi;
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL)
return NULL;
bgp->peer_self = peer_new (bgp);
bgp->peer_self->host = strdup ("Static announcement");
2002-12-13 21:15:29 +01:00
bgp->peer = list_new ();
bgp->peer->cmp = (int (*)(void *, void *)) peer_cmp;
bgp->group = list_new ();
bgp->group->cmp = (int (*)(void *, void *)) peer_group_cmp;
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
bgp->rsclient = list_new ();
bgp->rsclient->cmp = (int (*)(void*, void*)) peer_cmp;
2002-12-13 21:15:29 +01:00
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
[bgpd] Record afi/safi in bgp_table. Serialise peer clear with FSM. 2006-02-21 Paul Jakma <paul.jakma@sun.com> * bgpd.h: move the clear_node_queue to be peer specific. Add a new peer status flag, PEER_STATUS_CLEARING. * bgp_table.h: (struct bgp_table) Add fields to record afi, safi of the table. (bgp_table_init) Take afi and safi to create table for. * bgp_table.c: (bgp_table_init) record the afi and safi. * bgp_nexthop.c: Update all calls to bgp_table_init. * bgp_vty.c: ditto. * bgpd.c: ditto. * bgp_fsm.c: (bgp_timer_set) dont bring up a session which is clearing. * bgp_route.c: (general) Update all bgp_table_init calls. (bgp_process_{rsclient,main}) clear_node is serialised via PEER_STATUS_CLEARING and fsm now. (struct bgp_clear_node_queue) can be removed. struct bgp_node can be the queue item data directly, as struct peer can be kept in the new wq global user data and afi/safi can be retrieved via bgp_node -> bgp_table. (bgp_clear_route_node) fix to get peer via wq->spec.data, afi/safi via bgp_node->bgp_table. (bgp_clear_node_queue_del) no more item data to delete, only unlock the bgp_node. (bgp_clear_node_complete) only need to unset CLEARING flag and unlock struct peer. (bgp_clear_node_queue_init) queue attaches to struct peer now. record peer name as queue name. (bgp_clear_route_table) If queue transitions to active, serialise clearing by setting PEER_STATUS_CLEARING rather than plugging process queue, and lock peer while queue active. Update to pass only bgp_node as per-queue-item specific data.
2006-02-21 02:09:01 +01:00
bgp->route[afi][safi] = bgp_table_init (afi, safi);
bgp->aggregate[afi][safi] = bgp_table_init (afi, safi);
bgp->rib[afi][safi] = bgp_table_init (afi, safi);
2002-12-13 21:15:29 +01:00
}
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
bgp->default_holdtime = BGP_DEFAULT_HOLDTIME;
bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE;
bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME;
2002-12-13 21:15:29 +01:00
bgp->as = *as;
if (name)
bgp->name = strdup (name);
return bgp;
}
/* Return first entry of BGP. */
struct bgp *
bgp_get_default (void)
2002-12-13 21:15:29 +01:00
{
if (bm->bgp->head)
return (listgetdata (listhead (bm->bgp)));
2002-12-13 21:15:29 +01:00
return NULL;
}
/* Lookup BGP entry. */
struct bgp *
bgp_lookup (as_t as, const char *name)
2002-12-13 21:15:29 +01:00
{
struct bgp *bgp;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
2002-12-13 21:15:29 +01:00
if (bgp->as == as
&& ((bgp->name == NULL && name == NULL)
|| (bgp->name && name && strcmp (bgp->name, name) == 0)))
return bgp;
return NULL;
}
/* Lookup BGP structure by view name. */
struct bgp *
bgp_lookup_by_name (const char *name)
2002-12-13 21:15:29 +01:00
{
struct bgp *bgp;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
2002-12-13 21:15:29 +01:00
if ((bgp->name == NULL && name == NULL)
|| (bgp->name && name && strcmp (bgp->name, name) == 0))
return bgp;
return NULL;
}
/* Called from VTY commands. */
int
bgp_get (struct bgp **bgp_val, as_t *as, const char *name)
2002-12-13 21:15:29 +01:00
{
struct bgp *bgp;
/* Multiple instance check. */
if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
{
if (name)
bgp = bgp_lookup_by_name (name);
else
bgp = bgp_get_default ();
/* Already exists. */
if (bgp)
{
if (bgp->as != *as)
{
*as = bgp->as;
return BGP_ERR_INSTANCE_MISMATCH;
}
*bgp_val = bgp;
return 0;
}
}
else
{
/* BGP instance name can not be specified for single instance. */
if (name)
return BGP_ERR_MULTIPLE_INSTANCE_NOT_SET;
/* Get default BGP structure if exists. */
bgp = bgp_get_default ();
if (bgp)
{
if (bgp->as != *as)
{
*as = bgp->as;
return BGP_ERR_AS_MISMATCH;
}
*bgp_val = bgp;
return 0;
}
}
bgp = bgp_create (as, name);
listnode_add (bm->bgp, bgp);
2004-10-03 20:18:34 +02:00
bgp_router_id_set(bgp, &router_id_zebra);
2002-12-13 21:15:29 +01:00
*bgp_val = bgp;
return 0;
}
/* Delete BGP instance. */
int
bgp_delete (struct bgp *bgp)
{
struct peer *peer;
struct peer_group *group;
struct listnode *node;
2002-12-13 21:15:29 +01:00
struct listnode *next;
afi_t afi;
safi_t safi;
int i;
/* Delete static route. */
bgp_static_delete (bgp);
/* Unset redistribution. */
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
if (i != ZEBRA_ROUTE_BGP)
bgp_redistribute_unset (bgp, afi, i);
for (ALL_LIST_ELEMENTS (bgp->group, node, next, group))
peer_group_delete (group);
list_delete (bgp->group);
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS (bgp->peer, node, next, peer))
peer_delete (peer);
list_delete (bgp->peer);
2002-12-13 21:15:29 +01:00
for (ALL_LIST_ELEMENTS (bgp->rsclient, node, next, peer))
peer_delete (peer);
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
list_delete (bgp->rsclient);
2002-12-13 21:15:29 +01:00
listnode_delete (bm->bgp, bgp);
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
2002-12-13 21:15:29 +01:00
if (bgp->name)
free (bgp->name);
for (afi = AFI_IP; afi < AFI_MAX; afi++)
for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
{
if (bgp->route[afi][safi])
XFREE (MTYPE_ROUTE_TABLE, bgp->route[afi][safi]);
if (bgp->aggregate[afi][safi])
XFREE (MTYPE_ROUTE_TABLE,bgp->aggregate[afi][safi]) ;
if (bgp->rib[afi][safi])
XFREE (MTYPE_ROUTE_TABLE,bgp->rib[afi][safi]);
}
XFREE (MTYPE_BGP, bgp);
return 0;
}
struct peer *
peer_lookup (struct bgp *bgp, union sockunion *su)
{
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! bgp)
bgp = bgp_get_default ();
if (! bgp)
return NULL;
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (sockunion_same (&peer->su, su)
&& ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
return peer;
2002-12-13 21:15:29 +01:00
}
return NULL;
}
struct peer *
peer_lookup_with_open (union sockunion *su, as_t remote_as,
struct in_addr *remote_id, int *as)
{
struct peer *peer;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct bgp *bgp;
bgp = bgp_get_default ();
if (! bgp)
return NULL;
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (sockunion_same (&peer->su, su)
&& ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
{
if (peer->as == remote_as
&& peer->remote_id.s_addr == remote_id->s_addr)
return peer;
if (peer->as == remote_as)
*as = 1;
}
2002-12-13 21:15:29 +01:00
}
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (sockunion_same (&peer->su, su)
&& ! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
{
if (peer->as == remote_as
&& peer->remote_id.s_addr == 0)
return peer;
if (peer->as == remote_as)
*as = 1;
}
2002-12-13 21:15:29 +01:00
}
return NULL;
}
/* If peer is configured at least one address family return 1. */
int
peer_active (struct peer *peer)
{
if (peer->afc[AFI_IP][SAFI_UNICAST]
|| peer->afc[AFI_IP][SAFI_MULTICAST]
|| peer->afc[AFI_IP][SAFI_MPLS_VPN]
|| peer->afc[AFI_IP6][SAFI_UNICAST]
|| peer->afc[AFI_IP6][SAFI_MULTICAST])
return 1;
return 0;
}
/* If peer is negotiated at least one address family return 1. */
int
peer_active_nego (struct peer *peer)
{
if (peer->afc_nego[AFI_IP][SAFI_UNICAST]
|| peer->afc_nego[AFI_IP][SAFI_MULTICAST]
|| peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
|| peer->afc_nego[AFI_IP6][SAFI_UNICAST]
|| peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
return 1;
return 0;
}
/* peer_flag_change_type. */
enum peer_change_type
{
peer_change_none,
peer_change_reset,
peer_change_reset_in,
peer_change_reset_out,
};
static void
2002-12-13 21:15:29 +01:00
peer_change_action (struct peer *peer, afi_t afi, safi_t safi,
enum peer_change_type type)
{
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return;
if (type == peer_change_reset)
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else if (type == peer_change_reset_in)
{
if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
|| CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
else
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
else if (type == peer_change_reset_out)
bgp_announce_route (peer, afi, safi);
}
struct peer_flag_action
{
/* Peer's flag. */
u_int32_t flag;
/* This flag can be set for peer-group member. */
u_char not_for_member;
/* Action when the flag is changed. */
enum peer_change_type type;
/* Peer down cause */
u_char peer_down;
2002-12-13 21:15:29 +01:00
};
struct peer_flag_action peer_flag_action_list[] =
{
{ PEER_FLAG_PASSIVE, 0, peer_change_reset },
{ PEER_FLAG_SHUTDOWN, 0, peer_change_reset },
{ PEER_FLAG_DONT_CAPABILITY, 0, peer_change_none },
{ PEER_FLAG_OVERRIDE_CAPABILITY, 0, peer_change_none },
{ PEER_FLAG_STRICT_CAP_MATCH, 0, peer_change_none },
{ PEER_FLAG_DYNAMIC_CAPABILITY, 0, peer_change_reset },
{ PEER_FLAG_DISABLE_CONNECTED_CHECK, 0, peer_change_reset },
2002-12-13 21:15:29 +01:00
{ 0, 0, 0 }
};
struct peer_flag_action peer_af_flag_action_list[] =
{
{ PEER_FLAG_NEXTHOP_SELF, 1, peer_change_reset_out },
{ PEER_FLAG_SEND_COMMUNITY, 1, peer_change_reset_out },
{ PEER_FLAG_SEND_EXT_COMMUNITY, 1, peer_change_reset_out },
{ PEER_FLAG_SOFT_RECONFIG, 0, peer_change_reset_in },
{ PEER_FLAG_REFLECTOR_CLIENT, 1, peer_change_reset },
{ PEER_FLAG_RSERVER_CLIENT, 1, peer_change_reset },
{ PEER_FLAG_AS_PATH_UNCHANGED, 1, peer_change_reset_out },
{ PEER_FLAG_NEXTHOP_UNCHANGED, 1, peer_change_reset_out },
{ PEER_FLAG_MED_UNCHANGED, 1, peer_change_reset_out },
{ PEER_FLAG_REMOVE_PRIVATE_AS, 1, peer_change_reset_out },
{ PEER_FLAG_ALLOWAS_IN, 0, peer_change_reset_in },
{ PEER_FLAG_ORF_PREFIX_SM, 1, peer_change_reset },
{ PEER_FLAG_ORF_PREFIX_RM, 1, peer_change_reset },
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
{ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED, 0, peer_change_reset_out },
2002-12-13 21:15:29 +01:00
{ 0, 0, 0 }
};
/* Proper action set. */
static int
2002-12-13 21:15:29 +01:00
peer_flag_action_set (struct peer_flag_action *action_list, int size,
struct peer_flag_action *action, u_int32_t flag)
{
int i;
int found = 0;
int reset_in = 0;
int reset_out = 0;
struct peer_flag_action *match = NULL;
/* Check peer's frag action. */
for (i = 0; i < size; i++)
{
match = &action_list[i];
if (match->flag == 0)
break;
if (match->flag & flag)
{
found = 1;
if (match->type == peer_change_reset_in)
reset_in = 1;
if (match->type == peer_change_reset_out)
reset_out = 1;
if (match->type == peer_change_reset)
{
reset_in = 1;
reset_out = 1;
}
if (match->not_for_member)
action->not_for_member = 1;
}
}
/* Set peer clear type. */
if (reset_in && reset_out)
action->type = peer_change_reset;
else if (reset_in)
action->type = peer_change_reset_in;
else if (reset_out)
action->type = peer_change_reset_out;
else
action->type = peer_change_none;
return found;
}
static void
2002-12-13 21:15:29 +01:00
peer_flag_modify_action (struct peer *peer, u_int32_t flag)
{
if (flag == PEER_FLAG_SHUTDOWN)
{
if (CHECK_FLAG (peer->flags, flag))
{
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
peer_nsf_stop (peer);
UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
if (peer->t_pmax_restart)
{
BGP_TIMER_OFF (peer->t_pmax_restart);
if (BGP_DEBUG (events, EVENTS))
zlog_debug ("%s Maximum-prefix restart timer canceled",
peer->host);
}
if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT))
peer_nsf_stop (peer);
2002-12-13 21:15:29 +01:00
if (peer->status == Established)
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
else
{
peer->v_start = BGP_INIT_START_TIMER;
BGP_EVENT_ADD (peer, BGP_Stop);
}
}
else if (peer->status == Established)
{
if (flag == PEER_FLAG_DYNAMIC_CAPABILITY)
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
else if (flag == PEER_FLAG_PASSIVE)
peer->last_reset = PEER_DOWN_PASSIVE_CHANGE;
else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)
peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
2002-12-13 21:15:29 +01:00
}
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
/* Change specified peer flag. */
static int
2002-12-13 21:15:29 +01:00
peer_flag_modify (struct peer *peer, u_int32_t flag, int set)
{
int found;
int size;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct peer_flag_action action;
memset (&action, 0, sizeof (struct peer_flag_action));
size = sizeof peer_flag_action_list / sizeof (struct peer_flag_action);
found = peer_flag_action_set (peer_flag_action_list, size, &action, flag);
/* No flag action is found. */
if (! found)
return BGP_ERR_INVALID_FLAG;
/* Not for peer-group member. */
if (action.not_for_member && peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
/* When unset the peer-group member's flag we have to check
peer-group configuration. */
if (! set && peer_group_active (peer))
if (CHECK_FLAG (peer->group->conf->flags, flag))
{
if (flag == PEER_FLAG_SHUTDOWN)
return BGP_ERR_PEER_GROUP_SHUTDOWN;
else
return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
}
/* Flag conflict check. */
if (set
&& CHECK_FLAG (peer->flags | flag, PEER_FLAG_STRICT_CAP_MATCH)
&& CHECK_FLAG (peer->flags | flag, PEER_FLAG_OVERRIDE_CAPABILITY))
return BGP_ERR_PEER_FLAG_CONFLICT;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (set && CHECK_FLAG (peer->flags, flag) == flag)
return 0;
if (! set && ! CHECK_FLAG (peer->flags, flag))
return 0;
}
if (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)
peer_flag_modify_action (peer, flag);
return 0;
}
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (set && CHECK_FLAG (peer->flags, flag) == flag)
continue;
if (! set && ! CHECK_FLAG (peer->flags, flag))
continue;
if (set)
SET_FLAG (peer->flags, flag);
else
UNSET_FLAG (peer->flags, flag);
if (action.type == peer_change_reset)
peer_flag_modify_action (peer, flag);
}
return 0;
}
int
peer_flag_set (struct peer *peer, u_int32_t flag)
{
return peer_flag_modify (peer, flag, 1);
}
int
peer_flag_unset (struct peer *peer, u_int32_t flag)
{
return peer_flag_modify (peer, flag, 0);
}
static int
2002-12-13 21:15:29 +01:00
peer_is_group_member (struct peer *peer, afi_t afi, safi_t safi)
{
if (peer->af_group[afi][safi])
return 1;
return 0;
}
static int
2002-12-13 21:15:29 +01:00
peer_af_flag_modify (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag,
int set)
{
int found;
int size;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct peer_group *group;
struct peer_flag_action action;
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;
/* Adress family must be activated. */
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
/* Not for peer-group member. */
if (action.not_for_member && peer_is_group_member (peer, afi, safi))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
/* Spcecial check for reflector client. */
if (flag & PEER_FLAG_REFLECTOR_CLIENT
&& peer_sort (peer) != BGP_PEER_IBGP)
return BGP_ERR_NOT_INTERNAL_PEER;
/* Spcecial check for remove-private-AS. */
if (flag & PEER_FLAG_REMOVE_PRIVATE_AS
&& peer_sort (peer) == BGP_PEER_IBGP)
return BGP_ERR_REMOVE_PRIVATE_AS;
/* When unset the peer-group member's flag we have to check
peer-group configuration. */
if (! set && peer->af_group[afi][safi])
if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi], flag))
return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
/* When current flag configuration is same as requested one. */
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
return 0;
if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
return 0;
}
if (set)
SET_FLAG (peer->af_flags[afi][safi], flag);
else
UNSET_FLAG (peer->af_flags[afi][safi], flag);
/* Execute action when peer is established. */
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
&& peer->status == Established)
{
if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
bgp_clear_adj_in (peer, afi, safi);
else
{
if (flag == PEER_FLAG_REFLECTOR_CLIENT)
peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
else if (flag == PEER_FLAG_RSERVER_CLIENT)
peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
else if (flag == PEER_FLAG_ORF_PREFIX_SM)
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
else if (flag == PEER_FLAG_ORF_PREFIX_RM)
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
peer_change_action (peer, afi, safi, action.type);
}
2002-12-13 21:15:29 +01:00
}
/* Peer group member updates. */
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (! peer->af_group[afi][safi])
continue;
if (set && CHECK_FLAG (peer->af_flags[afi][safi], flag) == flag)
continue;
if (! set && ! CHECK_FLAG (peer->af_flags[afi][safi], flag))
continue;
if (set)
SET_FLAG (peer->af_flags[afi][safi], flag);
else
UNSET_FLAG (peer->af_flags[afi][safi], flag);
if (peer->status == Established)
{
if (! set && flag == PEER_FLAG_SOFT_RECONFIG)
bgp_clear_adj_in (peer, afi, safi);
else
{
if (flag == PEER_FLAG_REFLECTOR_CLIENT)
peer->last_reset = PEER_DOWN_RR_CLIENT_CHANGE;
else if (flag == PEER_FLAG_RSERVER_CLIENT)
peer->last_reset = PEER_DOWN_RS_CLIENT_CHANGE;
else if (flag == PEER_FLAG_ORF_PREFIX_SM)
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
else if (flag == PEER_FLAG_ORF_PREFIX_RM)
peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE;
peer_change_action (peer, afi, safi, action.type);
}
2002-12-13 21:15:29 +01:00
}
}
}
return 0;
}
int
peer_af_flag_set (struct peer *peer, afi_t afi, safi_t safi, u_int32_t flag)
{
return peer_af_flag_modify (peer, afi, safi, flag, 1);
}
int
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)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (peer_sort (peer) == BGP_PEER_IBGP)
return 0;
peer->ttl = ttl;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2002-12-13 21:15:29 +01:00
}
else
{
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
if (peer_sort (peer) == BGP_PEER_IBGP)
continue;
2002-12-13 21:15:29 +01:00
peer->ttl = group->conf->ttl;
2002-12-13 21:15:29 +01:00
if (peer->fd >= 0)
sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
}
2002-12-13 21:15:29 +01:00
}
return 0;
}
int
peer_ebgp_multihop_unset (struct peer *peer)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (peer_sort (peer) == BGP_PEER_IBGP)
return 0;
if (peer_group_active (peer))
peer->ttl = peer->group->conf->ttl;
else
peer->ttl = 1;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP)
sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
2002-12-13 21:15:29 +01:00
}
else
{
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
{
if (peer_sort (peer) == BGP_PEER_IBGP)
continue;
peer->ttl = 1;
if (peer->fd >= 0)
sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl);
}
2002-12-13 21:15:29 +01:00
}
return 0;
}
/* Neighbor description. */
int
peer_description_set (struct peer *peer, char *desc)
{
if (peer->desc)
XFREE (MTYPE_PEER_DESC, peer->desc);
peer->desc = XSTRDUP (MTYPE_PEER_DESC, desc);
return 0;
}
int
peer_description_unset (struct peer *peer)
{
if (peer->desc)
XFREE (MTYPE_PEER_DESC, peer->desc);
peer->desc = NULL;
return 0;
}
/* Neighbor update-source. */
int
peer_update_source_if_set (struct peer *peer, const char *ifname)
2002-12-13 21:15:29 +01:00
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (peer->update_if)
{
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
&& strcmp (peer->update_if, ifname) == 0)
return 0;
XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
peer->update_if = NULL;
}
if (peer->update_source)
{
sockunion_free (peer->update_source);
peer->update_source = NULL;
}
peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
}
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (peer->update_if)
{
if (strcmp (peer->update_if, ifname) == 0)
continue;
XFREE (MTYPE_PEER_UPDATE_SOURCE, peer->update_if);
peer->update_if = NULL;
}
if (peer->update_source)
{
sockunion_free (peer->update_source);
peer->update_source = NULL;
}
peer->update_if = XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, ifname);
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
return 0;
}
int
peer_update_source_addr_set (struct peer *peer, union sockunion *su)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (peer->update_source)
{
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
&& sockunion_cmp (peer->update_source, su) == 0)
return 0;
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;
}
peer->update_source = sockunion_dup (su);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
}
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (peer->update_source)
{
if (sockunion_cmp (peer->update_source, su) == 0)
continue;
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;
}
peer->update_source = sockunion_dup (su);
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
return 0;
}
int
peer_update_source_unset (struct peer *peer)
{
union sockunion *su;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
&& ! peer->update_source
&& ! peer->update_if)
return 0;
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;
}
if (peer_group_active (peer))
{
group = peer->group;
if (group->conf->update_source)
{
su = sockunion_dup (group->conf->update_source);
peer->update_source = su;
}
else if (group->conf->update_if)
peer->update_if =
XSTRDUP (MTYPE_PEER_UPDATE_SOURCE, group->conf->update_if);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
}
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (! peer->update_source && ! peer->update_if)
continue;
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;
}
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
return 0;
}
int
peer_default_originate_set (struct peer *peer, afi_t afi, safi_t safi,
const char *rmap)
2002-12-13 21:15:29 +01:00
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
/* Adress family must be activated. */
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
/* Default originate can't be used for peer group memeber. */
if (peer_is_group_member (peer, afi, safi))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
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)
{
if (peer->default_rmap[afi][safi].name)
free (peer->default_rmap[afi][safi].name);
peer->default_rmap[afi][safi].name = strdup (rmap);
peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
}
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established && peer->afc_nego[afi][safi])
bgp_default_originate (peer, afi, safi, 0);
return 0;
}
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
if (rmap)
{
if (peer->default_rmap[afi][safi].name)
free (peer->default_rmap[afi][safi].name);
peer->default_rmap[afi][safi].name = strdup (rmap);
peer->default_rmap[afi][safi].map = route_map_lookup_by_name (rmap);
}
if (peer->status == Established && peer->afc_nego[afi][safi])
bgp_default_originate (peer, afi, safi, 0);
}
return 0;
}
int
peer_default_originate_unset (struct peer *peer, afi_t afi, safi_t safi)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
/* Adress family must be activated. */
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
/* Default originate can't be used for peer group memeber. */
if (peer_is_group_member (peer, afi, 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)
free (peer->default_rmap[afi][safi].name);
peer->default_rmap[afi][safi].name = NULL;
peer->default_rmap[afi][safi].map = NULL;
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established && peer->afc_nego[afi][safi])
bgp_default_originate (peer, afi, safi, 1);
return 0;
}
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE);
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;
if (peer->status == Established && peer->afc_nego[afi][safi])
bgp_default_originate (peer, afi, safi, 1);
}
return 0;
}
int
peer_port_set (struct peer *peer, u_int16_t port)
{
peer->port = port;
return 0;
}
int
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)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
SET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
peer->weight = weight;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
peer->weight = group->conf->weight;
}
return 0;
}
int
peer_weight_unset (struct peer *peer)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
/* Set default weight. */
if (peer_group_active (peer))
peer->weight = peer->group->conf->weight;
else
peer->weight = 0;
UNSET_FLAG (peer->config, PEER_CONFIG_WEIGHT);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
peer->weight = 0;
}
return 0;
}
int
peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
/* Not for peer group memeber. */
if (peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
/* keepalive value check. */
if (keepalive > 65535)
return BGP_ERR_INVALID_VALUE;
/* Holdtime value check. */
if (holdtime > 65535)
return BGP_ERR_INVALID_VALUE;
/* Holdtime value must be either 0 or greater than 3. */
if (holdtime < 3 && holdtime != 0)
return BGP_ERR_INVALID_VALUE;
/* Set value to the configuration. */
SET_FLAG (peer->config, PEER_CONFIG_TIMER);
peer->holdtime = holdtime;
peer->keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
SET_FLAG (peer->config, PEER_CONFIG_TIMER);
peer->holdtime = group->conf->holdtime;
peer->keepalive = group->conf->keepalive;
}
return 0;
}
int
peer_timers_unset (struct peer *peer)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
/* Clear configuration. */
UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
peer->keepalive = 0;
peer->holdtime = 0;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
/* peer-group member updates. */
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
UNSET_FLAG (peer->config, PEER_CONFIG_TIMER);
peer->holdtime = 0;
peer->keepalive = 0;
}
return 0;
}
int
peer_timers_connect_set (struct peer *peer, u_int32_t connect)
{
if (peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
if (connect > 65535)
return BGP_ERR_INVALID_VALUE;
/* Set value to the configuration. */
SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
peer->connect = connect;
/* Set value to timer setting. */
peer->v_connect = connect;
return 0;
}
int
peer_timers_connect_unset (struct peer *peer)
{
if (peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
/* Clear configuration. */
UNSET_FLAG (peer->config, PEER_CONFIG_CONNECT);
peer->connect = 0;
/* Set timer setting to default value. */
peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
return 0;
}
int
peer_advertise_interval_set (struct peer *peer, u_int32_t routeadv)
{
if (peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
if (routeadv > 600)
return BGP_ERR_INVALID_VALUE;
SET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
peer->routeadv = routeadv;
peer->v_routeadv = routeadv;
return 0;
}
int
peer_advertise_interval_unset (struct peer *peer)
{
if (peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
UNSET_FLAG (peer->config, PEER_CONFIG_ROUTEADV);
peer->routeadv = 0;
if (peer_sort (peer) == BGP_PEER_IBGP)
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)
2002-12-13 21:15:29 +01:00
{
if (peer->ifname)
free (peer->ifname);
peer->ifname = strdup (str);
return 0;
}
int
peer_interface_unset (struct peer *peer)
{
if (peer->ifname)
free (peer->ifname);
peer->ifname = NULL;
return 0;
}
/* Allow-as in. */
int
peer_allowas_in_set (struct peer *peer, afi_t afi, safi_t safi, int allow_num)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (allow_num < 1 || allow_num > 10)
return BGP_ERR_INVALID_VALUE;
if (peer->allowas_in[afi][safi] != allow_num)
{
peer->allowas_in[afi][safi] = allow_num;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN);
peer_change_action (peer, afi, safi, peer_change_reset_in);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (peer->allowas_in[afi][safi] != allow_num)
{
peer->allowas_in[afi][safi] = 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;
}
int
peer_allowas_in_unset (struct peer *peer, afi_t afi, safi_t safi)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
{
peer->allowas_in[afi][safi] = 0;
peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
}
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
{
peer->allowas_in[afi][safi] = 0;
peer_af_flag_unset (peer, afi, safi, PEER_FLAG_ALLOWAS_IN);
}
}
return 0;
}
int
peer_local_as_set (struct peer *peer, as_t as, int no_prepend)
{
struct bgp *bgp = peer->bgp;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (peer_sort (peer) != BGP_PEER_EBGP
&& peer_sort (peer) != BGP_PEER_INTERNAL)
return BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP;
if (bgp->as == as)
return BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS;
if (peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
if (peer->change_local_as == as &&
((CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && no_prepend)
|| (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) && ! no_prepend)))
return 0;
peer->change_local_as = as;
if (no_prepend)
SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
else
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
}
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
peer->change_local_as = as;
if (no_prepend)
SET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
else
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
return 0;
}
int
peer_local_as_unset (struct peer *peer)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (peer_group_active (peer))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
if (! peer->change_local_as)
return 0;
peer->change_local_as = 0;
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
return 0;
}
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
peer->change_local_as = 0;
UNSET_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND);
if (peer->status == Established)
{
peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE;
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
2002-12-13 21:15:29 +01:00
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
return 0;
}
[bgpd] TCP-MD5: password vty configuration and initial Linux support 2008-07-21 Paul Jakma <paul.jakma@sun.com> * bgp_packet.c: (bgp_open_receive) fix warning in a zlog call * bgp_vty.c: (bgp_vty_return) add return code * bgpd.c: (bgp_master_init) setup the socket list. * bgp_network.c: Remove the dual IPv4/6 socket thing for now, which was implemented by Michael, until such time as its clear its required for Linux (see sockopt comments). IPv6 support, including IPv4 sessions on AF_INET6 sockets, therefore is broken, and the '-l 0.0.0.0' arguments would need to be given to bgpd to make things work here. 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Tomohiko Kusuda <kusuda@inetcore.com> Leigh Brown <leigh@solinno.co.uk> * bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5 sockopt and bgpd. (bgp_md5_set_socket) Helper for bgp_connect (bgp_md5_set) setup TCP-MD5SIG for the given peer. (bgp_connect) call out to bgp_md5_set_socket for the outgoing connect socket. (bgp_socket) save references to the listen sockets, needed if TCP-MD5SIG is applied later or changed. * bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password' commands. * bgpd.c: (peer_{new,delete) manage TCP-MD5 password (peer_group2peer_config_copy) inherit TCP-MD5 password (peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5 passwords: applying checks, stopping peers, and trying to return errors to UI, etc. (bgp_config_write_peer) save password. Fix missing newline in writeout of neighbor ... port. 2008-07-21 Paul Jakma <paul.jakma@sun.com> * sockunion.c: ifdef out various places that converted v4mapped sockets to pure v4. Doesn't seem necessary at all, presumably a workaround for now historical inet_ntop bugs (?) 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> * sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
/* Set password for authenticating with the peer. */
int
peer_password_set (struct peer *peer, const char *password)
{
struct listnode *nn, *nnode;
int len = password ? strlen(password) : 0;
int ret = BGP_SUCCESS;
if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
return BGP_ERR_INVALID_VALUE;
if (peer->password && strcmp (peer->password, password) == 0
&& ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
if (peer->password)
XFREE (MTYPE_PEER_PASSWORD, peer->password);
peer->password = XSTRDUP (MTYPE_PEER_PASSWORD, password);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer->status == Established)
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;
}
for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
{
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;
}
return ret;
}
int
peer_password_unset (struct peer *peer)
{
struct listnode *nn, *nnode;
if (!peer->password
&& !CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
if (!CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
{
if (peer_group_active (peer)
&& peer->group->conf->password
&& strcmp (peer->group->conf->password, peer->password) == 0)
return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
if (peer->status == Established)
bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
else
BGP_EVENT_ADD (peer, BGP_Stop);
if (peer->password)
XFREE (MTYPE_PEER_PASSWORD, peer->password);
peer->password = NULL;
bgp_md5_set (peer);
return 0;
}
XFREE (MTYPE_PEER_PASSWORD, peer->password);
peer->password = NULL;
for (ALL_LIST_ELEMENTS (peer->group->peer, nn, nnode, peer))
{
if (!peer->password)
continue;
if (peer->status == Established)
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;
bgp_md5_set (peer);
}
return 0;
}
2002-12-13 21:15:29 +01:00
/* Set distribute list to the peer. */
int
peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
const char *name)
2002-12-13 21:15:29 +01:00
{
struct bgp_filter *filter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
if (direct != FILTER_IN && direct != FILTER_OUT)
return BGP_ERR_INVALID_VALUE;
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
filter = &peer->filter[afi][safi];
if (filter->plist[direct].name)
return BGP_ERR_PEER_FILTER_CONFLICT;
if (filter->dlist[direct].name)
free (filter->dlist[direct].name);
filter->dlist[direct].name = strdup (name);
filter->dlist[direct].alist = access_list_lookup (afi, name);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
if (! peer->af_group[afi][safi])
continue;
if (filter->dlist[direct].name)
free (filter->dlist[direct].name);
filter->dlist[direct].name = strdup (name);
filter->dlist[direct].alist = access_list_lookup (afi, name);
}
return 0;
}
int
peer_distribute_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
{
struct bgp_filter *filter;
struct bgp_filter *gfilter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
if (direct != FILTER_IN && direct != FILTER_OUT)
return BGP_ERR_INVALID_VALUE;
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
filter = &peer->filter[afi][safi];
/* apply peer-group filter */
if (peer->af_group[afi][safi])
{
gfilter = &peer->group->conf->filter[afi][safi];
if (gfilter->dlist[direct].name)
{
if (filter->dlist[direct].name)
free (filter->dlist[direct].name);
filter->dlist[direct].name = strdup (gfilter->dlist[direct].name);
filter->dlist[direct].alist = gfilter->dlist[direct].alist;
return 0;
}
}
if (filter->dlist[direct].name)
free (filter->dlist[direct].name);
filter->dlist[direct].name = NULL;
filter->dlist[direct].alist = NULL;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
if (! peer->af_group[afi][safi])
continue;
if (filter->dlist[direct].name)
free (filter->dlist[direct].name);
filter->dlist[direct].name = NULL;
filter->dlist[direct].alist = NULL;
}
return 0;
}
/* Update distribute list. */
static void
2002-12-13 21:15:29 +01:00
peer_distribute_update (struct access_list *access)
{
afi_t afi;
safi_t safi;
int direct;
struct listnode *mnode, *mnnode;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct bgp *bgp;
struct peer *peer;
struct peer_group *group;
struct bgp_filter *filter;
for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
2002-12-13 21:15:29 +01:00
{
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
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->dlist[direct].name)
filter->dlist[direct].alist =
access_list_lookup (afi, filter->dlist[direct].name);
else
filter->dlist[direct].alist = NULL;
}
}
}
for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
2002-12-13 21:15:29 +01:00
{
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->dlist[direct].name)
filter->dlist[direct].alist =
access_list_lookup (afi, filter->dlist[direct].name);
else
filter->dlist[direct].alist = NULL;
}
}
}
}
}
/* Set prefix list to the peer. */
int
peer_prefix_list_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
const char *name)
2002-12-13 21:15:29 +01:00
{
struct bgp_filter *filter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
if (direct != FILTER_IN && direct != FILTER_OUT)
return BGP_ERR_INVALID_VALUE;
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
filter = &peer->filter[afi][safi];
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);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
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);
}
return 0;
}
int
peer_prefix_list_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
{
struct bgp_filter *filter;
struct bgp_filter *gfilter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
if (direct != FILTER_IN && direct != FILTER_OUT)
return BGP_ERR_INVALID_VALUE;
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
filter = &peer->filter[afi][safi];
/* apply peer-group filter */
if (peer->af_group[afi][safi])
{
gfilter = &peer->group->conf->filter[afi][safi];
if (gfilter->plist[direct].name)
{
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;
return 0;
}
}
if (filter->plist[direct].name)
free (filter->plist[direct].name);
filter->plist[direct].name = NULL;
filter->plist[direct].plist = NULL;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
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;
}
return 0;
}
/* Update prefix-list list. */
static void
2002-12-13 21:15:29 +01:00
peer_prefix_list_update (struct prefix_list *plist)
{
struct listnode *mnode, *mnnode;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
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))
2002-12-13 21:15:29 +01:00
{
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
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))
2002-12-13 21:15:29 +01:00
{
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;
}
}
}
}
}
int
peer_aslist_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
const char *name)
2002-12-13 21:15:29 +01:00
{
struct bgp_filter *filter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
if (direct != FILTER_IN && direct != FILTER_OUT)
return BGP_ERR_INVALID_VALUE;
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
filter = &peer->filter[afi][safi];
if (filter->aslist[direct].name)
free (filter->aslist[direct].name);
filter->aslist[direct].name = strdup (name);
filter->aslist[direct].aslist = as_list_lookup (name);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
if (! peer->af_group[afi][safi])
continue;
if (filter->aslist[direct].name)
free (filter->aslist[direct].name);
filter->aslist[direct].name = strdup (name);
filter->aslist[direct].aslist = as_list_lookup (name);
}
return 0;
}
int
peer_aslist_unset (struct peer *peer,afi_t afi, safi_t safi, int direct)
{
struct bgp_filter *filter;
struct bgp_filter *gfilter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
if (direct != FILTER_IN && direct != FILTER_OUT)
2002-12-13 21:15:29 +01:00
return BGP_ERR_INVALID_VALUE;
if (direct == FILTER_OUT && peer_is_group_member (peer, afi, safi))
2002-12-13 21:15:29 +01:00
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
filter = &peer->filter[afi][safi];
/* apply peer-group filter */
if (peer->af_group[afi][safi])
{
gfilter = &peer->group->conf->filter[afi][safi];
if (gfilter->aslist[direct].name)
{
if (filter->aslist[direct].name)
free (filter->aslist[direct].name);
filter->aslist[direct].name = strdup (gfilter->aslist[direct].name);
filter->aslist[direct].aslist = gfilter->aslist[direct].aslist;
return 0;
}
}
if (filter->aslist[direct].name)
free (filter->aslist[direct].name);
filter->aslist[direct].name = NULL;
filter->aslist[direct].aslist = NULL;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
if (! peer->af_group[afi][safi])
continue;
if (filter->aslist[direct].name)
free (filter->aslist[direct].name);
filter->aslist[direct].name = NULL;
filter->aslist[direct].aslist = NULL;
}
return 0;
}
static void
2002-12-13 21:15:29 +01:00
peer_aslist_update ()
{
afi_t afi;
safi_t safi;
int direct;
struct listnode *mnode, *mnnode;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
struct bgp *bgp;
struct peer *peer;
struct peer_group *group;
struct bgp_filter *filter;
for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
2002-12-13 21:15:29 +01:00
{
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
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->aslist[direct].name)
filter->aslist[direct].aslist =
as_list_lookup (filter->aslist[direct].name);
else
filter->aslist[direct].aslist = NULL;
}
}
}
for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
2002-12-13 21:15:29 +01:00
{
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->aslist[direct].name)
filter->aslist[direct].aslist =
as_list_lookup (filter->aslist[direct].name);
else
filter->aslist[direct].aslist = NULL;
}
}
}
}
}
/* Set route-map to the peer. */
int
peer_route_map_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
const char *name)
2002-12-13 21:15:29 +01:00
{
struct bgp_filter *filter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if (direct != RMAP_IN && direct != RMAP_OUT &&
direct != RMAP_IMPORT && direct != RMAP_EXPORT)
2002-12-13 21:15:29 +01:00
return BGP_ERR_INVALID_VALUE;
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
&& peer_is_group_member (peer, afi, safi))
2002-12-13 21:15:29 +01:00
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
filter = &peer->filter[afi][safi];
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);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
if (! peer->af_group[afi][safi])
continue;
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);
}
return 0;
}
/* Unset route-map from the peer. */
int
peer_route_map_unset (struct peer *peer, afi_t afi, safi_t safi, int direct)
{
struct bgp_filter *filter;
struct bgp_filter *gfilter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
if (direct != RMAP_IN && direct != RMAP_OUT &&
direct != RMAP_IMPORT && direct != RMAP_EXPORT)
2002-12-13 21:15:29 +01:00
return BGP_ERR_INVALID_VALUE;
if ( (direct == RMAP_OUT || direct == RMAP_IMPORT)
&& peer_is_group_member (peer, afi, safi))
2002-12-13 21:15:29 +01:00
return BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER;
filter = &peer->filter[afi][safi];
/* apply peer-group filter */
if (peer->af_group[afi][safi])
{
gfilter = &peer->group->conf->filter[afi][safi];
if (gfilter->map[direct].name)
{
if (filter->map[direct].name)
free (filter->map[direct].name);
filter->map[direct].name = strdup (gfilter->map[direct].name);
filter->map[direct].map = gfilter->map[direct].map;
return 0;
}
}
if (filter->map[direct].name)
free (filter->map[direct].name);
filter->map[direct].name = NULL;
filter->map[direct].map = NULL;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
if (! peer->af_group[afi][safi])
continue;
if (filter->map[direct].name)
free (filter->map[direct].name);
filter->map[direct].name = NULL;
filter->map[direct].map = NULL;
}
return 0;
}
/* Set unsuppress-map to the peer. */
int
peer_unsuppress_map_set (struct peer *peer, afi_t afi, safi_t safi,
const char *name)
2002-12-13 21:15:29 +01:00
{
struct bgp_filter *filter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
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;
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);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
if (! peer->af_group[afi][safi])
continue;
if (filter->usmap.name)
free (filter->usmap.name);
filter->usmap.name = strdup (name);
filter->usmap.map = route_map_lookup_by_name (name);
}
return 0;
}
/* Unset route-map from the peer. */
int
peer_unsuppress_map_unset (struct peer *peer, afi_t afi, safi_t safi)
{
struct bgp_filter *filter;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
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;
filter = &peer->filter[afi][safi];
if (filter->usmap.name)
free (filter->usmap.name);
filter->usmap.name = NULL;
filter->usmap.map = NULL;
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
filter = &peer->filter[afi][safi];
if (! peer->af_group[afi][safi])
continue;
if (filter->usmap.name)
free (filter->usmap.name);
filter->usmap.name = NULL;
filter->usmap.map = NULL;
}
return 0;
}
int
peer_maximum_prefix_set (struct peer *peer, afi_t afi, safi_t safi,
u_int32_t max, u_char threshold,
int warning, u_int16_t restart)
2002-12-13 21:15:29 +01:00
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
peer->pmax[afi][safi] = max;
peer->pmax_threshold[afi][safi] = threshold;
peer->pmax_restart[afi][safi] = restart;
2002-12-13 21:15:29 +01:00
if (warning)
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
else
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (! peer->af_group[afi][safi])
continue;
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
peer->pmax[afi][safi] = max;
peer->pmax_threshold[afi][safi] = threshold;
peer->pmax_restart[afi][safi] = restart;
2002-12-13 21:15:29 +01:00
if (warning)
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
else
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
}
return 0;
}
int
peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi)
{
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
if (! peer->afc[afi][safi])
return BGP_ERR_PEER_INACTIVE;
/* apply peer-group config */
if (peer->af_group[afi][safi])
{
if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
PEER_FLAG_MAX_PREFIX))
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
else
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
if (CHECK_FLAG (peer->group->conf->af_flags[afi][safi],
PEER_FLAG_MAX_PREFIX_WARNING))
SET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
else
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
peer->pmax[afi][safi] = peer->group->conf->pmax[afi][safi];
peer->pmax_threshold[afi][safi] = peer->group->conf->pmax_threshold[afi][safi];
peer->pmax_restart[afi][safi] = peer->group->conf->pmax_restart[afi][safi];
2002-12-13 21:15:29 +01:00
return 0;
}
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
peer->pmax[afi][safi] = 0;
peer->pmax_threshold[afi][safi] = 0;
peer->pmax_restart[afi][safi] = 0;
2002-12-13 21:15:29 +01:00
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
return 0;
group = peer->group;
for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (! peer->af_group[afi][safi])
continue;
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX);
UNSET_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING);
peer->pmax[afi][safi] = 0;
peer->pmax_threshold[afi][safi] = 0;
peer->pmax_restart[afi][safi] = 0;
2002-12-13 21:15:29 +01:00
}
return 0;
}
int
peer_clear (struct peer *peer)
{
if (! CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
{
if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
{
UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
if (peer->t_pmax_restart)
{
BGP_TIMER_OFF (peer->t_pmax_restart);
if (BGP_DEBUG (events, EVENTS))
zlog_debug ("%s Maximum-prefix restart timer canceled",
peer->host);
}
BGP_EVENT_ADD (peer, BGP_Start);
return 0;
}
2002-12-13 21:15:29 +01:00
peer->v_start = BGP_INIT_START_TIMER;
if (peer->status == Established)
bgp_notify_send (peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_ADMIN_RESET);
else
BGP_EVENT_ADD (peer, BGP_Stop);
}
return 0;
}
int
peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
enum bgp_clear_type stype)
{
if (peer->status != Established)
return 0;
if (! peer->afc[afi][safi])
return BGP_ERR_AF_UNCONFIGURED;
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
if (stype == BGP_CLEAR_SOFT_RSCLIENT)
{
if (! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
return 0;
bgp_check_local_routes_rsclient (peer, afi, safi);
bgp_soft_reconfig_rsclient (peer, afi, safi);
}
2002-12-13 21:15:29 +01:00
if (stype == BGP_CLEAR_SOFT_OUT || stype == BGP_CLEAR_SOFT_BOTH)
bgp_announce_route (peer, afi, safi);
if (stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
{
if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV)
&& (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)
|| CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)))
{
struct bgp_filter *filter = &peer->filter[afi][safi];
u_char prefix_type;
if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV))
prefix_type = ORF_TYPE_PREFIX;
else
prefix_type = ORF_TYPE_PREFIX_OLD;
if (filter->plist[FILTER_IN].plist)
{
if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
bgp_route_refresh_send (peer, afi, safi,
prefix_type, REFRESH_DEFER, 1);
bgp_route_refresh_send (peer, afi, safi, prefix_type,
REFRESH_IMMEDIATE, 0);
}
else
{
if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND))
bgp_route_refresh_send (peer, afi, safi,
prefix_type, REFRESH_IMMEDIATE, 1);
else
bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
}
return 0;
}
}
if (stype == BGP_CLEAR_SOFT_IN || stype == BGP_CLEAR_SOFT_BOTH
|| stype == BGP_CLEAR_SOFT_IN_ORF_PREFIX)
{
/* If neighbor has soft reconfiguration inbound flag.
Use Adj-RIB-In database. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
bgp_soft_reconfig_in (peer, afi, safi);
else
{
/* If neighbor has route refresh capability, send route refresh
message to the peer. */
if (CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_OLD_RCV)
|| CHECK_FLAG (peer->cap, PEER_CAP_REFRESH_NEW_RCV))
bgp_route_refresh_send (peer, afi, safi, 0, 0, 0);
else
return BGP_ERR_SOFT_RECONFIG_UNCONFIGURED;
}
}
return 0;
}
/* Display peer uptime.*/
/* XXX: why does this function return char * when it takes buffer? */
2002-12-13 21:15:29 +01:00
char *
peer_uptime (time_t uptime2, char *buf, size_t len)
{
time_t uptime1;
struct tm *tm;
/* Check buffer length. */
if (len < BGP_UPTIME_LEN)
{
zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
/* XXX: should return status instead of buf... */
snprintf (buf, len, "<error> ");
return buf;
2002-12-13 21:15:29 +01:00
}
/* If there is no connection has been done before print `never'. */
if (uptime2 == 0)
{
snprintf (buf, len, "never ");
return buf;
}
/* Get current time. */
uptime1 = time (NULL);
uptime1 -= uptime2;
tm = gmtime (&uptime1);
/* Making formatted timer strings. */
#define ONE_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7
if (uptime1 < ONE_DAY_SECOND)
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",
tm->tm_yday, tm->tm_hour, tm->tm_min);
else
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
2002-12-13 21:15:29 +01:00
bgp_config_write_filter (struct vty *vty, struct peer *peer,
afi_t afi, safi_t safi)
{
struct bgp_filter *filter;
struct bgp_filter *gfilter = NULL;
char *addr;
int in = FILTER_IN;
int out = FILTER_OUT;
addr = peer->host;
filter = &peer->filter[afi][safi];
if (peer->af_group[afi][safi])
gfilter = &peer->group->conf->filter[afi][safi];
/* distribute-list. */
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,
filter->dlist[in].name, VTY_NEWLINE);
if (filter->dlist[out].name && ! gfilter)
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);
/* route-map. */
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
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)
2002-12-13 21:15:29 +01:00
vty_out (vty, " neighbor %s route-map %s in%s", addr,
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
filter->map[RMAP_IN].name, VTY_NEWLINE);
if (filter->map[RMAP_OUT].name && ! gfilter)
2002-12-13 21:15:29 +01:00
vty_out (vty, " neighbor %s route-map %s out%s", addr,
2004-09-13 Jose Luis Rubio <jrubio@dit.upm.es> (at Technical University of Madrid as part of Euro6ix Project) Enhanced Route Server functionality and Route-Maps: * bgpd/bgpd.h: Modified 'struct peer' and 'struct bgp_filter' to support rs-clients. A 'struct bgp_table *rib' has been added to the first (to mantain a separated RIB for each rs-client) and two new route-maps have been added to the last (for import/export policies). Added the following #defines: RMAP_{IN|OUT|IMPORT|EXPORT|MAX}, PEER_RMAP_TYPE_{IMPORT|EXPORT} and BGP_CLEAR_SOFT_RSCLIENT. * bgpd/bgpd.c: Modified the functions that create/delete/etc peers in order to consider the new fields included in 'struct peer' for supporting rs-clients, i.e. the import/export route-maps and the 'struct bgp_table'. * bgpd/bgp_route.{ch}: Modified several functions related with receiving/sending announces in order to support the new Route Server capabilities. Function 'bgp_process' has been reorganized, creating an auxiliar function for best path selection ('bgp_best_selection'). Modified 'bgp_show' and 'bgp_show_route' for displaying information about any RIB (and not only the main bgp RIB). Added commands for displaying information about RS-clients RIBs: 'show bgp rsclient (A.B.C.D|X:X::X:X)', 'show bgp rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M', etc * bgpd/bgp_table.{ch}: The structure 'struct bgp_table' now has two new fields: type (which can take the values BGP_TABLE_{MAIN|RSCLIENT}) and 'void *owner' which points to 'struct bgp' or 'struct peer' which owns the table. When creating a new bgp_table by default 'type=BGP_TABLE_MAIN' is set. * bgpd/bgp_vty.c: The commands 'neighbor ... route-server-client' and 'no neighbor ... route-server-client' now not only set/unset the flag PEER_FLAG_RSERVER_CLIENT, but they create/destroy the 'struct bgp_table' of the peer. Special actions are taken for peer_groups. Command 'neighbor ... route-map WORD (in|out)' now also supports two new kinds of route-map: 'import' and 'export'. Added commands 'clear bgp * rsclient', etc. These commands allow a new kind of soft_reconfig which affects only the RIB of the specified RS-client. Added commands 'show bgp rsclient summary', etc which display a summary of the rs-clients configured for the corresponding address family. * bgpd/bgp_routemap.c: A new match statement is available, 'match peer (A.B.C.D|X:X::X:X)'. This statement can only be used in import/export route-maps, and it matches when the peer who announces (when used in an import route-map) or is going to receive (when used in an export route-map) the route is the same than the one specified in the statement. For peer-groups the statement matches if the specified peer is member of the peer-group. A special version of the command, 'match peer local', matches with routes originated by the Route Server (defined with 'network ...', redistributed routes and default-originate). * lib/routemap.{ch}: Added a new clause 'call NAME' for use in route-maps. It jumps into the specified route-map and when it returns the first route-map ends if the called RM returns DENY_MATCH, or continues in other case.
2004-09-13 07:12:46 +02:00
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,
filter->map[RMAP_IMPORT].name, VTY_NEWLINE);
if (filter->map[RMAP_EXPORT].name)
if (! gfilter || ! gfilter->map[RMAP_EXPORT].name
|| strcmp (filter->map[RMAP_EXPORT].name,
gfilter->map[RMAP_EXPORT].name) != 0)
vty_out (vty, " neighbor %s route-map %s export%s", addr,
filter->map[RMAP_EXPORT].name, VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
/* unsuppress-map */
if (filter->usmap.name && ! gfilter)
vty_out (vty, " neighbor %s unsuppress-map %s%s", addr,
filter->usmap.name, VTY_NEWLINE);
/* filter-list. */
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,
filter->aslist[in].name, VTY_NEWLINE);
if (filter->aslist[out].name && ! gfilter)
vty_out (vty, " neighbor %s filter-list %s out%s", addr,
filter->aslist[out].name, VTY_NEWLINE);
}
/* BGP peer configuration display function. */
static void
2002-12-13 21:15:29 +01:00
bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
struct peer *peer, afi_t afi, safi_t safi)
{
struct bgp_filter *filter;
struct peer *g_peer = NULL;
char buf[SU_ADDRSTRLEN];
char *addr;
filter = &peer->filter[afi][safi];
addr = peer->host;
if (peer_group_active (peer))
g_peer = peer->group->conf;
/************************************
****** Global to the neighbor ******
************************************/
if (afi == AFI_IP && safi == SAFI_UNICAST)
{
/* remote-as. */
if (! peer_group_active (peer))
{
if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
vty_out (vty, " neighbor %s peer-group%s", addr,
VTY_NEWLINE);
if (peer->as)
vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
2002-12-13 21:15:29 +01:00
VTY_NEWLINE);
}
else
{
if (! g_peer->as)
vty_out (vty, " neighbor %s remote-as %u%s", addr, peer->as,
2002-12-13 21:15:29 +01:00
VTY_NEWLINE);
if (peer->af_group[AFI_IP][SAFI_UNICAST])
vty_out (vty, " neighbor %s peer-group %s%s", addr,
peer->group->name, VTY_NEWLINE);
}
/* local-as. */
if (peer->change_local_as)
if (! peer_group_active (peer))
vty_out (vty, " neighbor %s local-as %u%s%s", addr,
2002-12-13 21:15:29 +01:00
peer->change_local_as,
CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ?
" no-prepend" : "", VTY_NEWLINE);
/* Description. */
if (peer->desc)
vty_out (vty, " neighbor %s description %s%s", addr, peer->desc,
VTY_NEWLINE);
/* Shutdown. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
[bgpd] TCP-MD5: password vty configuration and initial Linux support 2008-07-21 Paul Jakma <paul.jakma@sun.com> * bgp_packet.c: (bgp_open_receive) fix warning in a zlog call * bgp_vty.c: (bgp_vty_return) add return code * bgpd.c: (bgp_master_init) setup the socket list. * bgp_network.c: Remove the dual IPv4/6 socket thing for now, which was implemented by Michael, until such time as its clear its required for Linux (see sockopt comments). IPv6 support, including IPv4 sessions on AF_INET6 sockets, therefore is broken, and the '-l 0.0.0.0' arguments would need to be given to bgpd to make things work here. 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Tomohiko Kusuda <kusuda@inetcore.com> Leigh Brown <leigh@solinno.co.uk> * bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5 sockopt and bgpd. (bgp_md5_set_socket) Helper for bgp_connect (bgp_md5_set) setup TCP-MD5SIG for the given peer. (bgp_connect) call out to bgp_md5_set_socket for the outgoing connect socket. (bgp_socket) save references to the listen sockets, needed if TCP-MD5SIG is applied later or changed. * bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password' commands. * bgpd.c: (peer_{new,delete) manage TCP-MD5 password (peer_group2peer_config_copy) inherit TCP-MD5 password (peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5 passwords: applying checks, stopping peers, and trying to return errors to UI, etc. (bgp_config_write_peer) save password. Fix missing newline in writeout of neighbor ... port. 2008-07-21 Paul Jakma <paul.jakma@sun.com> * sockunion.c: ifdef out various places that converted v4mapped sockets to pure v4. Doesn't seem necessary at all, presumably a workaround for now historical inet_ntop bugs (?) 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> * sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
/* Password. */
if (peer->password)
if (!peer_group_active (peer)
|| ! g_peer->password
|| strcmp (peer->password, g_peer->password) != 0)
vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
/* BGP port. */
if (peer->port != BGP_PORT_DEFAULT)
[bgpd] TCP-MD5: password vty configuration and initial Linux support 2008-07-21 Paul Jakma <paul.jakma@sun.com> * bgp_packet.c: (bgp_open_receive) fix warning in a zlog call * bgp_vty.c: (bgp_vty_return) add return code * bgpd.c: (bgp_master_init) setup the socket list. * bgp_network.c: Remove the dual IPv4/6 socket thing for now, which was implemented by Michael, until such time as its clear its required for Linux (see sockopt comments). IPv6 support, including IPv4 sessions on AF_INET6 sockets, therefore is broken, and the '-l 0.0.0.0' arguments would need to be given to bgpd to make things work here. 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Tomohiko Kusuda <kusuda@inetcore.com> Leigh Brown <leigh@solinno.co.uk> * bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5 sockopt and bgpd. (bgp_md5_set_socket) Helper for bgp_connect (bgp_md5_set) setup TCP-MD5SIG for the given peer. (bgp_connect) call out to bgp_md5_set_socket for the outgoing connect socket. (bgp_socket) save references to the listen sockets, needed if TCP-MD5SIG is applied later or changed. * bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password' commands. * bgpd.c: (peer_{new,delete) manage TCP-MD5 password (peer_group2peer_config_copy) inherit TCP-MD5 password (peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5 passwords: applying checks, stopping peers, and trying to return errors to UI, etc. (bgp_config_write_peer) save password. Fix missing newline in writeout of neighbor ... port. 2008-07-21 Paul Jakma <paul.jakma@sun.com> * sockunion.c: ifdef out various places that converted v4mapped sockets to pure v4. Doesn't seem necessary at all, presumably a workaround for now historical inet_ntop bugs (?) 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> * sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
2002-12-13 21:15:29 +01:00
VTY_NEWLINE);
/* Local interface name. */
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) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSIVE))
vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE);
/* EBGP multihop. */
if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1)
if (! peer_group_active (peer) ||
g_peer->ttl != peer->ttl)
vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl,
VTY_NEWLINE);
/* disable-connected-check. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
2002-12-13 21:15:29 +01:00
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
vty_out (vty, " neighbor %s disable-connected-check%s", addr, VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
/* Update-source. */
if (peer->update_if)
if (! peer_group_active (peer) || ! g_peer->update_if
|| strcmp (g_peer->update_if, peer->update_if) != 0)
vty_out (vty, " neighbor %s update-source %s%s", addr,
peer->update_if, VTY_NEWLINE);
if (peer->update_source)
if (! peer_group_active (peer) || ! g_peer->update_source
|| sockunion_cmp (g_peer->update_source,
peer->update_source) != 0)
vty_out (vty, " neighbor %s update-source %s%s", addr,
sockunion2str (peer->update_source, buf, SU_ADDRSTRLEN),
VTY_NEWLINE);
/* 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);
/* timers. */
if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER)
&& ! peer_group_active (peer))
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,
peer->connect, VTY_NEWLINE);
/* Default weight. */
if (CHECK_FLAG (peer->config, PEER_CONFIG_WEIGHT))
if (! peer_group_active (peer) ||
g_peer->weight != peer->weight)
vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight,
VTY_NEWLINE);
/* Dynamic capability. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY))
vty_out (vty, " neighbor %s capability dynamic%s", addr,
VTY_NEWLINE);
/* dont capability negotiation. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_DONT_CAPABILITY))
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_DONT_CAPABILITY))
vty_out (vty, " neighbor %s dont-capability-negotiate%s", addr,
VTY_NEWLINE);
/* override capability negotiation. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_OVERRIDE_CAPABILITY))
vty_out (vty, " neighbor %s override-capability%s", addr,
VTY_NEWLINE);
/* strict capability negotiation. */
if (CHECK_FLAG (peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
if (! peer_group_active (peer) ||
! CHECK_FLAG (g_peer->flags, PEER_FLAG_STRICT_CAP_MATCH))
vty_out (vty, " neighbor %s strict-capability-match%s", addr,
VTY_NEWLINE);
if (! peer_group_active (peer))
{
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
{
if (peer->afc[AFI_IP][SAFI_UNICAST])
vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
}
else
{
if (! peer->afc[AFI_IP][SAFI_UNICAST])
vty_out (vty, " no neighbor %s activate%s", addr, VTY_NEWLINE);
}
}
}
/************************************
****** Per AF to the neighbor ******
************************************/
if (! (afi == AFI_IP && safi == SAFI_UNICAST))
{
if (peer->af_group[afi][safi])
vty_out (vty, " neighbor %s peer-group %s%s", addr,
peer->group->name, VTY_NEWLINE);
else
vty_out (vty, " neighbor %s activate%s", addr, VTY_NEWLINE);
}
/* ORF capability. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
if (! peer->af_group[afi][safi])
{
vty_out (vty, " neighbor %s capability orf prefix-list", addr);
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM)
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_RM))
vty_out (vty, " both");
else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ORF_PREFIX_SM))
vty_out (vty, " send");
else
vty_out (vty, " receive");
vty_out (vty, "%s", VTY_NEWLINE);
}
/* 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_NEWLINE);
/* Nexthop self. */
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)
&& ! peer->af_group[afi][safi])
vty_out (vty, " neighbor %s next-hop-self%s", addr, VTY_NEWLINE);
/* Remove private AS. */
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
&& ! peer->af_group[afi][safi])
vty_out (vty, " neighbor %s remove-private-AS%s",
addr, VTY_NEWLINE);
/* send-community print. */
if (! peer->af_group[afi][safi])
{
if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
{
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))
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))
vty_out (vty, " neighbor %s send-community%s", addr, VTY_NEWLINE);
}
else
{
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, " no neighbor %s send-community both%s",
addr, VTY_NEWLINE);
else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_EXT_COMMUNITY))
vty_out (vty, " no neighbor %s send-community extended%s",
addr, VTY_NEWLINE);
else if (! peer_af_flag_check (peer, afi, safi, PEER_FLAG_SEND_COMMUNITY))
vty_out (vty, " no neighbor %s send-community%s",
addr, VTY_NEWLINE);
}
}
/* Default information */
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE)
&& ! peer->af_group[afi][safi])
{
vty_out (vty, " neighbor %s default-originate", addr);
if (peer->default_rmap[afi][safi].name)
vty_out (vty, " route-map %s", peer->default_rmap[afi][safi].name);
vty_out (vty, "%s", VTY_NEWLINE);
}
/* Soft reconfiguration inbound. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
if (! peer->af_group[afi][safi] ||
! CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
vty_out (vty, " neighbor %s soft-reconfiguration inbound%s", addr,
VTY_NEWLINE);
/* maximum-prefix. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
if (! peer->af_group[afi][safi]
|| g_peer->pmax[afi][safi] != peer->pmax[afi][safi]
|| g_peer->pmax_threshold[afi][safi] != peer->pmax_threshold[afi][safi]
2002-12-13 21:15:29 +01:00
|| CHECK_FLAG (g_peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)
!= CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
{
vty_out (vty, " neighbor %s maximum-prefix %ld", addr, peer->pmax[afi][safi]);
if (peer->pmax_threshold[afi][safi] != MAXIMUM_PREFIX_THRESHOLD_DEFAULT)
vty_out (vty, " %d", peer->pmax_threshold[afi][safi]);
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
vty_out (vty, " warning-only");
if (peer->pmax_restart[afi][safi])
vty_out (vty, " restart %d", peer->pmax_restart[afi][safi]);
vty_out (vty, "%s", VTY_NEWLINE);
}
2002-12-13 21:15:29 +01:00
/* Route server client. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
&& ! peer->af_group[afi][safi])
vty_out (vty, " neighbor %s route-server-client%s", addr, VTY_NEWLINE);
/* Allow AS in. */
if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_ALLOWAS_IN))
if (! peer_group_active (peer)
|| ! peer_af_flag_check (g_peer, afi, safi, PEER_FLAG_ALLOWAS_IN)
|| peer->allowas_in[afi][safi] != g_peer->allowas_in[afi][safi])
{
if (peer->allowas_in[afi][safi] == 3)
vty_out (vty, " neighbor %s allowas-in%s", addr, VTY_NEWLINE);
else
vty_out (vty, " neighbor %s allowas-in %d%s", addr,
peer->allowas_in[afi][safi], VTY_NEWLINE);
}
/* Filter. */
bgp_config_write_filter (vty, peer, afi, safi);
/* atribute-unchanged. */
if ((CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
|| CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
&& ! peer->af_group[afi][safi])
{
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)
&& CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
&& 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,
(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)) ?
" next-hop" : "",
(CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) ?
" med" : "", VTY_NEWLINE);
}
}
/* Display "address-family" configuration header. */
void
bgp_config_write_family_header (struct vty *vty, afi_t afi, safi_t safi,
int *write)
{
if (*write)
return;
if (afi == AFI_IP && safi == SAFI_UNICAST)
return;
vty_out (vty, "!%s address-family ", VTY_NEWLINE);
if (afi == AFI_IP)
{
if (safi == SAFI_MULTICAST)
vty_out (vty, "ipv4 multicast");
else if (safi == SAFI_MPLS_VPN)
vty_out (vty, "vpnv4 unicast");
}
else if (afi == AFI_IP6)
{
vty_out (vty, "ipv6");
if (safi == SAFI_MULTICAST)
vty_out (vty, " multicast");
}
2002-12-13 21:15:29 +01:00
vty_out (vty, "%s", VTY_NEWLINE);
*write = 1;
}
/* Address family based peer configuration display. */
static int
2002-12-13 21:15:29 +01:00
bgp_config_write_family (struct vty *vty, struct bgp *bgp, afi_t afi,
safi_t safi)
{
int write = 0;
struct peer *peer;
struct peer_group *group;
struct listnode *node, *nnode;
2002-12-13 21:15:29 +01:00
bgp_config_write_network (vty, bgp, afi, safi, &write);
bgp_config_write_redistribute (vty, bgp, afi, safi, &write);
for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
2002-12-13 21:15:29 +01:00
{
if (group->conf->afc[afi][safi])
{
bgp_config_write_family_header (vty, afi, safi, &write);
bgp_config_write_peer (vty, bgp, group->conf, afi, safi);
}
}
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (peer->afc[afi][safi])
{
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
{
bgp_config_write_family_header (vty, afi, safi, &write);
bgp_config_write_peer (vty, bgp, peer, afi, safi);
}
}
}
if (write)
vty_out (vty, " exit-address-family%s", VTY_NEWLINE);
return write;
}
int
bgp_config_write (struct vty *vty)
{
int write = 0;
struct bgp *bgp;
struct peer_group *group;
struct peer *peer;
struct listnode *node, *nnode;
struct listnode *mnode, *mnnode;
2002-12-13 21:15:29 +01:00
/* 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++;
}
/* BGP configuration. */
for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
2002-12-13 21:15:29 +01:00
{
if (write)
vty_out (vty, "!%s", VTY_NEWLINE);
/* Router bgp ASN */
vty_out (vty, "router bgp %u", bgp->as);
2002-12-13 21:15:29 +01:00
if (bgp_option_check (BGP_OPT_MULTIPLE_INSTANCE))
{
if (bgp->name)
vty_out (vty, " view %s", bgp->name);
}
vty_out (vty, "%s", VTY_NEWLINE);
/* No Synchronization */
if (bgp_option_check (BGP_OPT_CONFIG_CISCO))
vty_out (vty, " no synchronization%s", VTY_NEWLINE);
/* 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);
/* 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_NEWLINE);
/* BGP log-neighbor-changes. */
if (bgp_flag_check (bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES))
vty_out (vty, " bgp log-neighbor-changes%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
/* BGP configuration. */
if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED))
vty_out (vty, " bgp always-compare-med%s", VTY_NEWLINE);
/* BGP default ipv4-unicast. */
if (bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4))
vty_out (vty, " no bgp default ipv4-unicast%s", VTY_NEWLINE);
/* BGP default local-preference. */
if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
vty_out (vty, " bgp default local-preference %d%s",
bgp->default_local_pref, VTY_NEWLINE);
/* 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),
VTY_NEWLINE);
/* Confederation identifier*/
2002-12-13 21:15:29 +01:00
if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION))
vty_out (vty, " bgp confederation identifier %i%s", bgp->confed_id,
VTY_NEWLINE);
/* Confederation peer */
if (bgp->confed_peers_cnt > 0)
2002-12-13 21:15:29 +01:00
{
int i;
2002-12-13 21:15:29 +01:00
vty_out (vty, " bgp confederation peers");
2002-12-13 21:15:29 +01:00
for (i = 0; i < bgp->confed_peers_cnt; i++)
vty_out(vty, " %u", bgp->confed_peers[i]);
2002-12-13 21:15:29 +01:00
vty_out (vty, "%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
}
/* BGP enforce-first-as. */
if (bgp_flag_check (bgp, BGP_FLAG_ENFORCE_FIRST_AS))
vty_out (vty, " bgp enforce-first-as%s", VTY_NEWLINE);
/* BGP deterministic-med. */
if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
vty_out (vty, " bgp deterministic-med%s", VTY_NEWLINE);
/* BGP graceful-restart. */
if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME)
vty_out (vty, " bgp graceful-restart stalepath-time %d%s",
bgp->stalepath_time, VTY_NEWLINE);
if (bgp_flag_check (bgp, BGP_FLAG_GRACEFUL_RESTART))
vty_out (vty, " bgp graceful-restart%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
/* BGP bestpath method. */
if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
vty_out (vty, " bgp bestpath as-path ignore%s", VTY_NEWLINE);
if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
vty_out (vty, " bgp bestpath as-path confed%s", VTY_NEWLINE);
2002-12-13 21:15:29 +01:00
if (bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID))
vty_out (vty, " bgp bestpath compare-routerid%s", VTY_NEWLINE);
if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
|| bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
{
vty_out (vty, " bgp bestpath med");
if (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED))
vty_out (vty, " confed");
if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
vty_out (vty, " missing-as-worst");
vty_out (vty, "%s", VTY_NEWLINE);
}
/* BGP network import check. */
if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
vty_out (vty, " bgp network import-check%s", VTY_NEWLINE);
/* BGP scan interval. */
bgp_config_write_scan_time (vty);
/* BGP flag dampening. */
if (CHECK_FLAG (bgp->af_flags[AFI_IP][SAFI_UNICAST],
BGP_CONFIG_DAMPENING))
bgp_config_write_damp (vty);
/* BGP static route configuration. */
bgp_config_write_network (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
/* BGP redistribute configuration. */
bgp_config_write_redistribute (vty, bgp, AFI_IP, SAFI_UNICAST, &write);
/* 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,
bgp->default_holdtime, VTY_NEWLINE);
/* peer-group */
for (ALL_LIST_ELEMENTS (bgp->group, node, nnode, group))
2002-12-13 21:15:29 +01:00
{
bgp_config_write_peer (vty, bgp, group->conf, AFI_IP, SAFI_UNICAST);
}
/* Normal neighbor configuration. */
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
2002-12-13 21:15:29 +01:00
{
if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER))
bgp_config_write_peer (vty, bgp, peer, AFI_IP, SAFI_UNICAST);
}
/* 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);
/* IPv4 multicast configuration. */
write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MULTICAST);
/* IPv4 VPN configuration. */
write += bgp_config_write_family (vty, bgp, AFI_IP, SAFI_MPLS_VPN);
/* IPv6 unicast configuration. */
write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_UNICAST);
/* IPv6 multicast configuration. */
write += bgp_config_write_family (vty, bgp, AFI_IP6, SAFI_MULTICAST);
2002-12-13 21:15:29 +01:00
write++;
}
return write;
}
void
bgp_master_init (void)
2002-12-13 21:15:29 +01:00
{
memset (&bgp_master, 0, sizeof (struct bgp_master));
bm = &bgp_master;
bm->bgp = list_new ();
[bgpd] TCP-MD5: password vty configuration and initial Linux support 2008-07-21 Paul Jakma <paul.jakma@sun.com> * bgp_packet.c: (bgp_open_receive) fix warning in a zlog call * bgp_vty.c: (bgp_vty_return) add return code * bgpd.c: (bgp_master_init) setup the socket list. * bgp_network.c: Remove the dual IPv4/6 socket thing for now, which was implemented by Michael, until such time as its clear its required for Linux (see sockopt comments). IPv6 support, including IPv4 sessions on AF_INET6 sockets, therefore is broken, and the '-l 0.0.0.0' arguments would need to be given to bgpd to make things work here. 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Tomohiko Kusuda <kusuda@inetcore.com> Leigh Brown <leigh@solinno.co.uk> * bgp_network.c: (bgp_md5_set_one) shim between libzebra tcp-md5 sockopt and bgpd. (bgp_md5_set_socket) Helper for bgp_connect (bgp_md5_set) setup TCP-MD5SIG for the given peer. (bgp_connect) call out to bgp_md5_set_socket for the outgoing connect socket. (bgp_socket) save references to the listen sockets, needed if TCP-MD5SIG is applied later or changed. * bgp_vty.c: (*neighbor_password_cmd) New 'neighbor ... password' commands. * bgpd.c: (peer_{new,delete) manage TCP-MD5 password (peer_group2peer_config_copy) inherit TCP-MD5 password (peer_password_{un,}set) orchestrate the whole add/remove of TCP-MD5 passwords: applying checks, stopping peers, and trying to return errors to UI, etc. (bgp_config_write_peer) save password. Fix missing newline in writeout of neighbor ... port. 2008-07-21 Paul Jakma <paul.jakma@sun.com> * sockunion.c: ifdef out various places that converted v4mapped sockets to pure v4. Doesn't seem necessary at all, presumably a workaround for now historical inet_ntop bugs (?) 2008-07-21 Michael H. Warfield <mhw@wittsend.com> YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> * sockopt.{c,h}: (sockopt_tcp_signature) Add TCP-MD5SIG support.
2008-07-21 23:02:49 +02:00
bm->listen_sockets = list_new ();
2002-12-13 21:15:29 +01:00
bm->port = BGP_PORT_DEFAULT;
bm->master = thread_master_create ();
bm->start_time = time (NULL);
}
2005-06-01 Paul Jakma <paul.jakma@sun.com> * bgpd/(general) refcount struct peer and bgp_info, hence allowing us add work_queues for bgp_process. * bgpd/bgp_route.h: (struct bgp_info) Add 'lock' field for refcount. Add bgp_info_{lock,unlock} helper functions. Add bgp_info_{add,delete} helpers, to remove need for users managing locking/freeing of bgp_info and bgp_node's. * bgpd/bgp_table.h: (struct bgp_node) Add a flags field, and BGP_NODE_PROCESS_SCHEDULED to merge redundant processing of nodes. * bgpd/bgp_fsm.h: Make the ON/OFF/ADD/REMOVE macros lock and unlock peer reference as appropriate. * bgpd/bgp_damp.c: Remove its internal prototypes for bgp_info_delete/free. Just use bgp_info_delete. * bgpd/bgpd.h: (struct bgp_master) Add work_queue pointers. (struct peer) Add reference count 'lock' (peer_lock,peer_unlock) New helpers to take/release reference on struct peer. * bgpd/bgp_advertise.c: (general) Add peer and bgp_info refcounting and balance how references are taken and released. (bgp_advertise_free) release bgp_info reference, if appropriate (bgp_adj_out_free) unlock peer (bgp_advertise_clean) leave the adv references alone, or else call bgp_advertise_free cant unlock them. (bgp_adj_out_set) lock the peer on new adj's, leave the reference alone otherwise. lock the new bgp_info reference. (bgp_adj_in_set) lock the peer reference (bgp_adj_in_remove) and unlock it here (bgp_sync_delete) make hash_free on peer conditional, just in case. * bgpd/bgp_fsm.c: (general) document that the timers depend on bgp_event to release a peer reference. (bgp_fsm_change_status) moved up the file, unchanged. (bgp_stop) Decrement peer lock as many times as cancel_event canceled - shouldnt be needed but just in case. stream_fifo_clean of obuf made conditional, just in case. (bgp_event) always unlock the peer, regardless of return value of bgp_fsm_change_status. * bgpd/bgp_packet.c: (general) change several bgp_stop's to BGP_EVENT's. (bgp_read) Add a mysterious extra peer_unlock for ACCEPT_PEERs along with a comment on it. * bgpd/bgp_route.c: (general) Add refcounting of bgp_info, cleanup some of the resource management around bgp_info. Refcount peer. Add workqueues for bgp_process and clear_table. (bgp_info_new) make static (bgp_info_free) Ditto, and unlock the peer reference. (bgp_info_lock,bgp_info_unlock) new exported functions (bgp_info_add) Add a bgp_info to a bgp_node in correct fashion, taking care of reference counts. (bgp_info_delete) do the opposite of bgp_info_add. (bgp_process_rsclient) Converted into a work_queue work function. (bgp_process_main) ditto. (bgp_processq_del) process work queue item deconstructor (bgp_process_queue_init) process work queue init (bgp_process) call init function if required, set up queue item and add to queue, rather than calling process functions directly. (bgp_rib_remove) let bgp_info_delete manage bgp_info refcounts (bgp_rib_withdraw) ditto (bgp_update_rsclient) let bgp_info_add manage refcounts (bgp_update_main) ditto (bgp_clear_route_node) clear_node_queue work function, does per-node aspects of what bgp_clear_route_table did previously (bgp_clear_node_queue_del) clear_node_queue item delete function (bgp_clear_node_complete) clear_node_queue completion function, it unplugs the process queues, which have to be blocked while clear_node_queue is being processed to prevent a race. (bgp_clear_node_queue_init) init function for clear_node_queue work queues (bgp_clear_route_table) Sets up items onto a workqueue now, rather than clearing each node directly. Plugs both process queues to avoid potential race. (bgp_static_withdraw_rsclient) let bgp_info_{add,delete} manage bgp_info refcounts. (bgp_static_update_rsclient) ditto (bgp_static_update_main) ditto (bgp_static_update_vpnv4) ditto, remove unneeded cast. (bgp_static_withdraw) see bgp_static_withdraw_rsclient (bgp_static_withdraw_vpnv4) ditto (bgp_aggregate_{route,add,delete}) ditto (bgp_redistribute_{add,delete,withdraw}) ditto * bgpd/bgp_vty.c: (peer_rsclient_set_vty) lock rsclient list peer reference (peer_rsclient_unset_vty) ditto, but unlock same reference * bgpd/bgpd.c: (peer_free) handle frees of info to be kept for lifetime of struct peer. (peer_lock,peer_unlock) peer refcount helpers (peer_new) add initial refcounts (peer_create,peer_create_accept) lock peer as appropriate (peer_delete) unlock as appropriate, move out some free's to peer_free. (peer_group_bind,peer_group_unbind) peer refcounting as appropriate. (bgp_create) check CALLOC return value. (bgp_terminate) free workqueues too. * lib/memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE
2005-06-01 13:17:05 +02:00
2002-12-13 21:15:29 +01:00
void
bgp_init (void)
2002-12-13 21:15:29 +01:00
{
/* BGP VTY commands installation. */
bgp_vty_init ();
/* Create BGP server socket. */
bgp_socket (NULL, bm->port, bm->address);
2002-12-13 21:15:29 +01:00
/* Init zebra. */
bgp_zebra_init ();
/* BGP inits. */
bgp_attr_init ();
bgp_debug_init ();
bgp_dump_init ();
bgp_route_init ();
bgp_route_map_init ();
bgp_scan_init ();
bgp_mplsvpn_init ();
/* Access list initialize. */
access_list_init ();
access_list_add_hook (peer_distribute_update);
access_list_delete_hook (peer_distribute_update);
/* Filter list initialize. */
bgp_filter_init ();
as_list_add_hook (peer_aslist_update);
as_list_delete_hook (peer_aslist_update);
/* Prefix list initialize.*/
prefix_list_init ();
prefix_list_add_hook (peer_prefix_list_update);
prefix_list_delete_hook (peer_prefix_list_update);
/* Community list initialize. */
bgp_clist = community_list_init ();
#ifdef HAVE_SNMP
bgp_snmp_init ();
#endif /* HAVE_SNMP */
}
void
bgp_terminate ()
{
struct bgp *bgp;
struct peer *peer;
struct listnode *node, *nnode;
struct listnode *mnode, *mnnode;
for (ALL_LIST_ELEMENTS (bm->bgp, mnode, mnnode, bgp))
for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
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);
bm->process_main_queue = NULL;
}
if (bm->process_rsclient_queue)
{
work_queue_free (bm->process_rsclient_queue);
bm->process_rsclient_queue = NULL;
}
}