+// SPDX-License-Identifier: GPL-2.0-or-later
/* BGP VTY interface.
* Copyright (C) 1996, 97, 98, 99, 2000 Kunihiro Ishiguro
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "buffer.h"
#include "linklist.h"
#include "stream.h"
-#include "thread.h"
+#include "event.h"
#include "log.h"
#include "memory.h"
#include "lib_vty.h"
PEER_FLAG_CAPABILITY_ENHE);
}
+/* neighbor capability software-version */
+DEFPY(neighbor_capability_software_version,
+ neighbor_capability_software_version_cmd,
+ "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor capability software-version",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Advertise capability to the peer\n"
+ "Advertise Software Version capability to the peer\n")
+{
+ struct peer *peer;
+
+ peer = peer_and_group_lookup_vty(vty, neighbor);
+ if (peer && peer->conf_if)
+ return CMD_SUCCESS;
+
+ if (no)
+ return peer_flag_unset_vty(vty, neighbor,
+ PEER_FLAG_CAPABILITY_SOFT_VERSION);
+ else
+ return peer_flag_set_vty(vty, neighbor,
+ PEER_FLAG_CAPABILITY_SOFT_VERSION);
+}
+
static int peer_af_flag_modify_vty(struct vty *vty, const char *peer_str,
- afi_t afi, safi_t safi, uint32_t flag,
+ afi_t afi, safi_t safi, uint64_t flag,
int set)
{
int ret;
}
static int peer_af_flag_set_vty(struct vty *vty, const char *peer_str,
- afi_t afi, safi_t safi, uint32_t flag)
+ afi_t afi, safi_t safi, uint64_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)
+ afi_t afi, safi_t safi, uint64_t flag)
{
return peer_af_flag_modify_vty(vty, peer_str, afi, safi, flag, 0);
}
{
struct peer *peer;
int idx = 0;
- const char *discard_attrs = NULL;
+ char *discard_attrs = NULL;
peer = peer_and_group_lookup_vty(vty, neighbor);
if (!peer)
bgp_path_attribute_discard_vty(vty, peer, discard_attrs, true);
+ XFREE(MTYPE_TMP, discard_attrs);
+
return CMD_SUCCESS;
}
{
struct peer *peer;
int idx = 0;
- const char *discard_attrs = NULL;
+ char *discard_attrs = NULL;
peer = peer_and_group_lookup_vty(vty, neighbor);
if (!peer)
bgp_path_attribute_discard_vty(vty, peer, discard_attrs, false);
+ XFREE(MTYPE_TMP, discard_attrs);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(neighbor_path_attribute_treat_as_withdraw,
+ neighbor_path_attribute_treat_as_withdraw_cmd,
+ "neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor path-attribute treat-as-withdraw (1-255)...",
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Manipulate path attributes from incoming UPDATE messages\n"
+ "Treat-as-withdraw any incoming BGP UPDATE messages that contain the specified attribute\n"
+ "Attribute number\n")
+{
+ struct peer *peer;
+ int idx = 0;
+ char *withdraw_attrs = NULL;
+
+ peer = peer_and_group_lookup_vty(vty, neighbor);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ argv_find(argv, argc, "(1-255)", &idx);
+ if (idx)
+ withdraw_attrs = argv_concat(argv, argc, idx);
+
+ bgp_path_attribute_withdraw_vty(vty, peer, withdraw_attrs, true);
+
+ XFREE(MTYPE_TMP, withdraw_attrs);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(no_neighbor_path_attribute_treat_as_withdraw,
+ no_neighbor_path_attribute_treat_as_withdraw_cmd,
+ "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor path-attribute treat-as-withdraw (1-255)...",
+ NO_STR
+ NEIGHBOR_STR
+ NEIGHBOR_ADDR_STR2
+ "Manipulate path attributes from incoming UPDATE messages\n"
+ "Treat-as-withdraw any incoming BGP UPDATE messages that contain the specified attribute\n"
+ "Attribute number\n")
+{
+ struct peer *peer;
+ int idx = 0;
+ char *withdraw_attrs = NULL;
+
+ peer = peer_and_group_lookup_vty(vty, neighbor);
+ if (!peer)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ argv_find(argv, argc, "(1-255)", &idx);
+ if (idx)
+ withdraw_attrs = argv_concat(argv, argc, idx);
+
+ bgp_path_attribute_withdraw_vty(vty, peer, withdraw_attrs, false);
+
+ XFREE(MTYPE_TMP, withdraw_attrs);
+
return CMD_SUCCESS;
}
bgp_get_default(), bgp);
if (yes) {
+ bgp->vpn_policy[afi].tovpn_rd_pretty =
+ XSTRDUP(MTYPE_BGP, rd_str);
bgp->vpn_policy[afi].tovpn_rd = prd;
SET_FLAG(bgp->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_RD_SET);
} else {
+ XFREE(MTYPE_BGP, bgp->vpn_policy[afi].tovpn_rd_pretty);
UNSET_FLAG(bgp->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_RD_SET);
}
peer_down_str[(int)peer->last_reset]);
json_object_int_add(json_peer, "lastResetCode",
peer->last_reset);
+ json_object_string_add(json_peer, "softwareVersion",
+ peer->soft_version ? peer->soft_version
+ : "n/a");
} else {
if (peer->last_reset == PEER_DOWN_NOTIFY_SEND
|| peer->last_reset == PEER_DOWN_NOTIFY_RECEIVED) {
BGP_NOTIFY_CEASE_HARD_RESET)
: "");
} else {
- vty_out(vty, " %s\n",
- peer_down_str[(int)peer->last_reset]);
+ vty_out(vty, " %s (%s)\n",
+ peer_down_str[(int)peer->last_reset],
+ peer->soft_version ? peer->soft_version
+ : "n/a");
}
}
}
vty_out(vty, "4 ");
vty_out(vty, ASN_FORMAT_SPACE(bgp->asnotation),
&peer->as);
- if (show_wide) {
+ if (show_wide)
vty_out(vty,
ASN_FORMAT_SPACE(
bgp->asnotation),
peer->change_local_as
? &peer->change_local_as
: &peer->local_as);
- vty_out(vty,
- " %9u %9u %8" PRIu64
- " %4zu %4zu %8s",
- PEER_TOTAL_RX(peer),
- PEER_TOTAL_TX(peer),
- peer->version[afi][safi],
- inq_count, outq_count,
- peer_uptime(peer->uptime,
- timebuf,
- BGP_UPTIME_LEN, 0,
- NULL));
- } else {
- vty_out(vty,
- " %9u %9u %8" PRIu64
- " %4zu %4zu %8s",
- PEER_TOTAL_RX(peer),
- PEER_TOTAL_TX(peer),
- peer->version[afi][safi],
- inq_count, outq_count,
- peer_uptime(peer->uptime,
- timebuf,
- BGP_UPTIME_LEN, 0,
- NULL));
- }
+ vty_out(vty,
+ " %9u %9u %8" PRIu64 " %4zu %4zu %8s",
+ PEER_TOTAL_RX(peer),
+ PEER_TOTAL_TX(peer),
+ peer->version[afi][safi], inq_count,
+ outq_count,
+ peer_uptime(peer->uptime, timebuf,
+ BGP_UPTIME_LEN, 0, NULL));
+
if (peer_established(peer)) {
if (peer->afc_recv[afi][safi]) {
if (CHECK_FLAG(
json_object_object_add(json_cap, "hostName",
json_hname);
+ /* Software Version capability */
+ json_object *json_soft_version = NULL;
+
+ json_soft_version = json_object_new_object();
+
+ if (CHECK_FLAG(p->cap, PEER_CAP_SOFT_VERSION_ADV))
+ json_object_string_add(
+ json_soft_version,
+ "advertisedSoftwareVersion",
+ cmd_software_version_get());
+
+ if (CHECK_FLAG(p->cap, PEER_CAP_SOFT_VERSION_RCV))
+ json_object_string_add(
+ json_soft_version,
+ "receivedSoftwareVersion",
+ p->soft_version ? p->soft_version
+ : "n/a");
+
+ json_object_object_add(json_cap, "softwareVersion",
+ json_soft_version);
+
/* Graceful Restart */
if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV) ||
CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV)) {
vty_out(vty, "\n");
+ /* Software Version capability */
+ vty_out(vty, " Version Capability:");
+
+ if (CHECK_FLAG(p->cap, PEER_CAP_SOFT_VERSION_ADV)) {
+ vty_out(vty,
+ " advertised software version (%s)",
+ cmd_software_version_get());
+ } else
+ vty_out(vty, " not advertised");
+
+ if (CHECK_FLAG(p->cap, PEER_CAP_SOFT_VERSION_RCV)) {
+ vty_out(vty, " received software version (%s)",
+ p->soft_version ? p->soft_version
+ : "n/a");
+ } else
+ vty_out(vty, " not received");
+
+ vty_out(vty, "\n");
+
/* Graceful Restart */
if (CHECK_FLAG(p->cap, PEER_CAP_RESTART_RCV) ||
CHECK_FLAG(p->cap, PEER_CAP_RESTART_ADV)) {
json_object_new_string(vname));
json_object_object_add(json, "exportToVrfs",
json_export_vrfs);
- json_object_string_addf(json, "routeDistinguisher",
- "%pRD",
- &bgp->vpn_policy[afi].tovpn_rd);
-
+ json_object_string_addf(
+ json, "routeDistinguisher", "%s",
+ bgp->vpn_policy[afi].tovpn_rd_pretty);
dir = BGP_VPN_POLICY_DIR_TOVPN;
if (bgp->vpn_policy[afi].rtlist[dir]) {
ecom_str = ecommunity_ecom2str(
/* peer-group helpers for config-write */
-static bool peergroup_flag_check(struct peer *peer, uint64_t flag)
+bool peergroup_flag_check(struct peer *peer, uint64_t flag)
{
if (!peer_group_active(peer)) {
if (CHECK_FLAG(peer->flags_invert, flag))
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 peer_af_flag_check(peer, afi, safi, flag);
}
return !!CHECK_FLAG(peer->af_flags_override[afi][safi], flag);
}
if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET))
- vty_out(vty, "%*srd vpn export %pRD\n", indent, "",
- &bgp->vpn_policy[afi].tovpn_rd);
+ vty_out(vty, "%*srd vpn export %s\n", indent, "",
+ bgp->vpn_policy[afi].tovpn_rd_pretty);
if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
BGP_VPN_POLICY_TOVPN_NEXTHOP_SET)) {
addr);
}
+ /* capability software-version */
+ if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_SOFT_VERSION))
+ vty_out(vty, " neighbor %s capability software-version\n",
+ addr);
+
/* dont-capability-negotiation */
if (peergroup_flag_check(peer, PEER_FLAG_DONT_CAPABILITY))
vty_out(vty, " neighbor %s dont-capability-negotiate\n", addr);
vty_out(vty, " neighbor %s path-attribute discard %s\n", addr,
discard_attrs_str);
+ /* path-attribute treat-as-withdraw */
+ char withdraw_attrs_str[BUFSIZ] = {0};
+ bool withdraw_attrs = bgp_path_attribute_treat_as_withdraw(
+ peer, withdraw_attrs_str, sizeof(withdraw_attrs_str));
+
+ if (withdraw_attrs)
+ vty_out(vty,
+ " neighbor %s path-attribute treat-as-withdraw %s\n",
+ addr, withdraw_attrs_str);
+
if (!CHECK_FLAG(peer->peer_gr_new_status_flag,
PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT)) {
install_element(BGP_NODE, &neighbor_path_attribute_discard_cmd);
install_element(BGP_NODE, &no_neighbor_path_attribute_discard_cmd);
+ /* "neighbor path-attribute treat-as-withdraw" commands. */
+ install_element(BGP_NODE,
+ &neighbor_path_attribute_treat_as_withdraw_cmd);
+ install_element(BGP_NODE,
+ &no_neighbor_path_attribute_treat_as_withdraw_cmd);
+
/* "neighbor passive" commands. */
install_element(BGP_NODE, &neighbor_passive_cmd);
install_element(BGP_NODE, &no_neighbor_passive_cmd);
install_element(BGP_NODE, &neighbor_capability_enhe_cmd);
install_element(BGP_NODE, &no_neighbor_capability_enhe_cmd);
+ /* "neighbor capability software-version" commands.*/
+ install_element(BGP_NODE, &neighbor_capability_software_version_cmd);
+
/* "neighbor capability orf prefix-list" commands.*/
install_element(BGP_NODE, &neighbor_capability_orf_prefix_hidden_cmd);
install_element(BGP_NODE,