]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #4322 from sworleys/Nexthop-Cmp
authorRenato Westphal <renato@opensourcerouting.org>
Tue, 28 May 2019 14:32:44 +0000 (11:32 -0300)
committerGitHub <noreply@github.com>
Tue, 28 May 2019 14:32:44 +0000 (11:32 -0300)
lib: Add nexthop_cmp

28 files changed:
bgpd/bgp_errors.c
bgpd/bgp_errors.h
bgpd/bgp_network.c
bgpd/bgp_route.c
bgpd/bgp_rpki.c
bgpd/bgp_vty.c
bgpd/bgpd.c
doc/developer/lists.rst
doc/user/basic.rst
doc/user/setup.rst
doc/user/zebra.rst
lib/frrstr.c
lib/frrstr.h
lib/sockunion.c
lib/sockunion.h
lib/thread.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]
tools/etc/frr/daemons
vtysh/vtysh.c
zebra/main.c
zebra/rib.h
zebra/zebra_rib.c
zebra/zebra_router.h

index 753ee6baf10043dad5d3966d66393c0d48091a7e..6e181697d64c07bf6da7cee88f00ae1678ef2051 100644 (file)
@@ -121,12 +121,6 @@ static struct log_ref ferr_bgp_warn[] = {
                .description = "BGP attempted to setup TCP MD5 configuration on the socket as per configuration but was unable to",
                .suggestion = "Please collect log files and open Issue",
        },
-       {
-               .code = EC_BGP_NO_SOCKOPT_MARK,
-               .title = "Unable to set socket MARK option",
-               .description = "BGP attempted to set the SO_MARK option for a socket and was unable to do so",
-               .suggestion = "Please collect log files and open Issue",
-       },
        {
                .code = EC_BGP_EVPN_PMSI_PRESENT,
                .title = "BGP Received a EVPN NLRI with PMSI included",
index 13bd318e274c0484ef17cae0e9dc056bb06ecdf8..39d043ff13c43662dde54ce999132bcc8fa748df 100644 (file)
@@ -88,7 +88,6 @@ enum bgp_log_refs {
        EC_BGP_UPDATE_PACKET_LONG,
        EC_BGP_UNRECOGNIZED_CAPABILITY,
        EC_BGP_NO_TCP_MD5,
-       EC_BGP_NO_SOCKOPT_MARK,
        EC_BGP_EVPN_PMSI_PRESENT,
        EC_BGP_EVPN_VPN_VNI,
        EC_BGP_EVPN_ESI,
index 6a5c2c4b38f9075c6a34d0883a0c5898860f7680..8e18ed75295c9a3a0886a113d04bdf8d7bd353ab 100644 (file)
@@ -588,8 +588,6 @@ static int bgp_update_source(struct peer *peer)
        return ret;
 }
 
-#define DATAPLANE_MARK 254     /* main table ID */
-
 /* BGP try to connect to the peer.  */
 int bgp_connect(struct peer *peer)
 {
@@ -619,10 +617,6 @@ int bgp_connect(struct peer *peer)
 
        sockopt_reuseaddr(peer->fd);
        sockopt_reuseport(peer->fd);
-       if (sockopt_mark_default(peer->fd, DATAPLANE_MARK, &bgpd_privs) < 0)
-               flog_warn(EC_BGP_NO_SOCKOPT_MARK,
-                         "Unable to set mark on FD for peer %s, err=%s",
-                         peer->host, safe_strerror(errno));
 
 #ifdef IPTOS_PREC_INTERNETCONTROL
        frr_elevate_privs(&bgpd_privs) {
index d526afd77bfa46e832e2616959e20c0f8680ecea..31243c899dc2219e6709b8998d54d99fd58aa6ac 100644 (file)
@@ -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)) {
@@ -8040,6 +8086,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();
@@ -8175,21 +8222,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)
@@ -8198,19 +8257,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));
                        }
                }
 
@@ -8392,10 +8460,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",
index 010322233d98eb15f67985d56b1747359712e39a..aa09026b789ad5630a464016489fd3581584e029 100644 (file)
@@ -737,28 +737,27 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
                         prefix->prefixlen, &result);
 
        // Print Debug output
