]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Show FQDN in `show [ip] bgp` output
authorDonatas Abraitis <donatas.abraitis@gmail.com>
Mon, 20 May 2019 13:43:01 +0000 (16:43 +0300)
committerDonatas Abraitis <donatas.abraitis@gmail.com>
Thu, 30 May 2019 14:10:51 +0000 (17:10 +0300)
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>
bgpd/bgp_route.c
tests/topotests/bgp_show_ip_bgp_fqdn/__init__.py [new file with mode: 0644]
tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_show_ip_bgp_fqdn/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py [new file with mode: 0644]

index fc6798fdfc8ff8284c1984e122367bb6f85de14d..f8eae135e87ebd7d66e626224da6ab77c748089d 100644 (file)
@@ -6863,6 +6863,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,
@@ -6879,6 +6886,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();
@@ -6974,42 +6982,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)) {
@@ -7018,12 +7042,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");
@@ -7033,7 +7064,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);
                }
        }
@@ -7046,9 +7079,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",
@@ -7060,10 +7097,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",
@@ -7102,10 +7143,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;
 
@@ -7117,10 +7160,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)
@@ -7848,6 +7894,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
        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();
@@ -7982,21 +8029,33 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
                            || 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)
@@ -8005,19 +8064,28 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
                } 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));
                        }
                }
 
@@ -8199,10 +8267,15 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
                        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 (file)
index 0000000..e69de29
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 (file)
index 0000000..235b42b
--- /dev/null
@@ -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 (file)
index 0000000..0a283c0
--- /dev/null
@@ -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 (file)
index 0000000..c05bfd5
--- /dev/null
@@ -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 (file)
index 0000000..5abba71
--- /dev/null
@@ -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 (file)
index 0000000..59ffd36
--- /dev/null
@@ -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))