summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas.abraitis@gmail.com>2019-05-20 16:43:01 +0300
committerDonatas Abraitis <donatas.abraitis@gmail.com>2019-05-21 11:28:20 +0300
commit25b5da8d50f366d52017a91dbb0e7ce8b752734e (patch)
treeea50f909e903b2b4be78241c6f2722aa6a9f0a66
parent84cdd5b375bb53fdcb25e3e9989af526cfa9983f (diff)
bgpd: Show FQDN in `show [ip] bgp` output
We already show this information in `show [ip] bgp <prefix`, thus why don't show it in global output. It's very handy when using at scale and to see the whole picture instead of resolving neighbor manually. It will show FQDN only if `bgp default show-hostname` is toggled. Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
-rw-r--r--bgpd/bgp_route.c177
-rw-r--r--tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py0
-rw-r--r--tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf4
-rw-r--r--tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf9
-rw-r--r--tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf5
-rw-r--r--tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf9
-rw-r--r--tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py109
7 files changed, 261 insertions, 52 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 4f89c8b5f7..e554b905f3 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -6930,6 +6930,13 @@ static void route_vty_short_status_out(struct vty *vty,
vty_out(vty, " ");
}
+static char *bgp_nexthop_fqdn(struct peer *peer)
+{
+ if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
+ return peer->hostname;
+ return NULL;
+}
+
/* called from terminal list command */
void route_vty_out(struct vty *vty, struct prefix *p,
struct bgp_path_info *path, int display, safi_t safi,
@@ -6946,6 +6953,7 @@ void route_vty_out(struct vty *vty, struct prefix *p,
bool nexthop_othervrf = false;
vrf_id_t nexthop_vrfid = VRF_DEFAULT;
const char *nexthop_vrfname = VRF_DEFAULT_NAME;
+ char *nexthop_fqdn = bgp_nexthop_fqdn(path->peer);
if (json_paths)
json_path = json_object_new_object();
@@ -7041,42 +7049,58 @@ void route_vty_out(struct vty *vty, struct prefix *p,
if (json_paths) {
json_nexthop_global = json_object_new_object();
- json_object_string_add(json_nexthop_global, "afi",
- (af == AF_INET) ? "ip" : "ipv6");
- json_object_string_add(json_nexthop_global,
- (af == AF_INET) ? "ip" : "ipv6",
- nexthop);
+ json_object_string_add(
+ json_nexthop_global, "afi",
+ nexthop_fqdn ? "fqdn"
+ : (af == AF_INET) ? "ip" : "ipv6");
+ json_object_string_add(
+ json_nexthop_global,
+ nexthop_fqdn ? "fqdn"
+ : (af == AF_INET) ? "ip" : "ipv6",
+ nexthop_fqdn ? nexthop_fqdn : nexthop);
json_object_boolean_true_add(json_nexthop_global,
"used");
} else
- vty_out(vty, "%s%s", nexthop, vrf_id_str);
+ vty_out(vty, "%s%s",
+ nexthop_fqdn ? nexthop_fqdn : nexthop,
+ vrf_id_str);
} else if (safi == SAFI_EVPN) {
if (json_paths) {
json_nexthop_global = json_object_new_object();
- json_object_string_add(json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ json_object_string_add(
+ json_nexthop_global,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn ? nexthop_fqdn
+ : inet_ntoa(attr->nexthop));
json_object_string_add(json_nexthop_global, "afi",
"ipv4");
json_object_boolean_true_add(json_nexthop_global,
"used");
} else
- vty_out(vty, "%-16s%s", inet_ntoa(attr->nexthop),
+ vty_out(vty, "%-16s%s",
+ nexthop_fqdn ?: inet_ntoa(attr->nexthop),
vrf_id_str);
} else if (safi == SAFI_FLOWSPEC) {
if (attr->nexthop.s_addr != 0) {
if (json_paths) {
json_nexthop_global = json_object_new_object();
json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ json_nexthop_global,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntoa(attr->nexthop));
json_object_string_add(json_nexthop_global,
"afi", "ipv4");
json_object_boolean_true_add(
json_nexthop_global,
"used");
} else {
- vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
+ vty_out(vty, "%-16s",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntoa(attr->nexthop));
}
}
} else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
@@ -7085,12 +7109,19 @@ void route_vty_out(struct vty *vty, struct prefix *p,
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(attr->mp_nexthop_global_in));
+ json_nexthop_global,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntoa(
+ attr->mp_nexthop_global_in));
else
json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ json_nexthop_global,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntoa(attr->nexthop));
json_object_string_add(json_nexthop_global, "afi",
"ipv4");
@@ -7100,7 +7131,9 @@ void route_vty_out(struct vty *vty, struct prefix *p,
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), "%s%s",
- inet_ntoa(attr->nexthop), vrf_id_str);
+ nexthop_fqdn ? nexthop_fqdn
+ : inet_ntoa(attr->nexthop),
+ vrf_id_str);
vty_out(vty, "%-16s", buf);
}
}
@@ -7113,9 +7146,13 @@ void route_vty_out(struct vty *vty, struct prefix *p,
if (json_paths) {
json_nexthop_global = json_object_new_object();
json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntop(AF_INET6, &attr->mp_nexthop_global,
- buf, BUFSIZ));
+ json_nexthop_global,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntop(AF_INET6,
+ &attr->mp_nexthop_global,
+ buf, BUFSIZ));
json_object_string_add(json_nexthop_global, "afi",
"ipv6");
json_object_string_add(json_nexthop_global, "scope",
@@ -7127,10 +7164,14 @@ void route_vty_out(struct vty *vty, struct prefix *p,
|| (path->peer->conf_if)) {
json_nexthop_ll = json_object_new_object();
json_object_string_add(
- json_nexthop_ll, "ip",
- inet_ntop(AF_INET6,
- &attr->mp_nexthop_local, buf,
- BUFSIZ));
+ json_nexthop_ll,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntop(
+ AF_INET6,
+ &attr->mp_nexthop_local,
+ buf, BUFSIZ));
json_object_string_add(json_nexthop_ll, "afi",
"ipv6");
json_object_string_add(json_nexthop_ll, "scope",
@@ -7169,10 +7210,12 @@ void route_vty_out(struct vty *vty, struct prefix *p,
} else {
len = vty_out(
vty, "%s%s",
- inet_ntop(
- AF_INET6,
- &attr->mp_nexthop_local,
- buf, BUFSIZ),
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntop(
+ AF_INET6,
+ &attr->mp_nexthop_local,
+ buf, BUFSIZ),
vrf_id_str);
len = 16 - len;
@@ -7184,10 +7227,13 @@ void route_vty_out(struct vty *vty, struct prefix *p,
} else {
len = vty_out(
vty, "%s%s",
- inet_ntop(AF_INET6,
- &attr->mp_nexthop_global, buf,
- BUFSIZ),
- vrf_id_str);
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntop(
+ AF_INET6,
+ &attr->mp_nexthop_global,
+ buf, BUFSIZ),
+ vrf_id_str);
len = 16 - len;
if (len < 1)
@@ -7664,7 +7710,7 @@ void route_vty_out_overlay(struct vty *vty, struct prefix *p,
vty_out(vty, "%s", str);
else
json_object_string_add(json_overlay, "esi", str);
-
+
XFREE(MTYPE_TMP, str);
if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
@@ -8039,6 +8085,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
bool nexthop_self =
CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
int i;
+ char *nexthop_fqdn = bgp_nexthop_fqdn(path->peer);
if (json_paths) {
json_path = json_object_new_object();
@@ -8174,21 +8221,33 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
|| safi == SAFI_EVPN) {
if (json_paths)
json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(
- attr->mp_nexthop_global_in));
+ json_nexthop_global,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntoa(
+ attr->mp_nexthop_global_in));
else
vty_out(vty, " %s",
- inet_ntoa(
- attr->mp_nexthop_global_in));
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntoa(
+ attr->mp_nexthop_global_in));
} else {
if (json_paths)
json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntoa(attr->nexthop));
+ json_nexthop_global,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntoa(
+ attr->nexthop));
else
vty_out(vty, " %s",
- inet_ntoa(attr->nexthop));
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntoa(
+ attr->nexthop));
}
if (json_paths)
@@ -8197,19 +8256,28 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
} else {
if (json_paths) {
json_object_string_add(
- json_nexthop_global, "ip",
- inet_ntop(AF_INET6,
- &attr->mp_nexthop_global, buf,
- INET6_ADDRSTRLEN));
+ json_nexthop_global,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntop(
+ AF_INET6,
+ &attr->mp_nexthop_global,
+ buf,
+ INET6_ADDRSTRLEN));
json_object_string_add(json_nexthop_global,
"afi", "ipv6");
json_object_string_add(json_nexthop_global,
"scope", "global");
} else {
vty_out(vty, " %s",
- inet_ntop(AF_INET6,
- &attr->mp_nexthop_global, buf,
- INET6_ADDRSTRLEN));
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntop(
+ AF_INET6,
+ &attr->mp_nexthop_global,
+ buf,
+ INET6_ADDRSTRLEN));
}
}
@@ -8391,10 +8459,15 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
if (json_paths) {
json_nexthop_ll = json_object_new_object();
json_object_string_add(
- json_nexthop_ll, "ip",
- inet_ntop(AF_INET6,
- &attr->mp_nexthop_local, buf,
- INET6_ADDRSTRLEN));
+ json_nexthop_ll,
+ nexthop_fqdn ? "fqdn" : "ip",
+ nexthop_fqdn
+ ? nexthop_fqdn
+ : inet_ntop(
+ AF_INET6,
+ &attr->mp_nexthop_local,
+ buf,
+ INET6_ADDRSTRLEN));
json_object_string_add(json_nexthop_ll, "afi",
"ipv6");
json_object_string_add(json_nexthop_ll, "scope",
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py b/tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf
new file mode 100644
index 0000000000..235b42b3d5
--- /dev/null
+++ b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf
@@ -0,0 +1,4 @@
+router bgp 65000
+ neighbor 192.168.255.2 remote-as 65001
+ address-family ipv4 unicast
+ redistribute connected
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf
new file mode 100644
index 0000000000..0a283c06d5
--- /dev/null
+++ b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf
@@ -0,0 +1,9 @@
+!
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf
new file mode 100644
index 0000000000..c05bfd5a6b
--- /dev/null
+++ b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf
@@ -0,0 +1,5 @@
+router bgp 65001
+ bgp default show-hostname
+ neighbor 192.168.255.1 remote-as 65000
+ address-family ipv4 unicast
+ redistribute connected
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf
new file mode 100644
index 0000000000..5abba71ce8
--- /dev/null
+++ b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf
@@ -0,0 +1,9 @@
+!
+interface lo
+ ip address 172.16.255.253/32
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py b/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py
new file mode 100644
index 0000000000..59ffd36ef3
--- /dev/null
+++ b/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+
+#
+# test_bgp_show_ip_bgp_fqdn.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2019 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# 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.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+
+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, 3):
+ tgen.add_router('r{}'.format(routern))
+
+ switch = tgen.add_switch('s1')
+ switch.add_link(tgen.gears['r1'])
+ switch.add_link(tgen.gears['r2'])
+
+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_maximum_prefix_invalid():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ def _bgp_converge(router, neighbor):
+ cmd = "show ip bgp neighbor {0} json".format(neighbor)
+ while True:
+ output = json.loads(tgen.gears[router].vtysh_cmd(cmd))
+ if output[neighbor]['bgpState'] == 'Established':
+ time.sleep(3)
+ return True
+
+ def _bgp_show_nexthop(router, prefix):
+ cmd = "show ip bgp json"
+ output = json.loads(tgen.gears[router].vtysh_cmd(cmd))
+ for nh in output['routes'][prefix][0]['nexthops']:
+ if 'fqdn' in nh:
+ return 'fqdn'
+ return 'ip'
+
+ if _bgp_converge('r2', '192.168.255.1'):
+ assert _bgp_show_nexthop('r2', '172.16.255.254/32') == 'fqdn'
+
+ if _bgp_converge('r1', '192.168.255.2'):
+ assert _bgp_show_nexthop('r1', '172.16.255.253/32') == 'ip'
+
+if __name__ == '__main__':
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))