-       prefix_string =
-               inet_ntop(prefix->family, &prefix->u.prefix, buf, BUFSIZ);
+       prefix_string = prefix2str(prefix, buf, sizeof(buf));
        switch (result) {
        case BGP_PFXV_STATE_VALID:
                RPKI_DEBUG(
-                       "Validating Prefix %s/%hhu from asn %u    Result: VALID",
-                       prefix_string, prefix->prefixlen, as_number);
+                       "Validating Prefix %s from asn %u    Result: VALID",
+                       prefix_string, as_number);
                return RPKI_VALID;
        case BGP_PFXV_STATE_NOT_FOUND:
                RPKI_DEBUG(
-                       "Validating Prefix %s/%hhu from asn %u    Result: NOT FOUND",
-                       prefix_string, prefix->prefixlen, as_number);
+                       "Validating Prefix %s from asn %u    Result: NOT FOUND",
+                       prefix_string, as_number);
                return RPKI_NOTFOUND;
        case BGP_PFXV_STATE_INVALID:
                RPKI_DEBUG(
-                       "Validating Prefix %s/%hhu from asn %u    Result: INVALID",
-                       prefix_string, prefix->prefixlen, as_number);
+                       "Validating Prefix %s from asn %u    Result: INVALID",
+                       prefix_string, as_number);
                return RPKI_INVALID;
        default:
                RPKI_DEBUG(
-                       "Validating Prefix %s/%hhu from asn %u    Result: CANNOT VALIDATE",
-                       prefix_string, prefix->prefixlen, as_number);
+                       "Validating Prefix %s from asn %u    Result: CANNOT VALIDATE",
+                       prefix_string, as_number);
                break;
        }
        return 0;
index 2a08619ec34b0716b402217a622c439f401f5163..ae51f1d780d72ad168e47d4fba53b33de9ca72a3 100644 (file)
@@ -10909,11 +10909,11 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                if (p->password)
                        vty_out(vty, "Peer Authentication Enabled\n");
 
