diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2019-12-06 20:07:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-06 20:07:42 +0100 |
commit | 4f6309324798c0b9d21b6ddddf75ce549112cf7e (patch) | |
tree | add2f053034c6f279ba71d468b8e923eda8107e9 /bgpd | |
parent | Merge pull request #5332 from mjstapp/remove_zapi_label_flag (diff) | |
parent | topojson: use empty vtysh.conf for frr-reload.py (diff) | |
download | frr-4f6309324798c0b9d21b6ddddf75ce549112cf7e.tar.xz frr-4f6309324798c0b9d21b6ddddf75ce549112cf7e.zip |
Merge pull request #4765 from opensourcerouting/defaults-v2
lib/*: new config defaults system, v2
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_evpn.c | 8 | ||||
-rw-r--r-- | bgpd/bgp_main.c | 1 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 1142 | ||||
-rw-r--r-- | bgpd/bgp_vty.h | 7 | ||||
-rw-r--r-- | bgpd/bgp_zebra.h | 4 | ||||
-rw-r--r-- | bgpd/bgpd.c | 1066 | ||||
-rw-r--r-- | bgpd/bgpd.h | 17 |
7 files changed, 1155 insertions, 1090 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 155658e93..b8798a7ce 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -49,6 +49,7 @@ #include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_addpath.h" #include "bgpd/bgp_mac.h" +#include "bgpd/bgp_vty.h" /* * Definitions and external declarations. @@ -5709,9 +5710,10 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, int ret = 0; - ret = bgp_get(&bgp_vrf, &as, vrf_id_to_name(vrf_id), - vrf_id == VRF_DEFAULT ? BGP_INSTANCE_TYPE_DEFAULT - : BGP_INSTANCE_TYPE_VRF); + ret = bgp_get_vty(&bgp_vrf, &as, vrf_id_to_name(vrf_id), + vrf_id == VRF_DEFAULT + ? BGP_INSTANCE_TYPE_DEFAULT + : BGP_INSTANCE_TYPE_VRF); switch (ret) { case BGP_ERR_AS_MISMATCH: flog_err(EC_BGP_EVPN_AS_MISMATCH, diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 08c5d3468..9cb3957a8 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -27,7 +27,6 @@ #include "thread.h" #include <lib/version.h> #include "memory.h" -#include "memory_vty.h" #include "prefix.h" #include "log.h" #include "privs.h" diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index fa236a24b..0ff64c527 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -32,7 +32,7 @@ #include "thread.h" #include "log.h" #include "memory.h" -#include "memory_vty.h" +#include "lib_vty.h" #include "hash.h" #include "queue.h" #include "filter.h" @@ -64,8 +64,46 @@ #include "bgpd/bgp_bfd.h" #include "bgpd/bgp_io.h" #include "bgpd/bgp_evpn.h" +#include "bgpd/bgp_evpn_vty.h" #include "bgpd/bgp_addpath.h" #include "bgpd/bgp_mac.h" +#include "bgpd/bgp_flowspec.h" +#if ENABLE_BGP_VNC +#include "bgpd/rfapi/bgp_rfapi_cfg.h" +#endif + +FRR_CFG_DEFAULT_BOOL(BGP_IMPORT_CHECK, + { .val_long = true, .match_profile = "datacenter", }, + { .val_long = false }, +) +FRR_CFG_DEFAULT_BOOL(BGP_SHOW_HOSTNAME, + { .val_long = true, .match_profile = "datacenter", }, + { .val_long = false }, +) +FRR_CFG_DEFAULT_BOOL(BGP_LOG_NEIGHBOR_CHANGES, + { .val_long = true, .match_profile = "datacenter", }, + { .val_long = false }, +) +FRR_CFG_DEFAULT_BOOL(BGP_DETERMINISTIC_MED, + { .val_long = true, .match_profile = "datacenter", }, + { .val_long = false }, +) +FRR_CFG_DEFAULT_ULONG(BGP_CONNECT_RETRY, + { .val_ulong = 10, .match_profile = "datacenter", }, + { .val_ulong = 120 }, +) +FRR_CFG_DEFAULT_ULONG(BGP_HOLDTIME, + { .val_ulong = 9, .match_profile = "datacenter", }, + { .val_ulong = 180 }, +) +FRR_CFG_DEFAULT_ULONG(BGP_KEEPALIVE, + { .val_ulong = 3, .match_profile = "datacenter", }, + { .val_ulong = 60 }, +) + +DEFINE_HOOK(bgp_inst_config_write, + (struct bgp *bgp, struct vty *vty), + (bgp, vty)) static struct peer_group *listen_range_exists(struct bgp *bgp, struct prefix *range, int exact); @@ -347,6 +385,29 @@ int argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index, return ret; } +int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name, + enum bgp_instance_type inst_type) +{ + int ret = bgp_get(bgp, as, name, inst_type); + + if (ret == BGP_CREATED) { + bgp_timers_set(*bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME, + DFLT_BGP_CONNECT_RETRY); + + if (DFLT_BGP_IMPORT_CHECK) + bgp_flag_set(*bgp, BGP_FLAG_IMPORT_CHECK); + if (DFLT_BGP_SHOW_HOSTNAME) + bgp_flag_set(*bgp, BGP_FLAG_SHOW_HOSTNAME); + if (DFLT_BGP_LOG_NEIGHBOR_CHANGES) + bgp_flag_set(*bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES); + if (DFLT_BGP_DETERMINISTIC_MED) + bgp_flag_set(*bgp, BGP_FLAG_DETERMINISTIC_MED); + + ret = BGP_SUCCESS; + } + return ret; +} + /* * bgp_vty_find_and_parse_afi_safi_bgp * @@ -1068,7 +1129,7 @@ DEFUN_NOSH (router_bgp, if (inst_type == BGP_INSTANCE_TYPE_DEFAULT) is_new_bgp = (bgp_lookup(as, name) == NULL); - ret = bgp_get(&bgp, &as, name, inst_type); + ret = bgp_get_vty(&bgp, &as, name, inst_type); switch (ret) { case BGP_ERR_AS_MISMATCH: vty_out(vty, "BGP is already running; AS is %u\n", as); @@ -1777,8 +1838,8 @@ ALIAS_HIDDEN(no_bgp_maxpaths_ibgp, no_bgp_maxpaths_ibgp_hidden_cmd, "Number of paths\n" "Match the cluster length\n") -void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp, afi_t afi, - safi_t safi) +static void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp, + afi_t afi, safi_t safi) { if (bgp->maxpaths[afi][safi].maxpaths_ebgp != MULTIPATH_NUM) { vty_out(vty, " maximum-paths %d\n", @@ -1821,7 +1882,7 @@ DEFUN (bgp_timers, return CMD_WARNING_CONFIG_FAILED; } - bgp_timers_set(bgp, keepalive, holdtime); + bgp_timers_set(bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY); return CMD_SUCCESS; } @@ -1836,7 +1897,8 @@ DEFUN (no_bgp_timers, "Holdtime\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_timers_unset(bgp); + bgp_timers_set(bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME, + DFLT_BGP_CONNECT_RETRY); return CMD_SUCCESS; } @@ -6956,8 +7018,8 @@ DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd, as_t as = bgp->as; /* Auto-create assuming the same AS */ - ret = bgp_get(&bgp_default, &as, NULL, - BGP_INSTANCE_TYPE_DEFAULT); + ret = bgp_get_vty(&bgp_default, &as, NULL, + BGP_INSTANCE_TYPE_DEFAULT); if (ret) { vty_out(vty, @@ -7042,8 +7104,8 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, bgp_default = bgp_get_default(); if (!bgp_default) { /* Auto-create assuming the same AS */ - ret = bgp_get(&bgp_default, &as, NULL, - BGP_INSTANCE_TYPE_DEFAULT); + ret = bgp_get_vty(&bgp_default, &as, NULL, + BGP_INSTANCE_TYPE_DEFAULT); if (ret) { vty_out(vty, @@ -7058,7 +7120,7 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, vrf_bgp = bgp_default; else /* Auto-create assuming the same AS */ - ret = bgp_get(&vrf_bgp, &as, import_name, bgp_type); + ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type); if (ret) { vty_out(vty, @@ -9725,9 +9787,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_neigh, "bgpTimerConfiguredKeepAliveIntervalMsecs", p->keepalive * 1000); - } else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) - || (bgp->default_keepalive - != BGP_DEFAULT_KEEPALIVE)) { + } else if ((bgp->default_holdtime != SAVE_BGP_HOLDTIME) + || (bgp->default_keepalive != SAVE_BGP_KEEPALIVE)) { json_object_int_add(json_neigh, "bgpTimerConfiguredHoldTimeMsecs", bgp->default_holdtime); @@ -9789,9 +9850,8 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, p->holdtime); vty_out(vty, ", keepalive interval is %d seconds\n", p->keepalive); - } else if ((bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) - || (bgp->default_keepalive - != BGP_DEFAULT_KEEPALIVE)) { + } else if ((bgp->default_holdtime != SAVE_BGP_HOLDTIME) + || (bgp->default_keepalive != SAVE_BGP_KEEPALIVE)) { vty_out(vty, " Configured hold time is %d", bgp->default_holdtime); vty_out(vty, ", keepalive interval is %d seconds\n", @@ -12809,8 +12869,8 @@ DEFUN (no_bgp_redistribute_ipv6, return bgp_redistribute_unset(bgp, AFI_IP6, type, 0); } -void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, afi_t afi, - safi_t safi) +static void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, + afi_t afi, safi_t safi) { int i; @@ -12847,8 +12907,86 @@ void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, afi_t afi, } } +/* peer-group helpers for config-write */ + +static bool peergroup_flag_check(struct peer *peer, uint32_t flag) +{ + if (!peer_group_active(peer)) { + if (CHECK_FLAG(peer->flags_invert, flag)) + return !CHECK_FLAG(peer->flags, flag); + else + return !!CHECK_FLAG(peer->flags, flag); + } + + return !!CHECK_FLAG(peer->flags_override, flag); +} + +static bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi, + uint32_t flag) +{ + if (!peer_group_active(peer)) { + if (CHECK_FLAG(peer->af_flags_invert[afi][safi], flag)) + return !peer_af_flag_check(peer, afi, safi, flag); + else + return !!peer_af_flag_check(peer, afi, safi, flag); + } + + return !!CHECK_FLAG(peer->af_flags_override[afi][safi], flag); +} + +static bool peergroup_filter_check(struct peer *peer, afi_t afi, safi_t safi, + uint8_t type, int direct) +{ + struct bgp_filter *filter; + + if (peer_group_active(peer)) + return !!CHECK_FLAG(peer->filter_override[afi][safi][direct], + type); + + filter = &peer->filter[afi][safi]; + switch (type) { + case PEER_FT_DISTRIBUTE_LIST: + return !!(filter->dlist[direct].name); + case PEER_FT_FILTER_LIST: + return !!(filter->aslist[direct].name); + case PEER_FT_PREFIX_LIST: + return !!(filter->plist[direct].name); + case PEER_FT_ROUTE_MAP: + return !!(filter->map[direct].name); + case PEER_FT_UNSUPPRESS_MAP: + return !!(filter->usmap.name); + default: + return false; + } +} + +/* Return true if the addpath type is set for peer and different from + * peer-group. + */ +static int peergroup_af_addpath_check(struct peer *peer, afi_t afi, safi_t safi) +{ + enum bgp_addpath_strat type, g_type; + + type = peer->addpath_type[afi][safi]; + + if (type != BGP_ADDPATH_NONE) { + if (peer_group_active(peer)) { + g_type = peer->group->conf->addpath_type[afi][safi]; + + if (type != g_type) + return 1; + else + return 0; + } + + return 1; + } + + return 0; +} + /* This is part of the address-family block (unicast only) */ -void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, +static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, afi_t afi) { int indent = 2; @@ -12948,6 +13086,970 @@ void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, } } +static void bgp_config_write_filter(struct vty *vty, struct peer *peer, + afi_t afi, safi_t safi) +{ + struct bgp_filter *filter; + char *addr; + + addr = peer->host; + filter = &peer->filter[afi][safi]; + + /* distribute-list. */ + if (peergroup_filter_check(peer, afi, safi, PEER_FT_DISTRIBUTE_LIST, + FILTER_IN)) + vty_out(vty, " neighbor %s distribute-list %s in\n", addr, + filter->dlist[FILTER_IN].name); + + if (peergroup_filter_check(peer, afi, safi, PEER_FT_DISTRIBUTE_LIST, + FILTER_OUT)) + vty_out(vty, " neighbor %s distribute-list %s out\n", addr, + filter->dlist[FILTER_OUT].name); + + /* prefix-list. */ + if (peergroup_filter_check(peer, afi, safi, PEER_FT_PREFIX_LIST, + FILTER_IN)) + vty_out(vty, " neighbor %s prefix-list %s in\n", addr, + filter->plist[FILTER_IN].name); + + if (peergroup_filter_check(peer, afi, safi, PEER_FT_PREFIX_LIST, + FILTER_OUT)) + vty_out(vty, " neighbor %s prefix-list %s out\n", addr, + filter->plist[FILTER_OUT].name); + + /* route-map. */ + if (peergroup_filter_check(peer, afi, safi, PEER_FT_ROUTE_MAP, RMAP_IN)) + vty_out(vty, " neighbor %s route-map %s in\n", addr, + filter->map[RMAP_IN].name); + + if (peergroup_filter_check(peer, afi, safi, PEER_FT_ROUTE_MAP, + RMAP_OUT)) + vty_out(vty, " neighbor %s route-map %s out\n", addr, + filter->map[RMAP_OUT].name); + + /* unsuppress-map */ + if (peergroup_filter_check(peer, afi, safi, PEER_FT_UNSUPPRESS_MAP, 0)) + vty_out(vty, " neighbor %s unsuppress-map %s\n", addr, + filter->usmap.name); + + /* filter-list. */ + if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST, + FILTER_IN)) + vty_out(vty, " neighbor %s filter-list %s in\n", addr, + filter->aslist[FILTER_IN].name); + + if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST, + FILTER_OUT)) + vty_out(vty, " neighbor %s filter-list %s out\n", addr, + filter->aslist[FILTER_OUT].name); +} + +/* BGP peer configuration display function. */ +static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, + struct peer *peer) +{ + struct peer *g_peer = NULL; + char buf[SU_ADDRSTRLEN]; + char *addr; + int if_pg_printed = false; + int if_ras_printed = false; + + /* Skip dynamic neighbors. */ + if (peer_dynamic_neighbor(peer)) + return; + + if (peer->conf_if) + addr = peer->conf_if; + else + addr = peer->host; + + /************************************ + ****** Global to the neighbor ****** + ************************************/ + if (peer->conf_if) { + if (CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) + vty_out(vty, " neighbor %s interface v6only", addr); + else + vty_out(vty, " neighbor %s interface", addr); + + if (peer_group_active(peer)) { + vty_out(vty, " peer-group %s", peer->group->name); + if_pg_printed = true; + } else if (peer->as_type == AS_SPECIFIED) { + vty_out(vty, " remote-as %u", peer->as); + if_ras_printed = true; + } else if (peer->as_type == AS_INTERNAL) { + vty_out(vty, " remote-as internal"); + if_ras_printed = true; + } else if (peer->as_type == AS_EXTERNAL) { + vty_out(vty, " remote-as external"); + if_ras_printed = true; + } + + vty_out(vty, "\n"); + } + + /* remote-as and peer-group */ + /* peer is a member of a peer-group */ + if (peer_group_active(peer)) { + g_peer = peer->group->conf; + + if (g_peer->as_type == AS_UNSPECIFIED && !if_ras_printed) { + if (peer->as_type == AS_SPECIFIED) { + vty_out(vty, " neighbor %s remote-as %u\n", + addr, peer->as); + } else if (peer->as_type == AS_INTERNAL) { + vty_out(vty, + " neighbor %s remote-as internal\n", + addr); + } else if (peer->as_type == AS_EXTERNAL) { + vty_out(vty, + " neighbor %s remote-as external\n", + addr); + } + } + + /* For swpX peers we displayed the peer-group + * via 'neighbor swpX interface peer-group PGNAME' */ + if (!if_pg_printed) + vty_out(vty, " neighbor %s peer-group %s\n", addr, + peer->group->name); + } + + /* peer is NOT a member of a peer-group */ + else { + /* peer is a peer-group, declare the peer-group */ + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + vty_out(vty, " neighbor %s peer-group\n", addr); + } + + if (!if_ras_printed) { + if (peer->as_type == AS_SPECIFIED) { + vty_out(vty, " neighbor %s remote-as %u\n", + addr, peer->as); + } else if (peer->as_type == AS_INTERNAL) { + vty_out(vty, + " neighbor %s remote-as internal\n", + addr); + } else if (peer->as_type == AS_EXTERNAL) { + vty_out(vty, + " neighbor %s remote-as external\n", + addr); + } + } + } + + /* local-as */ + if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS)) { + vty_out(vty, " neighbor %s local-as %u", addr, + peer->change_local_as); + if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND)) + vty_out(vty, " no-prepend"); + if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS)) + vty_out(vty, " replace-as"); + vty_out(vty, "\n"); + } + + /* description */ + if (peer->desc) { + vty_out(vty, " neighbor %s description %s\n", addr, peer->desc); + } + + /* shutdown */ + if (peergroup_flag_check(peer, PEER_FLAG_SHUTDOWN)) { + if (peer->tx_shutdown_message) + vty_out(vty, " neighbor %s shutdown message %s\n", addr, + peer->tx_shutdown_message); + else + vty_out(vty, " neighbor %s shutdown\n", addr); + } + + /* bfd */ + if (peer->bfd_info) { + if (!peer_group_active(peer) || !g_peer->bfd_info) { + bgp_bfd_peer_config_write(vty, peer, addr); + } + } + + /* password */ + if (peergroup_flag_check(peer, PEER_FLAG_PASSWORD)) + vty_out(vty, " neighbor %s password %s\n", addr, + peer->password); + + /* neighbor solo */ + if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL)) { + if (!peer_group_active(peer)) { + vty_out(vty, " neighbor %s solo\n", addr); + } + } + + /* BGP port */ + if (peer->port != BGP_PORT_DEFAULT) { + vty_out(vty, " neighbor %s port %d\n", addr, peer->port); + } + + /* Local interface name */ + if (peer->ifname) { + vty_out(vty, " neighbor %s interface %s\n", addr, peer->ifname); + } + + /* passive */ + if (peergroup_flag_check(peer, PEER_FLAG_PASSIVE)) + vty_out(vty, " neighbor %s passive\n", addr); + + /* ebgp-multihop */ + if (peer->sort != BGP_PEER_IBGP && peer->ttl != BGP_DEFAULT_TTL + && !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL)) { + if (!peer_group_active(peer) || g_peer->ttl != peer->ttl) { + vty_out(vty, " neighbor %s ebgp-multihop %d\n", addr, + peer->ttl); + } + } + + /* ttl-security hops */ + if (peer->gtsm_hops != 0) { + if (!peer_group_active(peer) + || g_peer->gtsm_hops != peer->gtsm_hops) { + vty_out(vty, " neighbor %s ttl-security hops %d\n", + addr, peer->gtsm_hops); + } + } + + /* disable-connected-check */ + if (peergroup_flag_check(peer, PEER_FLAG_DISABLE_CONNECTED_CHECK)) + vty_out(vty, " neighbor %s disable-connected-check\n", addr); + + /* enforce-first-as */ + if (peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS)) + vty_out(vty, " neighbor %s enforce-first-as\n", addr); + + /* update-source */ + if (peergroup_flag_check(peer, PEER_FLAG_UPDATE_SOURCE)) { + if (peer->update_source) + vty_out(vty, " neighbor %s update-source %s\n", addr, + sockunion2str(peer->update_source, buf, + SU_ADDRSTRLEN)); + else if (peer->update_if) + vty_out(vty, " neighbor %s update-source %s\n", addr, + peer->update_if); + } + + /* advertisement-interval */ + if (peergroup_flag_check(peer, PEER_FLAG_ROUTEADV)) + vty_out(vty, " neighbor %s advertisement-interval %u\n", addr, + peer->routeadv); + + /* timers */ + if (peergroup_flag_check(peer, PEER_FLAG_TIMER)) + vty_out(vty, " neighbor %s timers %u %u\n", addr, + peer->keepalive, peer->holdtime); + + /* timers connect */ + if (peergroup_flag_check(peer, PEER_FLAG_TIMER_CONNECT)) + vty_out(vty, " neighbor %s timers connect %u\n", addr, + peer->connect); + /* need special-case handling for changed default values due to + * config profile / version (because there is no "timers bgp connect" + * command, we need to save this per-peer :/) + */ + else if (!peer_group_active(peer) && !peer->connect && + peer->bgp->default_connect_retry != SAVE_BGP_CONNECT_RETRY) + vty_out(vty, " neighbor %s timers connect %u\n", addr, + peer->bgp->default_connect_retry); + + /* capability dynamic */ + if (peergroup_flag_check(peer, PEER_FLAG_DYNAMIC_CAPABILITY)) + vty_out(vty, " neighbor %s capability dynamic\n", addr); + + /* capability extended-nexthop */ + if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_ENHE)) { + if (!peer->conf_if) { + if (CHECK_FLAG(peer->flags_invert, + PEER_FLAG_CAPABILITY_ENHE)) + vty_out(vty, + " no neighbor %s capability extended-nexthop\n", + addr); + else + vty_out(vty, + " neighbor %s capability extended-nexthop\n", + addr); + } + } + + /* dont-capability-negotiation */ + if (peergroup_flag_check(peer, PEER_FLAG_DONT_CAPABILITY)) + vty_out(vty, " neighbor %s dont-capability-negotiate\n", addr); + + /* override-capability */ + if (peergroup_flag_check(peer, PEER_FLAG_OVERRIDE_CAPABILITY)) + vty_out(vty, " neighbor %s override-capability\n", addr); + + /* strict-capability-match */ + if (peergroup_flag_check(peer, PEER_FLAG_STRICT_CAP_MATCH)) + vty_out(vty, " neighbor %s strict-capability-match\n", addr); + + /* Sender side AS path loop detection. */ + if (peer->as_path_loop_detection) + vty_out(vty, " neighbor %s sender-as-path-loop-detection\n", + addr); +} + +/* BGP peer configuration display function. */ +static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, + struct peer *peer, afi_t afi, safi_t safi) +{ + struct peer *g_peer = NULL; + char *addr; + bool flag_scomm, flag_secomm, flag_slcomm; + + /* Skip dynamic neighbors. */ + if (peer_dynamic_neighbor(peer)) + return; + + if (peer->conf_if) + addr = peer->conf_if; + else + addr = peer->host; + + /************************************ + ****** Per AF to the neighbor ****** + ************************************/ + if (peer_group_active(peer)) { + g_peer = peer->group->conf; + + /* If the peer-group is active but peer is not, print a 'no + * activate' */ + if (g_peer->afc[afi][safi] && !peer->afc[afi][safi]) { + vty_out(vty, " no neighbor %s activate\n", addr); + } + + /* If the peer-group is not active but peer is, print an + 'activate' */ + else if (!g_peer->afc[afi][safi] && peer->afc[afi][safi]) { + vty_out(vty, " neighbor %s activate\n", addr); + } + } else { + if (peer->afc[afi][safi]) { + if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) { + if (bgp_flag_check(bgp, + BGP_FLAG_NO_DEFAULT_IPV4)) { + vty_out(vty, " neighbor %s activate\n", + addr); + } + } else + vty_out(vty, " neighbor %s activate\n", addr); + } else { + if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) { + if (!bgp_flag_check(bgp, + BGP_FLAG_NO_DEFAULT_IPV4)) { + vty_out(vty, + " no neighbor %s activate\n", + addr); + } + } + } + } + + /* addpath TX knobs */ + if (peergroup_af_addpath_check(peer, afi, safi)) { + switch (peer->addpath_type[afi][safi]) { + case BGP_ADDPATH_ALL: + vty_out(vty, " neighbor %s addpath-tx-all-paths\n", + addr); + break; + case BGP_ADDPATH_BEST_PER_AS: + vty_out(vty, + " neighbor %s addpath-tx-bestpath-per-AS\n", + addr); + break; + case BGP_ADDPATH_MAX: + case BGP_ADDPATH_NONE: + break; + } + } + + /* ORF capability. */ + if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_ORF_PREFIX_RM)) { + vty_out(vty, " neighbor %s capability orf prefix-list", addr); + + if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_ORF_PREFIX_SM) + && peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_ORF_PREFIX_RM)) + vty_out(vty, " both"); + else if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_ORF_PREFIX_SM)) + vty_out(vty, " send"); + else + vty_out(vty, " receive"); + vty_out(vty, "\n"); + } + + /* BGP flag dampening. */ + if (CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_DAMPENING)) + bgp_config_write_damp(vty, afi, safi); + + /* Route reflector client. */ + if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_REFLECTOR_CLIENT)) { + vty_out(vty, " neighbor %s route-reflector-client\n", addr); + } + + /* next-hop-self force */ + if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_FORCE_NEXTHOP_SELF)) { + vty_out(vty, " neighbor %s next-hop-self force\n", addr); + } + + /* next-hop-self */ + if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)) { + vty_out(vty, " neighbor %s next-hop-self\n", addr); + } + + /* remove-private-AS */ + if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)) { + vty_out(vty, " neighbor %s remove-private-AS all replace-AS\n", + addr); + } + + else if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) { + vty_out(vty, " neighbor %s remove-private-AS replace-AS\n", + addr); + } + + else if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) { + vty_out(vty, " neighbor %s remove-private-AS all\n", addr); + } + + else if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_REMOVE_PRIVATE_AS)) { + vty_out(vty, " neighbor %s remove-private-AS\n", addr); + } + + /* as-override */ + if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) { + vty_out(vty, " neighbor %s as-override\n", addr); + } + + /* send-community print. */ + flag_scomm = peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_SEND_COMMUNITY); + flag_secomm = peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_SEND_EXT_COMMUNITY); + flag_slcomm = peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_SEND_LARGE_COMMUNITY); + + if (flag_scomm && flag_secomm && flag_slcomm) { + vty_out(vty, " no neighbor %s send-community all\n", addr); + } else { + if (flag_scomm) + vty_out(vty, " no neighbor %s send-community\n", addr); + if (flag_secomm) + vty_out(vty, + " no neighbor %s send-community extended\n", + addr); + + if (flag_slcomm) + vty_out(vty, " no neighbor %s send-community large\n", + addr); + } + + /* Default information */ + if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_DEFAULT_ORIGINATE)) { + 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, "\n"); + } + + /* Soft reconfiguration inbound. */ + if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_SOFT_RECONFIG)) { + vty_out(vty, " neighbor %s soft-reconfiguration inbound\n", + addr); + } + + /* maximum-prefix. */ + if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_MAX_PREFIX)) { + vty_out(vty, " neighbor %s maximum-prefix %" PRIu32, addr, + peer->pmax[afi][safi]); + + if (peer->pmax_threshold[afi][safi] + != MAXIMUM_PREFIX_THRESHOLD_DEFAULT) + vty_out(vty, " %u", peer->pmax_threshold[afi][safi]); + if (peer_af_flag_check(peer, afi, safi, + PEER_FLAG_MAX_PREFIX_WARNING)) + vty_out(vty, " warning-only"); + if (peer->pmax_restart[afi][safi]) + vty_out(vty, " restart %u", + peer->pmax_restart[afi][safi]); + + vty_out(vty, "\n"); + } + + /* Route server client. */ + if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_RSERVER_CLIENT)) { + vty_out(vty, " neighbor %s route-server-client\n", addr); + } + + /* Nexthop-local unchanged. */ + if (peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)) { + vty_out(vty, " neighbor %s nexthop-local unchanged\n", addr); + } + + /* allowas-in <1-10> */ + if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ALLOWAS_IN)) { + if (peer_af_flag_check(peer, afi, safi, + PEER_FLAG_ALLOWAS_IN_ORIGIN)) { + vty_out(vty, " neighbor %s allowas-in origin\n", addr); + } else if (peer->allowas_in[afi][safi] == 3) { + vty_out(vty, " neighbor %s allowas-in\n", addr); + } else { + vty_out(vty, " neighbor %s allowas-in %d\n", addr, + peer->allowas_in[afi][safi]); + } + } + + /* weight */ + if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_WEIGHT)) + vty_out(vty, " neighbor %s weight %lu\n", addr, + peer->weight[afi][safi]); + + /* Filter. */ + bgp_config_write_filter(vty, peer, afi, safi); + + /* atribute-unchanged. */ + if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) + || (safi != SAFI_EVPN + && peer_af_flag_check(peer, afi, safi, + PEER_FLAG_NEXTHOP_UNCHANGED)) + || peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) { + + if (!peer_group_active(peer) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_AS_PATH_UNCHANGED) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_NEXTHOP_UNCHANGED) + || peergroup_af_flag_check(peer, afi, safi, + PEER_FLAG_MED_UNCHANGED)) { + + vty_out(vty, + " neighbor %s attribute-unchanged%s%s%s\n", + addr, + peer_af_flag_check(peer, afi, safi, + PEER_FLAG_AS_PATH_UNCHANGED) + ? " as-path" + : "", + peer_af_flag_check(peer, afi, safi, + PEER_FLAG_NEXTHOP_UNCHANGED) + ? " next-hop" + : "", + peer_af_flag_check(peer, afi, safi, + PEER_FLAG_MED_UNCHANGED) + ? " med" + : ""); + } + } +} + +/* Address family based peer configuration display. */ +static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, + safi_t safi) +{ + struct peer *peer; + struct peer_group *group; + struct listnode *node, *nnode; + + + vty_frame(vty, " !\n address-family "); + if (afi == AFI_IP) { + if (safi == SAFI_UNICAST) + vty_frame(vty, "ipv4 unicast"); + else if (safi == SAFI_LABELED_UNICAST) + vty_frame(vty, "ipv4 labeled-unicast"); + else if (safi == SAFI_MULTICAST) + vty_frame(vty, "ipv4 multicast"); + else if (safi == SAFI_MPLS_VPN) + vty_frame(vty, "ipv4 vpn"); + else if (safi == SAFI_ENCAP) + vty_frame(vty, "ipv4 encap"); + else if (safi == SAFI_FLOWSPEC) + vty_frame(vty, "ipv4 flowspec"); + } else if (afi == AFI_IP6) { + if (safi == SAFI_UNICAST) + vty_frame(vty, "ipv6 unicast"); + else if (safi == SAFI_LABELED_UNICAST) + vty_frame(vty, "ipv6 labeled-unicast"); + else if (safi == SAFI_MULTICAST) + vty_frame(vty, "ipv6 multicast"); + else if (safi == SAFI_MPLS_VPN) + vty_frame(vty, "ipv6 vpn"); + else if (safi == SAFI_ENCAP) + vty_frame(vty, "ipv6 encap"); + else if (safi == SAFI_FLOWSPEC) + vty_frame(vty, "ipv6 flowspec"); + } else if (afi == AFI_L2VPN) { + if (safi == SAFI_EVPN) + vty_frame(vty, "l2vpn evpn"); + } + vty_frame(vty, "\n"); + + bgp_config_write_distance(vty, bgp, afi, safi); + + bgp_config_write_network(vty, bgp, afi, safi); + + bgp_config_write_redistribute(vty, bgp, afi, safi); + + for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) + bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi); + + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + /* Skip dynamic neighbors. */ + if (peer_dynamic_neighbor(peer)) + continue; + + /* Do not display doppelganger peers */ + if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) + bgp_config_write_peer_af(vty, bgp, peer, afi, safi); + } + + bgp_config_write_maxpaths(vty, bgp, afi, safi); + bgp_config_write_table_map(vty, bgp, afi, safi); + + if (safi == SAFI_EVPN) + bgp_config_write_evpn_info(vty, bgp, afi, safi); + + if (safi == SAFI_FLOWSPEC) + bgp_fs_config_write_pbr(vty, bgp, afi, safi); + + if (safi == SAFI_UNICAST) { + bgp_vpn_policy_config_write_afi(vty, bgp, afi); + if (CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)) { + + vty_out(vty, " export vpn\n"); + } + if (CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) { + + vty_out(vty, " import vpn\n"); + } + if (CHECK_FLAG(bgp->af_flags[afi][safi], + BGP_CONFIG_VRF_TO_VRF_IMPORT)) { + char *name; + + for (ALL_LIST_ELEMENTS_RO( + bgp->vpn_policy[afi].import_vrf, node, + name)) + vty_out(vty, " import vrf %s\n", name); + } + } + + vty_endframe(vty, " exit-address-family\n"); +} + +int bgp_config_write(struct vty *vty) +{ + struct bgp *bgp; + struct peer_group *group; + struct peer *peer; + struct listnode *node, *nnode; + struct listnode *mnode, *mnnode; + + if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER) + vty_out(vty, "bgp route-map delay-timer %u\n", + bm->rmap_update_timer); + + /* 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); + + if (bgp->name) + vty_out(vty, " %s %s", + (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) + ? "view" : "vrf", bgp->name); + vty_out(vty, "\n"); + + /* BGP fast-external-failover. */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) + vty_out(vty, " no bgp fast-external-failover\n"); + + /* BGP router ID. */ + if (bgp->router_id_static.s_addr != 0) + vty_out(vty, " bgp router-id %s\n", + inet_ntoa(bgp->router_id_static)); + + /* BGP log-neighbor-changes. */ + if (!!bgp_flag_check(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES) + != SAVE_BGP_LOG_NEIGHBOR_CHANGES) + vty_out(vty, " %sbgp log-neighbor-changes\n", + bgp_flag_check(bgp, + BGP_FLAG_LOG_NEIGHBOR_CHANGES) + ? "" + : "no "); + + /* BGP configuration. */ + if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED)) + vty_out(vty, " bgp always-compare-med\n"); + + /* RFC8212 default eBGP policy. */ + if (bgp->ebgp_requires_policy + == DEFAULT_EBGP_POLICY_ENABLED) + vty_out(vty, " bgp ebgp-requires-policy\n"); + + /* draft-ietf-idr-deprecate-as-set-confed-set */ + if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) + vty_out(vty, " bgp reject-as-sets\n"); + + /* BGP default ipv4-unicast. */ + if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4)) + vty_out(vty, " no bgp default ipv4-unicast\n"); + + /* BGP default local-preference. */ + if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF) + vty_out(vty, " bgp default local-preference %u\n", + bgp->default_local_pref); + + /* BGP default show-hostname */ + if (!!bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME) + != SAVE_BGP_SHOW_HOSTNAME) + vty_out(vty, " %sbgp default show-hostname\n", + bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME) + ? "" + : "no "); + + /* BGP default subgroup-pkt-queue-max. */ + if (bgp->default_subgroup_pkt_queue_max + != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX) + vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n", + bgp->default_subgroup_pkt_queue_max); + + /* 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"); + + /* BGP cluster ID. */ + if (CHECK_FLAG(bgp->config, BGP_CONFIG_CLUSTER_ID)) + vty_out(vty, " bgp cluster-id %s\n", + inet_ntoa(bgp->cluster_id)); + + /* Disable ebgp connected nexthop check */ + if (bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) + vty_out(vty, + " bgp disable-ebgp-connected-route-check\n"); + + /* Confederation identifier*/ + if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) + vty_out(vty, " bgp confederation identifier %u\n", + bgp->confed_id); + + /* Confederation peer */ + if (bgp->confed_peers_cnt > 0) { + int i; + + vty_out(vty, " bgp confederation peers"); + + for (i = 0; i < bgp->confed_peers_cnt; i++) + vty_out(vty, " %u", bgp->confed_peers[i]); + + vty_out(vty, "\n"); + } + + /* BGP deterministic-med. */ + if (!!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED) + != SAVE_BGP_DETERMINISTIC_MED) + vty_out(vty, " %sbgp deterministic-med\n", + bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED) + ? "" + : "no "); + + /* BGP update-delay. */ + bgp_config_write_update_delay(vty, bgp); + + if (bgp->v_maxmed_onstartup + != BGP_MAXMED_ONSTARTUP_UNCONFIGURED) { + vty_out(vty, " bgp max-med on-startup %u", + bgp->v_maxmed_onstartup); + if (bgp->maxmed_onstartup_value + != BGP_MAXMED_VALUE_DEFAULT) + vty_out(vty, " %u", + bgp->maxmed_onstartup_value); + vty_out(vty, "\n"); + } + if (bgp->v_maxmed_admin != BGP_MAXMED_ADMIN_UNCONFIGURED) { + vty_out(vty, " bgp max-med administrative"); + if (bgp->maxmed_admin_value != BGP_MAXMED_VALUE_DEFAULT) + vty_out(vty, " %u", bgp->maxmed_admin_value); + vty_out(vty, "\n"); + } + + /* 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); + + /* BGP graceful-restart. */ + if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME) + vty_out(vty, + " bgp graceful-restart stalepath-time %u\n", + bgp->stalepath_time); + if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME) + vty_out(vty, " bgp graceful-restart restart-time %u\n", + bgp->restart_time); + if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_RESTART)) + vty_out(vty, " bgp graceful-restart\n"); + + /* BGP graceful-shutdown */ + if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) + vty_out(vty, " bgp graceful-shutdown\n"); + + /* BGP graceful-restart Preserve State F bit. */ + if (bgp_flag_check(bgp, BGP_FLAG_GR_PRESERVE_FWD)) + vty_out(vty, + " bgp graceful-restart preserve-fw-state\n"); + + /* BGP bestpath method. */ + if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE)) + vty_out(vty, " bgp bestpath as-path ignore\n"); + if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED)) + vty_out(vty, " bgp bestpath as-path confed\n"); + + if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) { + if (bgp_flag_check(bgp, + BGP_FLAG_MULTIPATH_RELAX_AS_SET)) { + vty_out(vty, + " bgp bestpath as-path multipath-relax as-set\n"); + } else { + vty_out(vty, + " bgp bestpath as-path multipath-relax\n"); + } + } + + if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) { + vty_out(vty, + " bgp route-reflector allow-outbound-policy\n"); + } + if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)) + vty_out(vty, " bgp bestpath compare-routerid\n"); + 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, "\n"); + } + + /* BGP network import check. */ + if (!!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK) + != SAVE_BGP_IMPORT_CHECK) + vty_out(vty, " %sbgp network import-check\n", + bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK) + ? "" + : "no "); + + /* BGP timers configuration. */ + if (bgp->default_keepalive != SAVE_BGP_KEEPALIVE + && bgp->default_holdtime != SAVE_BGP_HOLDTIME) + vty_out(vty, " timers bgp %u %u\n", + bgp->default_keepalive, bgp->default_holdtime); + + /* peer-group */ + for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) { + bgp_config_write_peer_global(vty, bgp, group->conf); + } + + /* Normal neighbor configuration. */ + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) + bgp_config_write_peer_global(vty, bgp, peer); + } + + /* 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"); + + /* IPv4 unicast configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST); + + /* IPv4 multicast configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MULTICAST); + + /* IPv4 labeled-unicast configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP, SAFI_LABELED_UNICAST); + + /* IPv4 VPN configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MPLS_VPN); + + /* ENCAPv4 configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP, SAFI_ENCAP); + + /* FLOWSPEC v4 configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP, SAFI_FLOWSPEC); + + /* IPv6 unicast configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_UNICAST); + + /* IPv6 multicast configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MULTICAST); + + /* IPv6 labeled-unicast configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP6, + SAFI_LABELED_UNICAST); + + /* IPv6 VPN configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MPLS_VPN); + + /* ENCAPv6 configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_ENCAP); + + /* FLOWSPEC v6 configuration. */ + bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_FLOWSPEC); + + /* EVPN configuration. */ + bgp_config_write_family(vty, bgp, AFI_L2VPN, SAFI_EVPN); + + hook_call(bgp_inst_config_write, bgp, vty); + +#if ENABLE_BGP_VNC + bgp_rfapi_cfg_write(vty, bgp); +#endif + + vty_out(vty, "!\n"); + } + return 0; +} + /* BGP node structure. */ static struct cmd_node bgp_node = { diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index 27b5ea47b..5f3ce9cd8 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -21,6 +21,8 @@ #ifndef _QUAGGA_BGP_VTY_H #define _QUAGGA_BGP_VTY_H +#include "bgpd/bgpd.h" + struct bgp; #define BGP_INSTANCE_HELP_STR "BGP view\nBGP VRF\nView/VRF name\n" @@ -46,6 +48,8 @@ struct bgp; extern void bgp_vty_init(void); extern const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json); +extern int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name, + enum bgp_instance_type inst_type); extern void bgp_config_write_update_delay(struct vty *vty, struct bgp *bgp); extern void bgp_config_write_wpkt_quanta(struct vty *vty, struct bgp *bgp); extern void bgp_config_write_rpkt_quanta(struct vty *vty, struct bgp *bgp); @@ -72,6 +76,5 @@ extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty, bool use_json); extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, safi_t safi, bool show_failed, bool use_json); -extern void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp, - afi_t afi); + #endif /* _QUAGGA_BGP_VTY_H */ diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index b912870b8..62c311cc1 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -32,10 +32,6 @@ extern void bgp_zebra_destroy(void); extern int bgp_zebra_get_table_range(uint32_t chunk_size, uint32_t *start, uint32_t *end); extern int bgp_if_update_all(void); -extern void bgp_config_write_maxpaths(struct vty *, struct bgp *, afi_t, - safi_t); -extern void bgp_config_write_redistribute(struct vty *, struct bgp *, afi_t, - safi_t); extern void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p, struct bgp_path_info *path, struct bgp *bgp, afi_t afi, safi_t safi); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 4283fe169..9b0e81491 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -95,9 +95,6 @@ DEFINE_QOBJ_TYPE(bgp_master) DEFINE_QOBJ_TYPE(bgp) DEFINE_QOBJ_TYPE(peer) DEFINE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp)) -DEFINE_HOOK(bgp_inst_config_write, - (struct bgp *bgp, struct vty *vty), - (bgp, vty)) /* BGP process wide configuration. */ static struct bgp_master bgp_master; @@ -407,19 +404,23 @@ time_t bgp_clock(void) } /* BGP timer configuration. */ -int bgp_timers_set(struct bgp *bgp, uint32_t keepalive, uint32_t holdtime) +int bgp_timers_set(struct bgp *bgp, uint32_t keepalive, uint32_t holdtime, + uint32_t connect_retry) { bgp->default_keepalive = (keepalive < holdtime / 3 ? keepalive : holdtime / 3); bgp->default_holdtime = holdtime; + bgp->default_connect_retry = connect_retry; return 0; } +/* mostly for completeness - CLI uses its own defaults */ int bgp_timers_unset(struct bgp *bgp) { bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE; bgp->default_holdtime = BGP_DEFAULT_HOLDTIME; + bgp->default_connect_retry = BGP_DEFAULT_CONNECT_RETRY; return 0; } @@ -883,82 +884,6 @@ void peer_af_flag_inherit(struct peer *peer, afi_t afi, safi_t safi, COND_FLAG(peer->af_flags[afi][safi], flag, group_val); } -static bool peergroup_flag_check(struct peer *peer, uint32_t flag) -{ - if (!peer_group_active(peer)) { - if (CHECK_FLAG(peer->flags_invert, flag)) - return !CHECK_FLAG(peer->flags, flag); - else - return !!CHECK_FLAG(peer->flags, flag); - } - - return !!CHECK_FLAG(peer->flags_override, flag); -} - -static bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi, - uint32_t flag) -{ - if (!peer_group_active(peer)) { - if (CHECK_FLAG(peer->af_flags_invert[afi][safi], flag)) - return !peer_af_flag_check(peer, afi, safi, flag); - else - return !!peer_af_flag_check(peer, afi, safi, flag); - } - - return !!CHECK_FLAG(peer->af_flags_override[afi][safi], flag); -} - -static bool peergroup_filter_check(struct peer *peer, afi_t afi, safi_t safi, - uint8_t type, int direct) -{ - struct bgp_filter *filter; - - if (peer_group_active(peer)) - return !!CHECK_FLAG(peer->filter_override[afi][safi][direct], - type); - - filter = &peer->filter[afi][safi]; - switch (type) { - case PEER_FT_DISTRIBUTE_LIST: - return !!(filter->dlist[direct].name); - case PEER_FT_FILTER_LIST: - return !!(filter->aslist[direct].name); - case PEER_FT_PREFIX_LIST: - return !!(filter->plist[direct].name); - case PEER_FT_ROUTE_MAP: - return !!(filter->map[direct].name); - case PEER_FT_UNSUPPRESS_MAP: - return !!(filter->usmap.name); - default: - return false; - } -} - -/* Return true if the addpath type is set for peer and different from - * peer-group. - */ -static int peergroup_af_addpath_check(struct peer *peer, afi_t afi, safi_t safi) -{ - enum bgp_addpath_strat type, g_type; - - type = peer->addpath_type[afi][safi]; - - if (type != BGP_ADDPATH_NONE) { - if (peer_group_active(peer)) { - g_type = peer->group->conf->addpath_type[afi][safi]; - - if (type != g_type) - return 1; - else - return 0; - } - - return 1; - } - - return 0; -} - /* 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) { @@ -1197,7 +1122,7 @@ struct peer *peer_new(struct bgp *bgp) /* Set default value. */ peer->fd = -1; peer->v_start = BGP_INIT_START_TIMER; - peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; + peer->v_connect = bgp->default_connect_retry; peer->status = Idle; peer->ostatus = Idle; peer->cur_event = peer->last_event = peer->last_major_event = 0; @@ -2496,7 +2421,7 @@ static void peer_group2peer_config_copy(struct peer_group *group, if (CHECK_FLAG(conf->flags, PEER_FLAG_TIMER_CONNECT)) peer->v_connect = conf->connect; else - peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; + peer->v_connect = peer->bgp->default_connect_retry; } /* advertisement-interval apply */ @@ -2983,26 +2908,13 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->default_local_pref = BGP_DEFAULT_LOCAL_PREF; bgp->default_subgroup_pkt_queue_max = BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX; - bgp->default_holdtime = BGP_DEFAULT_HOLDTIME; - bgp->default_keepalive = BGP_DEFAULT_KEEPALIVE; + bgp_timers_unset(bgp); bgp->restart_time = BGP_DEFAULT_RESTART_TIME; bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME; bgp->dynamic_neighbors_limit = BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT; bgp->dynamic_neighbors_count = 0; bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_DISABLED; bgp->reject_as_sets = BGP_REJECT_AS_SETS_DISABLED; -#if DFLT_BGP_IMPORT_CHECK - bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK); -#endif -#if DFLT_BGP_SHOW_HOSTNAME - bgp_flag_set(bgp, BGP_FLAG_SHOW_HOSTNAME); -#endif -#if DFLT_BGP_LOG_NEIGHBOR_CHANGES - bgp_flag_set(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES); -#endif -#if DFLT_BGP_DETERMINISTIC_MED - bgp_flag_set(bgp, BGP_FLAG_DETERMINISTIC_MED); -#endif bgp_addpath_init_bgp_data(&bgp->tx_addpath); bgp->as = *as; @@ -3255,7 +3167,7 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, bgp_zebra_instance_register(bgp); } - return BGP_SUCCESS; + return BGP_CREATED; } /* @@ -5059,7 +4971,7 @@ int peer_timers_connect_unset(struct peer *peer) if (peer->connect) peer->v_connect = peer->connect; else - peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; + peer->v_connect = peer->bgp->default_connect_retry; /* Skip peer-group mechanics for regular peers. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) @@ -5077,7 +4989,7 @@ int peer_timers_connect_unset(struct peer *peer) /* Remove flag and configuration on peer-group member. */ UNSET_FLAG(member->flags, PEER_FLAG_TIMER_CONNECT); member->connect = 0; - member->v_connect = BGP_DEFAULT_CONNECT_RETRY; + member->v_connect = peer->bgp->default_connect_retry; } return 0; @@ -6899,962 +6811,6 @@ char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json, return buf; } -static void bgp_config_write_filter(struct vty *vty, struct peer *peer, - afi_t afi, safi_t safi) -{ - struct bgp_filter *filter; - char *addr; - - addr = peer->host; - filter = &peer->filter[afi][safi]; - - /* distribute-list. */ - if (peergroup_filter_check(peer, afi, safi, PEER_FT_DISTRIBUTE_LIST, - FILTER_IN)) - vty_out(vty, " neighbor %s distribute-list %s in\n", addr, - filter->dlist[FILTER_IN].name); - - if (peergroup_filter_check(peer, afi, safi, PEER_FT_DISTRIBUTE_LIST, - FILTER_OUT)) - vty_out(vty, " neighbor %s distribute-list %s out\n", addr, - filter->dlist[FILTER_OUT].name); - - /* prefix-list. */ - if (peergroup_filter_check(peer, afi, safi, PEER_FT_PREFIX_LIST, - FILTER_IN)) - vty_out(vty, " neighbor %s prefix-list %s in\n", addr, - filter->plist[FILTER_IN].name); - - if (peergroup_filter_check(peer, afi, safi, PEER_FT_PREFIX_LIST, - FILTER_OUT)) - vty_out(vty, " neighbor %s prefix-list %s out\n", addr, - filter->plist[FILTER_OUT].name); - - /* route-map. */ - if (peergroup_filter_check(peer, afi, safi, PEER_FT_ROUTE_MAP, RMAP_IN)) - vty_out(vty, " neighbor %s route-map %s in\n", addr, - filter->map[RMAP_IN].name); - - if (peergroup_filter_check(peer, afi, safi, PEER_FT_ROUTE_MAP, - RMAP_OUT)) - vty_out(vty, " neighbor %s route-map %s out\n", addr, - filter->map[RMAP_OUT].name); - - /* unsuppress-map */ - if (peergroup_filter_check(peer, afi, safi, PEER_FT_UNSUPPRESS_MAP, 0)) - vty_out(vty, " neighbor %s unsuppress-map %s\n", addr, - filter->usmap.name); - - /* filter-list. */ - if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST, - FILTER_IN)) - vty_out(vty, " neighbor %s filter-list %s in\n", addr, - filter->aslist[FILTER_IN].name); - - if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST, - FILTER_OUT)) - vty_out(vty, " neighbor %s filter-list %s out\n", addr, - filter->aslist[FILTER_OUT].name); -} - -/* BGP peer configuration display function. */ -static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, - struct peer *peer) -{ - struct peer *g_peer = NULL; - char buf[SU_ADDRSTRLEN]; - char *addr; - int if_pg_printed = false; - int if_ras_printed = false; - - /* Skip dynamic neighbors. */ - if (peer_dynamic_neighbor(peer)) - return; - - if (peer->conf_if) - addr = peer->conf_if; - else - addr = peer->host; - - /************************************ - ****** Global to the neighbor ****** - ************************************/ - if (peer->conf_if) { - if (CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY)) - vty_out(vty, " neighbor %s interface v6only", addr); - else - vty_out(vty, " neighbor %s interface", addr); - - if (peer_group_active(peer)) { - vty_out(vty, " peer-group %s", peer->group->name); - if_pg_printed = true; - } else if (peer->as_type == AS_SPECIFIED) { - vty_out(vty, " remote-as %u", peer->as); - if_ras_printed = true; - } else if (peer->as_type == AS_INTERNAL) { - vty_out(vty, " remote-as internal"); - if_ras_printed = true; - } else if (peer->as_type == AS_EXTERNAL) { - vty_out(vty, " remote-as external"); - if_ras_printed = true; - } - - vty_out(vty, "\n"); - } - - /* remote-as and peer-group */ - /* peer is a member of a peer-group */ - if (peer_group_active(peer)) { - g_peer = peer->group->conf; - - if (g_peer->as_type == AS_UNSPECIFIED && !if_ras_printed) { - if (peer->as_type == AS_SPECIFIED) { - vty_out(vty, " neighbor %s remote-as %u\n", - addr, peer->as); - } else if (peer->as_type == AS_INTERNAL) { - vty_out(vty, - " neighbor %s remote-as internal\n", - addr); - } else if (peer->as_type == AS_EXTERNAL) { - vty_out(vty, - " neighbor %s remote-as external\n", - addr); - } - } - - /* For swpX peers we displayed the peer-group - * via 'neighbor swpX interface peer-group PGNAME' */ - if (!if_pg_printed) - vty_out(vty, " neighbor %s peer-group %s\n", addr, - peer->group->name); - } - - /* peer is NOT a member of a peer-group */ - else { - /* peer is a peer-group, declare the peer-group */ - if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - vty_out(vty, " neighbor %s peer-group\n", addr); - } - - if (!if_ras_printed) { - if (peer->as_type == AS_SPECIFIED) { - vty_out(vty, " neighbor %s remote-as %u\n", - addr, peer->as); - } else if (peer->as_type == AS_INTERNAL) { - vty_out(vty, - " neighbor %s remote-as internal\n", - addr); - } else if (peer->as_type == AS_EXTERNAL) { - vty_out(vty, - " neighbor %s remote-as external\n", - addr); - } - } - } - - /* local-as */ - if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS)) { - vty_out(vty, " neighbor %s local-as %u", addr, - peer->change_local_as); - if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_NO_PREPEND)) - vty_out(vty, " no-prepend"); - if (peergroup_flag_check(peer, PEER_FLAG_LOCAL_AS_REPLACE_AS)) - vty_out(vty, " replace-as"); - vty_out(vty, "\n"); - } - - /* description */ - if (peer->desc) { - vty_out(vty, " neighbor %s description %s\n", addr, peer->desc); - } - - /* shutdown */ - if (peergroup_flag_check(peer, PEER_FLAG_SHUTDOWN)) { - if (peer->tx_shutdown_message) - vty_out(vty, " neighbor %s shutdown message %s\n", addr, - peer->tx_shutdown_message); - else - vty_out(vty, " neighbor %s shutdown\n", addr); - } - - /* bfd */ - if (peer->bfd_info) { - if (!peer_group_active(peer) || !g_peer->bfd_info) { - bgp_bfd_peer_config_write(vty, peer, addr); - } - } - - /* password */ - if (peergroup_flag_check(peer, PEER_FLAG_PASSWORD)) - vty_out(vty, " neighbor %s password %s\n", addr, - peer->password); - - /* neighbor solo */ - if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL)) { - if (!peer_group_active(peer)) { - vty_out(vty, " neighbor %s solo\n", addr); - } - } - - /* BGP port */ - if (peer->port != BGP_PORT_DEFAULT) { - vty_out(vty, " neighbor %s port %d\n", addr, peer->port); - } - - /* Local interface name */ - if (peer->ifname) { - vty_out(vty, " neighbor %s interface %s\n", addr, peer->ifname); - } - - /* passive */ - if (peergroup_flag_check(peer, PEER_FLAG_PASSIVE)) - vty_out(vty, " neighbor %s passive\n", addr); - - /* ebgp-multihop */ - if (peer->sort != BGP_PEER_IBGP && peer->ttl != BGP_DEFAULT_TTL - && !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL)) { - if (!peer_group_active(peer) || g_peer->ttl != peer->ttl) { - vty_out(vty, " neighbor %s ebgp-multihop %d\n", addr, - peer->ttl); - } - } - - /* ttl-security hops */ - if (peer->gtsm_hops != 0) { - if (!peer_group_active(peer) - || g_peer->gtsm_hops != peer->gtsm_hops) { - vty_out(vty, " neighbor %s ttl-security hops %d\n", - addr, peer->gtsm_hops); - } - } - - /* disable-connected-check */ - if (peergroup_flag_check(peer, PEER_FLAG_DISABLE_CONNECTED_CHECK)) - vty_out(vty, " neighbor %s disable-connected-check\n", addr); - - /* enforce-first-as */ - if (peergroup_flag_check(peer, PEER_FLAG_ENFORCE_FIRST_AS)) - vty_out(vty, " neighbor %s enforce-first-as\n", addr); - - /* update-source */ - if (peergroup_flag_check(peer, PEER_FLAG_UPDATE_SOURCE)) { - if (peer->update_source) - vty_out(vty, " neighbor %s update-source %s\n", addr, - sockunion2str(peer->update_source, buf, - SU_ADDRSTRLEN)); - else if (peer->update_if) - vty_out(vty, " neighbor %s update-source %s\n", addr, - peer->update_if); - } - - /* advertisement-interval */ - if (peergroup_flag_check(peer, PEER_FLAG_ROUTEADV)) - vty_out(vty, " neighbor %s advertisement-interval %u\n", addr, - peer->routeadv); - - /* timers */ - if (peergroup_flag_check(peer, PEER_FLAG_TIMER)) - vty_out(vty, " neighbor %s timers %u %u\n", addr, - peer->keepalive, peer->holdtime); - - /* timers connect */ - if (peergroup_flag_check(peer, PEER_FLAG_TIMER_CONNECT)) - vty_out(vty, " neighbor %s timers connect %u\n", addr, - peer->connect); - - /* capability dynamic */ - if (peergroup_flag_check(peer, PEER_FLAG_DYNAMIC_CAPABILITY)) - vty_out(vty, " neighbor %s capability dynamic\n", addr); - - /* capability extended-nexthop */ - if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_ENHE)) { - if (!peer->conf_if) { - if (CHECK_FLAG(peer->flags_invert, - PEER_FLAG_CAPABILITY_ENHE)) - vty_out(vty, - " no neighbor %s capability extended-nexthop\n", - addr); - else - vty_out(vty, - " neighbor %s capability extended-nexthop\n", - addr); - } - } - - /* dont-capability-negotiation */ - if (peergroup_flag_check(peer, PEER_FLAG_DONT_CAPABILITY)) - vty_out(vty, " neighbor %s dont-capability-negotiate\n", addr); - - /* override-capability */ - if (peergroup_flag_check(peer, PEER_FLAG_OVERRIDE_CAPABILITY)) - vty_out(vty, " neighbor %s override-capability\n", addr); - - /* strict-capability-match */ - if (peergroup_flag_check(peer, PEER_FLAG_STRICT_CAP_MATCH)) - vty_out(vty, " neighbor %s strict-capability-match\n", addr); - - /* Sender side AS path loop detection. */ - if (peer->as_path_loop_detection) - vty_out(vty, " neighbor %s sender-as-path-loop-detection\n", - addr); -} - -/* BGP peer configuration display function. */ -static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp, - struct peer *peer, afi_t afi, safi_t safi) -{ - struct peer *g_peer = NULL; - char *addr; - bool flag_scomm, flag_secomm, flag_slcomm; - - /* Skip dynamic neighbors. */ - if (peer_dynamic_neighbor(peer)) - return; - - if (peer->conf_if) - addr = peer->conf_if; - else - addr = peer->host; - - /************************************ - ****** Per AF to the neighbor ****** - ************************************/ - if (peer_group_active(peer)) { - g_peer = peer->group->conf; - - /* If the peer-group is active but peer is not, print a 'no - * activate' */ - if (g_peer->afc[afi][safi] && !peer->afc[afi][safi]) { - vty_out(vty, " no neighbor %s activate\n", addr); - } - - /* If the peer-group is not active but peer is, print an - 'activate' */ - else if (!g_peer->afc[afi][safi] && peer->afc[afi][safi]) { - vty_out(vty, " neighbor %s activate\n", addr); - } - } else { - if (peer->afc[afi][safi]) { - if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) { - if (bgp_flag_check(bgp, - BGP_FLAG_NO_DEFAULT_IPV4)) { - vty_out(vty, " neighbor %s activate\n", - addr); - } - } else - vty_out(vty, " neighbor %s activate\n", addr); - } else { - if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) { - if (!bgp_flag_check(bgp, - BGP_FLAG_NO_DEFAULT_IPV4)) { - vty_out(vty, - " no neighbor %s activate\n", - addr); - } - } - } - } - - /* addpath TX knobs */ - if (peergroup_af_addpath_check(peer, afi, safi)) { - switch (peer->addpath_type[afi][safi]) { - case BGP_ADDPATH_ALL: - vty_out(vty, " neighbor %s addpath-tx-all-paths\n", - addr); - break; - case BGP_ADDPATH_BEST_PER_AS: - vty_out(vty, - " neighbor %s addpath-tx-bestpath-per-AS\n", - addr); - break; - case BGP_ADDPATH_MAX: - case BGP_ADDPATH_NONE: - break; - } - } - - /* ORF capability. */ - if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ORF_PREFIX_SM) - || peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_ORF_PREFIX_RM)) { - vty_out(vty, " neighbor %s capability orf prefix-list", addr); - - if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_ORF_PREFIX_SM) - && peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_ORF_PREFIX_RM)) - vty_out(vty, " both"); - else if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_ORF_PREFIX_SM)) - vty_out(vty, " send"); - else - vty_out(vty, " receive"); - vty_out(vty, "\n"); - } - - /* BGP flag dampening. */ - if (CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_DAMPENING)) - bgp_config_write_damp(vty, afi, safi); - - /* Route reflector client. */ - if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_REFLECTOR_CLIENT)) { - vty_out(vty, " neighbor %s route-reflector-client\n", addr); - } - - /* next-hop-self force */ - if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_FORCE_NEXTHOP_SELF)) { - vty_out(vty, " neighbor %s next-hop-self force\n", addr); - } - - /* next-hop-self */ - if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_NEXTHOP_SELF)) { - vty_out(vty, " neighbor %s next-hop-self\n", addr); - } - - /* remove-private-AS */ - if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)) { - vty_out(vty, " neighbor %s remove-private-AS all replace-AS\n", - addr); - } - - else if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) { - vty_out(vty, " neighbor %s remove-private-AS replace-AS\n", - addr); - } - - else if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) { - vty_out(vty, " neighbor %s remove-private-AS all\n", addr); - } - - else if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_REMOVE_PRIVATE_AS)) { - vty_out(vty, " neighbor %s remove-private-AS\n", addr); - } - - /* as-override */ - if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) { - vty_out(vty, " neighbor %s as-override\n", addr); - } - - /* send-community print. */ - flag_scomm = peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_SEND_COMMUNITY); - flag_secomm = peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_SEND_EXT_COMMUNITY); - flag_slcomm = peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_SEND_LARGE_COMMUNITY); - - if (flag_scomm && flag_secomm && flag_slcomm) { - vty_out(vty, " no neighbor %s send-community all\n", addr); - } else { - if (flag_scomm) - vty_out(vty, " no neighbor %s send-community\n", addr); - if (flag_secomm) - vty_out(vty, - " no neighbor %s send-community extended\n", - addr); - - if (flag_slcomm) - vty_out(vty, " no neighbor %s send-community large\n", - addr); - } - - /* Default information */ - if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_DEFAULT_ORIGINATE)) { - 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, "\n"); - } - - /* Soft reconfiguration inbound. */ - if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_SOFT_RECONFIG)) { - vty_out(vty, " neighbor %s soft-reconfiguration inbound\n", - addr); - } - - /* maximum-prefix. */ - if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_MAX_PREFIX)) { - vty_out(vty, " neighbor %s maximum-prefix %" PRIu32, addr, - peer->pmax[afi][safi]); - - if (peer->pmax_threshold[afi][safi] - != MAXIMUM_PREFIX_THRESHOLD_DEFAULT) - vty_out(vty, " %u", peer->pmax_threshold[afi][safi]); - if (peer_af_flag_check(peer, afi, safi, - PEER_FLAG_MAX_PREFIX_WARNING)) - vty_out(vty, " warning-only"); - if (peer->pmax_restart[afi][safi]) - vty_out(vty, " restart %u", - peer->pmax_restart[afi][safi]); - - vty_out(vty, "\n"); - } - - /* Route server client. */ - if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_RSERVER_CLIENT)) { - vty_out(vty, " neighbor %s route-server-client\n", addr); - } - - /* Nexthop-local unchanged. */ - if (peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)) { - vty_out(vty, " neighbor %s nexthop-local unchanged\n", addr); - } - - /* allowas-in <1-10> */ - if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_ALLOWAS_IN)) { - if (peer_af_flag_check(peer, afi, safi, - PEER_FLAG_ALLOWAS_IN_ORIGIN)) { - vty_out(vty, " neighbor %s allowas-in origin\n", addr); - } else if (peer->allowas_in[afi][safi] == 3) { - vty_out(vty, " neighbor %s allowas-in\n", addr); - } else { - vty_out(vty, " neighbor %s allowas-in %d\n", addr, - peer->allowas_in[afi][safi]); - } - } - - /* weight */ - if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_WEIGHT)) - vty_out(vty, " neighbor %s weight %lu\n", addr, - peer->weight[afi][safi]); - - /* Filter. */ - bgp_config_write_filter(vty, peer, afi, safi); - - /* atribute-unchanged. */ - if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_PATH_UNCHANGED) - || (safi != SAFI_EVPN - && peer_af_flag_check(peer, afi, safi, - PEER_FLAG_NEXTHOP_UNCHANGED)) - || peer_af_flag_check(peer, afi, safi, PEER_FLAG_MED_UNCHANGED)) { - - if (!peer_group_active(peer) - || peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_AS_PATH_UNCHANGED) - || peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_NEXTHOP_UNCHANGED) - || peergroup_af_flag_check(peer, afi, safi, - PEER_FLAG_MED_UNCHANGED)) { - - vty_out(vty, - " neighbor %s attribute-unchanged%s%s%s\n", - addr, - peer_af_flag_check(peer, afi, safi, - PEER_FLAG_AS_PATH_UNCHANGED) - ? " as-path" - : "", - peer_af_flag_check(peer, afi, safi, - PEER_FLAG_NEXTHOP_UNCHANGED) - ? " next-hop" - : "", - peer_af_flag_check(peer, afi, safi, - PEER_FLAG_MED_UNCHANGED) - ? " med" - : ""); - } - } -} - -/* Address family based peer configuration display. */ -static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, - safi_t safi) -{ - struct peer *peer; - struct peer_group *group; - struct listnode *node, *nnode; - - - vty_frame(vty, " !\n address-family "); - if (afi == AFI_IP) { - if (safi == SAFI_UNICAST) - vty_frame(vty, "ipv4 unicast"); - else if (safi == SAFI_LABELED_UNICAST) - vty_frame(vty, "ipv4 labeled-unicast"); - else if (safi == SAFI_MULTICAST) - vty_frame(vty, "ipv4 multicast"); - else if (safi == SAFI_MPLS_VPN) - vty_frame(vty, "ipv4 vpn"); - else if (safi == SAFI_ENCAP) - vty_frame(vty, "ipv4 encap"); - else if (safi == SAFI_FLOWSPEC) - vty_frame(vty, "ipv4 flowspec"); - } else if (afi == AFI_IP6) { - if (safi == SAFI_UNICAST) - vty_frame(vty, "ipv6 unicast"); - else if (safi == SAFI_LABELED_UNICAST) - vty_frame(vty, "ipv6 labeled-unicast"); - else if (safi == SAFI_MULTICAST) - vty_frame(vty, "ipv6 multicast"); - else if (safi == SAFI_MPLS_VPN) - vty_frame(vty, "ipv6 vpn"); - else if (safi == SAFI_ENCAP) - vty_frame(vty, "ipv6 encap"); - else if (safi == SAFI_FLOWSPEC) - vty_frame(vty, "ipv6 flowspec"); - } else if (afi == AFI_L2VPN) { - if (safi == SAFI_EVPN) - vty_frame(vty, "l2vpn evpn"); - } - vty_frame(vty, "\n"); - - bgp_config_write_distance(vty, bgp, afi, safi); - - bgp_config_write_network(vty, bgp, afi, safi); - - bgp_config_write_redistribute(vty, bgp, afi, safi); - - for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) - bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi); - - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - /* Skip dynamic neighbors. */ - if (peer_dynamic_neighbor(peer)) - continue; - - /* Do not display doppelganger peers */ - if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) - bgp_config_write_peer_af(vty, bgp, peer, afi, safi); - } - - bgp_config_write_maxpaths(vty, bgp, afi, safi); - bgp_config_write_table_map(vty, bgp, afi, safi); - - if (safi == SAFI_EVPN) - bgp_config_write_evpn_info(vty, bgp, afi, safi); - - if (safi == SAFI_FLOWSPEC) - bgp_fs_config_write_pbr(vty, bgp, afi, safi); - - if (safi == SAFI_UNICAST) { - bgp_vpn_policy_config_write_afi(vty, bgp, afi); - if (CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)) { - - vty_out(vty, " export vpn\n"); - } - if (CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) { - - vty_out(vty, " import vpn\n"); - } - if (CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_VRF_TO_VRF_IMPORT)) { - char *name; - - for (ALL_LIST_ELEMENTS_RO( - bgp->vpn_policy[afi].import_vrf, node, - name)) - vty_out(vty, " import vrf %s\n", name); - } - } - - vty_endframe(vty, " exit-address-family\n"); -} - -int bgp_config_write(struct vty *vty) -{ - struct bgp *bgp; - struct peer_group *group; - struct peer *peer; - struct listnode *node, *nnode; - struct listnode *mnode, *mnnode; - - if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER) - vty_out(vty, "bgp route-map delay-timer %u\n", - bm->rmap_update_timer); - - /* 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); - - if (bgp->name) - vty_out(vty, " %s %s", - (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) - ? "view" : "vrf", bgp->name); - vty_out(vty, "\n"); - - /* BGP fast-external-failover. */ - if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) - vty_out(vty, " no bgp fast-external-failover\n"); - - /* BGP router ID. */ - if (bgp->router_id_static.s_addr != 0) - vty_out(vty, " bgp router-id %s\n", - inet_ntoa(bgp->router_id_static)); - - /* BGP log-neighbor-changes. */ - if (!!bgp_flag_check(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES) - != DFLT_BGP_LOG_NEIGHBOR_CHANGES) - vty_out(vty, " %sbgp log-neighbor-changes\n", - bgp_flag_check(bgp, - BGP_FLAG_LOG_NEIGHBOR_CHANGES) - ? "" - : "no "); - - /* BGP configuration. */ - if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED)) - vty_out(vty, " bgp always-compare-med\n"); - - /* RFC8212 default eBGP policy. */ - if (bgp->ebgp_requires_policy - == DEFAULT_EBGP_POLICY_ENABLED) - vty_out(vty, " bgp ebgp-requires-policy\n"); - - /* draft-ietf-idr-deprecate-as-set-confed-set */ - if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) - vty_out(vty, " bgp reject-as-sets\n"); - - /* BGP default ipv4-unicast. */ - if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4)) - vty_out(vty, " no bgp default ipv4-unicast\n"); - - /* BGP default local-preference. */ - if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF) - vty_out(vty, " bgp default local-preference %u\n", - bgp->default_local_pref); - - /* BGP default show-hostname */ - if (!!bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME) - != DFLT_BGP_SHOW_HOSTNAME) - vty_out(vty, " %sbgp default show-hostname\n", - bgp_flag_check(bgp, BGP_FLAG_SHOW_HOSTNAME) - ? "" - : "no "); - - /* BGP default subgroup-pkt-queue-max. */ - if (bgp->default_subgroup_pkt_queue_max - != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX) - vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n", - bgp->default_subgroup_pkt_queue_max); - - /* 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"); - - /* BGP cluster ID. */ - if (CHECK_FLAG(bgp->config, BGP_CONFIG_CLUSTER_ID)) - vty_out(vty, " bgp cluster-id %s\n", - inet_ntoa(bgp->cluster_id)); - - /* Disable ebgp connected nexthop check */ - if (bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK)) - vty_out(vty, - " bgp disable-ebgp-connected-route-check\n"); - - /* Confederation identifier*/ - if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) - vty_out(vty, " bgp confederation identifier %u\n", - bgp->confed_id); - - /* Confederation peer */ - if (bgp->confed_peers_cnt > 0) { - int i; - - vty_out(vty, " bgp confederation peers"); - - for (i = 0; i < bgp->confed_peers_cnt; i++) - vty_out(vty, " %u", bgp->confed_peers[i]); - - vty_out(vty, "\n"); - } - - /* BGP deterministic-med. */ - if (!!bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED) - != DFLT_BGP_DETERMINISTIC_MED) - vty_out(vty, " %sbgp deterministic-med\n", - bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED) - ? "" - : "no "); - - /* BGP update-delay. */ - bgp_config_write_update_delay(vty, bgp); - - if (bgp->v_maxmed_onstartup - != BGP_MAXMED_ONSTARTUP_UNCONFIGURED) { - vty_out(vty, " bgp max-med on-startup %u", - bgp->v_maxmed_onstartup); - if (bgp->maxmed_onstartup_value - != BGP_MAXMED_VALUE_DEFAULT) - vty_out(vty, " %u", - bgp->maxmed_onstartup_value); - vty_out(vty, "\n"); - } - if (bgp->v_maxmed_admin != BGP_MAXMED_ADMIN_UNCONFIGURED) { - vty_out(vty, " bgp max-med administrative"); - if (bgp->maxmed_admin_value != BGP_MAXMED_VALUE_DEFAULT) - vty_out(vty, " %u", bgp->maxmed_admin_value); - vty_out(vty, "\n"); - } - - /* 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); - - /* BGP graceful-restart. */ - if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME) - vty_out(vty, - " bgp graceful-restart stalepath-time %u\n", - bgp->stalepath_time); - if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME) - vty_out(vty, " bgp graceful-restart restart-time %u\n", - bgp->restart_time); - if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_RESTART)) - vty_out(vty, " bgp graceful-restart\n"); - - /* BGP graceful-shutdown */ - if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) - vty_out(vty, " bgp graceful-shutdown\n"); - - /* BGP graceful-restart Preserve State F bit. */ - if (bgp_flag_check(bgp, BGP_FLAG_GR_PRESERVE_FWD)) - vty_out(vty, - " bgp graceful-restart preserve-fw-state\n"); - - /* BGP bestpath method. */ - if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE)) - vty_out(vty, " bgp bestpath as-path ignore\n"); - if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED)) - vty_out(vty, " bgp bestpath as-path confed\n"); - - if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) { - if (bgp_flag_check(bgp, - BGP_FLAG_MULTIPATH_RELAX_AS_SET)) { - vty_out(vty, - " bgp bestpath as-path multipath-relax as-set\n"); - } else { - vty_out(vty, - " bgp bestpath as-path multipath-relax\n"); - } - } - - if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) { - vty_out(vty, - " bgp route-reflector allow-outbound-policy\n"); - } - if (bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)) - vty_out(vty, " bgp bestpath compare-routerid\n"); - 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, "\n"); - } - - /* BGP network import check. */ - if (!!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK) - != DFLT_BGP_IMPORT_CHECK) - vty_out(vty, " %sbgp network import-check\n", - bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK) - ? "" - : "no "); - - /* BGP timers configuration. */ - if (bgp->default_keepalive != BGP_DEFAULT_KEEPALIVE - && bgp->default_holdtime != BGP_DEFAULT_HOLDTIME) - vty_out(vty, " timers bgp %u %u\n", - bgp->default_keepalive, bgp->default_holdtime); - - /* peer-group */ - for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) { - bgp_config_write_peer_global(vty, bgp, group->conf); - } - - /* Normal neighbor configuration. */ - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE)) - bgp_config_write_peer_global(vty, bgp, peer); - } - - /* 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"); - - /* IPv4 unicast configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP, SAFI_UNICAST); - - /* IPv4 multicast configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MULTICAST); - - /* IPv4 labeled-unicast configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP, SAFI_LABELED_UNICAST); - - /* IPv4 VPN configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP, SAFI_MPLS_VPN); - - /* ENCAPv4 configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP, SAFI_ENCAP); - - /* FLOWSPEC v4 configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP, SAFI_FLOWSPEC); - - /* IPv6 unicast configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_UNICAST); - - /* IPv6 multicast configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MULTICAST); - - /* IPv6 labeled-unicast configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP6, - SAFI_LABELED_UNICAST); - - /* IPv6 VPN configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_MPLS_VPN); - - /* ENCAPv6 configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_ENCAP); - - /* FLOWSPEC v6 configuration. */ - bgp_config_write_family(vty, bgp, AFI_IP6, SAFI_FLOWSPEC); - - /* EVPN configuration. */ - bgp_config_write_family(vty, bgp, AFI_L2VPN, SAFI_EVPN); - - hook_call(bgp_inst_config_write, bgp, vty); - -#if ENABLE_BGP_VNC - bgp_rfapi_cfg_write(vty, bgp); -#endif - - vty_out(vty, "!\n"); - } - return 0; -} - void bgp_master_init(struct thread_master *master, const int buffer_size) { qobj_init(); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 568438b0c..7d8157900 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -457,6 +457,7 @@ struct bgp { /* BGP default timer. */ uint32_t default_holdtime; uint32_t default_keepalive; + uint32_t default_connect_retry; /* BGP graceful restart */ uint32_t restart_time; @@ -1429,13 +1430,17 @@ struct bgp_nlri { #define BGP_EVENTS_MAX 15 /* BGP timers default value. */ -/* note: the DFLT_ ones depend on compile-time "defaults" selection */ #define BGP_INIT_START_TIMER 1 -#define BGP_DEFAULT_HOLDTIME DFLT_BGP_HOLDTIME -#define BGP_DEFAULT_KEEPALIVE DFLT_BGP_KEEPALIVE +/* The following 3 are RFC defaults that are overridden in bgp_vty.c with + * version-/profile-specific values. The values here do not matter, they only + * exist to provide a clear layering separation between core and CLI. + */ +#define BGP_DEFAULT_HOLDTIME 180 +#define BGP_DEFAULT_KEEPALIVE 60 +#define BGP_DEFAULT_CONNECT_RETRY 120 + #define BGP_DEFAULT_EBGP_ROUTEADV 0 #define BGP_DEFAULT_IBGP_ROUTEADV 0 -#define BGP_DEFAULT_CONNECT_RETRY DFLT_BGP_TIMERS_CONNECT /* BGP default local preference. */ #define BGP_DEFAULT_LOCAL_PREF 100 @@ -1480,6 +1485,7 @@ enum bgp_clear_type { /* BGP error codes. */ #define BGP_SUCCESS 0 +#define BGP_CREATED 1 #define BGP_ERR_INVALID_VALUE -1 #define BGP_ERR_INVALID_FLAG -2 #define BGP_ERR_INVALID_AS -3 @@ -1626,7 +1632,8 @@ extern int bgp_confederation_peers_check(struct bgp *, as_t); extern int bgp_confederation_peers_add(struct bgp *, as_t); extern int bgp_confederation_peers_remove(struct bgp *, as_t); -extern int bgp_timers_set(struct bgp *, uint32_t keepalive, uint32_t holdtime); +extern int bgp_timers_set(struct bgp *, uint32_t keepalive, uint32_t holdtime, + uint32_t connect_retry); extern int bgp_timers_unset(struct bgp *); extern int bgp_default_local_preference_set(struct bgp *, uint32_t); |