const char *arg)
{
int ret;
+ bool found = false;
struct peer *peer;
struct listnode *node, *nnode;
/* Clear all neighbors. */
/*
* Pass along pointer to next node to peer_clear() when walking all
- * nodes
- * on the BGP instance as that may get freed if it is a doppelganger
+ * nodes on the BGP instance as that may get freed if it is a
+ * doppelganger
*/
if (sort == clear_all) {
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+ if (!peer->afc[afi][safi])
+ continue;
+
if (stype == BGP_CLEAR_SOFT_NONE)
ret = peer_clear(peer, &nnode);
- else if (peer->afc[afi][safi])
- ret = peer_clear_soft(peer, afi, safi, stype);
else
- ret = 0;
+ ret = peer_clear_soft(peer, afi, safi, stype);
if (ret < 0)
bgp_clear_vty_error(vty, peer, afi, safi, ret);
+ else
+ found = true;
}
/* This is to apply read-only mode on this clear. */
if (stype == BGP_CLEAR_SOFT_NONE)
bgp->update_delay_over = 0;
+ if (!found)
+ vty_out(vty, "%%BGP: No %s peer configured",
+ afi_safi_print(afi, safi));
+
return CMD_SUCCESS;
}
- /* Clear specified neighbors. */
+ /* Clear specified neighbor. */
if (sort == clear_peer) {
union sockunion su;
- int ret;
/* Make sockunion for lookup. */
ret = str2sockunion(arg, &su);
}
}
- if (stype == BGP_CLEAR_SOFT_NONE)
+ if (!peer->afc[afi][safi])
+ ret = BGP_ERR_AF_UNCONFIGURED;
+ else if (stype == BGP_CLEAR_SOFT_NONE)
ret = peer_clear(peer, NULL);
else
ret = peer_clear_soft(peer, afi, safi, stype);
return CMD_SUCCESS;
}
- /* Clear all peer-group members. */
+ /* Clear all neighbors belonging to a specific peer-group. */
if (sort == clear_group) {
struct peer_group *group;
}
for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
- if (stype == BGP_CLEAR_SOFT_NONE) {
- peer_clear(peer, NULL);
- continue;
- }
-
if (!peer->afc[afi][safi])
continue;
- ret = peer_clear_soft(peer, afi, safi, stype);
+ if (stype == BGP_CLEAR_SOFT_NONE)
+ ret = peer_clear(peer, NULL);
+ else
+ ret = peer_clear_soft(peer, afi, safi, stype);
if (ret < 0)
bgp_clear_vty_error(vty, peer, afi, safi, ret);
+ else
+ found = true;
}
+
+ if (!found)
+ vty_out(vty,
+ "%%BGP: No %s peer belonging to peer-group %s is configured\n",
+ afi_safi_print(afi, safi), arg);
+
return CMD_SUCCESS;
}
+ /* Clear all external (eBGP) neighbors. */
if (sort == clear_external) {
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (peer->sort == BGP_PEER_IBGP)
continue;
+ if (!peer->afc[afi][safi])
+ continue;
+
if (stype == BGP_CLEAR_SOFT_NONE)
ret = peer_clear(peer, &nnode);
else
if (ret < 0)
bgp_clear_vty_error(vty, peer, afi, safi, ret);
+ else
+ found = true;
}
+
+ if (!found)
+ vty_out(vty,
+ "%%BGP: No external %s peer is configured\n",
+ afi_safi_print(afi, safi));
+
return CMD_SUCCESS;
}
+ /* Clear all neighbors belonging to a specific AS. */
if (sort == clear_as) {
- as_t as;
- int find = 0;
-
- as = strtoul(arg, NULL, 10);
+ as_t as = strtoul(arg, NULL, 10);
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
if (peer->as != as)
continue;
- find = 1;
- if (stype == BGP_CLEAR_SOFT_NONE)
+ if (!peer->afc[afi][safi])
+ ret = BGP_ERR_AF_UNCONFIGURED;
+ else if (stype == BGP_CLEAR_SOFT_NONE)
ret = peer_clear(peer, &nnode);
else
ret = peer_clear_soft(peer, afi, safi, stype);
if (ret < 0)
bgp_clear_vty_error(vty, peer, afi, safi, ret);
+ else
+ found = true;
}
- if (!find)
+
+ if (!found)
vty_out(vty,
- "%%BGP: No peer is configured with AS %s\n",
- arg);
+ "%%BGP: No %s peer is configured with AS %s\n",
+ afi_safi_print(afi, safi), arg);
+
return CMD_SUCCESS;
}
#endif
/* BGP global configuration. */
-
-DEFUN (bgp_multiple_instance_func,
- bgp_multiple_instance_cmd,
- "bgp multiple-instance",
- BGP_STR
- "Enable bgp multiple instance\n")
+#if defined(VERSION_TYPE_DEV) && (CONFDATE > 20190601)
+CPP_NOTICE("bgpd: time to remove deprecated bgp multiple-instance")
+CPP_NOTICE("This includes BGP_OPT_MULTIPLE_INSTANCE")
+#endif
+DEFUN_HIDDEN (bgp_multiple_instance_func,
+ bgp_multiple_instance_cmd,
+ "bgp multiple-instance",
+ BGP_STR
+ "Enable bgp multiple instance\n")
{
bgp_option_set(BGP_OPT_MULTIPLE_INSTANCE);
return CMD_SUCCESS;
}
-DEFUN (no_bgp_multiple_instance,
+DEFUN_HIDDEN (no_bgp_multiple_instance,
no_bgp_multiple_instance_cmd,
"no bgp multiple-instance",
NO_STR
{
int ret;
+ vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
+ vty_out(vty, "if you are using this please let the developers know\n");
+ zlog_warn("Deprecated option: `bgp multiple-instance` being used");
ret = bgp_option_unset(BGP_OPT_MULTIPLE_INSTANCE);
if (ret < 0) {
vty_out(vty, "%% There are more than two BGP instances\n");
return CMD_SUCCESS;
}
-DEFUN (bgp_config_type,
- bgp_config_type_cmd,
- "bgp config-type <cisco|zebra>",
- BGP_STR
- "Configuration type\n"
- "cisco\n"
- "zebra\n")
+#if defined(VERSION_TYPE_DEV) && (CONFDATE > 20190601)
+CPP_NOTICE("bgpd: time to remove deprecated cli bgp config-type cisco")
+CPP_NOTICE("This includes BGP_OPT_CISCO_CONFIG")
+#endif
+DEFUN_HIDDEN (bgp_config_type,
+ bgp_config_type_cmd,
+ "bgp config-type <cisco|zebra>",
+ BGP_STR
+ "Configuration type\n"
+ "cisco\n"
+ "zebra\n")
{
int idx = 0;
- if (argv_find(argv, argc, "cisco", &idx))
+ if (argv_find(argv, argc, "cisco", &idx)) {
+ vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
+ vty_out(vty, "if you are using this please let the developers know!\n");
+ zlog_warn("Deprecated option: `bgp config-type cisco` being used");
bgp_option_set(BGP_OPT_CONFIG_CISCO);
- else
+ } else
bgp_option_unset(BGP_OPT_CONFIG_CISCO);
return CMD_SUCCESS;
}
-DEFUN (no_bgp_config_type,
- no_bgp_config_type_cmd,
- "no bgp config-type [<cisco|zebra>]",
- NO_STR
- BGP_STR
- "Display configuration type\n"
- "cisco\n"
- "zebra\n")
+DEFUN_HIDDEN (no_bgp_config_type,
+ no_bgp_config_type_cmd,
+ "no bgp config-type [<cisco|zebra>]",
+ NO_STR
+ BGP_STR
+ "Display configuration type\n"
+ "cisco\n"
+ "zebra\n")
{
bgp_option_unset(BGP_OPT_CONFIG_CISCO);
return CMD_SUCCESS;
}
/* "bgp enforce-first-as" configuration. */
-DEFUN (bgp_enforce_first_as,
+#if defined(VERSION_TYPE_DEV) && CONFDATE > 20180517
+CPP_NOTICE("bgpd: remove deprecated '[no] bgp enforce-first-as' commands")
+#endif
+
+DEFUN_DEPRECATED (bgp_enforce_first_as,
bgp_enforce_first_as_cmd,
"bgp enforce-first-as",
BGP_STR
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_set(bgp, BGP_FLAG_ENFORCE_FIRST_AS);
- bgp_clear_star_soft_in(vty, bgp->name);
return CMD_SUCCESS;
}
-DEFUN (no_bgp_enforce_first_as,
+DEFUN_DEPRECATED (no_bgp_enforce_first_as,
no_bgp_enforce_first_as_cmd,
"no bgp enforce-first-as",
NO_STR
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
bgp_flag_unset(bgp, BGP_FLAG_ENFORCE_FIRST_AS);
- bgp_clear_star_soft_in(vty, bgp->name);
return CMD_SUCCESS;
}
"Peer-group name\n")
static int peer_flag_modify_vty(struct vty *vty, const char *ip_str,
- uint16_t flag, int set)
+ uint32_t flag, int set)
{
int ret;
struct peer *peer;
return bgp_vty_return(vty, ret);
}
-static int peer_flag_set_vty(struct vty *vty, const char *ip_str, uint16_t flag)
+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,
- uint16_t flag)
+ uint32_t flag)
{
return peer_flag_modify_vty(vty, ip_str, flag, 0);
}
"Send Community attribute to this neighbor\n")
{
int idx_peer = 1;
+
return peer_af_flag_set_vty(vty, argv[idx_peer]->arg, bgp_node_afi(vty),
bgp_node_safi(vty),
PEER_FLAG_SEND_COMMUNITY);
"Send Community attribute to this neighbor\n")
{
int idx_peer = 2;
+
return peer_af_flag_unset_vty(vty, argv[idx_peer]->arg,
bgp_node_afi(vty), bgp_node_safi(vty),
PEER_FLAG_SEND_COMMUNITY);
"Send Standard Community attributes\n"
"Send Large Community attributes\n")
{
- int idx = 0;
+ int idx_peer = 1;
uint32_t flag = 0;
+ const char *type = argv[argc - 1]->text;
- char *peer = argv[1]->arg;
-
- if (argv_find(argv, argc, "standard", &idx))
+ if (strmatch(type, "standard")) {
SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY);
- else if (argv_find(argv, argc, "extended", &idx))
+ } else if (strmatch(type, "extended")) {
SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
- else if (argv_find(argv, argc, "large", &idx))
+ } else if (strmatch(type, "large")) {
SET_FLAG(flag, PEER_FLAG_SEND_LARGE_COMMUNITY);
- else if (argv_find(argv, argc, "both", &idx)) {
+ } else if (strmatch(type, "both")) {
SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
- } else {
+ } else { /* if (strmatch(type, "all")) */
SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_LARGE_COMMUNITY);
}
- return peer_af_flag_set_vty(vty, peer, bgp_node_afi(vty),
+ return peer_af_flag_set_vty(vty, argv[idx_peer]->arg, bgp_node_afi(vty),
bgp_node_safi(vty), flag);
}
"Send Large Community attributes\n")
{
int idx_peer = 2;
-
+ uint32_t flag = 0;
const char *type = argv[argc - 1]->text;
- if (strmatch(type, "standard"))
- return peer_af_flag_unset_vty(
- vty, argv[idx_peer]->arg, bgp_node_afi(vty),
- bgp_node_safi(vty), PEER_FLAG_SEND_COMMUNITY);
- if (strmatch(type, "extended"))
- return peer_af_flag_unset_vty(
- vty, argv[idx_peer]->arg, bgp_node_afi(vty),
- bgp_node_safi(vty), PEER_FLAG_SEND_EXT_COMMUNITY);
- if (strmatch(type, "large"))
- return peer_af_flag_unset_vty(
- vty, argv[idx_peer]->arg, bgp_node_afi(vty),
- bgp_node_safi(vty), PEER_FLAG_SEND_LARGE_COMMUNITY);
- if (strmatch(type, "both"))
- return peer_af_flag_unset_vty(
- vty, argv[idx_peer]->arg, bgp_node_afi(vty),
- bgp_node_safi(vty),
- PEER_FLAG_SEND_COMMUNITY
- | PEER_FLAG_SEND_EXT_COMMUNITY);
-
- /* if (strmatch (type, "all")) */
- return peer_af_flag_unset_vty(
- vty, argv[idx_peer]->arg, bgp_node_afi(vty), bgp_node_safi(vty),
- (PEER_FLAG_SEND_COMMUNITY | PEER_FLAG_SEND_EXT_COMMUNITY
- | PEER_FLAG_SEND_LARGE_COMMUNITY));
+ if (strmatch(type, "standard")) {
+ SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY);
+ } else if (strmatch(type, "extended")) {
+ SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
+ } else if (strmatch(type, "large")) {
+ SET_FLAG(flag, PEER_FLAG_SEND_LARGE_COMMUNITY);
+ } else if (strmatch(type, "both")) {
+ SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY);
+ SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
+ } else { /* if (strmatch(type, "all")) */
+ SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY);
+ SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
+ SET_FLAG(flag, PEER_FLAG_SEND_LARGE_COMMUNITY);
+ }
+
+ return peer_af_flag_unset_vty(vty, argv[idx_peer]->arg,
+ bgp_node_afi(vty), bgp_node_safi(vty),
+ flag);
}
ALIAS_HIDDEN(
PEER_FLAG_DISABLE_CONNECTED_CHECK);
}
+
+/* enforce-first-as */
+DEFUN (neighbor_enforce_first_as,
+ neighbor_enforce_first_as_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD> enforce-first-as",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Enforce the first AS for EBGP routes\n")
+{
+ int idx_peer = 1;
+
+ return peer_flag_set_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_ENFORCE_FIRST_AS);
+}
+
+DEFUN (no_neighbor_enforce_first_as,
+ no_neighbor_enforce_first_as_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD> enforce-first-as",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Enforce the first AS for EBGP routes\n")
+{
+ int idx_peer = 2;
+
+ return peer_flag_unset_vty(vty, argv[idx_peer]->arg,
+ PEER_FLAG_ENFORCE_FIRST_AS);
+}
+
+
DEFUN (neighbor_description,
neighbor_description_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> description LINE...",
const char *direct_str)
{
int ret;
- struct peer *peer;
int direct = FILTER_IN;
+ struct peer *peer;
peer = peer_and_group_lookup_vty(vty, ip_str);
if (!peer)
return CMD_SUCCESS;
}
-static int vpn_policy_getafi(struct vty *vty, int *doafi)
+/*
+ * v2vimport is true if we are handling a `import vrf ...` command
+ */
+static afi_t vpn_policy_getafi(struct vty *vty, struct bgp *bgp, bool v2vimport)
{
+ afi_t afi;
+
switch (vty->node) {
case BGP_IPV4_NODE:
- doafi[AFI_IP] = 1;
+ afi = AFI_IP;
break;
case BGP_IPV6_NODE:
- doafi[AFI_IP6] = 1;
+ afi = AFI_IP6;
break;
default:
vty_out(vty,
"%% context error: valid only in address-family <ipv4|ipv6> unicast block\n");
- return CMD_WARNING_CONFIG_FAILED;
+ return AFI_MAX;
}
- return CMD_SUCCESS;
+
+ if (!v2vimport) {
+ 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)) {
+ vty_out(vty,
+ "%% error: Please unconfigure import vrf commands before using vpn commands\n");
+ return AFI_MAX;
+ }
+ } else {
+ if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+ BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
+ || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+ BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) {
+ vty_out(vty,
+ "%% error: Please unconfigure vpn to vrf commands before using import vrf commands\n");
+ return AFI_MAX;
+ }
+ }
+ return afi;
}
DEFPY (af_rd_vpn_export,
VTY_DECLVAR_CONTEXT(bgp, bgp);
struct prefix_rd prd;
int ret;
- int doafi[AFI_MAX] = {0};
afi_t afi;
int idx = 0;
int yes = 1;
}
}
- ret = vpn_policy_getafi(vty, doafi);
- if (ret != CMD_SUCCESS)
- return ret;
-
-
- for (afi = 0; afi < AFI_MAX; ++afi) {
- if (!doafi[afi])
- continue;
-
- /* pre-change: un-export vpn routes (vpn->vrf routes unaffected)
- */
- vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
- bgp_get_default(), bgp);
+ afi = vpn_policy_getafi(vty, bgp, false);
+ if (afi == AFI_MAX)
+ return CMD_WARNING_CONFIG_FAILED;
- if (yes) {
- bgp->vpn_policy[afi].tovpn_rd = prd;
- SET_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_RD_SET);
- } else {
- UNSET_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_RD_SET);
- }
+ /*
+ * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
+ */
+ vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
+ bgp_get_default(), bgp);
- /* post-change: re-export vpn routes */
- vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
- bgp_get_default(), bgp);
+ if (yes) {
+ bgp->vpn_policy[afi].tovpn_rd = prd;
+ SET_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_RD_SET);
+ } else {
+ UNSET_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_RD_SET);
}
+ /* post-change: re-export vpn routes */
+ vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
+ bgp_get_default(), bgp);
+
return CMD_SUCCESS;
}
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
mpls_label_t label = MPLS_LABEL_NONE;
- int doafi[AFI_MAX] = {0};
afi_t afi;
- int ret;
int idx = 0;
int yes = 1;
if (argv_find(argv, argc, "no", &idx))
yes = 0;
+ /* If "no ...", squash trailing parameter */
+ if (!yes)
+ label_auto = NULL;
+
if (yes) {
if (!label_auto)
label = label_val; /* parser should force unsigned */
}
- ret = vpn_policy_getafi(vty, doafi);
- if (ret != CMD_SUCCESS)
- return ret;
+ afi = vpn_policy_getafi(vty, bgp, false);
+ if (afi == AFI_MAX)
+ return CMD_WARNING_CONFIG_FAILED;
- for (afi = 0; afi < AFI_MAX; ++afi) {
- if (!doafi[afi])
- continue;
- if (label_auto && CHECK_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_LABEL_AUTO))
+ if (label_auto && CHECK_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_AUTO))
+ /* no change */
+ return CMD_SUCCESS;
- continue; /* no change */
+ /*
+ * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
+ */
+ vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
+ bgp_get_default(), bgp);
- /*
- * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
- */
- vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
- bgp_get_default(), bgp);
-
- if (!label_auto && CHECK_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
-
- if (bgp->vpn_policy[afi].tovpn_label !=
- MPLS_LABEL_NONE) {
-
- /*
- * label has previously been automatically
- * assigned by labelpool: release it
- *
- * NB if tovpn_label == MPLS_LABEL_NONE it
- * means the automatic assignment is in flight
- * and therefore the labelpool callback must
- * detect that the auto label is not needed.
- */
-
- bgp_lp_release(LP_TYPE_VRF,
- &bgp->vpn_policy[afi],
- bgp->vpn_policy[afi].tovpn_label);
- }
- UNSET_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_LABEL_AUTO);
- }
+ if (!label_auto && CHECK_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) {
+
+ if (bgp->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE) {
- bgp->vpn_policy[afi].tovpn_label = label;
- if (label_auto) {
- SET_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_LABEL_AUTO);
- bgp_lp_get(LP_TYPE_VRF, &bgp->vpn_policy[afi],
- vpn_leak_label_callback);
+ /*
+ * label has previously been automatically
+ * assigned by labelpool: release it
+ *
+ * NB if tovpn_label == MPLS_LABEL_NONE it
+ * means the automatic assignment is in flight
+ * and therefore the labelpool callback must
+ * detect that the auto label is not needed.
+ */
+
+ bgp_lp_release(LP_TYPE_VRF,
+ &bgp->vpn_policy[afi],
+ bgp->vpn_policy[afi].tovpn_label);
}
+ UNSET_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_AUTO);
+ }
- /* post-change: re-export vpn routes */
- vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
- bgp_get_default(), bgp);
+ bgp->vpn_policy[afi].tovpn_label = label;
+ if (label_auto) {
+ SET_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_LABEL_AUTO);
+ bgp_lp_get(LP_TYPE_VRF, &bgp->vpn_policy[afi],
+ vpn_leak_label_callback);
}
+ /* post-change: re-export vpn routes */
+ vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
+ bgp_get_default(), bgp);
+
return CMD_SUCCESS;
}
"IPv6 prefix\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
- int doafi[AFI_MAX] = {0};
afi_t afi;
- int ret;
struct prefix p;
int idx = 0;
int yes = 1;
return CMD_WARNING_CONFIG_FAILED;
}
- ret = vpn_policy_getafi(vty, doafi);
- if (ret != CMD_SUCCESS)
- return ret;
-
- for (afi = 0; afi < AFI_MAX; ++afi) {
- if (!doafi[afi])
- continue;
-
- /*
- * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
- */
- vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
- bgp_get_default(), bgp);
+ afi = vpn_policy_getafi(vty, bgp, false);
+ if (afi == AFI_MAX)
+ return CMD_WARNING_CONFIG_FAILED;
- if (yes) {
- bgp->vpn_policy[afi].tovpn_nexthop = p;
- SET_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_NEXTHOP_SET);
- } else {
- UNSET_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_NEXTHOP_SET);
- }
+ /*
+ * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
+ */
+ vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
+ bgp_get_default(), bgp);
- /* post-change: re-export vpn routes */
- vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
- bgp_get_default(), bgp);
+ if (yes) {
+ bgp->vpn_policy[afi].tovpn_nexthop = p;
+ SET_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_NEXTHOP_SET);
+ } else {
+ UNSET_FLAG(bgp->vpn_policy[afi].flags,
+ BGP_VPN_POLICY_TOVPN_NEXTHOP_SET);
}
+ /* post-change: re-export vpn routes */
+ vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
+ bgp_get_default(), bgp);
+
return CMD_SUCCESS;
}
int ret;
struct ecommunity *ecom = NULL;
int dodir[BGP_VPN_POLICY_DIR_MAX] = {0};
- int doafi[AFI_MAX] = {0};
vpn_policy_direction_t dir;
afi_t afi;
int idx = 0;
if (argv_find(argv, argc, "no", &idx))
yes = 0;
- ret = vpn_policy_getafi(vty, doafi);
- if (ret != CMD_SUCCESS)
- return ret;
+ afi = vpn_policy_getafi(vty, bgp, false);
+ if (afi == AFI_MAX)
+ return CMD_WARNING_CONFIG_FAILED;
ret = vpn_policy_getdirs(vty, direction_str, dodir);
if (ret != CMD_SUCCESS)
}
}
- for (afi = 0; afi < AFI_MAX; ++afi) {
- if (!doafi[afi])
+ for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
+ if (!dodir[dir])
continue;
- for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
- if (!dodir[dir])
- continue;
-
- vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
- if (yes) {
- if (bgp->vpn_policy[afi].rtlist[dir])
- ecommunity_free(
- &bgp->vpn_policy[afi].rtlist[dir]);
- bgp->vpn_policy[afi].rtlist[dir] =
- ecommunity_dup(ecom);
- } else {
- if (bgp->vpn_policy[afi].rtlist[dir])
- ecommunity_free(
- &bgp->vpn_policy[afi].rtlist[dir]);
- bgp->vpn_policy[afi].rtlist[dir] = NULL;
- }
+ vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
- vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
+ if (yes) {
+ if (bgp->vpn_policy[afi].rtlist[dir])
+ ecommunity_free(
+ &bgp->vpn_policy[afi].rtlist[dir]);
+ bgp->vpn_policy[afi].rtlist[dir] =
+ ecommunity_dup(ecom);
+ } else {
+ if (bgp->vpn_policy[afi].rtlist[dir])
+ ecommunity_free(
+ &bgp->vpn_policy[afi].rtlist[dir]);
+ bgp->vpn_policy[afi].rtlist[dir] = NULL;
}
+
+ vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
}
+
if (ecom)
ecommunity_free(&ecom);
VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
int dodir[BGP_VPN_POLICY_DIR_MAX] = {0};
- int doafi[AFI_MAX] = {0};
vpn_policy_direction_t dir;
afi_t afi;
int idx = 0;
if (argv_find(argv, argc, "no", &idx))
yes = 0;
- ret = vpn_policy_getafi(vty, doafi);
- if (ret != CMD_SUCCESS)
- return ret;
+ afi = vpn_policy_getafi(vty, bgp, false);
+ if (afi == AFI_MAX)
+ return CMD_WARNING_CONFIG_FAILED;
ret = vpn_policy_getdirs(vty, direction_str, dodir);
if (ret != CMD_SUCCESS)
return ret;
- for (afi = 0; afi < AFI_MAX; ++afi) {
- if (!doafi[afi])
+ for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
+ if (!dodir[dir])
continue;
- for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
- if (!dodir[dir])
- continue;
- vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
+ vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
- if (yes) {
- if (bgp->vpn_policy[afi].rmap_name[dir])
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp->vpn_policy[afi].rmap_name[dir]);
- bgp->vpn_policy[afi].rmap_name[dir] = XSTRDUP(
- MTYPE_ROUTE_MAP_NAME, rmap_str);
- bgp->vpn_policy[afi].rmap[dir] =
- route_map_lookup_by_name(rmap_str);
- } else {
- if (bgp->vpn_policy[afi].rmap_name[dir])
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp->vpn_policy[afi].rmap_name[dir]);
- bgp->vpn_policy[afi].rmap_name[dir] = NULL;
- bgp->vpn_policy[afi].rmap[dir] = NULL;
- }
-
- vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
+ if (yes) {
+ if (bgp->vpn_policy[afi].rmap_name[dir])
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp->vpn_policy[afi].rmap_name[dir]);
+ bgp->vpn_policy[afi].rmap_name[dir] = XSTRDUP(
+ MTYPE_ROUTE_MAP_NAME, rmap_str);
+ bgp->vpn_policy[afi].rmap[dir] =
+ route_map_lookup_by_name(rmap_str);
+ if (!bgp->vpn_policy[afi].rmap[dir])
+ return CMD_SUCCESS;
+ } else {
+ if (bgp->vpn_policy[afi].rmap_name[dir])
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp->vpn_policy[afi].rmap_name[dir]);
+ bgp->vpn_policy[afi].rmap_name[dir] = NULL;
+ bgp->vpn_policy[afi].rmap[dir] = NULL;
}
+
+ vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
}
return CMD_SUCCESS;
"For routes leaked from vpn to current address-family\n"
"For routes leaked from current address-family to vpn\n")
+DEFPY(af_import_vrf_route_map, af_import_vrf_route_map_cmd,
+ "[no] import vrf route-map RMAP$rmap_str",
+ NO_STR
+ "Import routes from another VRF\n"
+ "Vrf routes being filtered\n"
+ "Specify route map\n"
+ "name of route-map\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ vpn_policy_direction_t dir = BGP_VPN_POLICY_DIR_FROMVPN;
+ afi_t afi;
+ int idx = 0;
+ int yes = 1;
+ struct bgp *bgp_default;
+
+ if (argv_find(argv, argc, "no", &idx))
+ yes = 0;
+
+ afi = vpn_policy_getafi(vty, bgp, true);
+ if (afi == AFI_MAX)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ bgp_default = bgp_get_default();
+ if (!bgp_default) {
+ int32_t ret;
+ as_t as = bgp->as;
+
+ /* Auto-create assuming the same AS */
+ ret = bgp_get(&bgp_default, &as, NULL,
+ BGP_INSTANCE_TYPE_DEFAULT);
+
+ if (ret) {
+ vty_out(vty,
+ "VRF default is not configured as a bgp instance\n");
+ return CMD_WARNING;
+ }
+ }
+
+ vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
+
+ if (yes) {
+ if (bgp->vpn_policy[afi].rmap_name[dir])
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp->vpn_policy[afi].rmap_name[dir]);
+ bgp->vpn_policy[afi].rmap_name[dir] =
+ XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
+ bgp->vpn_policy[afi].rmap[dir] =
+ route_map_lookup_by_name(rmap_str);
+ if (!bgp->vpn_policy[afi].rmap[dir])
+ return CMD_SUCCESS;
+ } else {
+ if (bgp->vpn_policy[afi].rmap_name[dir])
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp->vpn_policy[afi].rmap_name[dir]);
+ bgp->vpn_policy[afi].rmap_name[dir] = NULL;
+ bgp->vpn_policy[afi].rmap[dir] = NULL;
+ }
+
+ vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
+
+ return CMD_SUCCESS;
+}
+
+ALIAS(af_import_vrf_route_map, af_no_import_vrf_route_map_cmd,
+ "no import vrf route-map",
+ NO_STR
+ "Import routes from another VRF\n"
+ "Vrf routes being filtered\n"
+ "Specify route map\n")
+
DEFPY (bgp_imexport_vrf,
bgp_imexport_vrf_cmd,
"[no] import vrf NAME$import_name",
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
struct listnode *node;
- struct bgp *vrf_bgp;
+ struct bgp *vrf_bgp, *bgp_default;
+ int32_t ret = 0;
+ as_t as = bgp->as;
bool remove = false;
int32_t idx = 0;
char *vname;
- const char *export_name;
+ enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF;
safi_t safi;
afi_t afi;
if (argv_find(argv, argc, "no", &idx))
remove = true;
- afi = bgp_node_afi(vty);
+ afi = vpn_policy_getafi(vty, bgp, true);
+ if (afi == AFI_MAX)
+ return CMD_WARNING_CONFIG_FAILED;
+
safi = bgp_node_safi(vty);
- vrf_bgp = bgp_lookup_by_name(import_name);
- if (!vrf_bgp) {
- int32_t ret;
- as_t as = bgp->as;
+ if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type)
+ && (strcmp(import_name, BGP_DEFAULT_NAME) == 0))
+ || (bgp->name && (strcmp(import_name, bgp->name) == 0))) {
+ vty_out(vty, "%% Cannot %s vrf %s into itself\n",
+ remove ? "unimport" : "import", import_name);
+ return CMD_WARNING;
+ }
+ bgp_default = bgp_get_default();
+ if (!bgp_default) {
/* Auto-create assuming the same AS */
- ret = bgp_get(&vrf_bgp, &as, import_name,
- BGP_INSTANCE_TYPE_VRF);
+ ret = bgp_get(&bgp_default, &as, NULL,
+ BGP_INSTANCE_TYPE_DEFAULT);
+
if (ret) {
- vty_out(vty, "VRF %s is not configured as a bgp instance\n",
- import_name);
+ vty_out(vty,
+ "VRF default is not configured as a bgp instance\n");
return CMD_WARNING;
}
}
- export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
-
- if (remove) {
- for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node,
- vname)) {
- if (strcmp(vname, import_name) == 0)
- break;
- }
+ vrf_bgp = bgp_lookup_by_name(import_name);
+ if (!vrf_bgp) {
+ if (strcmp(import_name, BGP_DEFAULT_NAME) == 0)
+ vrf_bgp = bgp_default;
+ else
+ /* Auto-create assuming the same AS */
+ ret = bgp_get(&vrf_bgp, &as, import_name, bgp_type);
- if (!vname) {
+ if (ret) {
vty_out(vty,
- "Specified VRF %s was not imported, ignoring",
+ "VRF %s is not configured as a bgp instance\n",
import_name);
return CMD_WARNING;
}
+ }
- listnode_delete(bgp->vpn_policy[afi].import_vrf, vname);
- XFREE(MTYPE_TMP, vname);
-
- if (bgp->vpn_policy[afi].import_vrf->count == 0) {
- UNSET_FLAG(bgp->af_flags[afi][safi],
- BGP_CONFIG_VRF_TO_VRF_IMPORT);
-
- ecommunity_free(
- &bgp->vpn_policy[afi]
- .rtlist[BGP_VPN_POLICY_DIR_FROMVPN]);
- }
-
- for (ALL_LIST_ELEMENTS_RO(vrf_bgp->vpn_policy[afi].export_vrf,
- node, vname)) {
- if (strcmp(vname, export_name) == 0)
- break;
- }
-
- listnode_delete(vrf_bgp->vpn_policy[afi].export_vrf, vname);
- XFREE(MTYPE_TMP, vname);
-
- UNSET_FLAG(vrf_bgp->af_flags[afi][safi],
- BGP_CONFIG_VRF_TO_VRF_EXPORT);
- UNSET_FLAG(vrf_bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_RD_SET);
-
- ecommunity_free(&vrf_bgp->vpn_policy[afi]
- .rtlist[BGP_VPN_POLICY_DIR_TOVPN]);
- vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp, vrf_bgp);
+ if (remove) {
+ vrf_unimport_from_vrf(bgp, vrf_bgp, afi, safi);
} else {
- char buf[1000];
-
+ /* Already importing from "import_vrf"? */
for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node,
vname)) {
if (strcmp(vname, import_name) == 0)
return CMD_WARNING;
}
- vname = XSTRDUP(MTYPE_TMP, import_name);
- listnode_add(bgp->vpn_policy[afi].import_vrf, vname);
-
- vname = XSTRDUP(MTYPE_TMP, export_name);
- listnode_add(vrf_bgp->vpn_policy[afi].export_vrf, vname);
-
- prefix_rd2str(&vrf_bgp->vrf_prd, buf, sizeof(buf));
- vrf_bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_TOVPN] =
- ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
- bgp->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN] =
- ecommunity_str2com(buf, ECOMMUNITY_ROUTE_TARGET, 0);
-
- SET_FLAG(bgp->af_flags[afi][safi],
- BGP_CONFIG_VRF_TO_VRF_IMPORT);
- SET_FLAG(vrf_bgp->af_flags[afi][safi],
- BGP_CONFIG_VRF_TO_VRF_EXPORT);
- SET_FLAG(vrf_bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_RD_SET);
- vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp,
- vrf_bgp);
+ vrf_import_from_vrf(bgp, vrf_bgp, afi, safi);
}
return CMD_SUCCESS;
VTY_DECLVAR_CONTEXT(bgp, bgp);
int ret;
struct ecommunity *ecom = NULL;
- int doafi[AFI_MAX] = {0};
afi_t afi;
int idx = 0;
int yes = 1;
if (argv_find(argv, argc, "no", &idx))
yes = 0;
- ret = vpn_policy_getafi(vty, doafi);
- if (ret != CMD_SUCCESS)
- return ret;
+ afi = vpn_policy_getafi(vty, bgp, false);
+ if (afi == AFI_MAX)
+ return CMD_WARNING_CONFIG_FAILED;
+
if (yes) {
if (!argv_find(argv, argc, "RTLIST", &idx)) {
vty_out(vty, "%% Missing RTLIST\n");
if (ret != CMD_SUCCESS)
return ret;
}
- for (afi = 0; afi < AFI_MAX; ++afi) {
- if (!doafi[afi])
- continue;
- if (yes) {
- if (bgp->vpn_policy[afi].import_redirect_rtlist)
- ecommunity_free(
- &bgp->vpn_policy[afi]
+
+ if (yes) {
+ if (bgp->vpn_policy[afi].import_redirect_rtlist)
+ ecommunity_free(&bgp->vpn_policy[afi]
.import_redirect_rtlist);
- bgp->vpn_policy[afi].import_redirect_rtlist =
- ecommunity_dup(ecom);
- } else {
- if (bgp->vpn_policy[afi].import_redirect_rtlist)
- ecommunity_free(
- &bgp->vpn_policy[afi]
+ bgp->vpn_policy[afi].import_redirect_rtlist =
+ ecommunity_dup(ecom);
+ } else {
+ if (bgp->vpn_policy[afi].import_redirect_rtlist)
+ ecommunity_free(&bgp->vpn_policy[afi]
.import_redirect_rtlist);
- bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
- }
+ bgp->vpn_policy[afi].import_redirect_rtlist = NULL;
}
+
if (ecom)
ecommunity_free(&ecom);
BGP_UPTIME_LEN, 0, NULL));
if (peer->status == Established)
- if (peer->afc_recv[afi][pfx_rcd_safi])
+ if (peer->afc_recv[afi][safi])
vty_out(vty, " %12ld",
peer->pcount[afi]
[pfx_rcd_safi]);
if (count)
vty_out(vty, "\nTotal number of neighbors %d\n", count);
else {
- if (use_json)
- vty_out(vty,
- "{\"error\": {\"message\": \"No %s neighbor configured\"}}\n",
- afi_safi_print(afi, safi));
- else
- vty_out(vty, "No %s neighbor is configured\n",
- afi_safi_print(afi, safi));
+ vty_out(vty, "No %s neighbor is configured\n",
+ afi_safi_print(afi, safi));
}
- if (dn_count && !use_json) {
+ if (dn_count) {
vty_out(vty, "* - dynamic neighbor\n");
vty_out(vty, "%d dynamic neighbor(s), limit %d\n",
dn_count, bgp->dynamic_neighbors_limit);
if (use_json)
json_object_boolean_true_add(json, "bgpNoSuchNeighbor");
else
- vty_out(vty, "%% No such neighbor\n");
+ vty_out(vty, "%% No such neighbor in this view/vrf\n");
}
if (use_json) {
lcom = (struct lcommunity *)backet->data;
vty_out(vty, "[%p] (%ld) %s\n", (void *)lcom, lcom->refcnt,
- lcommunity_str(lcom));
+ lcommunity_str(lcom, false));
}
/* Show BGP's community internal data. */
return CMD_SUCCESS;
}
+static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
+ afi_t afi, safi_t safi)
+{
+ struct bgp *bgp;
+ struct listnode *node;
+ char *vname;
+ char buf1[INET6_ADDRSTRLEN];
+ char *ecom_str;
+ vpn_policy_direction_t dir;
+
+ if (name) {
+ bgp = bgp_lookup_by_name(name);
+ if (!bgp) {
+ vty_out(vty, "%% No such BGP instance exist\n");
+ return CMD_WARNING;
+ }
+ } else {
+ bgp = bgp_get_default();
+ if (!bgp) {
+ vty_out(vty,
+ "%% Default BGP instance does not exist\n");
+ return CMD_WARNING;
+ }
+ }
+
+ if (!CHECK_FLAG(bgp->af_flags[afi][safi],
+ BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
+ vty_out(vty,
+ "This VRF is not importing %s routes from any other VRF\n",
+ afi_safi_print(afi, safi));
+ } else {
+ vty_out(vty,
+ "This VRF is importing %s routes from the following VRFs:\n",
+ afi_safi_print(afi, safi));
+ for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node,
+ vname)) {
+ vty_out(vty, " %s\n", vname);
+ }
+ dir = BGP_VPN_POLICY_DIR_FROMVPN;
+ ecom_str = ecommunity_ecom2str(
+ bgp->vpn_policy[afi].rtlist[dir],
+ ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+ vty_out(vty, "Import RT(s): %s\n", ecom_str);
+ XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ }
+
+ if (!CHECK_FLAG(bgp->af_flags[afi][safi],
+ BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
+ vty_out(vty,
+ "This VRF is not exporting %s routes to any other VRF\n",
+ afi_safi_print(afi, safi));
+ } else {
+ vty_out(vty,
+ "This VRF is exporting %s routes to the following VRFs:\n",
+ afi_safi_print(afi, safi));
+ for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].export_vrf, node,
+ vname)) {
+ vty_out(vty, " %s\n", vname);
+ }
+ vty_out(vty, "RD: %s\n",
+ prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd,
+ buf1, RD_ADDRSTRLEN));
+ dir = BGP_VPN_POLICY_DIR_TOVPN;
+ ecom_str = ecommunity_ecom2str(
+ bgp->vpn_policy[afi].rtlist[dir],
+ ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+ vty_out(vty, "Emport RT: %s\n", ecom_str);
+ XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+ }
+
+ return CMD_SUCCESS;
+}
+
+/* "show [ip] bgp route-leak" command. */
+DEFUN (show_ip_bgp_route_leak,
+ show_ip_bgp_route_leak_cmd,
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] route-leak",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ BGP_INSTANCE_HELP_STR
+ BGP_AFI_HELP_STR
+ BGP_SAFI_HELP_STR
+ "Route leaking information\n")
+{
+ char *vrf = NULL;
+ afi_t afi = AFI_MAX;
+ safi_t safi = SAFI_MAX;
+
+ int idx = 0;
+
+ /* show [ip] bgp */
+ if (argv_find(argv, argc, "ip", &idx)) {
+ afi = AFI_IP;
+ safi = SAFI_UNICAST;
+ }
+ /* [vrf VIEWVRFNAME] */
+ if (argv_find(argv, argc, "view", &idx)) {
+ vty_out(vty,
+ "%% This command is not applicable to BGP views\n");
+ return CMD_WARNING;
+ }
+
+ if (argv_find(argv, argc, "vrf", &idx))
+ vrf = argv[++idx]->arg;
+ /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
+ if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
+ argv_find_and_parse_safi(argv, argc, &idx, &safi);
+ }
+
+ if (!((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)) {
+ vty_out(vty,
+ "%% This command is applicable only for unicast ipv4|ipv6\n");
+ return CMD_WARNING;
+ }
+
+ return bgp_show_route_leak_vty(vty, vrf, afi, safi);
+}
+
static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi,
safi_t safi)
{
{
int indent = 2;
+ if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN])
+ vty_out(vty, "%*simport vrf route-map %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],
XFREE(MTYPE_ECOMMUNITY_STR, b);
}
}
- if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]) {
- vty_out(vty, "%*sroute-map vpn import %s\n", indent, "",
- bgp->vpn_policy[afi]
- .rmap_name[BGP_VPN_POLICY_DIR_FROMVPN]);
- }
- if (bgp->vpn_policy[afi].rmap_name[BGP_VPN_POLICY_DIR_TOVPN]) {
+
+ 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]
{
struct bgp *bgp;
struct peer *peer;
- struct peer_group *group;
struct listnode *lnbgp, *lnpeer;
for (ALL_LIST_ELEMENTS_RO(bm->bgp, lnbgp, bgp)) {
vector_set(comps, XSTRDUP(MTYPE_COMPLETION, name));
}
-
- if (token->type == VARIABLE_TKN)
- for (ALL_LIST_ELEMENTS_RO(bgp->group, lnpeer, group))
- vector_set(comps, XSTRDUP(MTYPE_COMPLETION,
- group->name));
}
}
{.varname = "peer", .completions = bgp_ac_neighbor},
{.completions = NULL}};
+static void bgp_ac_peergroup(vector comps, struct cmd_token *token)
+{
+ struct bgp *bgp;
+ struct peer_group *group;
+ struct listnode *lnbgp, *lnpeer;
+
+ for (ALL_LIST_ELEMENTS_RO(bm->bgp, lnbgp, bgp)) {
+ for (ALL_LIST_ELEMENTS_RO(bgp->group, lnpeer, group))
+ vector_set(comps, XSTRDUP(MTYPE_COMPLETION,
+ group->name));
+ }
+}
+
+static const struct cmd_variable_handler bgp_var_peergroup[] = {
+ {.tokenname = "PGNAME", .completions = bgp_ac_peergroup},
+ {.completions = NULL} };
+
void bgp_vty_init(void)
{
cmd_variable_handler_register(bgp_var_neighbor);
+ cmd_variable_handler_register(bgp_var_peergroup);
/* Install bgp top node. */
install_node(&bgp_node, bgp_config_write);
install_element(BGP_VPNV4_NODE, &no_neighbor_nexthop_self_cmd);
install_element(BGP_VPNV6_NODE, &neighbor_nexthop_self_cmd);
install_element(BGP_VPNV6_NODE, &no_neighbor_nexthop_self_cmd);
+ install_element(BGP_EVPN_NODE, &neighbor_nexthop_self_cmd);
+ install_element(BGP_EVPN_NODE, &no_neighbor_nexthop_self_cmd);
/* "neighbor next-hop-self force" commands. */
install_element(BGP_NODE, &neighbor_nexthop_self_force_hidden_cmd);
install_element(BGP_NODE, &neighbor_disable_connected_check_cmd);
install_element(BGP_NODE, &no_neighbor_disable_connected_check_cmd);
+ /* "neighbor enforce-first-as" commands. */
+ install_element(BGP_NODE, &neighbor_enforce_first_as_cmd);
+ install_element(BGP_NODE, &no_neighbor_enforce_first_as_cmd);
+
/* "neighbor description" commands. */
install_element(BGP_NODE, &neighbor_description_cmd);
install_element(BGP_NODE, &no_neighbor_description_cmd);
install_element(VIEW_NODE, &show_ip_bgp_lcommunity_info_cmd);
/* "show [ip] bgp attribute-info" commands. */
install_element(VIEW_NODE, &show_ip_bgp_attr_info_cmd);
+ /* "show [ip] bgp route-leak" command */
+ install_element(VIEW_NODE, &show_ip_bgp_route_leak_cmd);
/* "redistribute" commands. */
install_element(BGP_NODE, &bgp_redistribute_ipv4_hidden_cmd);
install_element(BGP_IPV6_NODE, &af_rt_vpn_imexport_cmd);
install_element(BGP_IPV4_NODE, &af_route_map_vpn_imexport_cmd);
install_element(BGP_IPV6_NODE, &af_route_map_vpn_imexport_cmd);
+ install_element(BGP_IPV4_NODE, &af_import_vrf_route_map_cmd);
+ install_element(BGP_IPV6_NODE, &af_import_vrf_route_map_cmd);
install_element(BGP_IPV4_NODE, &af_routetarget_import_cmd);
install_element(BGP_IPV6_NODE, &af_routetarget_import_cmd);
install_element(BGP_IPV6_NODE, &af_no_rt_vpn_imexport_cmd);
install_element(BGP_IPV4_NODE, &af_no_route_map_vpn_imexport_cmd);
install_element(BGP_IPV6_NODE, &af_no_route_map_vpn_imexport_cmd);
+ install_element(BGP_IPV4_NODE, &af_no_import_vrf_route_map_cmd);
+ install_element(BGP_IPV6_NODE, &af_no_import_vrf_route_map_cmd);
}
#include "memory.h"
return CMD_SUCCESS;
}
+/* Return configuration string of community-list entry. */
+static const char *community_list_config_str(struct community_entry *entry)
+{
+ const char *str;
+
+ if (entry->any)
+ str = "";
+ else {
+ if (entry->style == COMMUNITY_LIST_STANDARD)
+ str = community_str(entry->u.com, false);
+ else if (entry->style == LARGE_COMMUNITY_LIST_STANDARD)
+ str = lcommunity_str(entry->u.lcom, false);
+ else
+ str = entry->config;
+ }
+ return str;
+}
+
static void community_list_show(struct vty *vty, struct community_list *list)
{
struct community_entry *entry;
else
vty_out(vty, " %s %s\n",
community_direct_str(entry->direct),
- entry->style == COMMUNITY_LIST_STANDARD
- ? community_str(entry->u.com, false)
- : entry->config);
+ community_list_config_str(entry));
}
}
else
vty_out(vty, " %s %s\n",
community_direct_str(entry->direct),
- entry->style == EXTCOMMUNITY_LIST_STANDARD
- ? entry->u.ecom->str
- : entry->config);
+ community_list_config_str(entry));
}
}
else
vty_out(vty, " %s %s\n",
community_direct_str(entry->direct),
- entry->style == EXTCOMMUNITY_LIST_STANDARD
- ? entry->u.ecom->str
- : entry->config);
+ community_list_config_str(entry));
}
}
return CMD_SUCCESS;
}
-/* Return configuration string of community-list entry. */
-static const char *community_list_config_str(struct community_entry *entry)
-{
- const char *str;
-
- if (entry->any)
- str = "";
- else {
- if (entry->style == COMMUNITY_LIST_STANDARD)
- str = community_str(entry->u.com, false);
- else
- str = entry->config;
- }
- return str;
-}
-
/* Display community-list and extcommunity-list configuration. */
static int community_list_config_write(struct vty *vty)
{