-               vty_out(vty, "Read thread: %s  Write thread: %s\n",
+               vty_out(vty, "Read thread: %s  Write thread: %s  FD used: %d\n",
                        p->t_read ? "on" : "off",
                        CHECK_FLAG(p->thread_flags, PEER_THREAD_WRITES_ON)
                                ? "on"
-                               : "off");
+                               : "off", p->fd);
        }
 
        if (p->notify.code == BGP_NOTIFY_OPEN_ERR
index 2a7663f195cda2e445e66e457b1be0bc2d99853f..2e648af1bb986b639f1457f7dd66da5fe89f0458 100644 (file)
@@ -2232,6 +2232,8 @@ int peer_delete(struct peer *peer)
 
        SET_FLAG(peer->flags, PEER_FLAG_DELETE);
 
+       bgp_bfd_deregister_peer(peer);
+
        /* If this peer belongs to peer group, clear up the
           relationship.  */
        if (peer->group) {
index 58c17248dd7b636563b0c2396534c0c15e6134e5..fc47a67e426f03014842417da209b6bcb505b9e6 100644 (file)
@@ -115,7 +115,7 @@ Functions provided:
 +------------------------------------+------+------+------+---------+------------+
 | _find_lt, _find_gteq               | --   | --   | --   | yes     | yes        |
 +------------------------------------+------+------+------+---------+------------+
-| use with for_each() macros         | yes  | yes  | yes  | yes     | yes        |
+| use with frr_each() macros         | yes  | yes  | yes  | yes     | yes        |
 +------------------------------------+------+------+------+---------+------------+
 
 
@@ -176,7 +176,7 @@ Common iteration macros
 
 The following iteration macros work across all data structures:
 
-.. c:function:: for_each(Z, &head, item)
+.. c:function:: frr_each(Z, &head, item)
 
    Equivalent to:
 
@@ -187,7 +187,7 @@ The following iteration macros work across all data structures:
    Note that this will fail if the list is modified while being iterated
    over.
 
-.. c:function:: for_each_safe(Z, &head, item)
+.. c:function:: frr_each_safe(Z, &head, item)
 
    Same as the previous, but the next element is pre-loaded into a "hidden"
    variable (named ``Z_safe``.)  Equivalent to:
@@ -206,7 +206,7 @@ The following iteration macros work across all data structures:
       tables is resized while iterating.  This will cause items to be
       skipped or iterated over twice.
 
-.. c:function:: for_each_from(Z, &head, item, from)
+.. c:function:: frr_each_from(Z, &head, item, from)
 
    Iterates over the list, starting at item ``from``.  This variant is "safe"
    as in the previous macro.  Equivalent to:
@@ -363,7 +363,7 @@ are several functions exposed to insert data:
 
       itemtype *prev = NULL, *item;
 
-      for_each_safe(Z, head, item) {
+      frr_each_safe(Z, head, item) {
           if (something) {
               Z_add_after(head, prev, item);
               break;
@@ -585,7 +585,7 @@ Iteration:
    struct item *i;
 
    pthread_rwlock_rdlock(&itemhead_rwlock);
-   for_each(itemlist, &itemhead, i) {
+   frr_each(itemlist, &itemhead, i) {
      /* lock must remain held while iterating */
      ...
    }
@@ -602,7 +602,7 @@ Head removal (pop) and deallocation:
    pthread_rwlock_unlock(&itemhead_rwlock);
 
    /* i might still be visible for another thread doing an
-    * for_each() (but won't be returned by another pop()) */
+    * frr_each() (but won't be returned by another pop()) */
    ...
 
    pthread_rwlock_wrlock(&itemhead_rwlock);
index f55b1b9d73a77a88fd350f2a282802203f709363..3df60169f7f75a526296b41a6faedeec4d9a2c76 100644 (file)
@@ -414,6 +414,22 @@ Terminal Mode Commands
         (view)  show [ip] bgp l2vpn evpn all overlay
         ...
 
+.. _common-show-commands:
+
+.. index:: show thread cpu
+.. clicmd:: show thread cpu [r|w|t|e|x]
+
+   This command displays system run statistics for all the different event
+   types. If no options is specified all different run types are displayed
+   together.  Additionally you can ask to look at (r)ead, (w)rite, (t)imer,
+   (e)vent and e(x)ecute thread event types.
+
+.. index:: show thread poll
+.. clicmd:: show thread poll
+
+   This command displays FRR's poll data.  It allows a glimpse into how
+   we are setting each individual fd for the poll command at that point
+   in time.
 
 .. _common-invocation-options:
 
index ffefe3790577d6d5085e4e62a44ab466fdef6a4f..2cdd3a7c7fd36a86d94006bc70e57d75d7205339 100644 (file)
@@ -6,8 +6,8 @@ Basic Setup
 After installing FRR, some basic configuration must be completed before it is
 ready to use.
 
-Daemons File
-------------
+Daemons Configuration File
+--------------------------
 After a fresh install, starting FRR will do nothing. This is because daemons
 must be explicitly enabled by editing a file in your configuration directory.
 This file is usually located at :file:`/etc/frr/daemons` and determines which
@@ -34,19 +34,6 @@ systemd. The file initially looks like this:
    bfdd=no
    fabricd=no
 
-To enable a particular daemon, simply change the corresponding 'no' to 'yes'.
-Subsequent service restarts should start the daemon.
-
-Daemons Configuration File
---------------------------
-There is another file that controls the default options passed to daemons when
-starting FRR as a service. This file is located in your configuration
-directory, usually at :file:`/etc/frr/daemons`.
-
-This file has several parts. Here is an example:
-
-::
-
    #
    # If this option is set the /etc/init.d/frr script automatically loads
    # the config via "vtysh -b" when the servers are started.
@@ -71,6 +58,7 @@ This file has several parts. Here is an example:
    bfdd_options="  --daemon -A 127.0.0.1"
    fabricd_options="  --daemon -A 127.0.0.1"
 
+   #MAX_FDS=1024
    # The list of daemons to watch is automatically generated by the init script.
    #watchfrr_options=""
 
@@ -83,6 +71,13 @@ This file has several parts. Here is an example:
 
 Breaking this file down:
 
+::
+
+   bgpd=yes
+
+To enable a particular daemon, simply change the corresponding 'no' to 'yes'.
+Subsequent service restarts should start the daemon.
+
 ::
 
    vtysh_enable=yes
@@ -91,6 +86,16 @@ As the comment says, this causes :ref:`VTYSH <vty-shell>` to apply
 configuration when starting the daemons. This is useful for a variety of
 reasons touched on in the VTYSH documentation and should generally be enabled.
 
+::
+
+   MAX_FDS=1024
+
+This allows the operator to control the number of open file descriptors
+each daemon is allowed to start with.  The current assumed value on
+most operating systems is 1024.  If the operator plans to run bgp with
+several thousands of peers than this is where we would modify FRR to
+allow this to happen.
+
 ::
 
    zebra_options=" -s 90000000 --daemon -A 127.0.0.1"
index f38db9d24105d6b3fbccf827adfb51445b5f424c..40d89492972531ea2ab26cce40d2d9c21f296ddd 100644 (file)
@@ -23,9 +23,12 @@ Besides the common invocation options (:ref:`common-invocation-options`), the
    Runs in batch mode. *zebra* parses configuration file and terminates
    immediately.
 
-.. option:: -k, --keep_kernel
+.. option:: -K TIME, --graceful_restart TIME
 
-   When zebra starts up, don't delete old self inserted routes.
+   If this option is specified, the graceful restart time is TIME seconds.
+   Zebra, when started, will read in routes.  Those routes that Zebra
+   identifies that it was the originator of will be swept in TIME seconds.
+   If no time is specified then we will sweep those routes immediately.
 
 .. option:: -r, --retain
 
index fbbc890ec69fe49cd9af1913fcc383a7907dcd31..c575c0b568ef7dd5981fadaa003d235f0ea643fc 100644 (file)
@@ -178,7 +178,7 @@ char *frrstr_replace(const char *str, const char *find, const char *replace)
        return nustr;
 }
 
-bool begins_with(const char *str, const char *prefix)
+bool frrstr_startswith(const char *str, const char *prefix)
 {
        if (!str || !prefix)
                return false;
@@ -192,6 +192,20 @@ bool begins_with(const char *str, const char *prefix)
        return strncmp(str, prefix, lenprefix) == 0;
 }
 
+bool frrstr_endswith(const char *str, const char *suffix)
+{
+       if (!str || !suffix)
+               return false;
+
+       size_t lenstr = strlen(str);
+       size_t lensuffix = strlen(suffix);
+
+       if (lensuffix > lenstr)
+               return false;
+
+       return strncmp(&str[lenstr - lensuffix], suffix, lensuffix) == 0;
+}
+
 int all_digit(const char *str)
 {
        for (; *str != '\0'; str++)
index d40ca14ba5eae6ebec0151dda98aadbf277d6545..3a935c90cb26062c0d9cf5d97888634aac2e10de 100644 (file)
@@ -109,6 +109,7 @@ void frrstr_strvec_free(vector v);
  *    the replacement on 'str'. This must be freed by the caller.
  */
 char *frrstr_replace(const char *str, const char *find, const char *replace);
+
 /*
  * Prefix match for string.
  *
@@ -119,9 +120,23 @@ char *frrstr_replace(const char *str, const char *find, const char *replace);
  *    prefix to look for
  *
  * Returns:
- *   true str starts with prefix, false otherwise
+ *   true if str starts with prefix, false otherwise
+ */
+bool frrstr_startswith(const char *str, const char *prefix);
+
+/*
+ * Suffix match for string.
+ *
+ * str
+ *    string to check for suffix match
+ *
+ * suffix
+ *    suffix to look for
+ *
+ * Returns:
+ *   true if str ends with suffix, false otherwise
  */
-bool begins_with(const char *str, const char *prefix);
+bool frrstr_endswith(const char *str, const char *suffix);
 
 /*
  * Check the string only contains digit characters.
index 5afd10eb4811ec6c127b3a99d75614aab937b25b..8fa9a3fad99187073a9114fedb42b66397237d50 100644 (file)
@@ -366,21 +366,6 @@ int sockopt_cork(int sock, int onoff)
        return 0;
 }
 
-int sockopt_mark_default(int sock, int mark, struct zebra_privs_t *cap)
-{
-#ifdef SO_MARK
-       int ret;
-
-       frr_elevate_privs(cap) {
-               ret = setsockopt(sock, SOL_SOCKET, SO_MARK, &mark,
-                                sizeof(mark));
-       }
-       return ret;
-#else
-       return 0;
-#endif
-}
-
 int sockopt_minttl(int family, int sock, int minttl)
 {
 #ifdef IP_MINTTL
index b9967355502e259a1360b76802fae40b7d127361..7091c1b5e78b5d95e03fb86d69703ef5d2d0dc05 100644 (file)
@@ -93,7 +93,6 @@ extern int sockunion_bind(int sock, union sockunion *, unsigned short,
 extern int sockopt_ttl(int family, int sock, int ttl);
 extern int sockopt_minttl(int family, int sock, int minttl);
 extern int sockopt_cork(int sock, int onoff);
-extern int sockopt_mark_default(int sock, int mark, struct zebra_privs_t *);
 extern int sockunion_socket(const union sockunion *su);
 extern const char *inet_sutop(const union sockunion *su, char *str);
 extern enum connect_result sockunion_connect(int fd, const union sockunion *su,
index 7a9a0ab608e6ff8cd57d22456274d6fe57b360ef..d3fb2cdf3650c688e74b3c852ebb07f8311cde0e 100644 (file)
@@ -281,7 +281,7 @@ DEFUN (show_thread_cpu,
        SHOW_STR
        "Thread information\n"
        "Thread CPU usage\n"
-       "Display filter (rwtexb)\n")
+       "Display filter (rwtex)\n")
 {
        uint8_t filter = (uint8_t)-1U;
        int idx = 0;
@@ -312,7 +312,8 @@ static void show_thread_poll_helper(struct vty *vty, struct thread_master *m)
 
        vty_out(vty, "\nShowing poll FD's for %s\n", name);
        vty_out(vty, "----------------------%s\n", underline);
-       vty_out(vty, "Count: %u\n", (uint32_t)m->handler.pfdcount);
+       vty_out(vty, "Count: %u/%d\n", (uint32_t)m->handler.pfdcount,
+               m->fd_limit);
        for (i = 0; i < m->handler.pfdcount; i++)
                vty_out(vty, "\t%6d fd:%6d events:%2d revents:%2d\n", i,
                        m->handler.pfds[i].fd,
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))
index b920621d70c8a3b5c1f792f05e3473f1726f37dc..79c52d30d103de5fd332f1505997432ec85db793 100644 (file)
@@ -56,6 +56,14 @@ bfdd_options="   -A 127.0.0.1"
 fabricd_options="-A 127.0.0.1"
 vrrpd_options="  -A 127.0.0.1"
 
+#
+# This is the maximum number of FD's that will be available.
+# Upon startup this is read by the control files and ulimit
+# is called.  Uncomment and use a reasonable value for your
+# setup if you are expecting a large number of peers in
+# say BGP.
+#MAX_FDS=1024
+
 # The list of daemons to watch is automatically generated by the init script.
 #watchfrr_options=""
 
index f1a5eca74bc4e21d5cc79e64b3a15fe9b9e9bfbd..a0b119c3ebaf23679efac8f33af7d252667dd505 100644 (file)
@@ -3347,7 +3347,7 @@ static void vtysh_update_all_instances(struct vtysh_client *head_client)
        dir = opendir(vtydir);
        if (dir) {
                while ((file = readdir(dir)) != NULL) {
-                       if (begins_with(file->d_name, "ospfd-")
+                       if (frrstr_startswith(file->d_name, "ospfd-")
                            && ends_with(file->d_name, ".vty")) {
                                if (n == MAXIMUM_INSTANCES) {
                                        fprintf(stderr,
index cff5e069337e4c81ad85e5fdecf059a8dc92f377..5797a5846aa8ef6f398a4148636cc7aa0e030cc6 100644 (file)
@@ -74,8 +74,7 @@ int retain_mode = 0;
 /* Allow non-quagga entities to delete quagga routes */
 int allow_delete = 0;
 
-/* Don't delete kernel route. */
-int keep_kernel_mode = 0;
+int graceful_restart;
 
 bool v6_rr_semantics = false;
 
@@ -95,6 +94,7 @@ struct option longopts[] = {
        {"label_socket", no_argument, NULL, 'l'},
        {"retain", no_argument, NULL, 'r'},
        {"vrfdefaultname", required_argument, NULL, 'o'},
+       {"graceful_restart", required_argument, NULL, 'K'},
 #ifdef HAVE_NETLINK
        {"vrfwnetns", no_argument, NULL, 'n'},
        {"nl-bufsize", required_argument, NULL, 's'},
@@ -262,13 +262,14 @@ int main(int argc, char **argv)
        char *netlink_fuzzing = NULL;
 #endif /* HANDLE_NETLINK_FUZZING */
 
+       graceful_restart = 0;
        vrf_configure_backend(VRF_BACKEND_VRF_LITE);
        logicalrouter_configure_backend(LOGICALROUTER_BACKEND_NETNS);
 
        frr_preinit(&zebra_di, argc, argv);
 
        frr_opt_add(
-               "bakz:e:l:o:r"
+               "baz:e:l:o:rK:"
 #ifdef HAVE_NETLINK
                "s:n"
 #endif
@@ -280,24 +281,24 @@ int main(int argc, char **argv)
 #endif /* HANDLE_NETLINK_FUZZING */
                ,
                longopts,
-               "  -b, --batch           Runs in batch mode\n"
-               "  -a, --allow_delete    Allow other processes to delete zebra routes\n"
-               "  -z, --socket          Set path of zebra socket\n"
-               "  -e, --ecmp            Specify ECMP to use.\n"
-               "  -l, --label_socket    Socket to external label manager\n"
-               "  -k, --keep_kernel     Don't delete old routes which were installed by zebra.\n"
-               "  -r, --retain          When program terminates, retain added route by zebra.\n"
-               "  -o, --vrfdefaultname  Set default VRF name.\n"
+               "  -b, --batch              Runs in batch mode\n"
+               "  -a, --allow_delete       Allow other processes to delete zebra routes\n"
+               "  -z, --socket             Set path of zebra socket\n"
+               "  -e, --ecmp               Specify ECMP to use.\n"
+               "  -l, --label_socket       Socket to external label manager\n"
+               "  -r, --retain             When program terminates, retain added route by zebra.\n"
+               "  -o, --vrfdefaultname     Set default VRF name.\n"
+               "  -K, --graceful_restart   Graceful restart at the kernel level, timer in seconds for expiration\n"
 #ifdef HAVE_NETLINK
-               "  -n, --vrfwnetns       Use NetNS as VRF backend\n"
-               "  -s, --nl-bufsize      Set netlink receive buffer size\n"
-               "      --v6-rr-semantics Use v6 RR semantics\n"
+               "  -n, --vrfwnetns          Use NetNS as VRF backend\n"
+               "  -s, --nl-bufsize         Set netlink receive buffer size\n"
+               "      --v6-rr-semantics    Use v6 RR semantics\n"
 #endif /* HAVE_NETLINK */
 #if defined(HANDLE_ZAPI_FUZZING)
-               "  -c <file>             Bypass normal startup and use this file for testing of zapi\n"
+               "  -c <file>                Bypass normal startup and use this file for testing of zapi\n"
 #endif /* HANDLE_ZAPI_FUZZING */
 #if defined(HANDLE_NETLINK_FUZZING)
-               "  -w <file>             Bypass normal startup and use this file for testing of netlink input\n"
+               "  -w <file>                Bypass normal startup and use this file for testing of netlink input\n"
 #endif /* HANDLE_NETLINK_FUZZING */
        );
 
@@ -316,9 +317,6 @@ int main(int argc, char **argv)
                case 'a':
                        allow_delete = 1;
                        break;
-               case 'k':
-                       keep_kernel_mode = 1;
-                       break;
                case 'e':
                        zrouter.multipath_num = atoi(optarg);
                        if (zrouter.multipath_num > MULTIPATH_NUM
@@ -348,6 +346,9 @@ int main(int argc, char **argv)
                case 'r':
                        retain_mode = 1;
                        break;
+               case 'K':
+                       graceful_restart = atoi(optarg);
+                       break;
 #ifdef HAVE_NETLINK
                case 's':
                        nl_rcvbufsize = atoi(optarg);
@@ -435,8 +436,9 @@ int main(int argc, char **argv)
        *  will be equal to the current getpid(). To know about such routes,
        * we have to have route_read() called before.
        */
-       if (!keep_kernel_mode)
-               rib_sweep_route();
+       zrouter.startup_time = monotime(NULL);
+       thread_add_timer(zrouter.master, rib_sweep_route,
+                        NULL, graceful_restart, NULL);
 
        /* Needed for BSD routing socket. */
        pid = getpid();
index ca0801c20977486668c1e42cb19d50e9944ae394..0353c9bb99bb9327282f6a484650817bee274c7f 100644 (file)
@@ -400,7 +400,7 @@ extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p,
 extern void rib_update(vrf_id_t vrf_id, rib_update_event_t event);
 extern void rib_update_table(struct route_table *table,
                             rib_update_event_t event);
-extern void rib_sweep_route(void);
+extern int rib_sweep_route(struct thread *t);
 extern void rib_sweep_table(struct route_table *table);
 extern void rib_close_table(struct route_table *table);
 extern void rib_init(void);
index b44ed3543f9c5d0a715e414ca583952d044af9b2..b31b6a12508b491073e7a61694bdd4042a6670f4 100644 (file)
@@ -3131,6 +3131,7 @@ void rib_sweep_table(struct route_table *table)
 
        for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
                RNODE_FOREACH_RE_SAFE (rn, re, next) {
+
                        if (IS_ZEBRA_DEBUG_RIB)
                                route_entry_dump(&rn->p, NULL, re);
 
@@ -3140,6 +3141,14 @@ void rib_sweep_table(struct route_table *table)
                        if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELFROUTE))
                                continue;
 
+                       /*
+                        * If routes are older than startup_time then
+                        * we know we read them in from the kernel.
+                        * As such we can safely remove them.
+                        */
+                       if (zrouter.startup_time < re->uptime)
+                               continue;
+
                        /*
                         * So we are starting up and have received
                         * routes from the kernel that we have installed
@@ -3169,7 +3178,7 @@ void rib_sweep_table(struct route_table *table)
 }
 
 /* Sweep all RIB tables.  */
-void rib_sweep_route(void)
+int rib_sweep_route(struct thread *t)
 {
        struct vrf *vrf;
        struct zebra_vrf *zvrf;
@@ -3183,6 +3192,8 @@ void rib_sweep_route(void)
        }
 
        zebra_router_sweep_route();
+
+       return 0;
 }
 
 /* Remove specific by protocol routes from 'table'. */
index b3def297ac6bfdc59ce9da411df71da36fde8295..6c9f3a0f281b7857ec0c7afe66682f5560f8dcad 100644 (file)
@@ -112,8 +112,15 @@ struct zebra_router {
        struct zebra_vrf *evpn_vrf;
 
        uint32_t multipath_num;
+
+       /*
+        * Time for when we sweep the rib from old routes
+        */
+       time_t startup_time;
 };
 
+#define GRACEFUL_RESTART_TIME 60
+
 extern struct zebra_router zrouter;
 
 extern void zebra_router_init(void);