#include "bgpd/bgp_route.h"
#include "bgpd/bgp_dump.h"
#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_errors.h"
#include "bgpd/bgp_community.h"
#include "bgpd/bgp_attr.h"
#include "bgpd/bgp_regex.h"
/* Allocate new peer af */
af = XCALLOC(MTYPE_BGP_PEER_AF, sizeof(struct peer_af));
- if (af == NULL) {
- zlog_err("Could not create af structure for peer %s",
- peer->host);
- return NULL;
- }
-
peer->peer_af_array[afid] = af;
af->afi = afi;
af->safi = safi;
}
}
-/* 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) {
- 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;
- }
- if (filter->aslist[i].name) {
- XFREE(MTYPE_BGP_FILTER_NAME, filter->aslist[i].name);
- filter->aslist[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;
- }
- }
-
- /* Clear unsuppress map. */
- if (filter->usmap.name)
- XFREE(MTYPE_BGP_FILTER_NAME, 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(afi, 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);
- SET_FLAG(peer->af_flags[afi][safi],
- PEER_FLAG_SEND_LARGE_COMMUNITY);
-
- SET_FLAG(peer->af_flags_invert[afi][safi],
- PEER_FLAG_SEND_COMMUNITY);
- SET_FLAG(peer->af_flags_invert[afi][safi],
- PEER_FLAG_SEND_EXT_COMMUNITY);
- SET_FLAG(peer->af_flags_invert[afi][safi],
- PEER_FLAG_SEND_LARGE_COMMUNITY);
- }
-
- /* Clear neighbor default_originate_rmap */
- 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;
- 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;
-}
-
-/* peer global config reset */
-static void peer_global_config_reset(struct peer *peer)
-{
- int saved_flags = 0;
-
- peer->change_local_as = 0;
- peer->ttl = (peer_sort(peer) == BGP_PEER_IBGP ? MAXTTL : 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;
-
- /* These are per-peer specific flags and so we must preserve them */
- saved_flags |= CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY);
- saved_flags |= CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN);
- peer->flags = 0;
- SET_FLAG(peer->flags, saved_flags);
-
- peer->holdtime = 0;
- peer->keepalive = 0;
- peer->connect = 0;
- peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
-
- /* Reset some other configs back to defaults. */
- peer->v_start = BGP_INIT_START_TIMER;
- peer->password = NULL;
- peer->local_id = peer->bgp->router_id;
- peer->v_holdtime = peer->bgp->default_holdtime;
- peer->v_keepalive = peer->bgp->default_keepalive;
-
- bfd_info_free(&(peer->bfd_info));
-
- /* Set back the CONFIG_NODE flag. */
- SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
-}
-
/* Check peer's AS number and determines if this peer is IBGP or EBGP */
static inline bgp_peer_sort_t peer_calc_sort(struct peer *peer)
{
else if (peer->as_type == AS_EXTERNAL)
return BGP_PEER_EBGP;
- else if (peer->as_type == AS_SPECIFIED && peer->as)
+ else if (peer->as_type == AS_SPECIFIED && peer->as) {
+ assert(bgp);
return (bgp->as == peer->as ? BGP_PEER_IBGP
: BGP_PEER_EBGP);
+ }
else {
struct peer *peer1;
int active;
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
- zlog_err("%s was called for peer-group %s", __func__,
- peer->host);
+ flog_err(BGP_ERR_PEER_GROUP, "%s was called for peer-group %s",
+ __func__, peer->host);
return 1;
}
safi_t safi)
{
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
- zlog_err("%s was called for peer-group %s", __func__,
- peer->host);
+ flog_err(BGP_ERR_PEER_GROUP, "%s was called for peer-group %s",
+ __func__, peer->host);
return 1;
}
peer->afc[afi][safi] = 0;
if (peer_af_delete(peer, afi, safi) != 0) {
- zlog_err("couldn't delete af structure for peer %s",
- peer->host);
+ flog_err(BGP_ERR_PEER_DELETE,
+ "couldn't delete af structure for peer %s",
+ peer->host);
return 1;
}
group = peer->group;
if (peer_af_delete(peer, afi, safi) != 0) {
- zlog_err("couldn't delete af structure for peer %s",
- peer->host);
+ flog_err(BGP_ERR_PEER_DELETE,
+ "couldn't delete af structure for peer %s",
+ peer->host);
}
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) {
return 0;
}
-int peer_group_unbind(struct bgp *bgp, struct peer *peer,
- struct peer_group *group)
-{
- struct peer *other;
- afi_t afi;
- safi_t safi;
-
- if (group != peer->group)
- return BGP_ERR_PEER_GROUP_MISMATCH;
-
- 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 */
- listnode_delete(group->peer, peer);
- peer->group = NULL;
- other = peer->doppelganger;
-
- if (group->conf->as) {
- peer_delete(peer);
- if (other && other->status != Deleted) {
- if (other->group) {
- peer_unlock(other);
- listnode_delete(group->peer, other);
- }
- other->group = NULL;
- peer_delete(other);
- }
- return 0;
- }
-
- bgp_bfd_deregister_peer(peer);
- peer_global_config_reset(peer);
-
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
- peer->last_reset = PEER_DOWN_RMAP_UNBIND;
- bgp_notify_send(peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- } else
- bgp_session_reset(peer);
-
- return 0;
-}
-
static int bgp_startup_timer_expire(struct thread *thread)
{
struct bgp *bgp;
assert(bgp);
THREAD_OFF(bgp->t_startup);
+ THREAD_OFF(bgp->t_maxmed_onstartup);
+ THREAD_OFF(bgp->t_update_delay);
+ THREAD_OFF(bgp->t_establish_wait);
if (BGP_DEBUG(zebra, ZEBRA)) {
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
.import_redirect_rtlist);
bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
}
- /* Remove visibility via the master list - there may however still be
- * routes to be processed still referencing the struct bgp.
- */
- listnode_delete(bm->bgp, bgp);
/* Deregister from Zebra, if needed */
if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
bgp_zebra_instance_deregister(bgp);
+ /* Remove visibility via the master list - there may however still be
+ * routes to be processed still referencing the struct bgp.
+ */
+ listnode_delete(bm->bgp, bgp);
+
/* Free interfaces in this instance. */
bgp_if_finish(bgp);
/* Action when the flag is changed. */
enum peer_change_type type;
-
- /* Peer down cause */
- uint8_t peer_down;
};
static const struct peer_flag_action peer_flag_action_list[] = {
if (flag & PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS) {
if (!bgp_flag_check(
bgp, BGP_FLAG_DETERMINISTIC_MED)) {
- zlog_warn(
+ zlog_info(
"%s: enabling bgp deterministic-med, this is required"
" for addpath-tx-bestpath-per-AS",
peer->host);
time_t uptime1, epoch_tbuf;
struct tm *tm;
- /* Check buffer length. */
- if (len < BGP_UPTIME_LEN) {
- if (!use_json) {
- zlog_warn("peer_uptime (): buffer shortage %lu",
- (unsigned long)len);
- /* XXX: should return status instead of buf... */
- snprintf(buf, len, "<error> ");
- }
- return buf;
- }
-
/* If there is no connection has been done before print `never'. */
if (uptime2 == 0) {
if (use_json) {
}
/* clang-format off */
-#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180517
+#if CONFDATE > 20190517
CPP_NOTICE("bgpd: remove 'bgp enforce-first-as' config migration from bgp_config_write")
#endif
/* clang-format on */
vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n",
bgp->default_subgroup_pkt_queue_max);
- /* BGP default autoshutdown neighbors */
- if (bgp->autoshutdown)
- vty_out(vty, " bgp default shutdown\n");
-
/* 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\n");
/* listen range and limit for dynamic BGP neighbors */
bgp_config_write_listen(vty, bgp);
+ /*
+ * BGP default autoshutdown neighbors
+ *
+ * This must be placed after any peer and peer-group
+ * configuration, to avoid setting all peers to shutdown after
+ * a daemon restart, which is undesired behavior. (see #2286)
+ */
+ if (bgp->autoshutdown)
+ vty_out(vty, " bgp default shutdown\n");
+
/* No auto-summary */
if (bgp_option_check(BGP_OPT_CONFIG_CISCO))
vty_out(vty, " no auto-summary\n");
}
}
-extern void bgp_snmp_init(void);
-
static void bgp_viewvrf_autocomplete(vector comps, struct cmd_token *token)
{
struct vrf *vrf = NULL;