#include "thread.h"
#include "buffer.h"
#include "stream.h"
+#include "ringbuf.h"
#include "command.h"
#include "sockunion.h"
#include "sockopt.h"
#include "jhash.h"
#include "table.h"
#include "lib/json.h"
+#include "frr_pthread.h"
#include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_bfd.h"
#include "bgpd/bgp_memory.h"
#include "bgpd/bgp_evpn_vty.h"
-
+#include "bgpd/bgp_keepalives.h"
+#include "bgpd/bgp_io.h"
+#include "bgpd/bgp_ecommunity.h"
DEFINE_MTYPE_STATIC(BGPD, PEER_TX_SHUTDOWN_MSG, "Peer shutdown message (TX)");
DEFINE_QOBJ_TYPE(bgp_master)
return 0;
/* EVPN uses router id in RD, withdraw them */
- if (bgp->advertise_all_vni)
+ if (is_evpn_enabled())
bgp_evpn_handle_router_id_update(bgp, TRUE);
IPV4_ADDR_COPY(&bgp->router_id, id);
}
/* EVPN uses router id in RD, update them */
- if (bgp->advertise_all_vni)
+ if (is_evpn_enabled())
bgp_evpn_handle_router_id_update(bgp, FALSE);
return 0;
}
/* Check peer's AS number and determines if this peer is IBGP or EBGP */
-static bgp_peer_sort_t peer_calc_sort(struct peer *peer)
+static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
{
struct bgp *bgp;
* but just to be sure..
*/
bgp_timer_set(peer);
- BGP_READ_OFF(peer->t_read);
- BGP_WRITE_OFF(peer->t_write);
+ bgp_reads_off(peer);
+ bgp_writes_off(peer);
+ assert(!peer->t_write);
+ assert(!peer->t_read);
BGP_EVENT_FLUSH(peer);
+ pthread_mutex_destroy(&peer->io_mtx);
+
/* Free connected nexthop, if present */
if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)
&& !peer_dynamic_neighbor(peer))
peer->password = NULL;
/* Set default flags. */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (!bgp_option_check(BGP_OPT_CONFIG_CISCO)) {
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_SEND_COMMUNITY);
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_SEND_EXT_COMMUNITY);
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_SEND_LARGE_COMMUNITY);
- }
- peer->orf_plist[afi][safi] = NULL;
+ FOREACH_AFI_SAFI (afi, 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);
+ SET_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_SEND_LARGE_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->ibuf = stream_fifo_new();
peer->obuf = stream_fifo_new();
+ pthread_mutex_init(&peer->io_mtx, NULL);
- /* We use a larger buffer for peer->work in the event that:
+ /* We use a larger buffer for peer->obuf_work in the event that:
* - We RX a BGP_UPDATE where the attributes alone are just
* under BGP_MAX_PACKET_SIZE
* - The user configures an outbound route-map that does many as-path
* bounds
* checking for every single attribute as we construct an UPDATE.
*/
- peer->work =
+ peer->obuf_work =
stream_new(BGP_MAX_PACKET_SIZE + BGP_MAX_PACKET_SIZE_OVERFLOW);
- peer->scratch = stream_new(BGP_MAX_PACKET_SIZE);
+ peer->ibuf_work =
+ ringbuf_new(BGP_MAX_PACKET_SIZE * BGP_READ_PACKET_MAX);
+ peer->scratch = stream_new(BGP_MAX_PACKET_SIZE);
bgp_sync_init(peer);
peer_dst->local_as = peer_src->local_as;
peer_dst->ifindex = peer_src->ifindex;
peer_dst->port = peer_src->port;
- peer_sort(peer_dst);
+ (void)peer_sort(peer_dst);
peer_dst->rmap_type = peer_src->rmap_type;
/* Timers */
peer_dst->password =
XSTRDUP(MTYPE_PEER_PASSWORD, peer_src->password);
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- peer_dst->afc[afi][safi] = peer_src->afc[afi][safi];
- peer_dst->af_flags[afi][safi] =
- peer_src->af_flags[afi][safi];
- peer_dst->allowas_in[afi][safi] =
- peer_src->allowas_in[afi][safi];
- peer_dst->weight[afi][safi] =
- peer_src->weight[afi][safi];
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ peer_dst->afc[afi][safi] = peer_src->afc[afi][safi];
+ peer_dst->af_flags[afi][safi] = peer_src->af_flags[afi][safi];
+ peer_dst->allowas_in[afi][safi] =
+ peer_src->allowas_in[afi][safi];
+ peer_dst->weight[afi][safi] = peer_src->weight[afi][safi];
+ }
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
paf = peer_src->peer_af_array[afidx];
afi_t afi;
safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- bgp_recalculate_afi_safi_bestpaths(bgp, afi, safi);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ bgp_recalculate_afi_safi_bestpaths(bgp, afi, safi);
}
}
listnode_add_sort(bgp->peer, peer);
hash_get(bgp->peerhash, peer, hash_alloc_intern);
+ /* Adjust update-group coalesce timer heuristics for # peers. */
+ if (bgp->heuristic_coalesce) {
+ long ct = BGP_DEFAULT_SUBGROUP_COALESCE_TIME
+ + (bgp->peer->count
+ * BGP_PEER_ADJUST_SUBGROUP_COALESCE_TIME);
+ bgp->coalesce_time = MIN(BGP_MAX_SUBGROUP_COALESCE_TIME, ct);
+ }
+
active = peer_active(peer);
/* Last read and reset time set */
BGP_NOTIFY_CEASE_CONFIG_CHANGE);
}
}
+ if (peer->status == OpenSent || peer->status == OpenConfirm) {
+ peer->last_reset = PEER_DOWN_AF_ACTIVATE;
+ bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ }
}
return 0;
bgp = peer->bgp;
accept_peer = CHECK_FLAG(peer->sflags, PEER_STATUS_ACCEPT_PEER);
+ bgp_reads_off(peer);
+ bgp_writes_off(peer);
+ assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_WRITES_ON));
+ assert(!CHECK_FLAG(peer->thread_flags, PEER_THREAD_READS_ON));
+
if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT))
peer_nsf_stop(peer);
/* Buffers. */
if (peer->ibuf) {
- stream_free(peer->ibuf);
+ stream_fifo_free(peer->ibuf);
peer->ibuf = NULL;
}
peer->obuf = NULL;
}
- if (peer->work) {
- stream_free(peer->work);
- peer->work = NULL;
+ if (peer->ibuf_work) {
+ ringbuf_del(peer->ibuf_work);
+ peer->ibuf_work = NULL;
+ }
+
+ if (peer->obuf_work) {
+ stream_free(peer->obuf_work);
+ peer->obuf_work = NULL;
}
if (peer->scratch) {
}
/* 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) {
- XFREE(MTYPE_BGP_FILTER_NAME,
- filter->dlist[i].name);
- filter->dlist[i].name = NULL;
- }
-
- if (filter->plist[i].name) {
- XFREE(MTYPE_BGP_FILTER_NAME,
- filter->plist[i].name);
- filter->plist[i].name = NULL;
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ filter = &peer->filter[afi][safi];
- if (filter->aslist[i].name) {
- XFREE(MTYPE_BGP_FILTER_NAME,
- filter->aslist[i].name);
- filter->aslist[i].name = NULL;
- }
+ for (i = FILTER_IN; i < FILTER_MAX; i++) {
+ if (filter->dlist[i].name) {
+ XFREE(MTYPE_BGP_FILTER_NAME,
+ filter->dlist[i].name);
+ filter->dlist[i].name = NULL;
}
- for (i = RMAP_IN; i < RMAP_MAX; i++) {
- if (filter->map[i].name) {
- XFREE(MTYPE_BGP_FILTER_NAME,
- filter->map[i].name);
- filter->map[i].name = NULL;
- }
+ if (filter->plist[i].name) {
+ XFREE(MTYPE_BGP_FILTER_NAME,
+ filter->plist[i].name);
+ filter->plist[i].name = NULL;
}
- if (filter->usmap.name) {
+ if (filter->aslist[i].name) {
XFREE(MTYPE_BGP_FILTER_NAME,
- filter->usmap.name);
- filter->usmap.name = NULL;
+ filter->aslist[i].name);
+ filter->aslist[i].name = NULL;
}
+ }
- if (peer->default_rmap[afi][safi].name) {
- XFREE(MTYPE_ROUTE_MAP_NAME,
- peer->default_rmap[afi][safi].name);
- peer->default_rmap[afi][safi].name = NULL;
+ for (i = RMAP_IN; i < RMAP_MAX; i++) {
+ if (filter->map[i].name) {
+ XFREE(MTYPE_BGP_FILTER_NAME,
+ filter->map[i].name);
+ filter->map[i].name = NULL;
}
}
+ if (filter->usmap.name) {
+ XFREE(MTYPE_BGP_FILTER_NAME, filter->usmap.name);
+ filter->usmap.name = NULL;
+ }
+
+ if (peer->default_rmap[afi][safi].name) {
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ peer->default_rmap[afi][safi].name);
+ peer->default_rmap[afi][safi].name = NULL;
+ }
+ }
+
FOREACH_AFI_SAFI (afi, safi)
peer_af_delete(peer, afi, safi);
group->conf->gtsm_hops = 0;
group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
UNSET_FLAG(group->conf->config, PEER_CONFIG_TIMER);
+ UNSET_FLAG(group->conf->config, PEER_GROUP_CONFIG_TIMER);
UNSET_FLAG(group->conf->config, PEER_CONFIG_CONNECT);
group->conf->keepalive = 0;
group->conf->holdtime = 0;
if (peer->conf_if && cap_enhe_preset)
peer_flag_set(peer, PEER_FLAG_CAPABILITY_ENHE);
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (group->conf->afc[afi][safi]) {
- peer->afc[afi][safi] = 1;
-
- if (peer_af_find(peer, afi, safi)
- || peer_af_create(peer, afi,
- safi)) {
- peer_group2peer_config_copy_af(
- group, peer, afi, safi);
- }
- } else if (peer->afc[afi][safi])
- peer_deactivate(peer, afi, safi);
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (group->conf->afc[afi][safi]) {
+ peer->afc[afi][safi] = 1;
+
+ if (peer_af_find(peer, afi, safi)
+ || peer_af_create(peer, afi, safi)) {
+ peer_group2peer_config_copy_af(
+ group, peer, afi, safi);
+ }
+ } else if (peer->afc[afi][safi])
+ peer_deactivate(peer, afi, safi);
}
if (peer->group) {
/* If the peer-group is active for this afi/safi then activate
* for this peer */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- if (group->conf->afc[afi][safi]) {
- peer->afc[afi][safi] = 1;
- peer_af_create(peer, afi, safi);
- peer_group2peer_config_copy_af(
- group, peer, afi, safi);
- } else if (peer->afc[afi][safi])
- peer_deactivate(peer, afi, safi);
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (group->conf->afc[afi][safi]) {
+ peer->afc[afi][safi] = 1;
+ peer_af_create(peer, afi, safi);
+ peer_group2peer_config_copy_af(group, peer, afi,
+ safi);
+ } else if (peer->afc[afi][safi])
+ peer_deactivate(peer, afi, safi);
+ }
SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
if (group != peer->group)
return BGP_ERR_PEER_GROUP_MISMATCH;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (peer->afc[afi][safi]) {
- peer->afc[afi][safi] = 0;
- peer_af_flag_reset(peer, afi, safi);
-
- if (peer_af_delete(peer, afi, safi) != 0) {
- zlog_err(
- "couldn't delete af structure for peer %s",
- peer->host);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (peer->afc[afi][safi]) {
+ peer->afc[afi][safi] = 0;
+ peer_af_flag_reset(peer, afi, safi);
+
+ if (peer_af_delete(peer, afi, safi) != 0) {
+ zlog_err(
+ "couldn't delete af structure for peer %s",
+ peer->host);
}
}
+ }
assert(listnode_lookup(group->peer, peer));
peer_unlock(peer); /* peer group list reference */
bgp->group = list_new();
bgp->group->cmp = (int (*)(void *, void *))peer_group_cmp;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- 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);
+ FOREACH_AFI_SAFI (afi, safi) {
+ 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);
- /* Enable maximum-paths */
- bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP,
- multipath_num, 0);
- bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_IBGP,
- multipath_num, 0);
- }
+ /* Enable maximum-paths */
+ bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_EBGP,
+ multipath_num, 0);
+ bgp_maximum_paths_set(bgp, afi, safi, BGP_PEER_IBGP,
+ multipath_num, 0);
+ }
bgp->v_update_delay = BGP_UPDATE_DELAY_DEF;
bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF;
bgp->restart_time, &bgp->t_startup);
}
- bgp->wpkt_quanta = BGP_WRITE_PACKET_MAX;
+ atomic_store_explicit(&bgp->wpkt_quanta, BGP_WRITE_PACKET_MAX,
+ memory_order_relaxed);
+ atomic_store_explicit(&bgp->rpkt_quanta, BGP_READ_PACKET_MAX,
+ memory_order_relaxed);
bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
QOBJ_REG(bgp, bgp);
bgp->name);
}
+ /* unmap from RT list */
+ bgp_evpn_vrf_delete(bgp);
+
/* Stop timers. */
if (bgp->t_rmap_def_originate_eval) {
BGP_TIMER_OFF(bgp->t_rmap_def_originate_eval);
bgp->peerhash = NULL;
}
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- /* Special handling for 2-level routing tables. */
- if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
- || safi == SAFI_EVPN) {
- for (rn = bgp_table_top(bgp->rib[afi][safi]);
- rn; rn = bgp_route_next(rn)) {
- table = (struct bgp_table *)rn->info;
- bgp_table_finish(&table);
- }
+ FOREACH_AFI_SAFI (afi, safi) {
+ /* Special handling for 2-level routing tables. */
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN) {
+ for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ table = (struct bgp_table *)rn->info;
+ bgp_table_finish(&table);
}
- if (bgp->route[afi][safi])
- bgp_table_finish(&bgp->route[afi][safi]);
- if (bgp->aggregate[afi][safi])
- bgp_table_finish(&bgp->aggregate[afi][safi]);
- if (bgp->rib[afi][safi])
- bgp_table_finish(&bgp->rib[afi][safi]);
- rmap = &bgp->table_map[afi][safi];
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
}
+ if (bgp->route[afi][safi])
+ bgp_table_finish(&bgp->route[afi][safi]);
+ if (bgp->aggregate[afi][safi])
+ bgp_table_finish(&bgp->aggregate[afi][safi]);
+ if (bgp->rib[afi][safi])
+ bgp_table_finish(&bgp->rib[afi][safi]);
+ rmap = &bgp->table_map[afi][safi];
+ if (rmap->name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ }
bgp_scan_finish(bgp);
bgp_address_destroy(bgp);
* peer_group_bind as that is sub-optimal and does some stuff we don't
* want.
*/
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
- if (!group->conf->afc[afi][safi])
- continue;
- peer->afc[afi][safi] = 1;
+ FOREACH_AFI_SAFI (afi, safi) {
+ if (!group->conf->afc[afi][safi])
+ continue;
+ peer->afc[afi][safi] = 1;
- if (!peer_af_find(peer, afi, safi))
- peer_af_create(peer, afi, safi);
+ if (!peer_af_find(peer, afi, safi))
+ peer_af_create(peer, afi, safi);
- peer_group2peer_config_copy_af(group, peer, afi, safi);
- }
+ peer_group2peer_config_copy_af(group, peer, afi, safi);
+ }
/* Mark as dynamic, but also as a "config node" for other things to
* work. */
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)) {
+ /* First work on real peers with timers */
+ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
SET_FLAG(peer->config, PEER_CONFIG_TIMER);
- peer->holdtime = group->conf->holdtime;
- peer->keepalive = group->conf->keepalive;
+ UNSET_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER);
+ } else {
+ /* Now work on the peer-group timers */
+ SET_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER);
+
+ /* peer-group member updates. */
+ group = peer->group;
+ for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
+ /* Skip peers that have their own timers */
+ if (CHECK_FLAG(peer->config, PEER_CONFIG_TIMER))
+ continue;
+
+ SET_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER);
+ peer->holdtime = group->conf->holdtime;
+ peer->keepalive = group->conf->keepalive;
+ }
}
+
return 0;
}
struct peer_group *group;
struct listnode *node, *nnode;
- /* 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)) {
+ /* First work on real peers vs the peer-group */
+ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
UNSET_FLAG(peer->config, PEER_CONFIG_TIMER);
- peer->holdtime = 0;
peer->keepalive = 0;
+ peer->holdtime = 0;
+
+ if (peer->group && peer->group->conf->holdtime) {
+ SET_FLAG(peer->config, PEER_GROUP_CONFIG_TIMER);
+ peer->keepalive = peer->group->conf->keepalive;
+ peer->holdtime = peer->group->conf->holdtime;
+ }
+ } else {
+ /* peer-group member updates. */
+ group = peer->group;
+ for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
+ if (!CHECK_FLAG(peer->config, PEER_CONFIG_TIMER)) {
+ UNSET_FLAG(peer->config,
+ PEER_GROUP_CONFIG_TIMER);
+ peer->holdtime = 0;
+ peer->keepalive = 0;
+ }
+ }
+
+ UNSET_FLAG(group->conf->config, PEER_GROUP_CONFIG_TIMER);
+ group->conf->holdtime = 0;
+ group->conf->keepalive = 0;
}
return 0;
update_group_policy_update(bgp, BGP_POLICY_FILTER_LIST,
access->name, 0, 0);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter = &peer->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->dlist[direct].name)
- filter->dlist[direct]
- .alist = access_list_lookup(
- afi,
- filter->dlist[direct]
- .name);
- else
+ FOREACH_AFI_SAFI (afi, 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]
- .alist = NULL;
- }
+ .name);
+ else
+ filter->dlist[direct].alist =
+ NULL;
}
+ }
}
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter =
- &group->conf->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->dlist[direct].name)
- filter->dlist[direct]
- .alist = access_list_lookup(
- afi,
- filter->dlist[direct]
- .name);
- else
+ FOREACH_AFI_SAFI (afi, 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]
- .alist = NULL;
- }
+ .name);
+ else
+ filter->dlist[direct].alist =
+ NULL;
}
+ }
}
#if ENABLE_BGP_VNC
vnc_prefix_list_update(bgp);
plist ? prefix_list_name(plist) : NULL, 0, 0);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter = &peer->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->plist[direct].name)
- filter->plist[direct]
- .plist = prefix_list_lookup(
- afi,
- filter->plist[direct]
- .name);
- else
+ FOREACH_AFI_SAFI (afi, 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]
- .plist = NULL;
- }
+ .name);
+ else
+ filter->plist[direct].plist =
+ NULL;
}
+ }
}
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter =
- &group->conf->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->plist[direct].name)
+ FOREACH_AFI_SAFI (afi, 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]
- .plist = prefix_list_lookup(
- afi,
- filter->plist[direct]
- .name);
- else
- filter->plist[direct]
- .plist = NULL;
- }
+ .name);
+ else
+ filter->plist[direct].plist =
+ NULL;
}
+ }
}
}
}
aslist_name, 0, 0);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter = &peer->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->aslist[direct].name)
+ FOREACH_AFI_SAFI (afi, 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]
- .aslist = as_list_lookup(
- filter->aslist[direct]
- .name);
- else
- filter->aslist[direct]
- .aslist = NULL;
- }
+ .name);
+ else
+ filter->aslist[direct].aslist =
+ NULL;
}
+ }
}
for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX;
- safi++) {
- filter =
- &group->conf->filter[afi][safi];
-
- for (direct = FILTER_IN;
- direct < FILTER_MAX; direct++) {
- if (filter->aslist[direct].name)
- filter->aslist[direct]
- .aslist = as_list_lookup(
- filter->aslist[direct]
- .name);
- else
+ FOREACH_AFI_SAFI (afi, 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]
- .aslist = NULL;
- }
+ .name);
+ else
+ filter->aslist[direct].aslist =
+ NULL;
}
+ }
}
}
}
}
/* timers */
- if (CHECK_FLAG(peer->config, PEER_CONFIG_TIMER)
+ if ((PEER_OR_GROUP_TIMER_SET(peer))
&& ((!peer_group_active(peer)
&& (peer->keepalive != BGP_DEFAULT_KEEPALIVE
|| peer->holdtime != BGP_DEFAULT_HOLDTIME))
/* BGP configuration. */
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
+
+ /* skip all auto created vrf as they dont have user config */
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
+ continue;
+
/* Router bgp ASN */
vty_out(vty, "router bgp %u", bgp->as);
/* write quanta */
bgp_config_write_wpkt_quanta(vty, bgp);
+ /* read quanta */
+ bgp_config_write_rpkt_quanta(vty, bgp);
/* coalesce time */
bgp_config_write_coalesce_time(vty, bgp);
if (bgp_option_check(BGP_OPT_CONFIG_CISCO))
vty_out(vty, " no auto-summary\n");
+ /* import route-target */
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) {
+ char *ecom_str;
+ struct listnode *node, *nnode;
+ struct ecommunity *ecom;
+
+ for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode,
+ ecom)) {
+ ecom_str = ecommunity_ecom2str(
+ ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+ vty_out(vty, " route-target import %s\n",
+ ecom_str);
+ XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ }
+ }
+
+ /* export route-target */
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) {
+ char *ecom_str;
+ struct listnode *node, *nnode;
+ struct ecommunity *ecom;
+
+ for (ALL_LIST_ELEMENTS(bgp->vrf_export_rtl, node, nnode,
+ ecom)) {
+ ecom_str = ecommunity_ecom2str(
+ ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+ vty_out(vty, " route-target export %s\n",
+ ecom_str);
+ XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ }
+ }
+
/* IPv4 unicast configuration. */
bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST);
bgp_process_queue_init();
+ /* init the rd id space.
+ assign 0th index in the bitfield,
+ so that we start with id 1
+ */
+ bf_init(bm->rd_idspace, UINT16_MAX);
+ bf_assign_zero_index(bm->rd_idspace);
+
/* Enable multiple instances by default. */
bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE);
{.completions = NULL},
};
+static void bgp_pthreads_init()
+{
+ frr_pthread_init();
+
+ frr_pthread_new("BGP i/o thread", PTHREAD_IO, bgp_io_start,
+ bgp_io_stop);
+ frr_pthread_new("BGP keepalives thread", PTHREAD_KEEPALIVES,
+ bgp_keepalives_start, bgp_keepalives_stop);
+
+ /* pre-run initialization */
+ bgp_keepalives_init();
+ bgp_io_init();
+}
+
+void bgp_pthreads_run()
+{
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
+
+ /*
+ * Please ensure that the io thread is running
+ * by calling bgp_io_running. The BGP threads
+ * depend on it being running when we start
+ * looking for it.
+ */
+ frr_pthread_run(PTHREAD_IO, &attr, NULL);
+ bgp_io_running();
+
+ frr_pthread_run(PTHREAD_KEEPALIVES, &attr, NULL);
+}
+
+void bgp_pthreads_finish()
+{
+ frr_pthread_stop_all();
+ frr_pthread_finish();
+}
+
void bgp_init(void)
{
/* allocates some vital data structures used by peer commands in
* vty_init */
+ /* pre-init pthreads */
+ bgp_pthreads_init();
+
/* Init zebra. */
bgp_zebra_init(bm->master);
*/
/* reverse bgp_master_init */
bgp_close();
+
if (bm->listen_sockets)
list_delete_and_null(&bm->listen_sockets);