Merge pull request #6744 from ton31337/fix/bgp_hostname_nexthop_if_unchanged_7.4

bgpd: [7.4] Show the real next-hop address in addition to hostname
This commit is contained in:
Rafael Zalamena 2020-07-16 09:53:16 -03:00 committed by GitHub
commit 57fe007c77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 180 additions and 249 deletions

View File

@ -7559,8 +7559,7 @@ static char *bgp_nexthop_hostname(struct peer *peer,
struct bgp_nexthop_cache *bnc) struct bgp_nexthop_cache *bnc)
{ {
if (peer->hostname if (peer->hostname
&& CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME) && bnc && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
&& CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
return peer->hostname; return peer->hostname;
return NULL; return NULL;
} }
@ -7570,6 +7569,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
struct bgp_path_info *path, int display, safi_t safi, struct bgp_path_info *path, int display, safi_t safi,
json_object *json_paths) json_object *json_paths)
{ {
int len;
struct attr *attr = path->attr; struct attr *attr = path->attr;
json_object *json_path = NULL; json_object *json_path = NULL;
json_object *json_nexthops = NULL; json_object *json_nexthops = NULL;
@ -7671,20 +7671,29 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_object_string_add(json_nexthop_global, "ip", json_object_string_add(json_nexthop_global, "ip",
nexthop); nexthop);
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global,
"hostname", "hostname",
nexthop_hostname); path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi", json_object_string_add(json_nexthop_global, "afi",
(af == AF_INET) ? "ipv4" (af == AF_INET) ? "ipv4"
: "ipv6"); : "ipv6");
json_object_boolean_true_add(json_nexthop_global, json_object_boolean_true_add(json_nexthop_global,
"used"); "used");
} else } else {
vty_out(vty, "%s%s", if (nexthop_hostname)
nexthop_hostname ? nexthop_hostname : nexthop, len = vty_out(vty, "%s(%s)%s", nexthop,
vrf_id_str); nexthop_hostname, vrf_id_str);
else
len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
len = 16 - len;
if (len < 1)
vty_out(vty, "\n%*s", 36, " ");
else
vty_out(vty, "%*s", len, " ");
}
} else if (safi == SAFI_EVPN) { } else if (safi == SAFI_EVPN) {
if (json_paths) { if (json_paths) {
json_nexthop_global = json_object_new_object(); json_nexthop_global = json_object_new_object();
@ -7692,20 +7701,29 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_object_string_add(json_nexthop_global, "ip", json_object_string_add(json_nexthop_global, "ip",
inet_ntoa(attr->nexthop)); inet_ntoa(attr->nexthop));
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global,
"hostname", "hostname",
nexthop_hostname); path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi", json_object_string_add(json_nexthop_global, "afi",
"ipv4"); "ipv4");
json_object_boolean_true_add(json_nexthop_global, json_object_boolean_true_add(json_nexthop_global,
"used"); "used");
} else } else {
vty_out(vty, "%-16s%s", if (nexthop_hostname)
nexthop_hostname ? nexthop_hostname len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
: inet_ntoa(attr->nexthop), nexthop_hostname, vrf_id_str);
else
len = vty_out(vty, "%pI4%s", &attr->nexthop,
vrf_id_str); vrf_id_str);
len = 16 - len;
if (len < 1)
vty_out(vty, "\n%*s", 36, " ");
else
vty_out(vty, "%*s", len, " ");
}
} else if (safi == SAFI_FLOWSPEC) { } else if (safi == SAFI_FLOWSPEC) {
if (attr->nexthop.s_addr != INADDR_ANY) { if (attr->nexthop.s_addr != INADDR_ANY) {
if (json_paths) { if (json_paths) {
@ -7717,19 +7735,30 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_nexthop_global, "ip", json_nexthop_global, "ip",
inet_ntoa(attr->nexthop)); inet_ntoa(attr->nexthop));
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add( json_object_string_add(
json_nexthop_global, "hostname", json_nexthop_global, "hostname",
nexthop_hostname); path->peer->hostname);
json_object_boolean_true_add( json_object_boolean_true_add(
json_nexthop_global, json_nexthop_global,
"used"); "used");
} else { } else {
vty_out(vty, "%-16s", if (nexthop_hostname)
nexthop_hostname len = vty_out(vty, "%pI4(%s)%s",
? nexthop_hostname &attr->nexthop,
: inet_ntoa(attr->nexthop)); nexthop_hostname,
vrf_id_str);
else
len = vty_out(vty, "%pI4%s",
&attr->nexthop,
vrf_id_str);
len = 16 - len;
if (len < 1)
vty_out(vty, "\n%*s", 36, " ");
else
vty_out(vty, "%*s", len, " ");
} }
} }
} else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
@ -7739,29 +7768,33 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
json_object_string_add(json_nexthop_global, "ip", json_object_string_add(json_nexthop_global, "ip",
inet_ntoa(attr->nexthop)); inet_ntoa(attr->nexthop));
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global,
"hostname", "hostname",
nexthop_hostname); path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi", json_object_string_add(json_nexthop_global, "afi",
"ipv4"); "ipv4");
json_object_boolean_true_add(json_nexthop_global, json_object_boolean_true_add(json_nexthop_global,
"used"); "used");
} else { } else {
char buf[BUFSIZ]; if (nexthop_hostname)
len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
snprintf(buf, sizeof(buf), "%s%s", nexthop_hostname, vrf_id_str);
nexthop_hostname ? nexthop_hostname else
: inet_ntoa(attr->nexthop), len = vty_out(vty, "%pI4%s", &attr->nexthop,
vrf_id_str); vrf_id_str);
vty_out(vty, "%-16s", buf);
len = 16 - len;
if (len < 1)
vty_out(vty, "\n%*s", 36, " ");
else
vty_out(vty, "%*s", len, " ");
} }
} }
/* IPv6 Next Hop */ /* IPv6 Next Hop */
else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
int len;
char buf[BUFSIZ]; char buf[BUFSIZ];
if (json_paths) { if (json_paths) {
@ -7771,10 +7804,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
inet_ntop(AF_INET6, &attr->mp_nexthop_global, inet_ntop(AF_INET6, &attr->mp_nexthop_global,
buf, BUFSIZ)); buf, BUFSIZ));
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global,
"hostname", "hostname",
nexthop_hostname); path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi", json_object_string_add(json_nexthop_global, "afi",
"ipv6"); "ipv6");
@ -7793,10 +7826,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
&attr->mp_nexthop_local, buf, &attr->mp_nexthop_local, buf,
BUFSIZ)); BUFSIZ));
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add( json_object_string_add(
json_nexthop_ll, "hostname", json_nexthop_ll, "hostname",
nexthop_hostname); path->peer->hostname);
json_object_string_add(json_nexthop_ll, "afi", json_object_string_add(json_nexthop_ll, "afi",
"ipv6"); "ipv6");
@ -7835,15 +7868,18 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
else else
vty_out(vty, "%*s", len, " "); vty_out(vty, "%*s", len, " ");
} else { } else {
if (nexthop_hostname)
len = vty_out( len = vty_out(
vty, "%s%s", vty, "%pI6(%s)%s",
nexthop_hostname
? nexthop_hostname
: inet_ntop(
AF_INET6,
&attr->mp_nexthop_local, &attr->mp_nexthop_local,
buf, BUFSIZ), nexthop_hostname,
vrf_id_str); vrf_id_str);
else
len = vty_out(
vty, "%pI6%s",
&attr->mp_nexthop_local,
vrf_id_str);
len = 16 - len; len = 16 - len;
if (len < 1) if (len < 1)
@ -7852,15 +7888,16 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
vty_out(vty, "%*s", len, " "); vty_out(vty, "%*s", len, " ");
} }
} else { } else {
len = vty_out( if (nexthop_hostname)
vty, "%s%s", len = vty_out(vty, "%pI6(%s)%s",
nexthop_hostname
? nexthop_hostname
: inet_ntop(
AF_INET6,
&attr->mp_nexthop_global, &attr->mp_nexthop_global,
buf, BUFSIZ), nexthop_hostname,
vrf_id_str); vrf_id_str);
else
len = vty_out(vty, "%pI6%s",
&attr->mp_nexthop_global,
vrf_id_str);
len = 16 - len; len = 16 - len;
if (len < 1) if (len < 1)
@ -7986,6 +8023,7 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
{ {
json_object *json_status = NULL; json_object *json_status = NULL;
json_object *json_net = NULL; json_object *json_net = NULL;
int len;
char buff[BUFSIZ]; char buff[BUFSIZ];
/* Route status display. */ /* Route status display. */
@ -8079,7 +8117,6 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
inet_ntoa(attr->nexthop)); inet_ntoa(attr->nexthop));
} else if (p->family == AF_INET6 } else if (p->family == AF_INET6
|| BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
int len;
char buf[BUFSIZ]; char buf[BUFSIZ];
len = vty_out( len = vty_out(
@ -8819,31 +8856,38 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
json_nexthop_global, "ip", json_nexthop_global, "ip",
inet_ntoa(attr->mp_nexthop_global_in)); inet_ntoa(attr->mp_nexthop_global_in));
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add( json_object_string_add(
json_nexthop_global, "hostname", json_nexthop_global, "hostname",
path->peer->hostname);
} else {
if (nexthop_hostname)
vty_out(vty, " %pI4(%s)",
&attr->mp_nexthop_global_in,
nexthop_hostname); nexthop_hostname);
} else else
vty_out(vty, " %s", vty_out(vty, " %pI4",
nexthop_hostname &attr->mp_nexthop_global_in);
? nexthop_hostname }
: inet_ntoa(
attr->mp_nexthop_global_in));
} else { } else {
if (json_paths) { if (json_paths) {
json_object_string_add( json_object_string_add(
json_nexthop_global, "ip", json_nexthop_global, "ip",
inet_ntoa(attr->nexthop)); inet_ntoa(attr->nexthop));
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add( json_object_string_add(
json_nexthop_global, "hostname", json_nexthop_global, "hostname",
path->peer->hostname);
} else {
if (nexthop_hostname)
vty_out(vty, " %pI4(%s)",
&attr->nexthop,
nexthop_hostname); nexthop_hostname);
} else else
vty_out(vty, " %s", vty_out(vty, " %pI4",
nexthop_hostname &attr->nexthop);
? nexthop_hostname }
: inet_ntoa(attr->nexthop));
} }
if (json_paths) if (json_paths)
@ -8856,22 +8900,23 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
inet_ntop(AF_INET6, &attr->mp_nexthop_global, inet_ntop(AF_INET6, &attr->mp_nexthop_global,
buf, INET6_ADDRSTRLEN)); buf, INET6_ADDRSTRLEN));
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add(json_nexthop_global, json_object_string_add(json_nexthop_global,
"hostname", "hostname",
nexthop_hostname); path->peer->hostname);
json_object_string_add(json_nexthop_global, "afi", json_object_string_add(json_nexthop_global, "afi",
"ipv6"); "ipv6");
json_object_string_add(json_nexthop_global, "scope", json_object_string_add(json_nexthop_global, "scope",
"global"); "global");
} else { } else {
vty_out(vty, " %s", if (nexthop_hostname)
nexthop_hostname vty_out(vty, " %pI6(%s)",
? nexthop_hostname
: inet_ntop(AF_INET6,
&attr->mp_nexthop_global, &attr->mp_nexthop_global,
buf, INET6_ADDRSTRLEN)); nexthop_hostname);
else
vty_out(vty, " %pI6",
&attr->mp_nexthop_global);
} }
} }
@ -9049,10 +9094,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
inet_ntop(AF_INET6, &attr->mp_nexthop_local, inet_ntop(AF_INET6, &attr->mp_nexthop_local,
buf, INET6_ADDRSTRLEN)); buf, INET6_ADDRSTRLEN));
if (nexthop_hostname) if (path->peer->hostname)
json_object_string_add(json_nexthop_ll, json_object_string_add(json_nexthop_ll,
"hostname", "hostname",
nexthop_hostname); path->peer->hostname);
json_object_string_add(json_nexthop_ll, "afi", "ipv6"); json_object_string_add(json_nexthop_ll, "afi", "ipv6");
json_object_string_add(json_nexthop_ll, "scope", json_object_string_add(json_nexthop_ll, "scope",

View File

@ -84,6 +84,10 @@ FRR_CFG_DEFAULT_BOOL(BGP_SHOW_HOSTNAME,
{ .val_bool = true, .match_profile = "datacenter", }, { .val_bool = true, .match_profile = "datacenter", },
{ .val_bool = false }, { .val_bool = false },
) )
FRR_CFG_DEFAULT_BOOL(BGP_SHOW_NEXTHOP_HOSTNAME,
{ .val_bool = true, .match_profile = "datacenter", },
{ .val_bool = false },
)
FRR_CFG_DEFAULT_BOOL(BGP_LOG_NEIGHBOR_CHANGES, FRR_CFG_DEFAULT_BOOL(BGP_LOG_NEIGHBOR_CHANGES,
{ .val_bool = true, .match_profile = "datacenter", }, { .val_bool = true, .match_profile = "datacenter", },
{ .val_bool = false }, { .val_bool = false },
@ -422,6 +426,8 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
SET_FLAG((*bgp)->flags, BGP_FLAG_IMPORT_CHECK); SET_FLAG((*bgp)->flags, BGP_FLAG_IMPORT_CHECK);
if (DFLT_BGP_SHOW_HOSTNAME) if (DFLT_BGP_SHOW_HOSTNAME)
SET_FLAG((*bgp)->flags, BGP_FLAG_SHOW_HOSTNAME); SET_FLAG((*bgp)->flags, BGP_FLAG_SHOW_HOSTNAME);
if (DFLT_BGP_SHOW_NEXTHOP_HOSTNAME)
SET_FLAG((*bgp)->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
if (DFLT_BGP_LOG_NEIGHBOR_CHANGES) if (DFLT_BGP_LOG_NEIGHBOR_CHANGES)
SET_FLAG((*bgp)->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); SET_FLAG((*bgp)->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
if (DFLT_BGP_DETERMINISTIC_MED) if (DFLT_BGP_DETERMINISTIC_MED)
@ -3100,6 +3106,32 @@ DEFUN (no_bgp_default_show_hostname,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
/* Display hostname in certain command outputs */
DEFUN (bgp_default_show_nexthop_hostname,
bgp_default_show_nexthop_hostname_cmd,
"bgp default show-nexthop-hostname",
"BGP specific commands\n"
"Configure BGP defaults\n"
"Show hostname for nexthop in certain command outputs\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
SET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
return CMD_SUCCESS;
}
DEFUN (no_bgp_default_show_nexthop_hostname,
no_bgp_default_show_nexthop_hostname_cmd,
"no bgp default show-nexthop-hostname",
NO_STR
"BGP specific commands\n"
"Configure BGP defaults\n"
"Show hostname for nexthop in certain command outputs\n")
{
VTY_DECLVAR_CONTEXT(bgp, bgp);
UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
return CMD_SUCCESS;
}
/* "bgp network import-check" configuration. */ /* "bgp network import-check" configuration. */
DEFUN (bgp_network_import_check, DEFUN (bgp_network_import_check,
bgp_network_import_check_cmd, bgp_network_import_check_cmd,
@ -15190,6 +15222,15 @@ int bgp_config_write(struct vty *vty)
? "" ? ""
: "no "); : "no ");
/* BGP default show-nexthop-hostname */
if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME)
!= SAVE_BGP_SHOW_HOSTNAME)
vty_out(vty, " %sbgp default show-nexthop-hostname\n",
CHECK_FLAG(bgp->flags,
BGP_FLAG_SHOW_NEXTHOP_HOSTNAME)
? ""
: "no ");
/* BGP default subgroup-pkt-queue-max. */ /* BGP default subgroup-pkt-queue-max. */
if (bgp->default_subgroup_pkt_queue_max if (bgp->default_subgroup_pkt_queue_max
!= BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX) != BGP_DEFAULT_SUBGROUP_PKT_QUEUE_MAX)
@ -15815,6 +15856,10 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &bgp_default_show_hostname_cmd); install_element(BGP_NODE, &bgp_default_show_hostname_cmd);
install_element(BGP_NODE, &no_bgp_default_show_hostname_cmd); install_element(BGP_NODE, &no_bgp_default_show_hostname_cmd);
/* bgp default show-nexthop-hostname */
install_element(BGP_NODE, &bgp_default_show_nexthop_hostname_cmd);
install_element(BGP_NODE, &no_bgp_default_show_nexthop_hostname_cmd);
/* "bgp default subgroup-pkt-queue-max" commands. */ /* "bgp default subgroup-pkt-queue-max" commands. */
install_element(BGP_NODE, &bgp_default_subgroup_pkt_queue_max_cmd); install_element(BGP_NODE, &bgp_default_subgroup_pkt_queue_max_cmd);
install_element(BGP_NODE, &no_bgp_default_subgroup_pkt_queue_max_cmd); install_element(BGP_NODE, &no_bgp_default_subgroup_pkt_queue_max_cmd);

View File

@ -447,6 +447,7 @@ struct bgp {
#define BGP_FLAG_SELECT_DEFER_DISABLE (1 << 23) #define BGP_FLAG_SELECT_DEFER_DISABLE (1 << 23)
#define BGP_FLAG_GR_DISABLE_EOR (1 << 24) #define BGP_FLAG_GR_DISABLE_EOR (1 << 24)
#define BGP_FLAG_EBGP_REQUIRES_POLICY (1 << 25) #define BGP_FLAG_EBGP_REQUIRES_POLICY (1 << 25)
#define BGP_FLAG_SHOW_NEXTHOP_HOSTNAME (1 << 26)
enum global_mode GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE] enum global_mode GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE]
[BGP_GLOBAL_GR_EVENT_CMD]; [BGP_GLOBAL_GR_EVENT_CMD];

View File

@ -1366,6 +1366,19 @@ Configuring Peers
on by default or not. This command defaults to on and is not displayed. on by default or not. This command defaults to on and is not displayed.
The `no bgp default ipv4-unicast` form of the command is displayed. The `no bgp default ipv4-unicast` form of the command is displayed.
.. index:: [no] bgp default show-hostname
.. clicmd:: [no] bgp default show-hostname
This command shows the hostname of the peer in certain BGP commands
outputs. It's easier to troubleshoot if you have a number of BGP peers.
.. index:: [no] bgp default show-nexthop-hostname
.. clicmd:: [no] bgp default show-nexthop-hostname
This command shows the hostname of the next-hop in certain BGP commands
outputs. It's easier to troubleshoot if you have a number of BGP peers
and a number of routes to check.
.. index:: [no] neighbor PEER advertisement-interval (0-600) .. index:: [no] neighbor PEER advertisement-interval (0-600)
.. clicmd:: [no] neighbor PEER advertisement-interval (0-600) .. clicmd:: [no] neighbor PEER advertisement-interval (0-600)

View File

@ -1,5 +0,0 @@
router bgp 65000
no bgp ebgp-requires-policy
neighbor 192.168.255.2 remote-as 65001
address-family ipv4 unicast
redistribute connected

View File

@ -1,9 +0,0 @@
!
interface lo
ip address 172.16.255.254/32
!
interface r1-eth0
ip address 192.168.255.1/24
!
ip forwarding
!

View File

@ -1,5 +0,0 @@
router bgp 65001
no bgp ebgp-requires-policy
bgp default show-hostname
neighbor 192.168.255.1 remote-as 65000
neighbor 192.168.254.1 remote-as 65001

View File

@ -1,12 +0,0 @@
!
interface lo
ip address 172.16.255.253/32
!
interface r2-eth0
ip address 192.168.255.2/24
!
interface r2-eth1
ip address 192.168.254.2/24
!
ip forwarding
!

View File

@ -1,3 +0,0 @@
router bgp 65001
bgp default show-hostname
neighbor 192.168.254.2 remote-as 65001

View File

@ -1,6 +0,0 @@
!
interface r3-eth0
ip address 192.168.254.1/24
!
ip forwarding
!

View File

@ -1,133 +0,0 @@
#!/usr/bin/env python
#
# test_bgp_show_ip_bgp_fqdn.py
# Part of NetDEF Topology Tests
#
# Copyright (c) 2019 by
# Donatas Abraitis <donatas.abraitis@gmail.com>
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
"""
test_bgp_show_ip_bgp_fqdn.py:
Test if FQND is visible in `show [ip] bgp` output if
`bgp default show-hostname` is toggled.
Topology:
r1 <-- eBGP --> r2 <-- iBGP --> r3
1. Check if both hostname and ip are added to JSON output
for 172.16.255.254/32 on r2.
2. Check if only ip is added to JSON output for 172.16.255.254/32 on r3.
"""
import os
import sys
import json
import time
import pytest
import functools
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, "../"))
# pylint: disable=C0413
from lib import topotest
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
from mininet.topo import Topo
class TemplateTopo(Topo):
def build(self, *_args, **_opts):
tgen = get_topogen(self)
for routern in range(1, 4):
tgen.add_router("r{}".format(routern))
switch = tgen.add_switch("s1")
switch.add_link(tgen.gears["r1"])
switch.add_link(tgen.gears["r2"])
switch = tgen.add_switch("s2")
switch.add_link(tgen.gears["r2"])
switch.add_link(tgen.gears["r3"])
def setup_module(mod):
tgen = Topogen(TemplateTopo, mod.__name__)
tgen.start_topology()
router_list = tgen.routers()
for i, (rname, router) in enumerate(router_list.iteritems(), 1):
router.load_config(
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
)
router.load_config(
TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
)
tgen.start_router()
def teardown_module(mod):
tgen = get_topogen()
tgen.stop_topology()
def test_bgp_show_ip_bgp_hostname():
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
def _bgp_converge(router):
output = json.loads(router.vtysh_cmd("show ip bgp 172.16.255.254/32 json"))
expected = {"prefix": "172.16.255.254/32"}
return topotest.json_cmp(output, expected)
def _bgp_show_nexthop_hostname_and_ip(router):
output = json.loads(router.vtysh_cmd("show ip bgp json"))
for nh in output["routes"]["172.16.255.254/32"][0]["nexthops"]:
if "hostname" in nh and "ip" in nh:
return True
return False
def _bgp_show_nexthop_ip_only(router):
output = json.loads(router.vtysh_cmd("show ip bgp json"))
for nh in output["routes"]["172.16.255.254/32"][0]["nexthops"]:
if "ip" in nh and not "hostname" in nh:
return True
return False
test_func = functools.partial(_bgp_converge, tgen.gears["r2"])
success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
test_func = functools.partial(_bgp_converge, tgen.gears["r3"])
success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r2"])
assert _bgp_show_nexthop_hostname_and_ip(tgen.gears["r2"]) == True
assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r3"])
assert _bgp_show_nexthop_ip_only(tgen.gears["r3"]) == True
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))