#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"
#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))
+
+#define GR_NO_OPER "The Graceful Restart No Operation was executed as cmd same as previous one."
+#define GR_INVALID "The Graceful Restart command used is not valid at this moment."
static struct peer_group *listen_range_exists(struct bgp *bgp,
struct prefix *range, int exact);
+/* Show BGP peer's information. */
+enum show_type {
+ show_all,
+ show_peer,
+ show_ipv4_all,
+ show_ipv6_all,
+ show_ipv4_peer,
+ show_ipv6_peer
+};
+
+static struct peer_group *listen_range_exists(
+ struct bgp *bgp,
+ struct prefix *range,
+ int exact);
+
+static void bgp_show_global_graceful_restart_mode_vty(
+ struct vty *vty,
+ struct bgp *bgp,
+ bool use_json,
+ json_object *json);
+
+static int bgp_show_neighbor_graceful_restart_afi_all(
+ struct vty *vty,
+ enum show_type type,
+ const char *ip_str,
+ afi_t afi,
+ bool use_json);
+
static enum node_type bgp_node_type(afi_t afi, safi_t safi)
{
switch (afi) {
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
*
str = "Operation not allowed on a directly connected neighbor";
break;
case BGP_ERR_PEER_SAFI_CONFLICT:
- str = "Cannot activate peer for both 'ipv4 unicast' and 'ipv4 labeled-unicast'";
+ str = GR_INVALID;
+ break;
+ case BGP_ERR_GR_INVALID_CMD:
+ str = "The Graceful Restart command used is not valid at this moment.";
+ break;
+ case BGP_ERR_GR_OPERATION_FAILED:
+ str = "The Graceful Restart Operation failed due to an err.";
+ break;
+ case BGP_GR_NO_OPERATION:
+ str = GR_NO_OPER;
break;
}
if (str) {
int ret = 0;
bool found = false;
struct peer *peer;
- struct listnode *node, *nnode;
+
+ VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
/* Clear all neighbors. */
/*
*/
if (sort == clear_all) {
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+
+ bgp_peer_gr_flags_update(peer);
+
+ if (CHECK_FLAG(peer->flags,
+ PEER_FLAG_GRACEFUL_RESTART))
+ gr_router_detected = true;
+
ret = bgp_peer_clear(peer, afi, safi, nnode,
stype);
if (ret < 0)
bgp_clear_vty_error(vty, peer, afi, safi, ret);
+
+ }
+
+ if (gr_router_detected &&
+ bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) {
+ bgp_zebra_send_capabilities(bgp, false);
+ } else if (!gr_router_detected &&
+ bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) {
+ bgp_zebra_send_capabilities(bgp, true);
}
/* This is to apply read-only mode on this clear. */
}
}
+ VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+ VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
ret = bgp_peer_clear(peer, afi, safi, NULL, stype);
/* if afi/safi not defined for this peer, let caller know */
if (peer->sort == BGP_PEER_IBGP)
continue;
+ bgp_peer_gr_flags_update(peer);
+
+ if (CHECK_FLAG(peer->flags,
+ PEER_FLAG_GRACEFUL_RESTART))
+ gr_router_detected = true;
+
ret = bgp_peer_clear(peer, afi, safi, nnode, stype);
if (ret < 0)
found = true;
}
+ if (gr_router_detected &&
+ bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) {
+ bgp_zebra_send_capabilities(bgp, false);
+ } else if (!gr_router_detected &&
+ bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) {
+ bgp_zebra_send_capabilities(bgp, true);
+ }
+
if (!found)
vty_out(vty,
"%%BGP: No external %s peer is configured\n",
if (peer->as != as)
continue;
+ bgp_peer_gr_flags_update(peer);
+
+ if (CHECK_FLAG(peer->flags,
+ PEER_FLAG_GRACEFUL_RESTART))
+ gr_router_detected = true;
+
ret = bgp_peer_clear(peer, afi, safi, nnode, stype);
if (ret < 0)
found = true;
}
+ if (gr_router_detected &&
+ bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) {
+ bgp_zebra_send_capabilities(bgp, false);
+ } else if (!gr_router_detected &&
+ bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) {
+ bgp_zebra_send_capabilities(bgp, true);
+ }
+
if (!found)
vty_out(vty,
"%%BGP: No %s peer is configured with AS %s\n",
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);
"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",
return CMD_WARNING_CONFIG_FAILED;
}
- bgp_timers_set(bgp, keepalive, holdtime);
+ bgp_timers_set(bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY);
return CMD_SUCCESS;
}
"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;
}
return CMD_SUCCESS;
}
-/* "bgp graceful-restart" configuration. */
+/* "bgp graceful-restart mode" configuration. */
DEFUN (bgp_graceful_restart,
- bgp_graceful_restart_cmd,
- "bgp graceful-restart",
- "BGP specific commands\n"
- "Graceful restart capability parameters\n")
+ bgp_graceful_restart_cmd,
+ "bgp graceful-restart",
+ "BGP specific commands\n"
+ GR_CMD
+ )
{
+ int ret = BGP_GR_FAILURE;
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("[BGP_GR] bgp_graceful_restart_cmd : START ");
+
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_set(bgp, BGP_FLAG_GRACEFUL_RESTART);
- return CMD_SUCCESS;
+
+ ret = bgp_gr_update_all(bgp, GLOBAL_GR_CMD);
+
+ VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp,
+ bgp->peer, ret);
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("[BGP_GR] bgp_graceful_restart_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset all peers to take effect\n");
+ return bgp_vty_return(vty, ret);
}
DEFUN (no_bgp_graceful_restart,
- no_bgp_graceful_restart_cmd,
- "no bgp graceful-restart",
- NO_STR
- "BGP specific commands\n"
- "Graceful restart capability parameters\n")
+ no_bgp_graceful_restart_cmd,
+ "no bgp graceful-restart",
+ NO_STR
+ "BGP specific commands\n"
+ NO_GR_CMD
+ )
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_GRACEFUL_RESTART);
- return CMD_SUCCESS;
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("[BGP_GR] no_bgp_graceful_restart_cmd : START ");
+
+ int ret = BGP_GR_FAILURE;
+
+ ret = bgp_gr_update_all(bgp, NO_GLOBAL_GR_CMD);
+
+ VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp,
+ bgp->peer, ret);
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug("[BGP_GR] no_bgp_graceful_restart_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset all peers to take effect\n");
+
+ return bgp_vty_return(vty, ret);
}
DEFUN (bgp_graceful_restart_stalepath_time,
- bgp_graceful_restart_stalepath_time_cmd,
- "bgp graceful-restart stalepath-time (1-4095)",
- "BGP specific commands\n"
- "Graceful restart capability parameters\n"
- "Set the max time to hold onto restarting peer's stale paths\n"
- "Delay value (seconds)\n")
+ bgp_graceful_restart_stalepath_time_cmd,
+ "bgp graceful-restart stalepath-time (1-4095)",
+ "BGP specific commands\n"
+ "Graceful restart capability parameters\n"
+ "Set the max time to hold onto restarting peer's stale paths\n"
+ "Delay value (seconds)\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_number = 3;
}
DEFUN (bgp_graceful_restart_restart_time,
- bgp_graceful_restart_restart_time_cmd,
- "bgp graceful-restart restart-time (1-4095)",
- "BGP specific commands\n"
- "Graceful restart capability parameters\n"
- "Set the time to wait to delete stale routes before a BGP open message is received\n"
- "Delay value (seconds)\n")
+ bgp_graceful_restart_restart_time_cmd,
+ "bgp graceful-restart restart-time (1-4095)",
+ "BGP specific commands\n"
+ "Graceful restart capability parameters\n"
+ "Set the time to wait to delete stale routes before a BGP open message is received\n"
+ "Delay value (seconds)\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_number = 3;
return CMD_SUCCESS;
}
-DEFUN (no_bgp_graceful_restart_stalepath_time,
- no_bgp_graceful_restart_stalepath_time_cmd,
- "no bgp graceful-restart stalepath-time [(1-4095)]",
- NO_STR
+DEFUN (bgp_graceful_restart_select_defer_time,
+ bgp_graceful_restart_select_defer_time_cmd,
+ "bgp graceful-restart select-defer-time (0-3600)",
"BGP specific commands\n"
"Graceful restart capability parameters\n"
- "Set the max time to hold onto restarting peer's stale paths\n"
- "Delay value (seconds)\n")
+ "Set the time to defer the BGP route selection after restart\n"
+ "Delay value (seconds, 0 - disable)\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
+ uint32_t defer_time;
+
+ defer_time = strtoul(argv[idx_number]->arg, NULL, 10);
+ bgp->select_defer_time = defer_time;
+ if (defer_time == 0)
+ bgp_flag_set(bgp, BGP_FLAG_SELECT_DEFER_DISABLE);
+ else
+ bgp_flag_unset(bgp, BGP_FLAG_SELECT_DEFER_DISABLE);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_graceful_restart_stalepath_time,
+ no_bgp_graceful_restart_stalepath_time_cmd,
+ "no bgp graceful-restart stalepath-time [(1-4095)]",
+ NO_STR
+ "BGP specific commands\n"
+ "Graceful restart capability parameters\n"
+ "Set the max time to hold onto restarting peer's stale paths\n"
+ "Delay value (seconds)\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
}
DEFUN (no_bgp_graceful_restart_restart_time,
- no_bgp_graceful_restart_restart_time_cmd,
- "no bgp graceful-restart restart-time [(1-4095)]",
+ no_bgp_graceful_restart_restart_time_cmd,
+ "no bgp graceful-restart restart-time [(1-4095)]",
+ NO_STR
+ "BGP specific commands\n"
+ "Graceful restart capability parameters\n"
+ "Set the time to wait to delete stale routes before a BGP open message is received\n"
+ "Delay value (seconds)\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_graceful_restart_select_defer_time,
+ no_bgp_graceful_restart_select_defer_time_cmd,
+ "no bgp graceful-restart select-defer-time [(0-3600)]",
NO_STR
"BGP specific commands\n"
"Graceful restart capability parameters\n"
- "Set the time to wait to delete stale routes before a BGP open message is received\n"
+ "Set the time to defer the BGP route selection after restart\n"
"Delay value (seconds)\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp->restart_time = BGP_DEFAULT_RESTART_TIME;
+ bgp->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME;
+ bgp_flag_unset(bgp, BGP_FLAG_SELECT_DEFER_DISABLE);
+
return CMD_SUCCESS;
}
DEFUN (bgp_graceful_restart_preserve_fw,
- bgp_graceful_restart_preserve_fw_cmd,
- "bgp graceful-restart preserve-fw-state",
- "BGP specific commands\n"
- "Graceful restart capability parameters\n"
- "Sets F-bit indication that fib is preserved while doing Graceful Restart\n")
+ bgp_graceful_restart_preserve_fw_cmd,
+ "bgp graceful-restart preserve-fw-state",
+ "BGP specific commands\n"
+ "Graceful restart capability parameters\n"
+ "Sets F-bit indication that fib is preserved while doing Graceful Restart\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set(bgp, BGP_FLAG_GR_PRESERVE_FWD);
}
DEFUN (no_bgp_graceful_restart_preserve_fw,
- no_bgp_graceful_restart_preserve_fw_cmd,
- "no bgp graceful-restart preserve-fw-state",
- NO_STR
- "BGP specific commands\n"
- "Graceful restart capability parameters\n"
- "Unsets F-bit indication that fib is preserved while doing Graceful Restart\n")
+ no_bgp_graceful_restart_preserve_fw_cmd,
+ "no bgp graceful-restart preserve-fw-state",
+ NO_STR
+ "BGP specific commands\n"
+ "Graceful restart capability parameters\n"
+ "Unsets F-bit indication that fib is preserved while doing Graceful Restart\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset(bgp, BGP_FLAG_GR_PRESERVE_FWD);
return CMD_SUCCESS;
}
-/* "bgp graceful-shutdown" configuration */
-DEFUN (bgp_graceful_shutdown,
- bgp_graceful_shutdown_cmd,
- "bgp graceful-shutdown",
- BGP_STR
- "Graceful shutdown parameters\n")
+DEFUN (bgp_graceful_restart_disable,
+ bgp_graceful_restart_disable_cmd,
+ "bgp graceful-restart-disable",
+ "BGP specific commands\n"
+ GR_DISABLE)
{
+ int ret = BGP_GR_FAILURE;
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] bgp_graceful_restart_disable_cmd : START ");
+
VTY_DECLVAR_CONTEXT(bgp, bgp);
- if (!bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
- bgp_flag_set(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
- bgp_static_redo_import_check(bgp);
- bgp_redistribute_redo(bgp);
- bgp_clear_star_soft_out(vty, bgp->name);
- bgp_clear_star_soft_in(vty, bgp->name);
- }
+ ret = bgp_gr_update_all(bgp, GLOBAL_DISABLE_CMD);
- return CMD_SUCCESS;
+ VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp,
+ bgp->peer, ret);
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] bgp_graceful_restart_disable_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset all peers to take effect\n");
+
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_bgp_graceful_shutdown,
- no_bgp_graceful_shutdown_cmd,
- "no bgp graceful-shutdown",
- NO_STR
- BGP_STR
- "Graceful shutdown parameters\n")
+DEFUN (no_bgp_graceful_restart_disable,
+ no_bgp_graceful_restart_disable_cmd,
+ "no bgp graceful-restart-disable",
+ NO_STR
+ "BGP specific commands\n"
+ NO_GR_DISABLE
+ )
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
- bgp_flag_unset(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
- bgp_static_redo_import_check(bgp);
- bgp_redistribute_redo(bgp);
- bgp_clear_star_soft_out(vty, bgp->name);
- bgp_clear_star_soft_in(vty, bgp->name);
- }
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] no_bgp_graceful_restart_disable_cmd : START ");
- return CMD_SUCCESS;
-}
+ int ret = BGP_GR_FAILURE;
-/* "bgp fast-external-failover" configuration. */
-DEFUN (bgp_fast_external_failover,
- bgp_fast_external_failover_cmd,
- "bgp fast-external-failover",
- BGP_STR
- "Immediately reset session if a link to a directly connected external peer goes down\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
- return CMD_SUCCESS;
-}
+ ret = bgp_gr_update_all(bgp, NO_GLOBAL_DISABLE_CMD);
-DEFUN (no_bgp_fast_external_failover,
- no_bgp_fast_external_failover_cmd,
- "no bgp fast-external-failover",
- NO_STR
- BGP_STR
- "Immediately reset session if a link to a directly connected external peer goes down\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_set(bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
- return CMD_SUCCESS;
-}
+ VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp,
+ bgp->peer, ret);
-/* "bgp bestpath compare-routerid" configuration. */
-DEFUN (bgp_bestpath_compare_router_id,
- bgp_bestpath_compare_router_id_cmd,
- "bgp bestpath compare-routerid",
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "Compare router-id for identical EBGP paths\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_set(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
- bgp_recalculate_all_bestpaths(bgp);
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] no_bgp_graceful_restart_disable_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset all peers to take effect\n");
- return CMD_SUCCESS;
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_bgp_bestpath_compare_router_id,
- no_bgp_bestpath_compare_router_id_cmd,
- "no bgp bestpath compare-routerid",
- NO_STR
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "Compare router-id for identical EBGP paths\n")
+DEFUN (bgp_neighbor_graceful_restart_set,
+ bgp_neighbor_graceful_restart_set_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ GR_NEIGHBOR_CMD
+ )
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
- bgp_recalculate_all_bestpaths(bgp);
+ int idx_peer = 1;
+ struct peer *peer;
+ int ret = BGP_GR_FAILURE;
- return CMD_SUCCESS;
-}
+ VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
-/* "bgp bestpath as-path ignore" configuration. */
-DEFUN (bgp_bestpath_aspath_ignore,
- bgp_bestpath_aspath_ignore_cmd,
- "bgp bestpath as-path ignore",
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "AS-path attribute\n"
- "Ignore as-path length in selecting a route\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_set(bgp, BGP_FLAG_ASPATH_IGNORE);
- bgp_recalculate_all_bestpaths(bgp);
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] bgp_neighbor_graceful_restart_set_cmd : START ");
- return CMD_SUCCESS;
-}
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
-DEFUN (no_bgp_bestpath_aspath_ignore,
- no_bgp_bestpath_aspath_ignore_cmd,
- "no bgp bestpath as-path ignore",
- NO_STR
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "AS-path attribute\n"
- "Ignore as-path length in selecting a route\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_ASPATH_IGNORE);
- bgp_recalculate_all_bestpaths(bgp);
+ ret = bgp_neighbor_graceful_restart(peer, PEER_GR_CMD);
- return CMD_SUCCESS;
+ VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+ VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] bgp_neighbor_graceful_restart_set_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset this peer to take effect\n");
+
+ return bgp_vty_return(vty, ret);
}
-/* "bgp bestpath as-path confed" configuration. */
-DEFUN (bgp_bestpath_aspath_confed,
- bgp_bestpath_aspath_confed_cmd,
- "bgp bestpath as-path confed",
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "AS-path attribute\n"
- "Compare path lengths including confederation sets & sequences in selecting a route\n")
+DEFUN (no_bgp_neighbor_graceful_restart,
+ no_bgp_neighbor_graceful_restart_set_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ NO_GR_NEIGHBOR_CMD
+ )
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_set(bgp, BGP_FLAG_ASPATH_CONFED);
- bgp_recalculate_all_bestpaths(bgp);
+ int idx_peer = 2;
+ int ret = BGP_GR_FAILURE;
+ struct peer *peer;
- return CMD_SUCCESS;
+ VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
+
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] no_bgp_neighbor_graceful_restart_set_cmd : START ");
+
+ ret = bgp_neighbor_graceful_restart(peer, NO_PEER_GR_CMD);
+
+ VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+ VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] no_bgp_neighbor_graceful_restart_set_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset this peer to take effect\n");
+
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_bgp_bestpath_aspath_confed,
- no_bgp_bestpath_aspath_confed_cmd,
- "no bgp bestpath as-path confed",
- NO_STR
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "AS-path attribute\n"
- "Compare path lengths including confederation sets & sequences in selecting a route\n")
+DEFUN (bgp_neighbor_graceful_restart_helper_set,
+ bgp_neighbor_graceful_restart_helper_set_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart-helper",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ GR_NEIGHBOR_HELPER_CMD
+ )
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_ASPATH_CONFED);
- bgp_recalculate_all_bestpaths(bgp);
+ int idx_peer = 1;
+ struct peer *peer;
+ int ret = BGP_GR_FAILURE;
- return CMD_SUCCESS;
-}
+ VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
-/* "bgp bestpath as-path multipath-relax" configuration. */
-DEFUN (bgp_bestpath_aspath_multipath_relax,
- bgp_bestpath_aspath_multipath_relax_cmd,
- "bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "AS-path attribute\n"
- "Allow load sharing across routes that have different AS paths (but same length)\n"
- "Generate an AS_SET\n"
- "Do not generate an AS_SET\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx = 0;
- bgp_flag_set(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] bgp_neighbor_graceful_restart_helper_set_cmd : START ");
- /* no-as-set is now the default behavior so we can silently
- * ignore it */
- if (argv_find(argv, argc, "as-set", &idx))
- bgp_flag_set(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
- else
- bgp_flag_unset(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- bgp_recalculate_all_bestpaths(bgp);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
- return CMD_SUCCESS;
-}
-DEFUN (no_bgp_bestpath_aspath_multipath_relax,
- no_bgp_bestpath_aspath_multipath_relax_cmd,
- "no bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
- NO_STR
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "AS-path attribute\n"
- "Allow load sharing across routes that have different AS paths (but same length)\n"
- "Generate an AS_SET\n"
- "Do not generate an AS_SET\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
- bgp_flag_unset(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
- bgp_recalculate_all_bestpaths(bgp);
+ ret = bgp_neighbor_graceful_restart(peer, PEER_HELPER_CMD);
- return CMD_SUCCESS;
-}
+ VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+ VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
-/* "bgp log-neighbor-changes" configuration. */
-DEFUN (bgp_log_neighbor_changes,
- bgp_log_neighbor_changes_cmd,
- "bgp log-neighbor-changes",
- "BGP specific commands\n"
- "Log neighbor up/down and reset reason\n")
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_set(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
- return CMD_SUCCESS;
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] bgp_neighbor_graceful_restart_helper_set_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset this peer to take effect\n");
+
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_bgp_log_neighbor_changes,
- no_bgp_log_neighbor_changes_cmd,
- "no bgp log-neighbor-changes",
- NO_STR
- "BGP specific commands\n"
- "Log neighbor up/down and reset reason\n")
+DEFUN (no_bgp_neighbor_graceful_restart_helper,
+ no_bgp_neighbor_graceful_restart_helper_set_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart-helper",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ NO_GR_NEIGHBOR_HELPER_CMD
+ )
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
- return CMD_SUCCESS;
+ int idx_peer = 2;
+ int ret = BGP_GR_FAILURE;
+ struct peer *peer;
+
+ VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
+
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] no_bgp_neighbor_graceful_restart_helper_set_cmd : START ");
+
+ ret = bgp_neighbor_graceful_restart(peer,
+ NO_PEER_HELPER_CMD);
+
+ VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+ VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] no_bgp_neighbor_graceful_restart_helper_set_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset this peer to take effect\n");
+
+ return bgp_vty_return(vty, ret);
}
-/* "bgp bestpath med" configuration. */
-DEFUN (bgp_bestpath_med,
- bgp_bestpath_med_cmd,
- "bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "MED attribute\n"
- "Compare MED among confederation paths\n"
- "Treat missing MED as the least preferred one\n"
- "Treat missing MED as the least preferred one\n"
- "Compare MED among confederation paths\n")
+DEFUN (bgp_neighbor_graceful_restart_disable_set,
+ bgp_neighbor_graceful_restart_disable_set_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart-disable",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ GR_NEIGHBOR_DISABLE_CMD
+ )
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_peer = 1;
+ struct peer *peer;
+ int ret = BGP_GR_FAILURE;
- int idx = 0;
- if (argv_find(argv, argc, "confed", &idx))
- bgp_flag_set(bgp, BGP_FLAG_MED_CONFED);
- idx = 0;
- if (argv_find(argv, argc, "missing-as-worst", &idx))
- bgp_flag_set(bgp, BGP_FLAG_MED_MISSING_AS_WORST);
+ VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
- bgp_recalculate_all_bestpaths(bgp);
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] bgp_neighbor_graceful_restart_disable_set_cmd : START ");
- return CMD_SUCCESS;
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ ret = bgp_neighbor_graceful_restart(peer,
+ PEER_DISABLE_CMD);
+
+ if (peer->bgp->t_startup)
+ bgp_peer_gr_flags_update(peer);
+
+ VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+ VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR]bgp_neighbor_graceful_restart_disable_set_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset this peer to take effect\n");
+
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_bgp_bestpath_med,
- no_bgp_bestpath_med_cmd,
- "no bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
- NO_STR
- "BGP specific commands\n"
- "Change the default bestpath selection\n"
- "MED attribute\n"
- "Compare MED among confederation paths\n"
- "Treat missing MED as the least preferred one\n"
- "Treat missing MED as the least preferred one\n"
- "Compare MED among confederation paths\n")
+DEFUN (no_bgp_neighbor_graceful_restart_disable,
+ no_bgp_neighbor_graceful_restart_disable_set_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> graceful-restart-disable",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ NO_GR_NEIGHBOR_DISABLE_CMD
+ )
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_peer = 2;
+ int ret = BGP_GR_FAILURE;
+ struct peer *peer;
- int idx = 0;
- if (argv_find(argv, argc, "confed", &idx))
- bgp_flag_unset(bgp, BGP_FLAG_MED_CONFED);
- idx = 0;
- if (argv_find(argv, argc, "missing-as-worst", &idx))
- bgp_flag_unset(bgp, BGP_FLAG_MED_MISSING_AS_WORST);
+ VTY_BGP_GR_DEFINE_LOOP_VARIABLE;
- bgp_recalculate_all_bestpaths(bgp);
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
- return CMD_SUCCESS;
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] no_bgp_neighbor_graceful_restart_disable_set_cmd : START ");
+
+ ret = bgp_neighbor_graceful_restart(peer, NO_PEER_DISABLE_CMD);
+
+ VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer);
+ VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret);
+
+ if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART))
+ zlog_debug(
+ "[BGP_GR] no_bgp_neighbor_graceful_restart_disable_set_cmd : END ");
+ vty_out(vty,
+ "Graceful restart configuration changed, reset this peer to take effect\n");
+
+ return bgp_vty_return(vty, ret);
}
-/* "no bgp default ipv4-unicast". */
-DEFUN (no_bgp_default_ipv4_unicast,
- no_bgp_default_ipv4_unicast_cmd,
- "no bgp default ipv4-unicast",
- NO_STR
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "Activate ipv4-unicast for a peer by default\n")
+DEFUN_HIDDEN (bgp_graceful_restart_disable_eor,
+ bgp_graceful_restart_disable_eor_cmd,
+ "bgp graceful-restart disable-eor",
+ "BGP specific commands\n"
+ "Graceful restart configuration parameters\n"
+ "Disable EOR Check\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_set(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+ bgp_flag_set(bgp, BGP_FLAG_GR_DISABLE_EOR);
+
return CMD_SUCCESS;
}
-DEFUN (bgp_default_ipv4_unicast,
- bgp_default_ipv4_unicast_cmd,
- "bgp default ipv4-unicast",
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "Activate ipv4-unicast for a peer by default\n")
+DEFUN_HIDDEN (no_bgp_graceful_restart_disable_eor,
+ no_bgp_graceful_restart_disable_eor_cmd,
+ "no bgp graceful-restart disable-eor",
+ NO_STR
+ "BGP specific commands\n"
+ "Graceful restart configuration parameters\n"
+ "Disable EOR Check\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+ bgp_flag_unset(bgp, BGP_FLAG_GR_DISABLE_EOR);
+
return CMD_SUCCESS;
}
-/* Display hostname in certain command outputs */
-DEFUN (bgp_default_show_hostname,
- bgp_default_show_hostname_cmd,
- "bgp default show-hostname",
+DEFUN (bgp_graceful_restart_rib_stale_time,
+ bgp_graceful_restart_rib_stale_time_cmd,
+ "bgp graceful-restart rib-stale-time (1-3600)",
"BGP specific commands\n"
- "Configure BGP defaults\n"
- "Show hostname in certain command outputs\n")
+ "Graceful restart configuration parameters\n"
+ "Specify the stale route removal timer in rib\n"
+ "Delay value (seconds)\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_set(bgp, BGP_FLAG_SHOW_HOSTNAME);
+ int idx_number = 3;
+ uint32_t stale_time;
+
+ stale_time = strtoul(argv[idx_number]->arg, NULL, 10);
+ bgp->rib_stale_time = stale_time;
+ /* Send the stale timer update message to RIB */
+ if (bgp_zebra_stale_timer_update(bgp))
+ return CMD_WARNING;
+
return CMD_SUCCESS;
}
-DEFUN (no_bgp_default_show_hostname,
- no_bgp_default_show_hostname_cmd,
- "no bgp default show-hostname",
+DEFUN (no_bgp_graceful_restart_rib_stale_time,
+ no_bgp_graceful_restart_rib_stale_time_cmd,
+ "no bgp graceful-restart rib-stale-time [(1-3600)]",
NO_STR
"BGP specific commands\n"
- "Configure BGP defaults\n"
- "Show hostname in certain command outputs\n")
+ "Graceful restart configuration parameters\n"
+ "Specify the stale route removal timer in rib\n"
+ "Delay value (seconds)\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_SHOW_HOSTNAME);
+
+ bgp->rib_stale_time = BGP_DEFAULT_RIB_STALE_TIME;
+ /* Send the stale timer update message to RIB */
+ if (bgp_zebra_stale_timer_update(bgp))
+ return CMD_WARNING;
+
return CMD_SUCCESS;
}
-/* "bgp network import-check" configuration. */
-DEFUN (bgp_network_import_check,
- bgp_network_import_check_cmd,
- "bgp network import-check",
- "BGP specific commands\n"
- "BGP network command\n"
- "Check BGP network route exists in IGP\n")
+/* "bgp graceful-shutdown" configuration */
+DEFUN (bgp_graceful_shutdown,
+ bgp_graceful_shutdown_cmd,
+ "bgp graceful-shutdown",
+ BGP_STR
+ "Graceful shutdown parameters\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- if (!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
- bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
+
+ if (!bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
+ bgp_flag_set(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
bgp_static_redo_import_check(bgp);
+ bgp_redistribute_redo(bgp);
+ bgp_clear_star_soft_out(vty, bgp->name);
+ bgp_clear_star_soft_in(vty, bgp->name);
}
return CMD_SUCCESS;
}
-ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd,
- "bgp network import-check exact",
- "BGP specific commands\n"
- "BGP network command\n"
- "Check BGP network route exists in IGP\n"
- "Match route precisely\n")
-
-DEFUN (no_bgp_network_import_check,
- no_bgp_network_import_check_cmd,
- "no bgp network import-check",
+DEFUN (no_bgp_graceful_shutdown,
+ no_bgp_graceful_shutdown_cmd,
+ "no bgp graceful-shutdown",
NO_STR
- "BGP specific commands\n"
- "BGP network command\n"
- "Check BGP network route exists in IGP\n")
+ BGP_STR
+ "Graceful shutdown parameters\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
- bgp_flag_unset(bgp, BGP_FLAG_IMPORT_CHECK);
+
+ if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
+ bgp_flag_unset(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN);
bgp_static_redo_import_check(bgp);
+ bgp_redistribute_redo(bgp);
+ bgp_clear_star_soft_out(vty, bgp->name);
+ bgp_clear_star_soft_in(vty, bgp->name);
}
return CMD_SUCCESS;
}
-DEFUN (bgp_default_local_preference,
- bgp_default_local_preference_cmd,
- "bgp default local-preference (0-4294967295)",
- "BGP specific commands\n"
- "Configure BGP defaults\n"
- "local preference (higher=more preferred)\n"
- "Configure default local preference value\n")
+/* "bgp fast-external-failover" configuration. */
+DEFUN (bgp_fast_external_failover,
+ bgp_fast_external_failover_cmd,
+ "bgp fast-external-failover",
+ BGP_STR
+ "Immediately reset session if a link to a directly connected external peer goes down\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_number = 3;
- uint32_t local_pref;
-
- local_pref = strtoul(argv[idx_number]->arg, NULL, 10);
-
- bgp_default_local_preference_set(bgp, local_pref);
- bgp_clear_star_soft_in(vty, bgp->name);
-
+ bgp_flag_unset(bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
return CMD_SUCCESS;
}
-DEFUN (no_bgp_default_local_preference,
- no_bgp_default_local_preference_cmd,
- "no bgp default local-preference [(0-4294967295)]",
+DEFUN (no_bgp_fast_external_failover,
+ no_bgp_fast_external_failover_cmd,
+ "no bgp fast-external-failover",
NO_STR
+ BGP_STR
+ "Immediately reset session if a link to a directly connected external peer goes down\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_set(bgp, BGP_FLAG_NO_FAST_EXT_FAILOVER);
+ return CMD_SUCCESS;
+}
+
+/* "bgp bestpath compare-routerid" configuration. */
+DEFUN (bgp_bestpath_compare_router_id,
+ bgp_bestpath_compare_router_id_cmd,
+ "bgp bestpath compare-routerid",
"BGP specific commands\n"
- "Configure BGP defaults\n"
- "local preference (higher=more preferred)\n"
- "Configure default local preference value\n")
+ "Change the default bestpath selection\n"
+ "Compare router-id for identical EBGP paths\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_default_local_preference_unset(bgp);
- bgp_clear_star_soft_in(vty, bgp->name);
+ bgp_flag_set(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
+ bgp_recalculate_all_bestpaths(bgp);
return CMD_SUCCESS;
}
-
-DEFUN (bgp_default_subgroup_pkt_queue_max,
- bgp_default_subgroup_pkt_queue_max_cmd,
- "bgp default subgroup-pkt-queue-max (20-100)",
+DEFUN (no_bgp_bestpath_compare_router_id,
+ no_bgp_bestpath_compare_router_id_cmd,
+ "no bgp bestpath compare-routerid",
+ NO_STR
"BGP specific commands\n"
- "Configure BGP defaults\n"
- "subgroup-pkt-queue-max\n"
- "Configure subgroup packet queue max\n")
+ "Change the default bestpath selection\n"
+ "Compare router-id for identical EBGP paths\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_number = 3;
- uint32_t max_size;
+ bgp_flag_unset(bgp, BGP_FLAG_COMPARE_ROUTER_ID);
+ bgp_recalculate_all_bestpaths(bgp);
- max_size = strtoul(argv[idx_number]->arg, NULL, 10);
+ return CMD_SUCCESS;
+}
- bgp_default_subgroup_pkt_queue_max_set(bgp, max_size);
+/* "bgp bestpath as-path ignore" configuration. */
+DEFUN (bgp_bestpath_aspath_ignore,
+ bgp_bestpath_aspath_ignore_cmd,
+ "bgp bestpath as-path ignore",
+ "BGP specific commands\n"
+ "Change the default bestpath selection\n"
+ "AS-path attribute\n"
+ "Ignore as-path length in selecting a route\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_set(bgp, BGP_FLAG_ASPATH_IGNORE);
+ bgp_recalculate_all_bestpaths(bgp);
return CMD_SUCCESS;
}
-DEFUN (no_bgp_default_subgroup_pkt_queue_max,
- no_bgp_default_subgroup_pkt_queue_max_cmd,
- "no bgp default subgroup-pkt-queue-max [(20-100)]",
+DEFUN (no_bgp_bestpath_aspath_ignore,
+ no_bgp_bestpath_aspath_ignore_cmd,
+ "no bgp bestpath as-path ignore",
NO_STR
"BGP specific commands\n"
- "Configure BGP defaults\n"
- "subgroup-pkt-queue-max\n"
- "Configure subgroup packet queue max\n")
+ "Change the default bestpath selection\n"
+ "AS-path attribute\n"
+ "Ignore as-path length in selecting a route\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_default_subgroup_pkt_queue_max_unset(bgp);
+ bgp_flag_unset(bgp, BGP_FLAG_ASPATH_IGNORE);
+ bgp_recalculate_all_bestpaths(bgp);
+
return CMD_SUCCESS;
}
-
-DEFUN (bgp_rr_allow_outbound_policy,
- bgp_rr_allow_outbound_policy_cmd,
- "bgp route-reflector allow-outbound-policy",
+/* "bgp bestpath as-path confed" configuration. */
+DEFUN (bgp_bestpath_aspath_confed,
+ bgp_bestpath_aspath_confed_cmd,
+ "bgp bestpath as-path confed",
"BGP specific commands\n"
- "Allow modifications made by out route-map\n"
- "on ibgp neighbors\n")
+ "Change the default bestpath selection\n"
+ "AS-path attribute\n"
+ "Compare path lengths including confederation sets & sequences in selecting a route\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
-
- if (!bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
- bgp_flag_set(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
- update_group_announce_rrclients(bgp);
- bgp_clear_star_soft_out(vty, bgp->name);
- }
+ bgp_flag_set(bgp, BGP_FLAG_ASPATH_CONFED);
+ bgp_recalculate_all_bestpaths(bgp);
return CMD_SUCCESS;
}
-DEFUN (no_bgp_rr_allow_outbound_policy,
- no_bgp_rr_allow_outbound_policy_cmd,
- "no bgp route-reflector allow-outbound-policy",
+DEFUN (no_bgp_bestpath_aspath_confed,
+ no_bgp_bestpath_aspath_confed_cmd,
+ "no bgp bestpath as-path confed",
NO_STR
"BGP specific commands\n"
- "Allow modifications made by out route-map\n"
- "on ibgp neighbors\n")
+ "Change the default bestpath selection\n"
+ "AS-path attribute\n"
+ "Compare path lengths including confederation sets & sequences in selecting a route\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
-
- if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
- bgp_flag_unset(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
- update_group_announce_rrclients(bgp);
- bgp_clear_star_soft_out(vty, bgp->name);
- }
+ bgp_flag_unset(bgp, BGP_FLAG_ASPATH_CONFED);
+ bgp_recalculate_all_bestpaths(bgp);
return CMD_SUCCESS;
}
-DEFUN (bgp_listen_limit,
- bgp_listen_limit_cmd,
- "bgp listen limit (1-5000)",
+/* "bgp bestpath as-path multipath-relax" configuration. */
+DEFUN (bgp_bestpath_aspath_multipath_relax,
+ bgp_bestpath_aspath_multipath_relax_cmd,
+ "bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
"BGP specific commands\n"
- "Configure BGP defaults\n"
- "maximum number of BGP Dynamic Neighbors that can be created\n"
- "Configure Dynamic Neighbors listen limit value\n")
+ "Change the default bestpath selection\n"
+ "AS-path attribute\n"
+ "Allow load sharing across routes that have different AS paths (but same length)\n"
+ "Generate an AS_SET\n"
+ "Do not generate an AS_SET\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_number = 3;
- int listen_limit;
+ int idx = 0;
+ bgp_flag_set(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
- listen_limit = strtoul(argv[idx_number]->arg, NULL, 10);
+ /* no-as-set is now the default behavior so we can silently
+ * ignore it */
+ if (argv_find(argv, argc, "as-set", &idx))
+ bgp_flag_set(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+ else
+ bgp_flag_unset(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
- bgp_listen_limit_set(bgp, listen_limit);
+ bgp_recalculate_all_bestpaths(bgp);
return CMD_SUCCESS;
}
-DEFUN (no_bgp_listen_limit,
- no_bgp_listen_limit_cmd,
- "no bgp listen limit [(1-5000)]",
+DEFUN (no_bgp_bestpath_aspath_multipath_relax,
+ no_bgp_bestpath_aspath_multipath_relax_cmd,
+ "no bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
+ NO_STR
"BGP specific commands\n"
- "Configure BGP defaults\n"
- "unset maximum number of BGP Dynamic Neighbors that can be created\n"
- "Configure Dynamic Neighbors listen limit value to default\n"
- "Configure Dynamic Neighbors listen limit value\n")
+ "Change the default bestpath selection\n"
+ "AS-path attribute\n"
+ "Allow load sharing across routes that have different AS paths (but same length)\n"
+ "Generate an AS_SET\n"
+ "Do not generate an AS_SET\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_listen_limit_unset(bgp);
+ bgp_flag_unset(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+ bgp_flag_unset(bgp, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+ bgp_recalculate_all_bestpaths(bgp);
+
return CMD_SUCCESS;
}
-
-/*
- * Check if this listen range is already configured. Check for exact
- * match or overlap based on input.
- */
-static struct peer_group *listen_range_exists(struct bgp *bgp,
- struct prefix *range, int exact)
+/* "bgp log-neighbor-changes" configuration. */
+DEFUN (bgp_log_neighbor_changes,
+ bgp_log_neighbor_changes_cmd,
+ "bgp log-neighbor-changes",
+ "BGP specific commands\n"
+ "Log neighbor up/down and reset reason\n")
{
- struct listnode *node, *nnode;
- struct listnode *node1, *nnode1;
- struct peer_group *group;
- struct prefix *lr;
- afi_t afi;
- int match;
-
- afi = family2afi(range->family);
- for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
- for (ALL_LIST_ELEMENTS(group->listen_range[afi], node1, nnode1,
- lr)) {
- if (exact)
- match = prefix_same(range, lr);
- else
- match = (prefix_match(range, lr)
- || prefix_match(lr, range));
- if (match)
- return group;
- }
- }
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_set(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+ return CMD_SUCCESS;
+}
- return NULL;
+DEFUN (no_bgp_log_neighbor_changes,
+ no_bgp_log_neighbor_changes_cmd,
+ "no bgp log-neighbor-changes",
+ NO_STR
+ "BGP specific commands\n"
+ "Log neighbor up/down and reset reason\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_unset(bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+ return CMD_SUCCESS;
}
-DEFUN (bgp_listen_range,
- bgp_listen_range_cmd,
- "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
+/* "bgp bestpath med" configuration. */
+DEFUN (bgp_bestpath_med,
+ bgp_bestpath_med_cmd,
+ "bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
"BGP specific commands\n"
- "Configure BGP dynamic neighbors listen range\n"
- "Configure BGP dynamic neighbors listen range\n"
- NEIGHBOR_ADDR_STR
- "Member of the peer-group\n"
- "Peer-group name\n")
+ "Change the default bestpath selection\n"
+ "MED attribute\n"
+ "Compare MED among confederation paths\n"
+ "Treat missing MED as the least preferred one\n"
+ "Treat missing MED as the least preferred one\n"
+ "Compare MED among confederation paths\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- struct prefix range;
- struct peer_group *group, *existing_group;
- afi_t afi;
- int ret;
- int idx = 0;
- argv_find(argv, argc, "A.B.C.D/M", &idx);
- argv_find(argv, argc, "X:X::X:X/M", &idx);
- char *prefix = argv[idx]->arg;
- argv_find(argv, argc, "PGNAME", &idx);
- char *peergroup = argv[idx]->arg;
+ int idx = 0;
+ if (argv_find(argv, argc, "confed", &idx))
+ bgp_flag_set(bgp, BGP_FLAG_MED_CONFED);
+ idx = 0;
+ if (argv_find(argv, argc, "missing-as-worst", &idx))
+ bgp_flag_set(bgp, BGP_FLAG_MED_MISSING_AS_WORST);
- /* Convert IP prefix string to struct prefix. */
- ret = str2prefix(prefix, &range);
- if (!ret) {
- vty_out(vty, "%% Malformed listen range\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ bgp_recalculate_all_bestpaths(bgp);
- afi = family2afi(range.family);
+ return CMD_SUCCESS;
+}
- if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&range.u.prefix6)) {
- vty_out(vty,
- "%% Malformed listen range (link-local address)\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- apply_mask(&range);
-
- /* Check if same listen range is already configured. */
- existing_group = listen_range_exists(bgp, &range, 1);
- if (existing_group) {
- if (strcmp(existing_group->name, peergroup) == 0)
- return CMD_SUCCESS;
- else {
- vty_out(vty,
- "%% Same listen range is attached to peer-group %s\n",
- existing_group->name);
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
+DEFUN (no_bgp_bestpath_med,
+ no_bgp_bestpath_med_cmd,
+ "no bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
+ NO_STR
+ "BGP specific commands\n"
+ "Change the default bestpath selection\n"
+ "MED attribute\n"
+ "Compare MED among confederation paths\n"
+ "Treat missing MED as the least preferred one\n"
+ "Treat missing MED as the least preferred one\n"
+ "Compare MED among confederation paths\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
- /* Check if an overlapping listen range exists. */
- if (listen_range_exists(bgp, &range, 0)) {
- vty_out(vty,
- "%% Listen range overlaps with existing listen range\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ int idx = 0;
+ if (argv_find(argv, argc, "confed", &idx))
+ bgp_flag_unset(bgp, BGP_FLAG_MED_CONFED);
+ idx = 0;
+ if (argv_find(argv, argc, "missing-as-worst", &idx))
+ bgp_flag_unset(bgp, BGP_FLAG_MED_MISSING_AS_WORST);
- group = peer_group_lookup(bgp, peergroup);
- if (!group) {
- vty_out(vty, "%% Configure the peer-group first\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ bgp_recalculate_all_bestpaths(bgp);
- ret = peer_group_listen_range_add(group, &range);
- return bgp_vty_return(vty, ret);
+ return CMD_SUCCESS;
}
-DEFUN (no_bgp_listen_range,
- no_bgp_listen_range_cmd,
- "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
+/* "no bgp default ipv4-unicast". */
+DEFUN (no_bgp_default_ipv4_unicast,
+ no_bgp_default_ipv4_unicast_cmd,
+ "no bgp default ipv4-unicast",
NO_STR
"BGP specific commands\n"
- "Unconfigure BGP dynamic neighbors listen range\n"
- "Unconfigure BGP dynamic neighbors listen range\n"
- NEIGHBOR_ADDR_STR
- "Member of the peer-group\n"
- "Peer-group name\n")
+ "Configure BGP defaults\n"
+ "Activate ipv4-unicast for a peer by default\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- struct prefix range;
- struct peer_group *group;
- afi_t afi;
- int ret;
- int idx = 0;
-
- argv_find(argv, argc, "A.B.C.D/M", &idx);
- argv_find(argv, argc, "X:X::X:X/M", &idx);
- char *prefix = argv[idx]->arg;
- argv_find(argv, argc, "WORD", &idx);
- char *peergroup = argv[idx]->arg;
-
- /* Convert IP prefix string to struct prefix. */
- ret = str2prefix(prefix, &range);
- if (!ret) {
- vty_out(vty, "%% Malformed listen range\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ bgp_flag_set(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+ return CMD_SUCCESS;
+}
- afi = family2afi(range.family);
+DEFUN (bgp_default_ipv4_unicast,
+ bgp_default_ipv4_unicast_cmd,
+ "bgp default ipv4-unicast",
+ "BGP specific commands\n"
+ "Configure BGP defaults\n"
+ "Activate ipv4-unicast for a peer by default\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_unset(bgp, BGP_FLAG_NO_DEFAULT_IPV4);
+ return CMD_SUCCESS;
+}
- if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&range.u.prefix6)) {
- vty_out(vty,
- "%% Malformed listen range (link-local address)\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+/* Display hostname in certain command outputs */
+DEFUN (bgp_default_show_hostname,
+ bgp_default_show_hostname_cmd,
+ "bgp default show-hostname",
+ "BGP specific commands\n"
+ "Configure BGP defaults\n"
+ "Show hostname in certain command outputs\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_set(bgp, BGP_FLAG_SHOW_HOSTNAME);
+ return CMD_SUCCESS;
+}
- apply_mask(&range);
+DEFUN (no_bgp_default_show_hostname,
+ no_bgp_default_show_hostname_cmd,
+ "no bgp default show-hostname",
+ NO_STR
+ "BGP specific commands\n"
+ "Configure BGP defaults\n"
+ "Show hostname in certain command outputs\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_unset(bgp, BGP_FLAG_SHOW_HOSTNAME);
+ return CMD_SUCCESS;
+}
- group = peer_group_lookup(bgp, peergroup);
- if (!group) {
- vty_out(vty, "%% Peer-group does not exist\n");
- return CMD_WARNING_CONFIG_FAILED;
+/* "bgp network import-check" configuration. */
+DEFUN (bgp_network_import_check,
+ bgp_network_import_check_cmd,
+ "bgp network import-check",
+ "BGP specific commands\n"
+ "BGP network command\n"
+ "Check BGP network route exists in IGP\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ if (!bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
+ bgp_flag_set(bgp, BGP_FLAG_IMPORT_CHECK);
+ bgp_static_redo_import_check(bgp);
}
- ret = peer_group_listen_range_del(group, &range);
- return bgp_vty_return(vty, ret);
+ return CMD_SUCCESS;
}
-void bgp_config_write_listen(struct vty *vty, struct bgp *bgp)
-{
- struct peer_group *group;
- struct listnode *node, *nnode, *rnode, *nrnode;
- struct prefix *range;
- afi_t afi;
- char buf[PREFIX2STR_BUFFER];
-
- if (bgp->dynamic_neighbors_limit != BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT)
- vty_out(vty, " bgp listen limit %d\n",
- bgp->dynamic_neighbors_limit);
+ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd,
+ "bgp network import-check exact",
+ "BGP specific commands\n"
+ "BGP network command\n"
+ "Check BGP network route exists in IGP\n"
+ "Match route precisely\n")
- for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
- for (afi = AFI_IP; afi < AFI_MAX; afi++) {
- for (ALL_LIST_ELEMENTS(group->listen_range[afi], rnode,
- nrnode, range)) {
- prefix2str(range, buf, sizeof(buf));
- vty_out(vty,
- " bgp listen range %s peer-group %s\n",
- buf, group->name);
- }
- }
+DEFUN (no_bgp_network_import_check,
+ no_bgp_network_import_check_cmd,
+ "no bgp network import-check",
+ NO_STR
+ "BGP specific commands\n"
+ "BGP network command\n"
+ "Check BGP network route exists in IGP\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
+ bgp_flag_unset(bgp, BGP_FLAG_IMPORT_CHECK);
+ bgp_static_redo_import_check(bgp);
}
-}
+ return CMD_SUCCESS;
+}
-DEFUN (bgp_disable_connected_route_check,
- bgp_disable_connected_route_check_cmd,
- "bgp disable-ebgp-connected-route-check",
+DEFUN (bgp_default_local_preference,
+ bgp_default_local_preference_cmd,
+ "bgp default local-preference (0-4294967295)",
"BGP specific commands\n"
- "Disable checking if nexthop is connected on ebgp sessions\n")
+ "Configure BGP defaults\n"
+ "local preference (higher=more preferred)\n"
+ "Configure default local preference value\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_set(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+ int idx_number = 3;
+ uint32_t local_pref;
+
+ local_pref = strtoul(argv[idx_number]->arg, NULL, 10);
+
+ bgp_default_local_preference_set(bgp, local_pref);
bgp_clear_star_soft_in(vty, bgp->name);
return CMD_SUCCESS;
}
-DEFUN (no_bgp_disable_connected_route_check,
- no_bgp_disable_connected_route_check_cmd,
- "no bgp disable-ebgp-connected-route-check",
+DEFUN (no_bgp_default_local_preference,
+ no_bgp_default_local_preference_cmd,
+ "no bgp default local-preference [(0-4294967295)]",
NO_STR
"BGP specific commands\n"
- "Disable checking if nexthop is connected on ebgp sessions\n")
+ "Configure BGP defaults\n"
+ "local preference (higher=more preferred)\n"
+ "Configure default local preference value\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp_flag_unset(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+ bgp_default_local_preference_unset(bgp);
bgp_clear_star_soft_in(vty, bgp->name);
return CMD_SUCCESS;
}
-static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
- const char *as_str, afi_t afi, safi_t safi)
+DEFUN (bgp_default_subgroup_pkt_queue_max,
+ bgp_default_subgroup_pkt_queue_max_cmd,
+ "bgp default subgroup-pkt-queue-max (20-100)",
+ "BGP specific commands\n"
+ "Configure BGP defaults\n"
+ "subgroup-pkt-queue-max\n"
+ "Configure subgroup packet queue max\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int ret;
- as_t as;
- int as_type = AS_SPECIFIED;
- union sockunion su;
-
- if (as_str[0] == 'i') {
- as = 0;
- as_type = AS_INTERNAL;
- } else if (as_str[0] == 'e') {
- as = 0;
- as_type = AS_EXTERNAL;
- } else {
- /* Get AS number. */
- as = strtoul(as_str, NULL, 10);
- }
+ int idx_number = 3;
+ uint32_t max_size;
- /* If peer is peer group or interface peer, call proper function. */
- ret = str2sockunion(peer_str, &su);
- if (ret < 0) {
- struct peer *peer;
+ max_size = strtoul(argv[idx_number]->arg, NULL, 10);
- /* Check if existing interface peer */
- peer = peer_lookup_by_conf_if(bgp, peer_str);
+ bgp_default_subgroup_pkt_queue_max_set(bgp, max_size);
- ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, afi,
- safi);
+ return CMD_SUCCESS;
+}
- /* if not interface peer, check peer-group settings */
- if (ret < 0 && !peer) {
- ret = peer_group_remote_as(bgp, peer_str, &as, as_type);
- if (ret < 0) {
- vty_out(vty,
- "%% Create the peer-group or interface first\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- return CMD_SUCCESS;
- }
- } else {
- if (peer_address_self_check(bgp, &su)) {
- vty_out(vty,
- "%% Can not configure the local system as neighbor\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- ret = peer_remote_as(bgp, &su, NULL, &as, as_type, afi, safi);
- }
-
- /* This peer belongs to peer group. */
- switch (ret) {
- case BGP_ERR_PEER_GROUP_MEMBER:
- vty_out(vty,
- "%% Peer-group member cannot override remote-as of peer-group\n");
- return CMD_WARNING_CONFIG_FAILED;
- case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
- vty_out(vty,
- "%% Peer-group members must be all internal or all external\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- return bgp_vty_return(vty, ret);
-}
-
-DEFUN (bgp_default_shutdown,
- bgp_default_shutdown_cmd,
- "[no] bgp default shutdown",
+DEFUN (no_bgp_default_subgroup_pkt_queue_max,
+ no_bgp_default_subgroup_pkt_queue_max_cmd,
+ "no bgp default subgroup-pkt-queue-max [(20-100)]",
NO_STR
- BGP_STR
+ "BGP specific commands\n"
"Configure BGP defaults\n"
- "Apply administrative shutdown to newly configured peers\n")
+ "subgroup-pkt-queue-max\n"
+ "Configure subgroup packet queue max\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- bgp->autoshutdown = !strmatch(argv[0]->text, "no");
+ bgp_default_subgroup_pkt_queue_max_unset(bgp);
return CMD_SUCCESS;
}
-DEFUN (neighbor_remote_as,
- neighbor_remote_as_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> remote-as <(1-4294967295)|internal|external>",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a BGP neighbor\n"
- AS_STR
- "Internal BGP peer\n"
- "External BGP peer\n")
+
+DEFUN (bgp_rr_allow_outbound_policy,
+ bgp_rr_allow_outbound_policy_cmd,
+ "bgp route-reflector allow-outbound-policy",
+ "BGP specific commands\n"
+ "Allow modifications made by out route-map\n"
+ "on ibgp neighbors\n")
{
- int idx_peer = 1;
- int idx_remote_as = 3;
- return peer_remote_as_vty(vty, argv[idx_peer]->arg,
- argv[idx_remote_as]->arg, AFI_IP,
- SAFI_UNICAST);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+
+ if (!bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+ bgp_flag_set(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
+ update_group_announce_rrclients(bgp);
+ bgp_clear_star_soft_out(vty, bgp->name);
+ }
+
+ return CMD_SUCCESS;
}
-static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
- afi_t afi, safi_t safi, int v6only,
- const char *peer_group_name,
- const char *as_str)
+DEFUN (no_bgp_rr_allow_outbound_policy,
+ no_bgp_rr_allow_outbound_policy_cmd,
+ "no bgp route-reflector allow-outbound-policy",
+ NO_STR
+ "BGP specific commands\n"
+ "Allow modifications made by out route-map\n"
+ "on ibgp neighbors\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- as_t as = 0;
- int as_type = AS_UNSPECIFIED;
- struct peer *peer;
- struct peer_group *group;
- int ret = 0;
- union sockunion su;
-
- group = peer_group_lookup(bgp, conf_if);
- if (group) {
- vty_out(vty, "%% Name conflict with peer-group \n");
- return CMD_WARNING_CONFIG_FAILED;
+ if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+ bgp_flag_unset(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
+ update_group_announce_rrclients(bgp);
+ bgp_clear_star_soft_out(vty, bgp->name);
}
- if (as_str) {
- if (as_str[0] == 'i') {
- as_type = AS_INTERNAL;
- } else if (as_str[0] == 'e') {
- as_type = AS_EXTERNAL;
- } else {
- /* Get AS number. */
- as = strtoul(as_str, NULL, 10);
- as_type = AS_SPECIFIED;
- }
- }
+ return CMD_SUCCESS;
+}
- peer = peer_lookup_by_conf_if(bgp, conf_if);
- if (peer) {
- if (as_str)
- ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type,
- afi, safi);
- } else {
- if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4)
- && afi == AFI_IP && safi == SAFI_UNICAST)
- peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
- as_type, 0, 0, NULL);
- else
- peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
- as_type, afi, safi, NULL);
+DEFUN (bgp_listen_limit,
+ bgp_listen_limit_cmd,
+ "bgp listen limit (1-5000)",
+ "BGP specific commands\n"
+ "BGP Dynamic Neighbors listen commands\n"
+ "Maximum number of BGP Dynamic Neighbors that can be created\n"
+ "Configure Dynamic Neighbors listen limit value\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 3;
+ int listen_limit;
- if (!peer) {
- vty_out(vty, "%% BGP failed to create peer\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ listen_limit = strtoul(argv[idx_number]->arg, NULL, 10);
- if (v6only)
- peer_flag_set(peer, PEER_FLAG_IFPEER_V6ONLY);
+ bgp_listen_limit_set(bgp, listen_limit);
- /* Request zebra to initiate IPv6 RAs on this interface. We do
- * this
- * any unnumbered peer in order to not worry about run-time
- * transitions
- * (e.g., peering is initially IPv4, but the IPv4 /30 or /31
- * address
- * gets deleted later etc.)
- */
- if (peer->ifp)
- bgp_zebra_initiate_radv(bgp, peer);
- }
+ return CMD_SUCCESS;
+}
- if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
- || (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))) {
- if (v6only)
- peer_flag_set(peer, PEER_FLAG_IFPEER_V6ONLY);
- else
- peer_flag_unset(peer, PEER_FLAG_IFPEER_V6ONLY);
+DEFUN (no_bgp_listen_limit,
+ no_bgp_listen_limit_cmd,
+ "no bgp listen limit [(1-5000)]",
+ NO_STR
+ "BGP specific commands\n"
+ "BGP Dynamic Neighbors listen commands\n"
+ "Maximum number of BGP Dynamic Neighbors that can be created\n"
+ "Configure Dynamic Neighbors listen limit value\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_listen_limit_unset(bgp);
+ return CMD_SUCCESS;
+}
- /* v6only flag changed. Reset bgp seesion */
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
- peer->last_reset = PEER_DOWN_V6ONLY_CHANGE;
- bgp_notify_send(peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_CONFIG_CHANGE);
- } else
- bgp_session_reset(peer);
- }
- if (!CHECK_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE)) {
- SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE);
- SET_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE);
- SET_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE);
- }
+/*
+ * Check if this listen range is already configured. Check for exact
+ * match or overlap based on input.
+ */
+static struct peer_group *listen_range_exists(struct bgp *bgp,
+ struct prefix *range, int exact)
+{
+ struct listnode *node, *nnode;
+ struct listnode *node1, *nnode1;
+ struct peer_group *group;
+ struct prefix *lr;
+ afi_t afi;
+ int match;
- if (peer_group_name) {
- group = peer_group_lookup(bgp, peer_group_name);
- if (!group) {
- vty_out(vty, "%% Configure the peer-group first\n");
- return CMD_WARNING_CONFIG_FAILED;
+ afi = family2afi(range->family);
+ for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
+ for (ALL_LIST_ELEMENTS(group->listen_range[afi], node1, nnode1,
+ lr)) {
+ if (exact)
+ match = prefix_same(range, lr);
+ else
+ match = (prefix_match(range, lr)
+ || prefix_match(lr, range));
+ if (match)
+ return group;
}
-
- ret = peer_group_bind(bgp, &su, peer, group, &as);
}
- return bgp_vty_return(vty, ret);
+ return NULL;
}
-DEFUN (neighbor_interface_config,
- neighbor_interface_config_cmd,
- "neighbor WORD interface [peer-group PGNAME]",
- NEIGHBOR_STR
- "Interface name or neighbor tag\n"
- "Enable BGP on interface\n"
+DEFUN (bgp_listen_range,
+ bgp_listen_range_cmd,
+ "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
+ "BGP specific commands\n"
+ "Configure BGP dynamic neighbors listen range\n"
+ "Configure BGP dynamic neighbors listen range\n"
+ NEIGHBOR_ADDR_STR
"Member of the peer-group\n"
"Peer-group name\n")
{
- int idx_word = 1;
- int idx_peer_group_word = 4;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ struct prefix range;
+ struct peer_group *group, *existing_group;
+ afi_t afi;
+ int ret;
+ int idx = 0;
- if (argc > idx_peer_group_word)
- return peer_conf_interface_get(
- vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 0,
- argv[idx_peer_group_word]->arg, NULL);
- else
- return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
- SAFI_UNICAST, 0, NULL, NULL);
-}
+ argv_find(argv, argc, "A.B.C.D/M", &idx);
+ argv_find(argv, argc, "X:X::X:X/M", &idx);
+ char *prefix = argv[idx]->arg;
+ argv_find(argv, argc, "PGNAME", &idx);
+ char *peergroup = argv[idx]->arg;
-DEFUN (neighbor_interface_config_v6only,
- neighbor_interface_config_v6only_cmd,
- "neighbor WORD interface v6only [peer-group PGNAME]",
- NEIGHBOR_STR
- "Interface name or neighbor tag\n"
- "Enable BGP on interface\n"
- "Enable BGP with v6 link-local only\n"
- "Member of the peer-group\n"
- "Peer-group name\n")
-{
- int idx_word = 1;
- int idx_peer_group_word = 5;
+ /* Convert IP prefix string to struct prefix. */
+ ret = str2prefix(prefix, &range);
+ if (!ret) {
+ vty_out(vty, "%% Malformed listen range\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (argc > idx_peer_group_word)
- return peer_conf_interface_get(
- vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 1,
- argv[idx_peer_group_word]->arg, NULL);
+ afi = family2afi(range.family);
- return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
- SAFI_UNICAST, 1, NULL, NULL);
-}
+ if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&range.u.prefix6)) {
+ vty_out(vty,
+ "%% Malformed listen range (link-local address)\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ apply_mask(&range);
-DEFUN (neighbor_interface_config_remote_as,
- neighbor_interface_config_remote_as_cmd,
- "neighbor WORD interface remote-as <(1-4294967295)|internal|external>",
- NEIGHBOR_STR
- "Interface name or neighbor tag\n"
- "Enable BGP on interface\n"
- "Specify a BGP neighbor\n"
- AS_STR
- "Internal BGP peer\n"
- "External BGP peer\n")
-{
- int idx_word = 1;
- int idx_remote_as = 4;
- return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
- SAFI_UNICAST, 0, NULL,
- argv[idx_remote_as]->arg);
-}
+ /* Check if same listen range is already configured. */
+ existing_group = listen_range_exists(bgp, &range, 1);
+ if (existing_group) {
+ if (strcmp(existing_group->name, peergroup) == 0)
+ return CMD_SUCCESS;
+ else {
+ vty_out(vty,
+ "%% Same listen range is attached to peer-group %s\n",
+ existing_group->name);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
-DEFUN (neighbor_interface_v6only_config_remote_as,
- neighbor_interface_v6only_config_remote_as_cmd,
- "neighbor WORD interface v6only remote-as <(1-4294967295)|internal|external>",
- NEIGHBOR_STR
- "Interface name or neighbor tag\n"
- "Enable BGP with v6 link-local only\n"
- "Enable BGP on interface\n"
- "Specify a BGP neighbor\n"
- AS_STR
- "Internal BGP peer\n"
- "External BGP peer\n")
-{
- int idx_word = 1;
- int idx_remote_as = 5;
- return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
- SAFI_UNICAST, 1, NULL,
- argv[idx_remote_as]->arg);
+ /* Check if an overlapping listen range exists. */
+ if (listen_range_exists(bgp, &range, 0)) {
+ vty_out(vty,
+ "%% Listen range overlaps with existing listen range\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ group = peer_group_lookup(bgp, peergroup);
+ if (!group) {
+ vty_out(vty, "%% Configure the peer-group first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = peer_group_listen_range_add(group, &range);
+ return bgp_vty_return(vty, ret);
}
-DEFUN (neighbor_peer_group,
- neighbor_peer_group_cmd,
- "neighbor WORD peer-group",
- NEIGHBOR_STR
- "Interface name or neighbor tag\n"
- "Configure peer-group\n")
+DEFUN (no_bgp_listen_range,
+ no_bgp_listen_range_cmd,
+ "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
+ NO_STR
+ "BGP specific commands\n"
+ "Unconfigure BGP dynamic neighbors listen range\n"
+ "Unconfigure BGP dynamic neighbors listen range\n"
+ NEIGHBOR_ADDR_STR
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_word = 1;
- struct peer *peer;
+ struct prefix range;
struct peer_group *group;
+ afi_t afi;
+ int ret;
+ int idx = 0;
- peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
- if (peer) {
- vty_out(vty, "%% Name conflict with interface: \n");
+ argv_find(argv, argc, "A.B.C.D/M", &idx);
+ argv_find(argv, argc, "X:X::X:X/M", &idx);
+ char *prefix = argv[idx]->arg;
+ argv_find(argv, argc, "PGNAME", &idx);
+ char *peergroup = argv[idx]->arg;
+
+ /* Convert IP prefix string to struct prefix. */
+ ret = str2prefix(prefix, &range);
+ if (!ret) {
+ vty_out(vty, "%% Malformed listen range\n");
return CMD_WARNING_CONFIG_FAILED;
}
- group = peer_group_get(bgp, argv[idx_word]->arg);
+ afi = family2afi(range.family);
+
+ if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&range.u.prefix6)) {
+ vty_out(vty,
+ "%% Malformed listen range (link-local address)\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ apply_mask(&range);
+
+ group = peer_group_lookup(bgp, peergroup);
if (!group) {
- vty_out(vty, "%% BGP failed to find or create peer-group\n");
+ vty_out(vty, "%% Peer-group does not exist\n");
return CMD_WARNING_CONFIG_FAILED;
}
- return CMD_SUCCESS;
+ ret = peer_group_listen_range_del(group, &range);
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_neighbor,
- no_neighbor_cmd,
- "no neighbor <WORD|<A.B.C.D|X:X::X:X> [remote-as <(1-4294967295)|internal|external>]>",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a BGP neighbor\n"
- AS_STR
- "Internal BGP peer\n"
- "External BGP peer\n")
+void bgp_config_write_listen(struct vty *vty, struct bgp *bgp)
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_peer = 2;
- int ret;
- union sockunion su;
struct peer_group *group;
- struct peer *peer;
- struct peer *other;
+ struct listnode *node, *nnode, *rnode, *nrnode;
+ struct prefix *range;
+ afi_t afi;
+ char buf[PREFIX2STR_BUFFER];
- ret = str2sockunion(argv[idx_peer]->arg, &su);
- if (ret < 0) {
- /* look up for neighbor by interface name config. */
- peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg);
- if (peer) {
- /* Request zebra to terminate IPv6 RAs on this
- * interface. */
- if (peer->ifp)
- bgp_zebra_terminate_radv(peer->bgp, peer);
- peer_notify_unconfig(peer);
- peer_delete(peer);
- return CMD_SUCCESS;
- }
+ if (bgp->dynamic_neighbors_limit != BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT)
+ vty_out(vty, " bgp listen limit %d\n",
+ bgp->dynamic_neighbors_limit);
- group = peer_group_lookup(bgp, argv[idx_peer]->arg);
- if (group) {
- peer_group_notify_unconfig(group);
- peer_group_delete(group);
- } else {
- vty_out(vty, "%% Create the peer-group first\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- } else {
- peer = peer_lookup(bgp, &su);
- if (peer) {
- if (peer_dynamic_neighbor(peer)) {
+ for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) {
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+ for (ALL_LIST_ELEMENTS(group->listen_range[afi], rnode,
+ nrnode, range)) {
+ prefix2str(range, buf, sizeof(buf));
vty_out(vty,
- "%% Operation not allowed on a dynamic neighbor\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- other = peer->doppelganger;
- peer_notify_unconfig(peer);
- peer_delete(peer);
- if (other && other->status != Deleted) {
- peer_notify_unconfig(other);
- peer_delete(other);
+ " bgp listen range %s peer-group %s\n",
+ buf, group->name);
}
}
}
+}
+
+
+DEFUN (bgp_disable_connected_route_check,
+ bgp_disable_connected_route_check_cmd,
+ "bgp disable-ebgp-connected-route-check",
+ "BGP specific commands\n"
+ "Disable checking if nexthop is connected on ebgp sessions\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp_flag_set(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+ bgp_clear_star_soft_in(vty, bgp->name);
return CMD_SUCCESS;
}
-DEFUN (no_neighbor_interface_config,
- no_neighbor_interface_config_cmd,
- "no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external>]",
+DEFUN (no_bgp_disable_connected_route_check,
+ no_bgp_disable_connected_route_check_cmd,
+ "no bgp disable-ebgp-connected-route-check",
NO_STR
- NEIGHBOR_STR
- "Interface name\n"
- "Configure BGP on interface\n"
- "Enable BGP with v6 link-local only\n"
- "Member of the peer-group\n"
- "Peer-group name\n"
- "Specify a BGP neighbor\n"
- AS_STR
- "Internal BGP peer\n"
- "External BGP peer\n")
+ "BGP specific commands\n"
+ "Disable checking if nexthop is connected on ebgp sessions\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_word = 2;
- struct peer *peer;
+ bgp_flag_unset(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+ bgp_clear_star_soft_in(vty, bgp->name);
- /* look up for neighbor by interface name config. */
- peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
- if (peer) {
- /* Request zebra to terminate IPv6 RAs on this interface. */
- if (peer->ifp)
- bgp_zebra_terminate_radv(peer->bgp, peer);
- peer_notify_unconfig(peer);
- peer_delete(peer);
- } else {
- vty_out(vty, "%% Create the bgp interface first\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
return CMD_SUCCESS;
}
-DEFUN (no_neighbor_peer_group,
- no_neighbor_peer_group_cmd,
- "no neighbor WORD peer-group",
- NO_STR
- NEIGHBOR_STR
- "Neighbor tag\n"
- "Configure peer-group\n")
+
+static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
+ const char *as_str, afi_t afi, safi_t safi)
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_word = 2;
- struct peer_group *group;
+ int ret;
+ as_t as;
+ int as_type = AS_SPECIFIED;
+ union sockunion su;
- group = peer_group_lookup(bgp, argv[idx_word]->arg);
- if (group) {
- peer_group_notify_unconfig(group);
- peer_group_delete(group);
+ if (as_str[0] == 'i') {
+ as = 0;
+ as_type = AS_INTERNAL;
+ } else if (as_str[0] == 'e') {
+ as = 0;
+ as_type = AS_EXTERNAL;
} else {
- vty_out(vty, "%% Create the peer-group first\n");
+ /* Get AS number. */
+ as = strtoul(as_str, NULL, 10);
+ }
+
+ /* If peer is peer group or interface peer, call proper function. */
+ ret = str2sockunion(peer_str, &su);
+ if (ret < 0) {
+ struct peer *peer;
+
+ /* Check if existing interface peer */
+ peer = peer_lookup_by_conf_if(bgp, peer_str);
+
+ ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, afi,
+ safi);
+
+ /* if not interface peer, check peer-group settings */
+ if (ret < 0 && !peer) {
+ ret = peer_group_remote_as(bgp, peer_str, &as, as_type);
+ if (ret < 0) {
+ vty_out(vty,
+ "%% Create the peer-group or interface first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ return CMD_SUCCESS;
+ }
+ } else {
+ if (peer_address_self_check(bgp, &su)) {
+ vty_out(vty,
+ "%% Can not configure the local system as neighbor\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ ret = peer_remote_as(bgp, &su, NULL, &as, as_type, afi, safi);
+ }
+
+ /* This peer belongs to peer group. */
+ switch (ret) {
+ case BGP_ERR_PEER_GROUP_MEMBER:
+ vty_out(vty,
+ "%% Peer-group member cannot override remote-as of peer-group\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ case BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT:
+ vty_out(vty,
+ "%% Peer-group members must be all internal or all external\n");
return CMD_WARNING_CONFIG_FAILED;
}
- return CMD_SUCCESS;
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_neighbor_interface_peer_group_remote_as,
- no_neighbor_interface_peer_group_remote_as_cmd,
- "no neighbor WORD remote-as <(1-4294967295)|internal|external>",
+DEFUN (bgp_default_shutdown,
+ bgp_default_shutdown_cmd,
+ "[no] bgp default shutdown",
NO_STR
+ BGP_STR
+ "Configure BGP defaults\n"
+ "Apply administrative shutdown to newly configured peers\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ bgp->autoshutdown = !strmatch(argv[0]->text, "no");
+ return CMD_SUCCESS;
+}
+
+DEFUN (neighbor_remote_as,
+ neighbor_remote_as_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> remote-as <(1-4294967295)|internal|external>",
NEIGHBOR_STR
- "Interface name or neighbor tag\n"
+ NEIGHBOR_ADDR_STR2
"Specify a BGP neighbor\n"
AS_STR
"Internal BGP peer\n"
"External BGP peer\n")
+{
+ int idx_peer = 1;
+ int idx_remote_as = 3;
+ return peer_remote_as_vty(vty, argv[idx_peer]->arg,
+ argv[idx_remote_as]->arg, AFI_IP,
+ SAFI_UNICAST);
+}
+
+static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
+ afi_t afi, safi_t safi, int v6only,
+ const char *peer_group_name,
+ const char *as_str)
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_word = 2;
- struct peer_group *group;
+ as_t as = 0;
+ int as_type = AS_UNSPECIFIED;
struct peer *peer;
+ struct peer_group *group;
+ int ret = 0;
+ union sockunion su;
- /* look up for neighbor by interface name config. */
- peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
- if (peer) {
- peer_as_change(peer, 0, AS_UNSPECIFIED);
- return CMD_SUCCESS;
- }
+ group = peer_group_lookup(bgp, conf_if);
- group = peer_group_lookup(bgp, argv[idx_word]->arg);
- if (group)
- peer_group_remote_as_delete(group);
- else {
- vty_out(vty, "%% Create the peer-group or interface first\n");
+ if (group) {
+ vty_out(vty, "%% Name conflict with peer-group \n");
return CMD_WARNING_CONFIG_FAILED;
}
- return CMD_SUCCESS;
-}
-DEFUN (neighbor_local_as,
- neighbor_local_as_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295)",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a local-as number\n"
- "AS number used as local AS\n")
-{
- int idx_peer = 1;
- int idx_number = 3;
- struct peer *peer;
- int ret;
- as_t as;
+ if (as_str) {
+ if (as_str[0] == 'i') {
+ as_type = AS_INTERNAL;
+ } else if (as_str[0] == 'e') {
+ as_type = AS_EXTERNAL;
+ } else {
+ /* Get AS number. */
+ as = strtoul(as_str, NULL, 10);
+ as_type = AS_SPECIFIED;
+ }
+ }
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
+ peer = peer_lookup_by_conf_if(bgp, conf_if);
+ if (peer) {
+ if (as_str)
+ ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type,
+ afi, safi);
+ } else {
+ if (bgp_flag_check(bgp, BGP_FLAG_NO_DEFAULT_IPV4)
+ && afi == AFI_IP && safi == SAFI_UNICAST)
+ peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
+ as_type, 0, 0, NULL);
+ else
+ peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
+ as_type, afi, safi, NULL);
- as = strtoul(argv[idx_number]->arg, NULL, 10);
- ret = peer_local_as_set(peer, as, 0, 0);
- return bgp_vty_return(vty, ret);
-}
+ if (!peer) {
+ vty_out(vty, "%% BGP failed to create peer\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
-DEFUN (neighbor_local_as_no_prepend,
- neighbor_local_as_no_prepend_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a local-as number\n"
- "AS number used as local AS\n"
- "Do not prepend local-as to updates from ebgp peers\n")
-{
- int idx_peer = 1;
- int idx_number = 3;
- struct peer *peer;
- int ret;
- as_t as;
+ if (v6only)
+ peer_flag_set(peer, PEER_FLAG_IFPEER_V6ONLY);
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
+ /* Request zebra to initiate IPv6 RAs on this interface. We do
+ * this
+ * any unnumbered peer in order to not worry about run-time
+ * transitions
+ * (e.g., peering is initially IPv4, but the IPv4 /30 or /31
+ * address
+ * gets deleted later etc.)
+ */
+ if (peer->ifp)
+ bgp_zebra_initiate_radv(bgp, peer);
+ }
- as = strtoul(argv[idx_number]->arg, NULL, 10);
- ret = peer_local_as_set(peer, as, 1, 0);
- return bgp_vty_return(vty, ret);
-}
+ if ((v6only && !CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))
+ || (!v6only && CHECK_FLAG(peer->flags, PEER_FLAG_IFPEER_V6ONLY))) {
+ if (v6only)
+ peer_flag_set(peer, PEER_FLAG_IFPEER_V6ONLY);
+ else
+ peer_flag_unset(peer, PEER_FLAG_IFPEER_V6ONLY);
-DEFUN (neighbor_local_as_no_prepend_replace_as,
- neighbor_local_as_no_prepend_replace_as_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend replace-as",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a local-as number\n"
- "AS number used as local AS\n"
- "Do not prepend local-as to updates from ebgp peers\n"
- "Do not prepend local-as to updates from ibgp peers\n")
-{
- int idx_peer = 1;
- int idx_number = 3;
- struct peer *peer;
- int ret;
- as_t as;
+ /* v6only flag changed. Reset bgp seesion */
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) {
+ peer->last_reset = PEER_DOWN_V6ONLY_CHANGE;
+ bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_CONFIG_CHANGE);
+ } else
+ bgp_session_reset(peer);
+ }
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
+ if (!CHECK_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE)) {
+ SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_ENHE);
+ SET_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE);
+ SET_FLAG(peer->flags_override, PEER_FLAG_CAPABILITY_ENHE);
+ }
+
+ if (peer_group_name) {
+ group = peer_group_lookup(bgp, peer_group_name);
+ if (!group) {
+ vty_out(vty, "%% Configure the peer-group first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = peer_group_bind(bgp, &su, peer, group, &as);
+ }
- as = strtoul(argv[idx_number]->arg, NULL, 10);
- ret = peer_local_as_set(peer, as, 1, 1);
return bgp_vty_return(vty, ret);
}
-DEFUN (no_neighbor_local_as,
- no_neighbor_local_as_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> local-as [(1-4294967295) [no-prepend [replace-as]]]",
- NO_STR
+DEFUN (neighbor_interface_config,
+ neighbor_interface_config_cmd,
+ "neighbor WORD interface [peer-group PGNAME]",
NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Specify a local-as number\n"
- "AS number used as local AS\n"
- "Do not prepend local-as to updates from ebgp peers\n"
- "Do not prepend local-as to updates from ibgp peers\n")
+ "Interface name or neighbor tag\n"
+ "Enable BGP on interface\n"
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
- int idx_peer = 2;
- struct peer *peer;
- int ret;
-
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
+ int idx_word = 1;
+ int idx_peer_group_word = 4;
- ret = peer_local_as_unset(peer);
- return bgp_vty_return(vty, ret);
+ if (argc > idx_peer_group_word)
+ return peer_conf_interface_get(
+ vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 0,
+ argv[idx_peer_group_word]->arg, NULL);
+ else
+ return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
+ SAFI_UNICAST, 0, NULL, NULL);
}
-
-DEFUN (neighbor_solo,
- neighbor_solo_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> solo",
+DEFUN (neighbor_interface_config_v6only,
+ neighbor_interface_config_v6only_cmd,
+ "neighbor WORD interface v6only [peer-group PGNAME]",
NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Solo peer - part of its own update group\n")
+ "Interface name or neighbor tag\n"
+ "Enable BGP on interface\n"
+ "Enable BGP with v6 link-local only\n"
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
- int idx_peer = 1;
- struct peer *peer;
- int ret;
+ int idx_word = 1;
+ int idx_peer_group_word = 5;
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
+ if (argc > idx_peer_group_word)
+ return peer_conf_interface_get(
+ vty, argv[idx_word]->arg, AFI_IP, SAFI_UNICAST, 1,
+ argv[idx_peer_group_word]->arg, NULL);
- ret = update_group_adjust_soloness(peer, 1);
- return bgp_vty_return(vty, ret);
+ return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
+ SAFI_UNICAST, 1, NULL, NULL);
}
-DEFUN (no_neighbor_solo,
- no_neighbor_solo_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> solo",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Solo peer - part of its own update group\n")
-{
- int idx_peer = 2;
- struct peer *peer;
- int ret;
-
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
-
- ret = update_group_adjust_soloness(peer, 0);
- return bgp_vty_return(vty, ret);
-}
-DEFUN (neighbor_password,
- neighbor_password_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> password LINE",
+DEFUN (neighbor_interface_config_remote_as,
+ neighbor_interface_config_remote_as_cmd,
+ "neighbor WORD interface remote-as <(1-4294967295)|internal|external>",
NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Set a password\n"
- "The password\n")
+ "Interface name or neighbor tag\n"
+ "Enable BGP on interface\n"
+ "Specify a BGP neighbor\n"
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
- int idx_peer = 1;
- int idx_line = 3;
- struct peer *peer;
- int ret;
-
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
-
- ret = peer_password_set(peer, argv[idx_line]->arg);
- return bgp_vty_return(vty, ret);
+ int idx_word = 1;
+ int idx_remote_as = 4;
+ return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
+ SAFI_UNICAST, 0, NULL,
+ argv[idx_remote_as]->arg);
}
-DEFUN (no_neighbor_password,
- no_neighbor_password_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> password [LINE]",
- NO_STR
+DEFUN (neighbor_interface_v6only_config_remote_as,
+ neighbor_interface_v6only_config_remote_as_cmd,
+ "neighbor WORD interface v6only remote-as <(1-4294967295)|internal|external>",
NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Set a password\n"
- "The password\n")
+ "Interface name or neighbor tag\n"
+ "Enable BGP with v6 link-local only\n"
+ "Enable BGP on interface\n"
+ "Specify a BGP neighbor\n"
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
- int idx_peer = 2;
- struct peer *peer;
- int ret;
-
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
-
- ret = peer_password_unset(peer);
- return bgp_vty_return(vty, ret);
+ int idx_word = 1;
+ int idx_remote_as = 5;
+ return peer_conf_interface_get(vty, argv[idx_word]->arg, AFI_IP,
+ SAFI_UNICAST, 1, NULL,
+ argv[idx_remote_as]->arg);
}
-DEFUN (neighbor_activate,
- neighbor_activate_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
+DEFUN (neighbor_peer_group,
+ neighbor_peer_group_cmd,
+ "neighbor WORD peer-group",
NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Enable the Address Family for this Neighbor\n")
+ "Interface name or neighbor tag\n"
+ "Configure peer-group\n")
{
- int idx_peer = 1;
- int ret;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_word = 1;
struct peer *peer;
+ struct peer_group *group;
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
+ peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
+ if (peer) {
+ vty_out(vty, "%% Name conflict with interface: \n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- ret = peer_activate(peer, bgp_node_afi(vty), bgp_node_safi(vty));
- return bgp_vty_return(vty, ret);
-}
-
-ALIAS_HIDDEN(neighbor_activate, neighbor_activate_hidden_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
- NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Enable the Address Family for this Neighbor\n")
-
-DEFUN (no_neighbor_activate,
- no_neighbor_activate_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
- NO_STR
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Enable the Address Family for this Neighbor\n")
-{
- int idx_peer = 2;
- int ret;
- struct peer *peer;
-
- /* Lookup peer. */
- peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
+ group = peer_group_get(bgp, argv[idx_word]->arg);
+ if (!group) {
+ vty_out(vty, "%% BGP failed to find or create peer-group\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
- ret = peer_deactivate(peer, bgp_node_afi(vty), bgp_node_safi(vty));
- return bgp_vty_return(vty, ret);
+ return CMD_SUCCESS;
}
-ALIAS_HIDDEN(no_neighbor_activate, no_neighbor_activate_hidden_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
- NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Enable the Address Family for this Neighbor\n")
-
-DEFUN (neighbor_set_peer_group,
- neighbor_set_peer_group_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+DEFUN (no_neighbor,
+ no_neighbor_cmd,
+ "no neighbor <WORD|<A.B.C.D|X:X::X:X> [remote-as <(1-4294967295)|internal|external>]>",
+ NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Member of the peer-group\n"
- "Peer-group name\n")
+ "Specify a BGP neighbor\n"
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_peer = 1;
- int idx_word = 3;
+ int idx_peer = 2;
int ret;
- as_t as;
union sockunion su;
- struct peer *peer;
struct peer_group *group;
+ struct peer *peer;
+ struct peer *other;
ret = str2sockunion(argv[idx_peer]->arg, &su);
if (ret < 0) {
+ /* look up for neighbor by interface name config. */
peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg);
- if (!peer) {
- vty_out(vty, "%% Malformed address or name: %s\n",
- argv[idx_peer]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
- } else {
- if (peer_address_self_check(bgp, &su)) {
- vty_out(vty,
- "%% Can not configure the local system as neighbor\n");
- return CMD_WARNING_CONFIG_FAILED;
+ if (peer) {
+ /* Request zebra to terminate IPv6 RAs on this
+ * interface. */
+ if (peer->ifp)
+ bgp_zebra_terminate_radv(peer->bgp, peer);
+ peer_notify_unconfig(peer);
+ peer_delete(peer);
+ return CMD_SUCCESS;
}
- /* Disallow for dynamic neighbor. */
- peer = peer_lookup(bgp, &su);
- if (peer && peer_dynamic_neighbor(peer)) {
- vty_out(vty,
- "%% Operation not allowed on a dynamic neighbor\n");
+ group = peer_group_lookup(bgp, argv[idx_peer]->arg);
+ if (group) {
+ peer_group_notify_unconfig(group);
+ peer_group_delete(group);
+ } else {
+ vty_out(vty, "%% Create the peer-group first\n");
return CMD_WARNING_CONFIG_FAILED;
}
- }
-
- group = peer_group_lookup(bgp, argv[idx_word]->arg);
- if (!group) {
- vty_out(vty, "%% Configure the peer-group first\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- ret = peer_group_bind(bgp, &su, peer, group, &as);
+ } else {
+ peer = peer_lookup(bgp, &su);
+ if (peer) {
+ if (peer_dynamic_neighbor(peer)) {
+ vty_out(vty,
+ "%% Operation not allowed on a dynamic neighbor\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- if (ret == BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT) {
- vty_out(vty,
- "%% Peer with AS %u cannot be in this peer-group, members must be all internal or all external\n",
- as);
- return CMD_WARNING_CONFIG_FAILED;
+ other = peer->doppelganger;
+ peer_notify_unconfig(peer);
+ peer_delete(peer);
+ if (other && other->status != Deleted) {
+ peer_notify_unconfig(other);
+ peer_delete(other);
+ }
+ }
}
- return bgp_vty_return(vty, ret);
+ return CMD_SUCCESS;
}
-ALIAS_HIDDEN(neighbor_set_peer_group, neighbor_set_peer_group_hidden_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
- NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Member of the peer-group\n"
- "Peer-group name\n")
-
-DEFUN (no_neighbor_set_peer_group,
- no_neighbor_set_peer_group_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+DEFUN (no_neighbor_interface_config,
+ no_neighbor_interface_config_cmd,
+ "no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external>]",
NO_STR
NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
+ "Interface name\n"
+ "Configure BGP on interface\n"
+ "Enable BGP with v6 link-local only\n"
"Member of the peer-group\n"
- "Peer-group name\n")
+ "Peer-group name\n"
+ "Specify a BGP neighbor\n"
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_peer = 2;
- int idx_word = 4;
- int ret;
+ int idx_word = 2;
struct peer *peer;
- struct peer_group *group;
- peer = peer_lookup_vty(vty, argv[idx_peer]->arg);
- if (!peer)
+ /* look up for neighbor by interface name config. */
+ peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
+ if (peer) {
+ /* Request zebra to terminate IPv6 RAs on this interface. */
+ if (peer->ifp)
+ bgp_zebra_terminate_radv(peer->bgp, peer);
+ peer_notify_unconfig(peer);
+ peer_delete(peer);
+ } else {
+ vty_out(vty, "%% Create the bgp interface first\n");
return CMD_WARNING_CONFIG_FAILED;
+ }
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_neighbor_peer_group,
+ no_neighbor_peer_group_cmd,
+ "no neighbor WORD peer-group",
+ NO_STR
+ NEIGHBOR_STR
+ "Neighbor tag\n"
+ "Configure peer-group\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_word = 2;
+ struct peer_group *group;
group = peer_group_lookup(bgp, argv[idx_word]->arg);
- if (!group) {
- vty_out(vty, "%% Configure the peer-group first\n");
+ if (group) {
+ peer_group_notify_unconfig(group);
+ peer_group_delete(group);
+ } else {
+ vty_out(vty, "%% Create the peer-group first\n");
return CMD_WARNING_CONFIG_FAILED;
}
-
- peer_notify_unconfig(peer);
- ret = peer_delete(peer);
-
- return bgp_vty_return(vty, ret);
+ return CMD_SUCCESS;
}
-ALIAS_HIDDEN(no_neighbor_set_peer_group, no_neighbor_set_peer_group_hidden_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
- NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Member of the peer-group\n"
- "Peer-group name\n")
-
-static int peer_flag_modify_vty(struct vty *vty, const char *ip_str,
- uint32_t flag, int set)
+DEFUN (no_neighbor_interface_peer_group_remote_as,
+ no_neighbor_interface_peer_group_remote_as_cmd,
+ "no neighbor WORD remote-as <(1-4294967295)|internal|external>",
+ NO_STR
+ NEIGHBOR_STR
+ "Interface name or neighbor tag\n"
+ "Specify a BGP neighbor\n"
+ AS_STR
+ "Internal BGP peer\n"
+ "External BGP peer\n")
{
- int ret;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_word = 2;
+ struct peer_group *group;
struct peer *peer;
- peer = peer_and_group_lookup_vty(vty, ip_str);
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
+ /* look up for neighbor by interface name config. */
+ peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
+ if (peer) {
+ peer_as_change(peer, 0, AS_UNSPECIFIED);
+ return CMD_SUCCESS;
+ }
- /*
- * If 'neighbor <interface>', then this is for directly connected peers,
- * we should not accept disable-connected-check.
- */
- if (peer->conf_if && (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)) {
- vty_out(vty,
- "%s is directly connected peer, cannot accept disable-"
- "connected-check\n",
- ip_str);
+ group = peer_group_lookup(bgp, argv[idx_word]->arg);
+ if (group)
+ peer_group_remote_as_delete(group);
+ else {
+ vty_out(vty, "%% Create the peer-group or interface first\n");
return CMD_WARNING_CONFIG_FAILED;
}
+ return CMD_SUCCESS;
+}
- if (!set && flag == PEER_FLAG_SHUTDOWN)
- peer_tx_shutdown_message_unset(peer);
+DEFUN (neighbor_local_as,
+ neighbor_local_as_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295)",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Specify a local-as number\n"
+ "AS number used as local AS\n")
+{
+ int idx_peer = 1;
+ int idx_number = 3;
+ struct peer *peer;
+ int ret;
+ as_t as;
- if (set)
- ret = peer_flag_set(peer, flag);
- else
- ret = peer_flag_unset(peer, flag);
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+ as = strtoul(argv[idx_number]->arg, NULL, 10);
+ ret = peer_local_as_set(peer, as, 0, 0);
return bgp_vty_return(vty, ret);
}
-static int peer_flag_set_vty(struct vty *vty, const char *ip_str, uint32_t flag)
+DEFUN (neighbor_local_as_no_prepend,
+ neighbor_local_as_no_prepend_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Specify a local-as number\n"
+ "AS number used as local AS\n"
+ "Do not prepend local-as to updates from ebgp peers\n")
{
- return peer_flag_modify_vty(vty, ip_str, flag, 1);
-}
+ int idx_peer = 1;
+ int idx_number = 3;
+ struct peer *peer;
+ int ret;
+ as_t as;
-static int peer_flag_unset_vty(struct vty *vty, const char *ip_str,
- uint32_t flag)
-{
- return peer_flag_modify_vty(vty, ip_str, flag, 0);
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ as = strtoul(argv[idx_number]->arg, NULL, 10);
+ ret = peer_local_as_set(peer, as, 1, 0);
+ return bgp_vty_return(vty, ret);
}
-/* neighbor passive. */
-DEFUN (neighbor_passive,
- neighbor_passive_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> passive",
+DEFUN (neighbor_local_as_no_prepend_replace_as,
+ neighbor_local_as_no_prepend_replace_as_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> local-as (1-4294967295) no-prepend replace-as",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Don't send open messages to this neighbor\n")
+ "Specify a local-as number\n"
+ "AS number used as local AS\n"
+ "Do not prepend local-as to updates from ebgp peers\n"
+ "Do not prepend local-as to updates from ibgp peers\n")
{
int idx_peer = 1;
- return peer_flag_set_vty(vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
+ int idx_number = 3;
+ struct peer *peer;
+ int ret;
+ as_t as;
+
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ as = strtoul(argv[idx_number]->arg, NULL, 10);
+ ret = peer_local_as_set(peer, as, 1, 1);
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_neighbor_passive,
- no_neighbor_passive_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> passive",
+DEFUN (no_neighbor_local_as,
+ no_neighbor_local_as_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> local-as [(1-4294967295) [no-prepend [replace-as]]]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Don't send open messages to this neighbor\n")
+ "Specify a local-as number\n"
+ "AS number used as local AS\n"
+ "Do not prepend local-as to updates from ebgp peers\n"
+ "Do not prepend local-as to updates from ibgp peers\n")
{
int idx_peer = 2;
- return peer_flag_unset_vty(vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
+ struct peer *peer;
+ int ret;
+
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ ret = peer_local_as_unset(peer);
+ return bgp_vty_return(vty, ret);
}
-/* neighbor shutdown. */
-DEFUN (neighbor_shutdown_msg,
- neighbor_shutdown_msg_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
+
+DEFUN (neighbor_solo,
+ neighbor_solo_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> solo",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Administratively shut down this neighbor\n"
- "Add a shutdown message (draft-ietf-idr-shutdown-06)\n"
- "Shutdown message\n")
+ "Solo peer - part of its own update group\n")
{
int idx_peer = 1;
+ struct peer *peer;
+ int ret;
- if (argc >= 5) {
- struct peer *peer =
- peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
- char *message;
-
- if (!peer)
- return CMD_WARNING_CONFIG_FAILED;
- message = argv_concat(argv, argc, 4);
- peer_tx_shutdown_message_set(peer, message);
- XFREE(MTYPE_TMP, message);
- }
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
- return peer_flag_set_vty(vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
+ ret = update_group_adjust_soloness(peer, 1);
+ return bgp_vty_return(vty, ret);
}
-ALIAS(neighbor_shutdown_msg, neighbor_shutdown_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
- NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Administratively shut down this neighbor\n")
-
-DEFUN (no_neighbor_shutdown_msg,
- no_neighbor_shutdown_msg_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
+DEFUN (no_neighbor_solo,
+ no_neighbor_solo_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> solo",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Administratively shut down this neighbor\n"
- "Remove a shutdown message (draft-ietf-idr-shutdown-06)\n"
- "Shutdown message\n")
+ "Solo peer - part of its own update group\n")
{
int idx_peer = 2;
+ struct peer *peer;
+ int ret;
- return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
- PEER_FLAG_SHUTDOWN);
-}
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
-ALIAS(no_neighbor_shutdown_msg, no_neighbor_shutdown_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
- NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Administratively shut down this neighbor\n")
+ ret = update_group_adjust_soloness(peer, 0);
+ return bgp_vty_return(vty, ret);
+}
-/* neighbor capability dynamic. */
-DEFUN (neighbor_capability_dynamic,
- neighbor_capability_dynamic_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
+DEFUN (neighbor_password,
+ neighbor_password_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> password LINE",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Advertise capability to the peer\n"
- "Advertise dynamic capability to this neighbor\n")
+ "Set a password\n"
+ "The password\n")
{
int idx_peer = 1;
- return peer_flag_set_vty(vty, argv[idx_peer]->arg,
- PEER_FLAG_DYNAMIC_CAPABILITY);
+ int idx_line = 3;
+ struct peer *peer;
+ int ret;
+
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ ret = peer_password_set(peer, argv[idx_line]->arg);
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_neighbor_capability_dynamic,
- no_neighbor_capability_dynamic_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
+DEFUN (no_neighbor_password,
+ no_neighbor_password_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> password [LINE]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Advertise capability to the peer\n"
- "Advertise dynamic capability to this neighbor\n")
+ "Set a password\n"
+ "The password\n")
{
int idx_peer = 2;
- return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
- PEER_FLAG_DYNAMIC_CAPABILITY);
+ struct peer *peer;
+ int ret;
+
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ ret = peer_password_unset(peer);
+ return bgp_vty_return(vty, ret);
}
-/* neighbor dont-capability-negotiate */
-DEFUN (neighbor_dont_capability_negotiate,
- neighbor_dont_capability_negotiate_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
+DEFUN (neighbor_activate,
+ neighbor_activate_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Do not perform capability negotiation\n")
+ "Enable the Address Family for this Neighbor\n")
{
int idx_peer = 1;
- return peer_flag_set_vty(vty, argv[idx_peer]->arg,
- PEER_FLAG_DONT_CAPABILITY);
+ int ret;
+ struct peer *peer;
+
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ ret = peer_activate(peer, bgp_node_afi(vty), bgp_node_safi(vty));
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_neighbor_dont_capability_negotiate,
- no_neighbor_dont_capability_negotiate_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
+ALIAS_HIDDEN(neighbor_activate, neighbor_activate_hidden_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> activate",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Enable the Address Family for this Neighbor\n")
+
+DEFUN (no_neighbor_activate,
+ no_neighbor_activate_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Do not perform capability negotiation\n")
+ "Enable the Address Family for this Neighbor\n")
{
int idx_peer = 2;
- return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
- PEER_FLAG_DONT_CAPABILITY);
+ int ret;
+ struct peer *peer;
+
+ /* Lookup peer. */
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ ret = peer_deactivate(peer, bgp_node_afi(vty), bgp_node_safi(vty));
+ return bgp_vty_return(vty, ret);
}
-/* neighbor capability extended next hop encoding */
-DEFUN (neighbor_capability_enhe,
- neighbor_capability_enhe_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
+ALIAS_HIDDEN(no_neighbor_activate, no_neighbor_activate_hidden_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> activate",
+ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Enable the Address Family for this Neighbor\n")
+
+DEFUN (neighbor_set_peer_group,
+ neighbor_set_peer_group_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Advertise capability to the peer\n"
- "Advertise extended next-hop capability to the peer\n")
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_peer = 1;
- return peer_flag_set_vty(vty, argv[idx_peer]->arg,
- PEER_FLAG_CAPABILITY_ENHE);
+ int idx_word = 3;
+ int ret;
+ as_t as;
+ union sockunion su;
+ struct peer *peer;
+ struct peer_group *group;
+
+ ret = str2sockunion(argv[idx_peer]->arg, &su);
+ if (ret < 0) {
+ peer = peer_lookup_by_conf_if(bgp, argv[idx_peer]->arg);
+ if (!peer) {
+ vty_out(vty, "%% Malformed address or name: %s\n",
+ argv[idx_peer]->arg);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else {
+ if (peer_address_self_check(bgp, &su)) {
+ vty_out(vty,
+ "%% Can not configure the local system as neighbor\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ /* Disallow for dynamic neighbor. */
+ peer = peer_lookup(bgp, &su);
+ if (peer && peer_dynamic_neighbor(peer)) {
+ vty_out(vty,
+ "%% Operation not allowed on a dynamic neighbor\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+
+ group = peer_group_lookup(bgp, argv[idx_word]->arg);
+ if (!group) {
+ vty_out(vty, "%% Configure the peer-group first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ ret = peer_group_bind(bgp, &su, peer, group, &as);
+
+ if (ret == BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT) {
+ vty_out(vty,
+ "%% Peer with AS %u cannot be in this peer-group, members must be all internal or all external\n",
+ as);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ return bgp_vty_return(vty, ret);
}
-DEFUN (no_neighbor_capability_enhe,
- no_neighbor_capability_enhe_cmd,
- "no neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
+ALIAS_HIDDEN(neighbor_set_peer_group, neighbor_set_peer_group_hidden_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Member of the peer-group\n"
+ "Peer-group name\n")
+
+DEFUN (no_neighbor_set_peer_group,
+ no_neighbor_set_peer_group_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Advertise capability to the peer\n"
- "Advertise extended next-hop capability to the peer\n")
+ "Member of the peer-group\n"
+ "Peer-group name\n")
{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
int idx_peer = 2;
- return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
- PEER_FLAG_CAPABILITY_ENHE);
-}
-
-static int peer_af_flag_modify_vty(struct vty *vty, const char *peer_str,
- afi_t afi, safi_t safi, uint32_t flag,
- int set)
-{
+ int idx_word = 4;
int ret;
struct peer *peer;
+ struct peer_group *group;
- peer = peer_and_group_lookup_vty(vty, peer_str);
+ peer = peer_lookup_vty(vty, argv[idx_peer]->arg);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
- if (set)
- ret = peer_af_flag_set(peer, afi, safi, flag);
- else
- ret = peer_af_flag_unset(peer, afi, safi, flag);
+ group = peer_group_lookup(bgp, argv[idx_word]->arg);
+ if (!group) {
+ vty_out(vty, "%% Configure the peer-group first\n");
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ peer_notify_unconfig(peer);
+ ret = peer_delete(peer);
return bgp_vty_return(vty, ret);
}
-static int peer_af_flag_set_vty(struct vty *vty, const char *peer_str,
- afi_t afi, safi_t safi, uint32_t flag)
-{
- return peer_af_flag_modify_vty(vty, peer_str, afi, safi, flag, 1);
-}
+ALIAS_HIDDEN(no_neighbor_set_peer_group, no_neighbor_set_peer_group_hidden_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
+ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Member of the peer-group\n"
+ "Peer-group name\n")
-static int peer_af_flag_unset_vty(struct vty *vty, const char *peer_str,
- afi_t afi, safi_t safi, uint32_t flag)
+static int peer_flag_modify_vty(struct vty *vty, const char *ip_str,
+ uint32_t flag, int set)
{
- return peer_af_flag_modify_vty(vty, peer_str, afi, safi, flag, 0);
+ int ret;
+ struct peer *peer;
+
+ peer = peer_and_group_lookup_vty(vty, ip_str);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ /*
+ * If 'neighbor <interface>', then this is for directly connected peers,
+ * we should not accept disable-connected-check.
+ */
+ if (peer->conf_if && (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK)) {
+ vty_out(vty,
+ "%s is directly connected peer, cannot accept disable-"
+ "connected-check\n",
+ ip_str);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (!set && flag == PEER_FLAG_SHUTDOWN)
+ peer_tx_shutdown_message_unset(peer);
+
+ if (set)
+ ret = peer_flag_set(peer, flag);
+ else
+ ret = peer_flag_unset(peer, flag);
+
+ return bgp_vty_return(vty, ret);
+}
+
+static int peer_flag_set_vty(struct vty *vty, const char *ip_str, uint32_t flag)
+{
+ return peer_flag_modify_vty(vty, ip_str, flag, 1);
+}
+
+static int peer_flag_unset_vty(struct vty *vty, const char *ip_str,
+ uint32_t flag)
+{
+ return peer_flag_modify_vty(vty, ip_str, flag, 0);
+}
+
+/* neighbor passive. */
+DEFUN (neighbor_passive,
+ neighbor_passive_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> passive",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Don't send open messages to this neighbor\n")
+{
+ int idx_peer = 1;
+ return peer_flag_set_vty(vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
+}
+
+DEFUN (no_neighbor_passive,
+ no_neighbor_passive_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> passive",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Don't send open messages to this neighbor\n")
+{
+ int idx_peer = 2;
+ return peer_flag_unset_vty(vty, argv[idx_peer]->arg, PEER_FLAG_PASSIVE);
+}
+
+/* neighbor shutdown. */
+DEFUN (neighbor_shutdown_msg,
+ neighbor_shutdown_msg_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Administratively shut down this neighbor\n"
+ "Add a shutdown message (draft-ietf-idr-shutdown-06)\n"
+ "Shutdown message\n")
+{
+ int idx_peer = 1;
+
+ if (argc >= 5) {
+ struct peer *peer =
+ peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ char *message;
+
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+ message = argv_concat(argv, argc, 4);
+ peer_tx_shutdown_message_set(peer, message);
+ XFREE(MTYPE_TMP, message);
+ }
+
+ return peer_flag_set_vty(vty, argv[idx_peer]->arg, PEER_FLAG_SHUTDOWN);
+}
+
+ALIAS(neighbor_shutdown_msg, neighbor_shutdown_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Administratively shut down this neighbor\n")
+
+DEFUN (no_neighbor_shutdown_msg,
+ no_neighbor_shutdown_msg_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown message MSG...",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Administratively shut down this neighbor\n"
+ "Remove a shutdown message (draft-ietf-idr-shutdown-06)\n"
+ "Shutdown message\n")
+{
+ int idx_peer = 2;
+
+ return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_SHUTDOWN);
+}
+
+ALIAS(no_neighbor_shutdown_msg, no_neighbor_shutdown_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> shutdown",
+ NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Administratively shut down this neighbor\n")
+
+/* neighbor capability dynamic. */
+DEFUN (neighbor_capability_dynamic,
+ neighbor_capability_dynamic_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Advertise capability to the peer\n"
+ "Advertise dynamic capability to this neighbor\n")
+{
+ int idx_peer = 1;
+ return peer_flag_set_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_DYNAMIC_CAPABILITY);
+}
+
+DEFUN (no_neighbor_capability_dynamic,
+ no_neighbor_capability_dynamic_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> capability dynamic",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Advertise capability to the peer\n"
+ "Advertise dynamic capability to this neighbor\n")
+{
+ int idx_peer = 2;
+ return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_DYNAMIC_CAPABILITY);
+}
+
+/* neighbor dont-capability-negotiate */
+DEFUN (neighbor_dont_capability_negotiate,
+ neighbor_dont_capability_negotiate_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Do not perform capability negotiation\n")
+{
+ int idx_peer = 1;
+ return peer_flag_set_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_DONT_CAPABILITY);
+}
+
+DEFUN (no_neighbor_dont_capability_negotiate,
+ no_neighbor_dont_capability_negotiate_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> dont-capability-negotiate",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Do not perform capability negotiation\n")
+{
+ int idx_peer = 2;
+ return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_DONT_CAPABILITY);
+}
+
+/* neighbor capability extended next hop encoding */
+DEFUN (neighbor_capability_enhe,
+ neighbor_capability_enhe_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Advertise capability to the peer\n"
+ "Advertise extended next-hop capability to the peer\n")
+{
+ int idx_peer = 1;
+ return peer_flag_set_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_CAPABILITY_ENHE);
+}
+
+DEFUN (no_neighbor_capability_enhe,
+ no_neighbor_capability_enhe_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> capability extended-nexthop",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Advertise capability to the peer\n"
+ "Advertise extended next-hop capability to the peer\n")
+{
+ int idx_peer = 2;
+ return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_CAPABILITY_ENHE);
+}
+
+static int peer_af_flag_modify_vty(struct vty *vty, const char *peer_str,
+ afi_t afi, safi_t safi, uint32_t flag,
+ int set)
+{
+ int ret;
+ struct peer *peer;
+
+ peer = peer_and_group_lookup_vty(vty, peer_str);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ if (set)
+ ret = peer_af_flag_set(peer, afi, safi, flag);
+ else
+ ret = peer_af_flag_unset(peer, afi, safi, flag);
+
+ return bgp_vty_return(vty, ret);
+}
+
+static int peer_af_flag_set_vty(struct vty *vty, const char *peer_str,
+ afi_t afi, safi_t safi, uint32_t flag)
+{
+ return peer_af_flag_modify_vty(vty, peer_str, afi, safi, flag, 1);
+}
+
+static int peer_af_flag_unset_vty(struct vty *vty, const char *peer_str,
+ afi_t afi, safi_t safi, uint32_t flag)
+{
+ return peer_af_flag_modify_vty(vty, peer_str, afi, safi, flag, 0);
}
/* neighbor capability orf prefix-list. */
return bgp_vty_return(vty, ret);
}
-/* Maximum number of prefix configuration. prefix count is different
- for each peer configuration. So this configuration can be set for
- each peer configuration. */
-DEFUN (neighbor_maximum_prefix,
- neighbor_maximum_prefix_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295)",
- NEIGHBOR_STR
- NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n")
+/* Maximum number of prefix to be sent to the neighbor. */
+DEFUN(neighbor_maximum_prefix_out,
+ neighbor_maximum_prefix_out_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out (1-4294967295)",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Maximum number of prefixes to be sent to this peer\n"
+ "Maximum no. of prefix limit\n")
{
int idx_peer = 1;
int idx_number = 3;
- return peer_maximum_prefix_set_vty(
- vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty),
- argv[idx_number]->arg, NULL, 0, NULL);
-}
+ struct peer *peer;
+ uint32_t max;
+ afi_t afi = bgp_node_afi(vty);
+ safi_t safi = bgp_node_safi(vty);
-ALIAS_HIDDEN(neighbor_maximum_prefix, neighbor_maximum_prefix_hidden_cmd,
- "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295)",
- NEIGHBOR_STR NEIGHBOR_ADDR_STR2
- "Maximum number of prefix accept from this peer\n"
- "maximum no. of prefix limit\n")
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
-DEFUN (neighbor_maximum_prefix_threshold,
+ max = strtoul(argv[idx_number]->arg, NULL, 10);
+
+ SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT);
+ peer->pmax_out[afi][safi] = max;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN(no_neighbor_maximum_prefix_out,
+ no_neighbor_maximum_prefix_out_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix-out",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Maximum number of prefixes to be sent to this peer\n")
+{
+ int idx_peer = 2;
+ struct peer *peer;
+ afi_t afi = bgp_node_afi(vty);
+ safi_t safi = bgp_node_safi(vty);
+
+ peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ peer->pmax_out[afi][safi] = 0;
+
+ return CMD_SUCCESS;
+}
+
+/* Maximum number of prefix configuration. prefix count is different
+ for each peer configuration. So this configuration can be set for
+ each peer configuration. */
+DEFUN (neighbor_maximum_prefix,
+ neighbor_maximum_prefix_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295)",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n")
+{
+ int idx_peer = 1;
+ int idx_number = 3;
+ return peer_maximum_prefix_set_vty(
+ vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty),
+ argv[idx_number]->arg, NULL, 0, NULL);
+}
+
+ALIAS_HIDDEN(neighbor_maximum_prefix, neighbor_maximum_prefix_hidden_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295)",
+ NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+ "Maximum number of prefix accept from this peer\n"
+ "maximum no. of prefix limit\n")
+
+DEFUN (neighbor_maximum_prefix_threshold,
neighbor_maximum_prefix_threshold_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> maximum-prefix (1-4294967295) (1-100)",
NEIGHBOR_STR
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,
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,
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,
if (!uj && count == 1) {
vty_out(vty,
"%4s %-5s %-16s %9s %10s %-37s\n",
- "Type", "Id", "routerId", "#PeersVfg",
+ "Type", "Id", "routerId", "#PeersCfg",
"#PeersEstb", "Name");
vty_out(vty, "%11s %-16s %-21s %-6s\n", " ",
"L3-VNI", "RouterMAC", "Interface");
return get_afi_safi_vty_str(afi, safi);
}
-/* Show BGP peer's information. */
-enum show_type { show_all, show_peer, show_ipv4_all, show_ipv6_all, show_ipv4_peer, show_ipv6_peer };
static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
afi_t afi, safi_t safi,
}
}
+static void bgp_show_neighnor_graceful_restart_rbit(struct vty *vty,
+ struct peer *p,
+ bool use_json,
+ json_object *json)
+{
+ bool rbit_status = 0;
+
+ if (!use_json)
+ vty_out(vty, "\n R bit : ");
+
+ if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV)
+ && (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV))
+ && (p->status == Established)) {
+
+ if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_BIT_RCV))
+ rbit_status = 1;
+ else
+ rbit_status = 0;
+ }
+
+ if (rbit_status) {
+ if (use_json)
+ json_object_boolean_true_add(json, "rBit");
+ else
+ vty_out(vty, "True\n");
+ } else {
+ if (use_json)
+ json_object_boolean_false_add(json, "rBit");
+ else
+ vty_out(vty, "False\n");
+ }
+}
+
+static void bgp_show_neighbor_graceful_restart_remote_mode(struct vty *vty,
+ struct peer *peer,
+ bool use_json,
+ json_object *json)
+{
+ const char *mode = "NotApplicable";
+
+ if (!use_json)
+ vty_out(vty, "\n Remote GR Mode : ");
+
+ if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
+ && (peer->status == Established)) {
+
+ if ((peer->nsf_af_count == 0)
+ && !CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+
+ mode = "Disable";
+
+ } else if (peer->nsf_af_count == 0
+ && CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+
+ mode = "Helper";
+
+ } else if (peer->nsf_af_count != 0
+ && CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV)) {
+
+ mode = "Restart";
+ }
+ }
+
+ if (use_json) {
+ json_object_string_add(json, "remoteGrMode", mode);
+ } else
+ vty_out(vty, mode, "\n");
+}
+
+static void bgp_show_neighbor_graceful_restart_local_mode(struct vty *vty,
+ struct peer *p,
+ bool use_json,
+ json_object *json)
+{
+ const char *mode = "Invalid";
+
+ if (!use_json)
+ vty_out(vty, " Local GR Mode : ");
+
+ if (bgp_peer_gr_mode_get(p) == PEER_HELPER)
+ mode = "Helper";
+ else if (bgp_peer_gr_mode_get(p) == PEER_GR)
+ mode = "Restart";
+ else if (bgp_peer_gr_mode_get(p) == PEER_DISABLE)
+ mode = "Disable";
+ else if (bgp_peer_gr_mode_get(p) == PEER_GLOBAL_INHERIT) {
+ if (bgp_global_gr_mode_get(p->bgp) == GLOBAL_HELPER)
+ mode = "Helper*";
+ else if (bgp_global_gr_mode_get(p->bgp) == GLOBAL_GR)
+ mode = "Restart*";
+ else if (bgp_global_gr_mode_get(p->bgp) == GLOBAL_DISABLE)
+ mode = "Disable*";
+ else
+ mode = "Invalid*";
+ }
+
+ if (use_json) {
+ json_object_string_add(json, "localGrMode", mode);
+ } else {
+ vty_out(vty, mode, "\n");
+ }
+}
+
+static void bgp_show_neighbor_graceful_restart_capability_per_afi_safi(
+ struct vty *vty, struct peer *peer, bool use_json, json_object *json)
+{
+ afi_t afi;
+ safi_t safi;
+ json_object *json_afi_safi = NULL;
+ json_object *json_timer = NULL;
+ json_object *json_endofrib_status = NULL;
+ bool eor_flag = false;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+ for (safi = SAFI_UNICAST; safi <= SAFI_MPLS_VPN; safi++) {
+ if (!peer->afc[afi][safi])
+ continue;
+
+ if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)
+ || !CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV))
+ continue;
+
+ if (use_json) {
+ json_afi_safi = json_object_new_object();
+ json_endofrib_status = json_object_new_object();
+ json_timer = json_object_new_object();
+ }
+
+ if (peer->eor_stime[afi][safi]
+ >= peer->pkt_stime[afi][safi])
+ eor_flag = true;
+ else
+ eor_flag = false;
+
+ if (!use_json) {
+ vty_out(vty, " %s :\n",
+ get_afi_safi_str(afi, safi, false));
+
+ vty_out(vty, " F bit : ");
+ }
+
+ if (peer->nsf[afi][safi]
+ && CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_RESTART_AF_PRESERVE_RCV)) {
+
+ if (use_json) {
+ json_object_boolean_true_add(
+ json_afi_safi, "fBit");
+ } else
+ vty_out(vty, "True\n");
+ } else {
+ if (use_json)
+ json_object_boolean_false_add(
+ json_afi_safi, "fBit");
+ else
+ vty_out(vty, "False\n");
+ }
+
+ if (!use_json)
+ vty_out(vty, " End-of-RIB Received : ");
+
+ if (CHECK_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_EOR_RECEIVED)) {
+ if (use_json)
+ json_object_boolean_true_add(
+ json_endofrib_status,
+ "endOfRibRecv");
+ else
+ vty_out(vty, "Yes\n");
+ } else {
+ if (use_json)
+ json_object_boolean_false_add(
+ json_endofrib_status,
+ "endOfRibRecv");
+ else
+ vty_out(vty, "No\n");
+ }
+
+ if (!use_json)
+ vty_out(vty, " End-of-RIB Send : ");
+
+ if (CHECK_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_EOR_SEND)) {
+ if (use_json) {
+ json_object_boolean_true_add(
+ json_endofrib_status,
+ "endOfRibSend");
+
+ PRINT_EOR_JSON(eor_flag);
+ } else {
+ vty_out(vty, "Yes\n");
+ vty_out(vty,
+ " EoRSentAfterUpdate : ");
+
+ PRINT_EOR(eor_flag);
+ }
+ } else {
+ if (use_json) {
+ json_object_boolean_false_add(
+ json_endofrib_status,
+ "endOfRibSend");
+ json_object_boolean_false_add(
+ json_endofrib_status,
+ "endOfRibSentAfterUpdate");
+ } else {
+ vty_out(vty, "No\n");
+ vty_out(vty,
+ " EoRSentAfterUpdate : ");
+ vty_out(vty, "No\n");
+ }
+ }
+
+ if (use_json) {
+ json_object_int_add(json_timer,
+ "stalePathTimer",
+ peer->bgp->stalepath_time);
+
+ if (peer->t_gr_stale != NULL) {
+ json_object_int_add(
+ json_timer,
+ "stalePathTimerRemaining",
+ thread_timer_remain_second(
+ peer->t_gr_stale));
+ }
+
+ /* Display Configured Selection
+ * Deferral only when when
+ * Gr mode is enabled.
+ */
+ if (CHECK_FLAG(peer->flags,
+ PEER_FLAG_GRACEFUL_RESTART)) {
+ json_object_int_add(
+ json_timer,
+ "selectionDeferralTimer",
+ peer->bgp->stalepath_time);
+ }
+
+ if (peer->bgp->gr_info[afi][safi]
+ .t_select_deferral
+ != NULL) {
+
+ json_object_int_add(
+ json_timer,
+ "selectionDeferralTimerRemaining",
+ thread_timer_remain_second(
+ peer->bgp
+ ->gr_info[afi]
+ [safi]
+ .t_select_deferral));
+ }
+ } else {
+ vty_out(vty, " Timers:\n");
+
+ vty_out(vty, "%*s", 6, "");
+ vty_out(vty,
+ "Configured Stale Path Time(sec)%*s: %u\n",
+ 8, "", peer->bgp->stalepath_time);
+
+ if (peer->t_gr_stale != NULL) {
+ vty_out(vty, "%*s", 6, "");
+ vty_out(vty,
+ "Stale Path Remaining(sec)%*s: %ld\n",
+ 14, "",
+ thread_timer_remain_second(
+ peer->t_gr_stale));
+ }
+ /* Display Configured Selection
+ * Deferral only when when
+ * Gr mode is enabled.
+ */
+ if (CHECK_FLAG(peer->flags,
+ PEER_FLAG_GRACEFUL_RESTART)) {
+ vty_out(vty, "%*s", 6, "");
+ vty_out(vty,
+ "Configured Selection Deferral Time(sec): %u\n",
+ peer->bgp->select_defer_time);
+ }
+
+ if (peer->bgp->gr_info[afi][safi]
+ .t_select_deferral
+ != NULL) {
+
+ vty_out(vty, "%*s", 6, "");
+ vty_out(vty,
+ "Selection Deferral Time Remaining(sec) : %ld\n",
+ thread_timer_remain_second(
+ peer->bgp
+ ->gr_info[afi]
+ [safi]
+ .t_select_deferral));
+ }
+ }
+ if (use_json) {
+ json_object_object_add(json_afi_safi,
+ "endOfRibStatus",
+ json_endofrib_status);
+ json_object_object_add(json_afi_safi, "timers",
+ json_timer);
+ json_object_object_add(
+ json, get_afi_safi_str(afi, safi, true),
+ json_afi_safi);
+ }
+ }
+ }
+}
+
+static void bgp_show_neighbor_graceful_restart_time(struct vty *vty,
+ struct peer *p,
+ bool use_json,
+ json_object *json)
+{
+ if (use_json) {
+ json_object *json_timer = NULL;
+
+ json_timer = json_object_new_object();
+
+ json_object_int_add(json_timer, "configuredRestartTimer",
+ p->bgp->restart_time);
+
+ json_object_int_add(json_timer, "receivedRestartTimer",
+ p->v_gr_restart);
+
+ if (p->t_gr_restart != NULL)
+ json_object_int_add(
+ json_timer, "restartTimerRemaining",
+ thread_timer_remain_second(p->t_gr_restart));
+
+ json_object_object_add(json, "timers", json_timer);
+ } else {
+
+ vty_out(vty, " Timers :\n");
+ vty_out(vty, " Configured Restart Time(sec) : %u\n",
+ p->bgp->restart_time);
+
+ vty_out(vty, " Received Restart Time(sec) : %u\n",
+ p->v_gr_restart);
+ if (p->t_gr_restart != NULL)
+ vty_out(vty,
+ " Restart Time Remaining(sec) : %ld\n",
+ thread_timer_remain_second(p->t_gr_restart));
+ }
+}
+
+static void bgp_show_peer_gr_status(struct vty *vty, struct peer *p,
+ bool use_json,
+ json_object *json)
+{
+ char buf[SU_ADDRSTRLEN] = {0};
+ char dn_flag[2] = {0};
+ char neighborAddr[INET6_ADDRSTRLEN] = {0};
+
+ if (!p->conf_if && peer_dynamic_neighbor(p))
+ dn_flag[0] = '*';
+
+ if (p->conf_if) {
+ if (use_json)
+ json_object_string_add(
+ json, "neighborAddr",
+ BGP_PEER_SU_UNSPEC(p)
+ ? "none"
+ : sockunion2str(&p->su, buf,
+ SU_ADDRSTRLEN));
+ else
+ vty_out(vty, "BGP neighbor on %s: %s\n", p->conf_if,
+ BGP_PEER_SU_UNSPEC(p)
+ ? "none"
+ : sockunion2str(&p->su, buf,
+ SU_ADDRSTRLEN));
+ } else {
+ sprintf(neighborAddr, "%s%s", dn_flag, p->host);
+
+ if (use_json)
+ json_object_string_add(
+ json, "neighborAddr",
+ neighborAddr);
+ else
+ vty_out(vty, "BGP neighbor is %s\n",
+ neighborAddr);
+ }
+
+ /* more gr info in new format */
+ BGP_SHOW_PEER_GR_CAPABILITY(vty, p, use_json, json);
+}
+
static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
safi_t safi, bool use_json,
json_object *json_neigh)
json_object_int_add(json_addr, "sentPrefixCounter",
(PAF_SUBGRP(paf))->scount);
+ /* Maximum prefix */
+ if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT))
+ json_object_int_add(json_addr, "prefixOutAllowedMax",
+ p->pmax_out[afi][safi]);
+
/* Maximum prefix */
if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) {
json_object_int_add(json_addr, "prefixAllowedMax",
"prefixAllowedRestartIntervalMsecs",
p->pmax_restart[afi][safi] * 60000);
}
- json_object_object_add(json_neigh, get_afi_safi_str(afi, safi, true),
+ json_object_object_add(json_neigh,
+ get_afi_safi_str(afi,
+ safi, true),
json_addr);
} else {
vty_out(vty, " %" PRIu32 " accepted prefixes\n",
p->pcount[afi][safi]);
+ /* maximum-prefix-out */
+ if (CHECK_FLAG(p->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX_OUT))
+ vty_out(vty,
+ " Maximum allowed prefixes sent %" PRIu32 "\n",
+ p->pmax_out[afi][safi]);
+
/* Maximum prefix */
if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) {
vty_out(vty,
uptime -= p->uptime;
epoch_tbuf = time(NULL) - uptime;
-#if CONFDATE > 20200101
- CPP_NOTICE(
- "bgpTimerUp should be deprecated and can be removed now");
-#endif
- /*
- * bgpTimerUp was miliseconds that was accurate
- * up to 1 day, then the value returned
- * became garbage. So in order to provide
- * some level of backwards compatability,
- * we still provde the data, but now
- * we are returning the correct value
- * and also adding a new bgpTimerUpMsec
- * which will allow us to deprecate
- * this eventually
- */
- json_object_int_add(json_neigh, "bgpTimerUp",
- uptime * 1000);
json_object_int_add(json_neigh, "bgpTimerUpMsec",
uptime * 1000);
json_object_string_add(json_neigh, "bgpTimerUpString",
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);
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",
vty_out(vty, "none");
vty_out(vty, "\n");
}
- }
+ } /* Gracefull Restart */
}
}
}
/* graceful restart information */
- if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV) || p->t_gr_restart
- || p->t_gr_stale) {
json_object *json_grace = NULL;
json_object *json_grace_send = NULL;
json_object *json_grace_recv = NULL;
json_grace_send = json_object_new_object();
json_grace_recv = json_object_new_object();
- if (p->status == Established) {
+ if ((p->status == Established) &&
+ CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) {
FOREACH_AFI_SAFI (afi, safi) {
if (CHECK_FLAG(p->af_sflags[afi][safi],
- PEER_STATUS_EOR_SEND)) {
+ PEER_STATUS_EOR_SEND)) {
json_object_boolean_true_add(
json_grace_send,
get_afi_safi_str(afi,
}
FOREACH_AFI_SAFI (afi, safi) {
if (CHECK_FLAG(
- p->af_sflags[afi][safi],
- PEER_STATUS_EOR_RECEIVED)) {
+ p->af_sflags[afi][safi],
+ PEER_STATUS_EOR_RECEIVED)) {
json_object_boolean_true_add(
json_grace_recv,
get_afi_safi_str(afi,
}
}
}
+ json_object_object_add(json_grace,
+ "endOfRibSend",
+ json_grace_send);
+ json_object_object_add(json_grace,
+ "endOfRibRecv",
+ json_grace_recv);
- json_object_object_add(json_grace, "endOfRibSend",
- json_grace_send);
- json_object_object_add(json_grace, "endOfRibRecv",
- json_grace_recv);
if (p->t_gr_restart)
json_object_int_add(json_grace,
thread_timer_remain_second(
p->t_gr_stale)
* 1000);
-
+ /* more gr info in new format */
+ BGP_SHOW_PEER_GR_CAPABILITY(vty, p, use_json,
+ json_grace);
json_object_object_add(
json_neigh, "gracefulRestartInfo", json_grace);
} else {
- vty_out(vty, " Graceful restart information:\n");
- if (p->status == Established) {
+ vty_out(vty, " Graceful restart informations:\n");
+ if ((p->status == Established) &&
+ CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV)) {
+
vty_out(vty, " End-of-RIB send: ");
FOREACH_AFI_SAFI (afi, safi) {
if (CHECK_FLAG(p->af_sflags[afi][safi],
eor_send_af_count ? ", "
: "",
get_afi_safi_str(afi,
- safi,
- false));
+ safi,
+ false));
eor_send_af_count++;
}
}
" The remaining time of stalepath timer is %ld\n",
thread_timer_remain_second(
p->t_gr_stale));
+
+ /* more gr info in new format */
+ BGP_SHOW_PEER_GR_CAPABILITY(vty, p, use_json, NULL);
}
- }
+
if (use_json) {
json_object *json_stat = NULL;
json_stat = json_object_new_object();
}
}
-static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
- enum show_type type, union sockunion *su,
- const char *conf_if, bool use_json,
- json_object *json)
+static int bgp_show_neighbor_graceful_restart(struct vty *vty,
+ struct bgp *bgp,
+ enum show_type type,
+ union sockunion *su,
+ const char *conf_if, afi_t afi,
+ bool use_json, json_object *json)
{
struct listnode *node, *nnode;
struct peer *peer;
int find = 0;
- bool nbr_output = false;
- afi_t afi = AFI_MAX;
- safi_t safi = SAFI_MAX;
-
- if (type == show_ipv4_peer || type == show_ipv4_all) {
- afi = AFI_IP;
- } else if (type == show_ipv6_peer || type == show_ipv6_all) {
- afi = AFI_IP6;
- }
+ safi_t safi = SAFI_UNICAST;
+ json_object *json_neighbor = NULL;
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+
if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
continue;
- switch (type) {
- case show_all:
- bgp_show_peer(vty, peer, use_json, json);
- nbr_output = true;
- break;
- case show_peer:
- if (conf_if) {
+ if ((peer->afc[afi][safi]) == 0)
+ continue;
+
+ if (use_json)
+ json_neighbor = json_object_new_object();
+
+ if (type == show_all) {
+ bgp_show_peer_gr_status(vty, peer, use_json,
+ json_neighbor);
+
+ if (use_json)
+ json_object_object_add(json, peer->host,
+ json_neighbor);
+
+ } else if (type == show_peer) {
+ if (conf_if) {
+ if ((peer->conf_if
+ && !strcmp(peer->conf_if, conf_if))
+ || (peer->hostname
+ && !strcmp(peer->hostname, conf_if))) {
+ find = 1;
+ bgp_show_peer_gr_status(vty, peer,
+ use_json,
+ json_neighbor);
+ }
+ } else {
+ if (sockunion_same(&peer->su, su)) {
+ find = 1;
+ bgp_show_peer_gr_status(vty, peer,
+ use_json,
+ json_neighbor);
+ }
+ }
+ if (use_json && find)
+ json_object_object_add(json, peer->host,
+ json_neighbor);
+ }
+
+ if (find)
+ break;
+ }
+
+ if (type == show_peer && !find) {
+ if (use_json)
+ json_object_boolean_true_add(json, "bgpNoSuchNeighbor");
+ else
+ vty_out(vty, "%% No such neighbor\n");
+ }
+ if (use_json) {
+ vty_out(vty, "%s\n",
+ json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ } else {
+ vty_out(vty, "\n");
+ }
+
+ return CMD_SUCCESS;
+}
+
+static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
+ enum show_type type, union sockunion *su,
+ const char *conf_if, bool use_json,
+ json_object *json)
+{
+ struct listnode *node, *nnode;
+ struct peer *peer;
+ int find = 0;
+ bool nbr_output = false;
+ afi_t afi = AFI_MAX;
+ safi_t safi = SAFI_MAX;
+
+ if (type == show_ipv4_peer || type == show_ipv4_all) {
+ afi = AFI_IP;
+ } else if (type == show_ipv6_peer || type == show_ipv6_all) {
+ afi = AFI_IP6;
+ }
+
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+ if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+ continue;
+
+ switch (type) {
+ case show_all:
+ bgp_show_peer(vty, peer, use_json, json);
+ nbr_output = true;
+ break;
+ case show_peer:
+ if (conf_if) {
if ((peer->conf_if
&& !strcmp(peer->conf_if, conf_if))
|| (peer->hostname
return CMD_SUCCESS;
}
+static void bgp_show_neighbor_graceful_restart_vty(struct vty *vty,
+ enum show_type type, const char *ip_str,
+ afi_t afi, bool use_json)
+{
+
+ int ret;
+ struct bgp *bgp;
+ union sockunion su;
+ json_object *json = NULL;
+
+ bgp = bgp_get_default();
+
+ if (!bgp)
+ return;
+
+ if (!use_json)
+ bgp_show_global_graceful_restart_mode_vty(vty, bgp, use_json,
+ NULL);
+
+ json = json_object_new_object();
+ if (ip_str) {
+ ret = str2sockunion(ip_str, &su);
+ if (ret < 0)
+ bgp_show_neighbor_graceful_restart(vty, bgp, type, NULL,
+ ip_str, afi,
+ use_json, json);
+ else
+ bgp_show_neighbor_graceful_restart(
+ vty, bgp, type, &su, NULL, afi, use_json, json);
+ } else
+ bgp_show_neighbor_graceful_restart(vty, bgp, type, NULL, NULL,
+ afi, use_json, json);
+ json_object_free(json);
+}
+
static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
enum show_type type,
const char *ip_str,
return CMD_SUCCESS;
}
+
+
+/* "show [ip] bgp neighbors graceful-restart" commands. */
+DEFUN (show_ip_bgp_neighbors_gracrful_restart,
+ show_ip_bgp_neighbors_graceful_restart_cmd,
+ "show bgp [<ipv4|ipv6>] neighbors [<A.B.C.D|X:X::X:X|WORD>] graceful-restart [json]",
+ SHOW_STR
+ BGP_STR
+ IP_STR
+ IPV6_STR
+ NEIGHBOR_STR
+ "Neighbor to display information about\n"
+ "Neighbor to display information about\n"
+ "Neighbor on BGP configured interface\n"
+ GR_SHOW
+ JSON_STR)
+{
+ char *sh_arg = NULL;
+ enum show_type sh_type;
+ int idx = 0;
+ afi_t afi = AFI_MAX;
+ bool uj = use_json(argc, argv);
+
+ if (!argv_find_and_parse_afi(argv, argc, &idx, &afi))
+ afi = AFI_MAX;
+
+ idx++;
+
+ if (argv_find(argv, argc, "A.B.C.D", &idx)
+ || argv_find(argv, argc, "X:X::X:X", &idx)
+ || argv_find(argv, argc, "WORD", &idx)) {
+ sh_type = show_peer;
+ sh_arg = argv[idx]->arg;
+ } else
+ sh_type = show_all;
+
+ if (!argv_find(argv, argc, "graceful-restart", &idx))
+ return CMD_SUCCESS;
+
+
+ return bgp_show_neighbor_graceful_restart_afi_all(vty,
+ sh_type, sh_arg,
+ afi, uj);
+}
+
/* "show [ip] bgp neighbors" commands. */
DEFUN (show_ip_bgp_neighbors,
show_ip_bgp_neighbors_cmd,
return CMD_SUCCESS;
}
+/* Graceful Restart */
+
+static void bgp_show_global_graceful_restart_mode_vty(struct vty *vty,
+ struct bgp *bgp,
+ bool use_json,
+ json_object *json)
+{
+ vty_out(vty, "\n%s", SHOW_GR_HEADER);
+
+ enum global_mode bgp_global_gr_mode = bgp_global_gr_mode_get(bgp);
+
+ switch (bgp_global_gr_mode) {
+
+ case GLOBAL_HELPER:
+ vty_out(vty, "Global BGP GR Mode : Helper\n");
+ break;
+
+ case GLOBAL_GR:
+ vty_out(vty, "Global BGP GR Mode : Restart\n");
+ break;
+
+ case GLOBAL_DISABLE:
+ vty_out(vty, "Global BGP GR Mode : Disable\n");
+ break;
+
+ case GLOBAL_INVALID:
+ vty_out(vty,
+ "Global BGP GR Mode Invalid\n");
+ break;
+ }
+ vty_out(vty, "\n");
+}
+
+static int bgp_show_neighbor_graceful_restart_afi_all(struct vty *vty,
+ enum show_type type,
+ const char *ip_str,
+ afi_t afi,
+ bool use_json)
+{
+ if ((afi == AFI_MAX) && (ip_str == NULL)) {
+ afi = AFI_IP;
+
+ while ((afi != AFI_L2VPN) && (afi < AFI_MAX)) {
+
+ bgp_show_neighbor_graceful_restart_vty(vty,
+ type, ip_str,
+ afi, use_json);
+ afi++;
+ }
+ } else if (afi != AFI_MAX) {
+ bgp_show_neighbor_graceful_restart_vty(vty,
+ type, ip_str,
+ afi, use_json);
+ } else {
+ return CMD_ERR_INCOMPLETE;
+ }
+
+ return CMD_SUCCESS;
+}
+/* Graceful Restart */
+
DEFUN (show_ip_bgp_attr_info,
show_ip_bgp_attr_info_cmd,
"show [ip] bgp attribute-info",
return CMD_WARNING_CONFIG_FAILED;
}
- return bgp_redistribute_unset(bgp, AFI_IP6, type, 0);
-}
+ return bgp_redistribute_unset(bgp, AFI_IP6, type, 0);
+}
+
+static void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp,
+ afi_t afi, safi_t safi)
+{
+ int i;
+
+ /* Unicast redistribution only. */
+ if (safi != SAFI_UNICAST)
+ return;
+
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+ /* Redistribute BGP does not make sense. */
+ if (i != ZEBRA_ROUTE_BGP) {
+ struct list *red_list;
+ struct listnode *node;
+ struct bgp_redist *red;
+
+ red_list = bgp->redist[afi][i];
+ if (!red_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
+ /* "redistribute" configuration. */
+ vty_out(vty, " redistribute %s",
+ zebra_route_string(i));
+ if (red->instance)
+ vty_out(vty, " %d", red->instance);
+ if (red->redist_metric_flag)
+ vty_out(vty, " metric %u",
+ red->redist_metric);
+ if (red->rmap.name)
+ vty_out(vty, " route-map %s",
+ red->rmap.name);
+ vty_out(vty, "\n");
+ }
+ }
+ }
+}
+
+/* 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) */
+static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
+ afi_t afi)
+{
+ int indent = 2;
+
+ if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]) {
+ if (listcount(bgp->vpn_policy[afi].import_vrf))
+ vty_out(vty, "%*simport vrf route-map %s\n", indent, "",
+ bgp->vpn_policy[afi]
+ .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]);
+ else
+ vty_out(vty, "%*sroute-map vpn import %s\n", indent, "",
+ bgp->vpn_policy[afi]
+ .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]);
+ }
+ if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+ BGP_CONFIG_VRF_TO_VRF_IMPORT)
+ || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+ BGP_CONFIG_VRF_TO_VRF_EXPORT))
+ return;
+
+ if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
+
+ vty_out(vty, "%*slabel vpn export %s\n", indent, "", "auto");
+
+ } else {
+ if (bgp->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE) {
+ vty_out(vty, "%*slabel vpn export %u\n", indent, "",
+ bgp->vpn_policy[afi].tovpn_label);
+ }
+ }
+ if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_RD_SET)) {
+ char buf[RD_ADDRSTRLEN];
+ vty_out(vty, "%*srd vpn export %s\n", indent, "",
+ prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
+ sizeof(buf)));
+ }
+ if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
+
+ char buf[PREFIX_STRLEN];
+ if (inet_ntop(bgp->vpn_policy[afi].tovpn_nexthop.family,
+ &bgp->vpn_policy[afi].tovpn_nexthop.u.prefix, buf,
+ sizeof(buf))) {
+
+ vty_out(vty, "%*snexthop vpn export %s\n",
+ indent, "", buf);
+ }
+ }
+ if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]
+ && bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]
+ && ecommunity_cmp(
+ bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
+ bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN])) {
+
+ char *b = ecommunity_ecom2str(
+ bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN],
+ ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET);
+ vty_out(vty, "%*srt vpn both %s\n", indent, "", b);
+ XFREE(MTYPE_ECOMMUNITY_STR, b);
+ } else {
+ if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) {
+ char *b = ecommunity_ecom2str(
+ bgp->vpn_policy[afi]
+ .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
+ ECOMMUNITY_FORMAT_ROUTE_MAP,
+ ECOMMUNITY_ROUTE_TARGET);
+ vty_out(vty, "%*srt vpn import %s\n", indent, "", b);
+ XFREE(MTYPE_ECOMMUNITY_STR, b);
+ }
+ if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) {
+ char *b = ecommunity_ecom2str(
+ bgp->vpn_policy[afi]
+ .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
+ ECOMMUNITY_FORMAT_ROUTE_MAP,
+ ECOMMUNITY_ROUTE_TARGET);
+ vty_out(vty, "%*srt vpn export %s\n", indent, "", b);
+ XFREE(MTYPE_ECOMMUNITY_STR, b);
+ }
+ }
+
+ if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN])
+ vty_out(vty, "%*sroute-map vpn export %s\n", indent, "",
+ bgp->vpn_policy[afi]
+ .rmap_name[BGP_VPN_POLICY_DIR_TOVPN]);
+
+ if (bgp->vpn_policy[afi].import_redirect_rtlist) {
+ char *b = ecommunity_ecom2str(
+ bgp->vpn_policy[afi]
+ .import_redirect_rtlist,
+ ECOMMUNITY_FORMAT_ROUTE_MAP,
+ ECOMMUNITY_ROUTE_TARGET);
+
+ vty_out(vty, "%*srt redirect import %s\n", indent, "", b);
+ XFREE(MTYPE_ECOMMUNITY_STR, b);
+ }
+}
+
+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);
+
+ if (!CHECK_FLAG(peer->peer_gr_new_status_flag,
+ PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT)) {
+
+ if (CHECK_FLAG(peer->peer_gr_new_status_flag,
+ PEER_GRACEFUL_RESTART_NEW_STATE_HELPER)) {
+ vty_out(vty,
+ " neighbor %s graceful-restart-helper\n", addr);
+ } else if (CHECK_FLAG(
+ peer->peer_gr_new_status_flag,
+ PEER_GRACEFUL_RESTART_NEW_STATE_RESTART)) {
+ vty_out(vty,
+ " neighbor %s graceful-restart\n", addr);
+ } else if (
+ (!(CHECK_FLAG(peer->peer_gr_new_status_flag,
+ PEER_GRACEFUL_RESTART_NEW_STATE_HELPER))
+ && !(CHECK_FLAG(
+ peer->peer_gr_new_status_flag,
+ PEER_GRACEFUL_RESTART_NEW_STATE_RESTART)))) {
+ vty_out(vty, " neighbor %s graceful-restart-disable\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");
+ }
+
+ /* maximum-prefix-out */
+ if (peergroup_af_flag_check(peer, afi, safi, PEER_FLAG_MAX_PREFIX_OUT))
+ vty_out(vty, " neighbor %s maximum-prefix-out %" PRIu32 "\n",
+ addr, peer->pmax_out[afi][safi]);
+
+ /* 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);
-void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp, afi_t afi,
- safi_t safi)
-{
- int i;
+ if (safi == SAFI_EVPN)
+ bgp_config_write_evpn_info(vty, bgp, afi, safi);
- /* Unicast redistribution only. */
- if (safi != SAFI_UNICAST)
- return;
+ if (safi == SAFI_FLOWSPEC)
+ bgp_fs_config_write_pbr(vty, bgp, afi, safi);
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- /* Redistribute BGP does not make sense. */
- if (i != ZEBRA_ROUTE_BGP) {
- struct list *red_list;
- struct listnode *node;
- struct bgp_redist *red;
+ 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)) {
- red_list = bgp->redist[afi][i];
- if (!red_list)
- continue;
+ vty_out(vty, " export vpn\n");
+ }
+ if (CHECK_FLAG(bgp->af_flags[afi][safi],
+ BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) {
- for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
- /* "redistribute" configuration. */
- vty_out(vty, " redistribute %s",
- zebra_route_string(i));
- if (red->instance)
- vty_out(vty, " %d", red->instance);
- if (red->redist_metric_flag)
- vty_out(vty, " metric %u",
- red->redist_metric);
- if (red->rmap.name)
- vty_out(vty, " route-map %s",
- red->rmap.name);
- vty_out(vty, "\n");
- }
+ 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");
}
-/* This is part of the address-family block (unicast only) */
-void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
- afi_t afi)
+int bgp_config_write(struct vty *vty)
{
- int indent = 2;
+ struct bgp *bgp;
+ struct peer_group *group;
+ struct peer *peer;
+ struct listnode *node, *nnode;
+ struct listnode *mnode, *mnnode;
- if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]) {
- if (listcount(bgp->vpn_policy[afi].import_vrf))
- vty_out(vty, "%*simport vrf route-map %s\n", indent, "",
- bgp->vpn_policy[afi]
- .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]);
- else
- vty_out(vty, "%*sroute-map vpn import %s\n", indent, "",
- bgp->vpn_policy[afi]
- .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]);
- }
- if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
- BGP_CONFIG_VRF_TO_VRF_IMPORT)
- || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
- BGP_CONFIG_VRF_TO_VRF_EXPORT))
- return;
+ if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER)
+ vty_out(vty, "bgp route-map delay-timer %u\n",
+ bm->rmap_update_timer);
- if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
+ /* BGP configuration. */
+ for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) {
- vty_out(vty, "%*slabel vpn export %s\n", indent, "", "auto");
+ /* skip all auto created vrf as they dont have user config */
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
+ continue;
- } else {
- if (bgp->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE) {
- vty_out(vty, "%*slabel vpn export %u\n", indent, "",
- bgp->vpn_policy[afi].tovpn_label);
+ /* 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");
}
- }
- if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_RD_SET)) {
- char buf[RD_ADDRSTRLEN];
- vty_out(vty, "%*srd vpn export %s\n", indent, "",
- prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
- sizeof(buf)));
- }
- if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
- char buf[PREFIX_STRLEN];
- if (inet_ntop(bgp->vpn_policy[afi].tovpn_nexthop.family,
- &bgp->vpn_policy[afi].tovpn_nexthop.u.prefix, buf,
- sizeof(buf))) {
+ /* 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");
+ }
- vty_out(vty, "%*snexthop vpn export %s\n",
- indent, "", buf);
+ /* 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->select_defer_time != BGP_DEFAULT_SELECT_DEFERRAL_TIME)
+ vty_out(vty,
+ " bgp graceful-restart select-defer-time %u\n",
+ bgp->select_defer_time);
+
+ if (bgp_global_gr_mode_get(bgp) == GLOBAL_GR)
+ vty_out(vty, " bgp graceful-restart\n");
+
+ if (bgp_global_gr_mode_get(bgp) == GLOBAL_DISABLE)
+ vty_out(vty, " bgp graceful-restart-disable\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");
+
+ /* Stale timer for RIB */
+ if (bgp->rib_stale_time != BGP_DEFAULT_RIB_STALE_TIME)
+ vty_out(vty,
+ " bgp graceful-restart rib-stale-time %u\n",
+ bgp->rib_stale_time);
+
+ /* 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->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]
- && bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]
- && ecommunity_cmp(
- bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
- bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN])) {
- char *b = ecommunity_ecom2str(
- bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN],
- ECOMMUNITY_FORMAT_ROUTE_MAP, ECOMMUNITY_ROUTE_TARGET);
- vty_out(vty, "%*srt vpn both %s\n", indent, "", b);
- XFREE(MTYPE_ECOMMUNITY_STR, b);
- } else {
- if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN]) {
- char *b = ecommunity_ecom2str(
- bgp->vpn_policy[afi]
- .rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
- ECOMMUNITY_FORMAT_ROUTE_MAP,
- ECOMMUNITY_ROUTE_TARGET);
- vty_out(vty, "%*srt vpn import %s\n", indent, "", b);
- XFREE(MTYPE_ECOMMUNITY_STR, b);
+ if (bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+ vty_out(vty,
+ " bgp route-reflector allow-outbound-policy\n");
}
- if (bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN]) {
- char *b = ecommunity_ecom2str(
- bgp->vpn_policy[afi]
- .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
- ECOMMUNITY_FORMAT_ROUTE_MAP,
- ECOMMUNITY_ROUTE_TARGET);
- vty_out(vty, "%*srt vpn export %s\n", indent, "", b);
- XFREE(MTYPE_ECOMMUNITY_STR, b);
+ 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");
}
- }
- if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN])
- vty_out(vty, "%*sroute-map vpn export %s\n", indent, "",
- bgp->vpn_policy[afi]
- .rmap_name[BGP_VPN_POLICY_DIR_TOVPN]);
+ /* 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);
+ }
- if (bgp->vpn_policy[afi].import_redirect_rtlist) {
- char *b = ecommunity_ecom2str(
- bgp->vpn_policy[afi]
- .import_redirect_rtlist,
- ECOMMUNITY_FORMAT_ROUTE_MAP,
- ECOMMUNITY_ROUTE_TARGET);
+ /* 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);
+ }
- vty_out(vty, "%*srt redirect import %s\n", indent, "", b);
- XFREE(MTYPE_ECOMMUNITY_STR, b);
+ /* 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;
}
install_element(BGP_NODE, &bgp_deterministic_med_cmd);
install_element(BGP_NODE, &no_bgp_deterministic_med_cmd);
- /* "bgp graceful-restart" commands */
- install_element(BGP_NODE, &bgp_graceful_restart_cmd);
- install_element(BGP_NODE, &no_bgp_graceful_restart_cmd);
+ /* "bgp graceful-restart" command */
+ install_element(BGP_NODE,
+ &bgp_graceful_restart_cmd);
+ install_element(BGP_NODE,
+ &no_bgp_graceful_restart_cmd);
+
+ /* "bgp graceful-restart-disable" command */
+ install_element(BGP_NODE,
+ &bgp_graceful_restart_disable_cmd);
+ install_element(BGP_NODE,
+ &no_bgp_graceful_restart_disable_cmd);
+
+ /* "neighbor a:b:c:d graceful-restart" command */
+ install_element(BGP_NODE,
+ &bgp_neighbor_graceful_restart_set_cmd);
+ install_element(BGP_NODE,
+ &no_bgp_neighbor_graceful_restart_set_cmd);
+
+ /* "neighbor a:b:c:d graceful-restart-disable" command */
+ install_element(BGP_NODE,
+ &bgp_neighbor_graceful_restart_disable_set_cmd);
+ install_element(BGP_NODE,
+ &no_bgp_neighbor_graceful_restart_disable_set_cmd);
+
+ /* "neighbor a:b:c:d graceful-restart-helper" command */
+ install_element(BGP_NODE,
+ &bgp_neighbor_graceful_restart_helper_set_cmd);
+ install_element(BGP_NODE,
+ &no_bgp_neighbor_graceful_restart_helper_set_cmd);
+
install_element(BGP_NODE, &bgp_graceful_restart_stalepath_time_cmd);
install_element(BGP_NODE, &no_bgp_graceful_restart_stalepath_time_cmd);
install_element(BGP_NODE, &bgp_graceful_restart_restart_time_cmd);
install_element(BGP_NODE, &no_bgp_graceful_restart_restart_time_cmd);
-
+ install_element(BGP_NODE, &bgp_graceful_restart_select_defer_time_cmd);
+ install_element(BGP_NODE,
+ &no_bgp_graceful_restart_select_defer_time_cmd);
install_element(BGP_NODE, &bgp_graceful_restart_preserve_fw_cmd);
install_element(BGP_NODE, &no_bgp_graceful_restart_preserve_fw_cmd);
+ install_element(BGP_NODE, &bgp_graceful_restart_disable_eor_cmd);
+ install_element(BGP_NODE, &no_bgp_graceful_restart_disable_eor_cmd);
+ install_element(BGP_NODE, &bgp_graceful_restart_rib_stale_time_cmd);
+ install_element(BGP_NODE, &no_bgp_graceful_restart_rib_stale_time_cmd);
+
/* "bgp graceful-shutdown" commands */
install_element(BGP_NODE, &bgp_graceful_shutdown_cmd);
install_element(BGP_NODE, &no_bgp_graceful_shutdown_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_unsuppress_map_cmd);
+ /* neighbor maximum-prefix-out commands. */
+ install_element(BGP_NODE, &neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_NODE, &no_neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV4_NODE, &neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV4_NODE, &no_neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV4M_NODE, &neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV4M_NODE, &no_neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV4L_NODE, &neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV4L_NODE, &no_neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV6_NODE, &neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV6_NODE, &no_neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV6M_NODE, &neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV6M_NODE, &no_neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV6L_NODE, &neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_IPV6L_NODE, &no_neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_VPNV4_NODE, &neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_VPNV4_NODE, &no_neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_VPNV6_NODE, &neighbor_maximum_prefix_out_cmd);
+ install_element(BGP_VPNV6_NODE, &no_neighbor_maximum_prefix_out_cmd);
+
/* "neighbor maximum-prefix" commands. */
install_element(BGP_NODE, &neighbor_maximum_prefix_hidden_cmd);
install_element(BGP_NODE,
/* "show [ip] bgp neighbors" commands. */
install_element(VIEW_NODE, &show_ip_bgp_neighbors_cmd);
+ install_element(VIEW_NODE,
+ &show_ip_bgp_neighbors_graceful_restart_cmd);
+
/* "show [ip] bgp peer-group" commands. */
install_element(VIEW_NODE, &show_ip_bgp_peer_groups_cmd);
/*community-list standard */
DEFUN (community_list_standard,
bgp_community_list_standard_cmd,
- "bgp community-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+ "bgp community-list <(1-99)|standard WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
BGP_STR
COMMUNITY_LIST_STR
"Community list number (standard)\n"
"Add an standard community-list entry\n"
"Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify community to reject\n"
"Specify community to accept\n"
COMMUNITY_VAL_STR)
{
char *cl_name_or_number = NULL;
+ char *seq = NULL;
int direct = 0;
int style = COMMUNITY_LIST_STANDARD;
int idx = 0;
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+
+ idx = 0;
argv_find(argv, argc, "(1-99)", &idx);
argv_find(argv, argc, "WORD", &idx);
cl_name_or_number = argv[idx]->arg;
argv_find(argv, argc, "AA:NN", &idx);
char *str = argv_concat(argv, argc, idx);
- int ret = community_list_set(bgp_clist, cl_name_or_number, str, direct,
- style);
+ int ret = community_list_set(bgp_clist, cl_name_or_number, str, seq,
+ direct, style);
XFREE(MTYPE_TMP, str);
DEFUN (no_community_list_standard_all,
no_bgp_community_list_standard_all_cmd,
- "no bgp community-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+ "no bgp community-list <(1-99)|standard WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
NO_STR
BGP_STR
COMMUNITY_LIST_STR
"Community list number (standard)\n"
"Add an standard community-list entry\n"
"Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify community to reject\n"
"Specify community to accept\n"
COMMUNITY_VAL_STR)
char *str = NULL;
int direct = 0;
int style = COMMUNITY_LIST_STANDARD;
-
+ char *seq = NULL;
int idx = 0;
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+
+ idx = 0;
argv_find(argv, argc, "permit", &idx);
argv_find(argv, argc, "deny", &idx);
argv_find(argv, argc, "WORD", &idx);
cl_name_or_number = argv[idx]->arg;
- int ret = community_list_unset(bgp_clist, cl_name_or_number, str,
+ int ret = community_list_unset(bgp_clist, cl_name_or_number, str, seq,
direct, style);
XFREE(MTYPE_TMP, str);
/*community-list expanded */
DEFUN (community_list_expanded_all,
bgp_community_list_expanded_all_cmd,
- "bgp community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...",
+ "bgp community-list <(100-500)|expanded WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
BGP_STR
COMMUNITY_LIST_STR
"Community list number (expanded)\n"
"Add an expanded community-list entry\n"
"Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify community to reject\n"
"Specify community to accept\n"
COMMUNITY_VAL_STR)
{
char *cl_name_or_number = NULL;
+ char *seq = NULL;
int direct = 0;
int style = COMMUNITY_LIST_EXPANDED;
-
int idx = 0;
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+
+ idx = 0;
+
argv_find(argv, argc, "(100-500)", &idx);
argv_find(argv, argc, "WORD", &idx);
cl_name_or_number = argv[idx]->arg;
argv_find(argv, argc, "AA:NN", &idx);
char *str = argv_concat(argv, argc, idx);
- int ret = community_list_set(bgp_clist, cl_name_or_number, str, direct,
- style);
+ int ret = community_list_set(bgp_clist, cl_name_or_number, str, seq,
+ direct, style);
XFREE(MTYPE_TMP, str);
DEFUN (no_community_list_expanded_all,
no_bgp_community_list_expanded_all_cmd,
- "no bgp community-list <(100-500)|expanded WORD> <deny|permit> AA:NN...",
+ "no bgp community-list <(100-500)|expanded WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
NO_STR
BGP_STR
COMMUNITY_LIST_STR
"Community list number (expanded)\n"
"Add an expanded community-list entry\n"
"Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify community to reject\n"
"Specify community to accept\n"
COMMUNITY_VAL_STR)
{
char *cl_name_or_number = NULL;
+ char *seq = NULL;
char *str = NULL;
int direct = 0;
int style = COMMUNITY_LIST_EXPANDED;
-
int idx = 0;
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+
+ idx = 0;
argv_find(argv, argc, "permit", &idx);
argv_find(argv, argc, "deny", &idx);
argv_find(argv, argc, "WORD", &idx);
cl_name_or_number = argv[idx]->arg;
- int ret = community_list_unset(bgp_clist, cl_name_or_number, str,
+ int ret = community_list_unset(bgp_clist, cl_name_or_number, str, seq,
direct, style);
XFREE(MTYPE_TMP, str);
char *str;
int idx = 0;
char *cl_name;
+ char *seq = NULL;
+
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+ idx = 0;
direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
: COMMUNITY_DENY;
else
str = NULL;
- ret = lcommunity_list_set(bgp_clist, cl_name, str, direct, style);
+ ret = lcommunity_list_set(bgp_clist, cl_name, str, seq, direct, style);
/* Free temporary community list string allocated by
argv_concat(). */
int direct = 0;
char *str = NULL;
int idx = 0;
+ char *seq = NULL;
+
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+ idx = 0;
argv_find(argv, argc, "permit", &idx);
argv_find(argv, argc, "deny", &idx);
argv_find(argv, argc, "WORD", &idx);
/* Unset community list. */
- ret = lcommunity_list_unset(bgp_clist, argv[idx]->arg, str, direct,
+ ret = lcommunity_list_unset(bgp_clist, argv[idx]->arg, str, seq, direct,
style);
/* Free temporary community list string allocated by
DEFUN (lcommunity_list_standard,
bgp_lcommunity_list_standard_cmd,
- "bgp large-community-list (1-99) <deny|permit> AA:BB:CC...",
+ "bgp large-community-list (1-99) [seq (1-4294967295)] <deny|permit> AA:BB:CC...",
BGP_STR
LCOMMUNITY_LIST_STR
"Large Community list number (standard)\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify large community to reject\n"
"Specify large community to accept\n"
LCOMMUNITY_VAL_STR)
DEFUN (lcommunity_list_expanded,
bgp_lcommunity_list_expanded_cmd,
- "bgp large-community-list (100-500) <deny|permit> LINE...",
+ "bgp large-community-list (100-500) [seq (1-4294967295)] <deny|permit> LINE...",
BGP_STR
LCOMMUNITY_LIST_STR
"Large Community list number (expanded)\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify large community to reject\n"
"Specify large community to accept\n"
"An ordered list as a regular-expression\n")
DEFUN (lcommunity_list_name_standard,
bgp_lcommunity_list_name_standard_cmd,
- "bgp large-community-list standard WORD <deny|permit> AA:BB:CC...",
+ "bgp large-community-list standard WORD [seq (1-4294967295)] <deny|permit> AA:BB:CC...",
BGP_STR
LCOMMUNITY_LIST_STR
"Specify standard large-community-list\n"
"Large Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify large community to reject\n"
"Specify large community to accept\n"
LCOMMUNITY_VAL_STR)
DEFUN (lcommunity_list_name_expanded,
bgp_lcommunity_list_name_expanded_cmd,
- "bgp large-community-list expanded WORD <deny|permit> LINE...",
+ "bgp large-community-list expanded WORD [seq (1-4294967295)] <deny|permit> LINE...",
BGP_STR
LCOMMUNITY_LIST_STR
"Specify expanded large-community-list\n"
"Large Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify large community to reject\n"
"Specify large community to accept\n"
"An ordered list as a regular-expression\n")
LARGE_COMMUNITY_LIST_EXPANDED, 1);
}
-DEFUN (no_lcommunity_list_standard_all,
- no_bgp_lcommunity_list_standard_all_cmd,
+DEFUN (no_lcommunity_list_all,
+ no_bgp_lcommunity_list_all_cmd,
"no bgp large-community-list <(1-99)|(100-500)|WORD>",
NO_STR
BGP_STR
LARGE_COMMUNITY_LIST_STANDARD);
}
+DEFUN (no_lcommunity_list_name_standard_all,
+ no_bgp_lcommunity_list_name_standard_all_cmd,
+ "no bgp large-community-list standard WORD",
+ NO_STR
+ BGP_STR
+ LCOMMUNITY_LIST_STR
+ "Specify standard large-community-list\n"
+ "Large Community list name\n")
+{
+ return lcommunity_list_unset_vty(vty, argc, argv,
+ LARGE_COMMUNITY_LIST_STANDARD);
+}
+
DEFUN (no_lcommunity_list_name_expanded_all,
no_bgp_lcommunity_list_name_expanded_all_cmd,
"no bgp large-community-list expanded WORD",
DEFUN (no_lcommunity_list_standard,
no_bgp_lcommunity_list_standard_cmd,
- "no bgp large-community-list (1-99) <deny|permit> AA:AA:NN...",
+ "no bgp large-community-list (1-99) [seq (1-4294967295)] <deny|permit> AA:AA:NN...",
NO_STR
BGP_STR
LCOMMUNITY_LIST_STR
"Large Community list number (standard)\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify large community to reject\n"
"Specify large community to accept\n"
LCOMMUNITY_VAL_STR)
DEFUN (no_lcommunity_list_expanded,
no_bgp_lcommunity_list_expanded_cmd,
- "no bgp large-community-list (100-500) <deny|permit> LINE...",
+ "no bgp large-community-list (100-500) [seq (1-4294967295)] <deny|permit> LINE...",
NO_STR
BGP_STR
LCOMMUNITY_LIST_STR
"Large Community list number (expanded)\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify large community to reject\n"
"Specify large community to accept\n"
"An ordered list as a regular-expression\n")
DEFUN (no_lcommunity_list_name_standard,
no_bgp_lcommunity_list_name_standard_cmd,
- "no bgp large-community-list standard WORD <deny|permit> AA:AA:NN...",
+ "no bgp large-community-list standard WORD [seq (1-4294967295)] <deny|permit> AA:AA:NN...",
NO_STR
BGP_STR
LCOMMUNITY_LIST_STR
"Specify standard large-community-list\n"
"Large Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify large community to reject\n"
"Specify large community to accept\n"
LCOMMUNITY_VAL_STR)
DEFUN (no_lcommunity_list_name_expanded,
no_bgp_lcommunity_list_name_expanded_cmd,
- "no bgp large-community-list expanded WORD <deny|permit> LINE...",
+ "no bgp large-community-list expanded WORD [seq (1-4294967295)] <deny|permit> LINE...",
NO_STR
BGP_STR
LCOMMUNITY_LIST_STR
"Specify expanded large-community-list\n"
"Large community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify large community to reject\n"
"Specify large community to accept\n"
"An ordered list as a regular-expression\n")
DEFUN (extcommunity_list_standard,
bgp_extcommunity_list_standard_cmd,
- "bgp extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+ "bgp extcommunity-list <(1-99)|standard WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
BGP_STR
EXTCOMMUNITY_LIST_STR
"Extended Community list number (standard)\n"
"Specify standard extcommunity-list\n"
"Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify community to reject\n"
"Specify community to accept\n"
EXTCOMMUNITY_VAL_STR)
int style = EXTCOMMUNITY_LIST_STANDARD;
int direct = 0;
char *cl_number_or_name = NULL;
+ char *seq = NULL;
int idx = 0;
argv_find(argv, argc, "(1-99)", &idx);
argv_find(argv, argc, "WORD", &idx);
cl_number_or_name = argv[idx]->arg;
+
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+
direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
: COMMUNITY_DENY;
argv_find(argv, argc, "AA:NN", &idx);
char *str = argv_concat(argv, argc, idx);
- int ret = extcommunity_list_set(bgp_clist, cl_number_or_name, str,
+ int ret = extcommunity_list_set(bgp_clist, cl_number_or_name, str, seq,
direct, style);
XFREE(MTYPE_TMP, str);
DEFUN (extcommunity_list_name_expanded,
bgp_extcommunity_list_name_expanded_cmd,
- "bgp extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...",
+ "bgp extcommunity-list <(100-500)|expanded WORD> [seq (1-4294967295)] <deny|permit> LINE...",
BGP_STR
EXTCOMMUNITY_LIST_STR
"Extended Community list number (expanded)\n"
"Specify expanded extcommunity-list\n"
"Extended Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify community to reject\n"
"Specify community to accept\n"
"An ordered list as a regular-expression\n")
int style = EXTCOMMUNITY_LIST_EXPANDED;
int direct = 0;
char *cl_number_or_name = NULL;
+ char *seq = NULL;
int idx = 0;
argv_find(argv, argc, "(100-500)", &idx);
argv_find(argv, argc, "WORD", &idx);
cl_number_or_name = argv[idx]->arg;
+
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+
direct = argv_find(argv, argc, "permit", &idx) ? COMMUNITY_PERMIT
: COMMUNITY_DENY;
argv_find(argv, argc, "LINE", &idx);
char *str = argv_concat(argv, argc, idx);
- int ret = extcommunity_list_set(bgp_clist, cl_number_or_name, str,
+ int ret = extcommunity_list_set(bgp_clist, cl_number_or_name, str, seq,
direct, style);
XFREE(MTYPE_TMP, str);
DEFUN (no_extcommunity_list_standard_all,
no_bgp_extcommunity_list_standard_all_cmd,
- "no bgp extcommunity-list <(1-99)|standard WORD> <deny|permit> AA:NN...",
+ "no bgp extcommunity-list <(1-99)|standard WORD> [seq (1-4294967295)] <deny|permit> AA:NN...",
NO_STR
BGP_STR
EXTCOMMUNITY_LIST_STR
"Extended Community list number (standard)\n"
"Specify standard extcommunity-list\n"
"Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify community to reject\n"
"Specify community to accept\n"
EXTCOMMUNITY_VAL_STR)
int direct = 0;
char *cl_number_or_name = NULL;
char *str = NULL;
+ char *seq = NULL;
int idx = 0;
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+
+ idx = 0;
argv_find(argv, argc, "permit", &idx);
argv_find(argv, argc, "deny", &idx);
-
if (idx) {
direct = argv_find(argv, argc, "permit", &idx)
? COMMUNITY_PERMIT
cl_number_or_name = argv[idx]->arg;
int ret = extcommunity_list_unset(bgp_clist, cl_number_or_name, str,
- direct, style);
+ seq, direct, style);
XFREE(MTYPE_TMP, str);
DEFUN (no_extcommunity_list_expanded_all,
no_bgp_extcommunity_list_expanded_all_cmd,
- "no bgp extcommunity-list <(100-500)|expanded WORD> <deny|permit> LINE...",
+ "no bgp extcommunity-list <(100-500)|expanded WORD> [seq (1-4294967295)] <deny|permit> LINE...",
NO_STR
BGP_STR
EXTCOMMUNITY_LIST_STR
"Extended Community list number (expanded)\n"
"Specify expanded extcommunity-list\n"
"Extended Community list name\n"
+ "Sequence number of an entry\n"
+ "Sequence number\n"
"Specify community to reject\n"
"Specify community to accept\n"
"An ordered list as a regular-expression\n")
int direct = 0;
char *cl_number_or_name = NULL;
char *str = NULL;
+ char *seq = NULL;
int idx = 0;
+ argv_find(argv, argc, "(1-4294967295)", &idx);
+ if (idx)
+ seq = argv[idx]->arg;
+
+ idx = 0;
argv_find(argv, argc, "permit", &idx);
argv_find(argv, argc, "deny", &idx);
cl_number_or_name = argv[idx]->arg;
int ret = extcommunity_list_unset(bgp_clist, cl_number_or_name, str,
- direct, style);
+ seq, direct, style);
XFREE(MTYPE_TMP, str);
for (list = cm->num.head; list; list = list->next)
for (entry = list->head; entry; entry = entry->next) {
- vty_out(vty, "bgp community-list %s %s %s\n", list->name,
+ vty_out(vty,
+ "bgp community-list %s seq %" PRId64 " %s %s\n",
+ list->name, entry->seq,
community_direct_str(entry->direct),
community_list_config_str(entry));
write++;
}
for (list = cm->str.head; list; list = list->next)
for (entry = list->head; entry; entry = entry->next) {
- vty_out(vty, "bgp community-list %s %s %s %s\n",
+ vty_out(vty,
+ "bgp community-list %s %s seq %" PRId64 " %s %s\n",
entry->style == COMMUNITY_LIST_STANDARD
? "standard"
: "expanded",
- list->name, community_direct_str(entry->direct),
+ list->name, entry->seq,
+ community_direct_str(entry->direct),
community_list_config_str(entry));
write++;
}
for (list = cm->num.head; list; list = list->next)
for (entry = list->head; entry; entry = entry->next) {
- vty_out(vty, "bgp extcommunity-list %s %s %s\n",
- list->name, community_direct_str(entry->direct),
+ vty_out(vty,
+ "bgp extcommunity-list %s seq %" PRId64 " %s %s\n",
+ list->name, entry->seq,
+ community_direct_str(entry->direct),
community_list_config_str(entry));
write++;
}
for (list = cm->str.head; list; list = list->next)
for (entry = list->head; entry; entry = entry->next) {
- vty_out(vty, "bgp extcommunity-list %s %s %s %s\n",
+ vty_out(vty,
+ "bgp extcommunity-list %s %s seq %" PRId64
+ " %s %s\n",
entry->style == EXTCOMMUNITY_LIST_STANDARD
? "standard"
: "expanded",
- list->name, community_direct_str(entry->direct),
+ list->name, entry->seq,
+ community_direct_str(entry->direct),
community_list_config_str(entry));
write++;
}
for (list = cm->num.head; list; list = list->next)
for (entry = list->head; entry; entry = entry->next) {
- vty_out(vty, "bgp large-community-list %s %s %s\n",
- list->name, community_direct_str(entry->direct),
+ vty_out(vty,
+ "bgp large-community-list %s seq %" PRId64
+ " %s %s\n",
+ list->name, entry->seq,
+ community_direct_str(entry->direct),
community_list_config_str(entry));
write++;
}
for (list = cm->str.head; list; list = list->next)
for (entry = list->head; entry; entry = entry->next) {
- vty_out(vty, "bgp large-community-list %s %s %s %s\n",
+ vty_out(vty,
+ "bgp large-community-list %s %s seq %" PRId64
+ " %s %s\n",
+
entry->style == LARGE_COMMUNITY_LIST_STANDARD
? "standard"
: "expanded",
- list->name, community_direct_str(entry->direct),
+ list->name, entry->seq, community_direct_str(entry->direct),
community_list_config_str(entry));
write++;
}
install_element(CONFIG_NODE, &bgp_lcommunity_list_expanded_cmd);
install_element(CONFIG_NODE, &bgp_lcommunity_list_name_standard_cmd);
install_element(CONFIG_NODE, &bgp_lcommunity_list_name_expanded_cmd);
- install_element(CONFIG_NODE, &no_bgp_lcommunity_list_standard_all_cmd);
+ install_element(CONFIG_NODE, &no_bgp_lcommunity_list_all_cmd);
+ install_element(CONFIG_NODE,
+ &no_bgp_lcommunity_list_name_standard_all_cmd);
install_element(CONFIG_NODE,
&no_bgp_lcommunity_list_name_expanded_all_cmd);
install_element(CONFIG_NODE, &no_bgp_lcommunity_list_standard_cmd);