diff options
| -rw-r--r-- | .github/workflows/base-branch-label.yml | 20 | ||||
| -rw-r--r-- | bgpd/bgp_packet.c | 1 | ||||
| -rw-r--r-- | bgpd/bgp_rpki.c | 204 | ||||
| -rw-r--r-- | debian/changelog | 6 | ||||
| -rw-r--r-- | doc/user/overview.rst | 2 | ||||
| -rw-r--r-- | doc/user/rpki.rst | 6 | ||||
| -rw-r--r-- | docker/alpine/Dockerfile | 7 | ||||
| -rw-r--r-- | docker/centos-7/Dockerfile | 8 | ||||
| -rw-r--r-- | docker/centos-8/Dockerfile | 6 | ||||
| -rw-r--r-- | docker/ubi-8/Dockerfile | 6 | ||||
| -rw-r--r-- | redhat/frr.spec.in | 88 | ||||
| -rw-r--r-- | tests/topotests/bgp_gr_notification/__init__.py | 0 | ||||
| -rw-r--r-- | tests/topotests/bgp_gr_notification/r1/bgpd.conf | 10 | ||||
| -rw-r--r-- | tests/topotests/bgp_gr_notification/r1/zebra.conf | 9 | ||||
| -rw-r--r-- | tests/topotests/bgp_gr_notification/r2/bgpd.conf | 11 | ||||
| -rw-r--r-- | tests/topotests/bgp_gr_notification/r2/zebra.conf | 9 | ||||
| -rw-r--r-- | tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py | 224 | ||||
| -rw-r--r-- | tests/topotests/cspf_topo1/reference/sharp-ted.json | 2 | ||||
| -rw-r--r-- | tests/topotests/pbr_topo1/test_pbr_topo1.py | 12 |
19 files changed, 563 insertions, 68 deletions
diff --git a/.github/workflows/base-branch-label.yml b/.github/workflows/base-branch-label.yml new file mode 100644 index 0000000000..9572ee7ee2 --- /dev/null +++ b/.github/workflows/base-branch-label.yml @@ -0,0 +1,20 @@ +name: Add base branch label + +on: + pull_request: + types: + - opened + - reopened + +jobs: + label: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - uses: actions/checkout@v2 + - uses: actions-ecosystem/action-add-labels@v1 + with: + labels: | + ${{ github.event.pull_request.base.ref }} diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index c8996ba634..5560469838 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -733,7 +733,6 @@ static void bgp_write_notify(struct peer *peer) /* Type should be notify. */ atomic_fetch_add_explicit(&peer->notify_out, 1, memory_order_relaxed); - peer->notify_out++; /* Double start timer. */ peer->v_start *= 2; diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 97e94a97ce..c28b81a413 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -1194,14 +1194,6 @@ DEFUN (show_rpki_prefix_table, RPKI_OUTPUT_STRING "Show validated prefixes which were received from RPKI Cache\n") { - struct listnode *cache_node; - struct cache *cache; - - for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) { - vty_out(vty, "host: %s port: %s\n", - cache->tr_config.tcp_config->host, - cache->tr_config.tcp_config->port); - } if (is_synchronized()) print_prefix_table(vty); else @@ -1278,62 +1270,137 @@ DEFPY (show_rpki_prefix, return CMD_SUCCESS; } -DEFUN (show_rpki_cache_server, +DEFPY (show_rpki_cache_server, show_rpki_cache_server_cmd, - "show rpki cache-server", + "show rpki cache-server [json$uj]", SHOW_STR RPKI_OUTPUT_STRING - "SHOW configured cache server\n") + "Show configured cache server\n" + JSON_STR) { + struct json_object *json = NULL; + struct json_object *json_server = NULL; + struct json_object *json_servers = NULL; struct listnode *cache_node; struct cache *cache; + if (uj) { + json = json_object_new_object(); + json_servers = json_object_new_array(); + json_object_object_add(json, "servers", json_servers); + } + for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) { if (cache->type == TCP) { - vty_out(vty, "host: %s port: %s\n", - cache->tr_config.tcp_config->host, - cache->tr_config.tcp_config->port); + if (!json) { + vty_out(vty, "host: %s port: %s\n", + cache->tr_config.tcp_config->host, + cache->tr_config.tcp_config->port); + } else { + json_server = json_object_new_object(); + json_object_string_add(json_server, "mode", + "tcp"); + json_object_string_add( + json_server, "host", + cache->tr_config.tcp_config->host); + json_object_string_add( + json_server, "port", + cache->tr_config.tcp_config->port); + json_object_array_add(json_servers, + json_server); + } #if defined(FOUND_SSH) } else if (cache->type == SSH) { - vty_out(vty, - "host: %s port: %d username: %s server_hostkey_path: %s client_privkey_path: %s\n", - cache->tr_config.ssh_config->host, - cache->tr_config.ssh_config->port, - cache->tr_config.ssh_config->username, - cache->tr_config.ssh_config - ->server_hostkey_path, - cache->tr_config.ssh_config - ->client_privkey_path); + if (!json) { + vty_out(vty, + "host: %s port: %d username: %s server_hostkey_path: %s client_privkey_path: %s\n", + cache->tr_config.ssh_config->host, + cache->tr_config.ssh_config->port, + cache->tr_config.ssh_config->username, + cache->tr_config.ssh_config + ->server_hostkey_path, + cache->tr_config.ssh_config + ->client_privkey_path); + } else { + json_server = json_object_new_object(); + json_object_string_add(json_server, "mode", + "ssh"); + json_object_string_add( + json_server, "host", + cache->tr_config.ssh_config->host); + json_object_int_add( + json_server, "port", + cache->tr_config.ssh_config->port); + json_object_string_add( + json_server, "username", + cache->tr_config.ssh_config->username); + json_object_string_add( + json_server, "serverHostkeyPath", + cache->tr_config.ssh_config + ->server_hostkey_path); + json_object_string_add( + json_server, "clientPrivkeyPath", + cache->tr_config.ssh_config + ->client_privkey_path); + json_object_array_add(json_servers, + json_server); + } #endif } } + if (json) + vty_json(vty, json); + return CMD_SUCCESS; } -DEFUN (show_rpki_cache_connection, +DEFPY (show_rpki_cache_connection, show_rpki_cache_connection_cmd, - "show rpki cache-connection", + "show rpki cache-connection [json$uj]", SHOW_STR RPKI_OUTPUT_STRING - "Show to which RPKI Cache Servers we have a connection\n") + "Show to which RPKI Cache Servers we have a connection\n" + JSON_STR) { + struct json_object *json = NULL; + struct json_object *json_conn = NULL; + struct json_object *json_conns = NULL; + struct listnode *cache_node; + struct cache *cache; + struct rtr_mgr_group *group; + + if (uj) + json = json_object_new_object(); + if (!is_synchronized()) { - vty_out(vty, "No connection to RPKI cache server.\n"); + if (!json) + vty_out(vty, "No connection to RPKI cache server.\n"); + else + vty_json(vty, json); return CMD_SUCCESS; } - struct listnode *cache_node; - struct cache *cache; - struct rtr_mgr_group *group = get_connected_group(); - + group = get_connected_group(); if (!group) { - vty_out(vty, "Cannot find a connected group.\n"); + if (!json) + vty_out(vty, "Cannot find a connected group.\n"); + else + vty_json(vty, json); + return CMD_SUCCESS; } - vty_out(vty, "Connected to group %d\n", group->preference); + + if (!json) { + vty_out(vty, "Connected to group %d\n", group->preference); + } else { + json_conns = json_object_new_array(); + json_object_int_add(json, "connectedGroup", group->preference); + json_object_object_add(json, "connections", json_conns); + } + for (ALL_LIST_ELEMENTS_RO(cache_list, cache_node, cache)) { struct tr_tcp_config *tcp_config; #if defined(FOUND_SSH) @@ -1342,22 +1409,66 @@ DEFUN (show_rpki_cache_connection, switch (cache->type) { case TCP: tcp_config = cache->tr_config.tcp_config; - vty_out(vty, "rpki tcp cache %s %s pref %hhu%s\n", - tcp_config->host, tcp_config->port, - cache->preference, - cache->rtr_socket->state == RTR_ESTABLISHED - ? " (connected)" - : ""); + + if (!json) { + vty_out(vty, + "rpki tcp cache %s %s pref %hhu%s\n", + tcp_config->host, tcp_config->port, + cache->preference, + cache->rtr_socket->state == + RTR_ESTABLISHED + ? " (connected)" + : ""); + } else { + json_conn = json_object_new_object(); + json_object_string_add(json_conn, "mode", + "tcp"); + json_object_string_add(json_conn, "host", + tcp_config->host); + json_object_string_add(json_conn, "port", + tcp_config->port); + json_object_int_add(json_conn, "preference", + cache->preference); + json_object_string_add( + json_conn, "state", + cache->rtr_socket->state == + RTR_ESTABLISHED + ? "connected" + : "disconnected"); + json_object_array_add(json_conns, json_conn); + } break; #if defined(FOUND_SSH) case SSH: ssh_config = cache->tr_config.ssh_config; - vty_out(vty, "rpki ssh cache %s %u pref %hhu%s\n", - ssh_config->host, ssh_config->port, - cache->preference, - cache->rtr_socket->state == RTR_ESTABLISHED - ? " (connected)" - : ""); + + if (!json) { + vty_out(vty, + "rpki ssh cache %s %u pref %hhu%s\n", + ssh_config->host, ssh_config->port, + cache->preference, + cache->rtr_socket->state == + RTR_ESTABLISHED + ? " (connected)" + : ""); + } else { + json_conn = json_object_new_object(); + json_object_string_add(json_conn, "mode", + "ssh"); + json_object_string_add(json_conn, "host", + ssh_config->host); + json_object_int_add(json_conn, "port", + ssh_config->port); + json_object_int_add(json_conn, "preference", + cache->preference); + json_object_string_add( + json_conn, "state", + cache->rtr_socket->state == + RTR_ESTABLISHED + ? "connected" + : "disconnected"); + json_object_array_add(json_conns, json_conn); + } break; #endif default: @@ -1365,6 +1476,9 @@ DEFUN (show_rpki_cache_connection, } } + if (json) + vty_json(vty, json); + return CMD_SUCCESS; } diff --git a/debian/changelog b/debian/changelog index f3e42199de..0661ffbb97 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,12 @@ frr (8.3~dev-1) UNRELEASED; urgency=medium -- Donatas Abraitis <donatas.abraitis@gmail.com> Tue, 01 Feb 2022 11:00:00 +0200 +frr (8.2-0) UNRELEASED; urgency=medium + + * New upstream release FRR 8.2 + + -- Jafar Al-Gharaibeh <jafar@atcorp.com> Tue, 01 Mar 2022 10:00:00 +0500 + frr (8.1-0) unstable; urgency=medium * New upstream release FRR 8.1 diff --git a/doc/user/overview.rst b/doc/user/overview.rst index 516650641a..9bcd2af346 100644 --- a/doc/user/overview.rst +++ b/doc/user/overview.rst @@ -519,7 +519,7 @@ Bug Reports For information on reporting bugs, please see :ref:`bug-reports`. -.. _frr: |PACKAGE_URL| +.. _frr: https://frrouting.org .. _github: https://github.com/frrouting/frr/ .. _github issues: https://github.com/frrouting/frr/issues .. _slack: https://frrouting.org/community diff --git a/doc/user/rpki.rst b/doc/user/rpki.rst index c2f8ad1268..ece788d9e3 100644 --- a/doc/user/rpki.rst +++ b/doc/user/rpki.rst @@ -216,10 +216,14 @@ Displaying RPKI received from the cache servers and stored in the router. Based on this data, the router validates BGP Updates. -.. clicmd:: show rpki cache-connection +.. clicmd:: show rpki cache-server [json] Display all configured cache servers, whether active or not. +.. clicmd:: show rpki cache-connection [json] + + Display all cache connections, and show which is connected or not. + .. clicmd:: show bgp [afi] [safi] <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> rpki <valid|invalid|notfound> Display for the specified prefix or address the bgp paths that match the given rpki state. diff --git a/docker/alpine/Dockerfile b/docker/alpine/Dockerfile index 79ae315679..fa4b9859b9 100644 --- a/docker/alpine/Dockerfile +++ b/docker/alpine/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 # Create a basic stage set up to build APKs -FROM alpine:3.13 as alpine-builder +FROM alpine:3.15 as alpine-builder RUN apk add \ --update-cache \ abuild \ @@ -22,7 +22,7 @@ RUN cd /libyang \ && abuild -r -P /pkgs/apk # This stage builds a dist tarball from the source -FROM alpine:3.13 as source-builder +FROM alpine:3.15 as source-builder RUN mkdir -p /src/alpine COPY alpine/APKBUILD.in /src/alpine @@ -33,6 +33,7 @@ RUN source /src/alpine/APKBUILD.in \ $makedepends \ gzip \ py-pip \ + rtrlib \ && pip install pytest RUN mkdir -p /pkgs/apk @@ -66,7 +67,7 @@ RUN cd /dist \ && abuild -r -P /pkgs/apk # This stage installs frr from the apk -FROM alpine:3.13 +FROM alpine:3.15 RUN mkdir -p /pkgs/apk COPY --from=frr-apk-builder /pkgs/apk/ /pkgs/apk/ RUN apk add \ diff --git a/docker/centos-7/Dockerfile b/docker/centos-7/Dockerfile index 73097df8fa..2d1ee9efa4 100644 --- a/docker/centos-7/Dockerfile +++ b/docker/centos-7/Dockerfile @@ -4,11 +4,11 @@ RUN yum install -y epel-release RUN yum install -y rpm-build autoconf automake libtool make \ readline-devel texinfo net-snmp-devel groff pkgconfig \ json-c-devel pam-devel bison flex pytest c-ares-devel \ - python3-devel python3-sphinx libcap-devel \ + python3-devel python3-sphinx libcap-devel systemd-devel \ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-7-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el7.x86_64.rpm \ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-7-x86_64-Packages/libyang2-devel-2.0.0.10.g2eb910e4-1.el7.x86_64.rpm \ - https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm \ - https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-devel-0.7.0-1.el7.centos.x86_64.rpm + https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm \ + https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-devel-0.8.0-1.el7.x86_64.rpm COPY . /src ARG PKGVER @@ -33,7 +33,7 @@ RUN echo '%_smp_mflags %( echo "-j$(/usr/bin/getconf _NPROCESSORS_ONLN)"; )' >> FROM centos:centos7 RUN mkdir -p /pkgs/rpm \ && yum install -y https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-7-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el7.x86_64.rpm \ - https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm + https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm COPY --from=centos-7-builder /rpmbuild/RPMS/ /pkgs/rpm/ diff --git a/docker/centos-8/Dockerfile b/docker/centos-8/Dockerfile index df095edcde..df772b8318 100644 --- a/docker/centos-8/Dockerfile +++ b/docker/centos-8/Dockerfile @@ -11,8 +11,8 @@ RUN dnf install --enablerepo=powertools -y rpm-build git autoconf pcre-devel \ c-ares-devel python3-devel python3-sphinx libcap-devel platform-python-devel \ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-devel-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \ - https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm \ - https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-devel-0.7.0-1.el7.centos.x86_64.rpm + https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm \ + https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-devel-0.8.0-1.el7.x86_64.rpm COPY . /src @@ -42,7 +42,7 @@ RUN sed -i -e "s|mirrorlist=|#mirrorlist=|g" /etc/yum.repos.d/CentOS-* \ RUN mkdir -p /pkgs/rpm \ && yum install -y https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \ - https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm + https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm COPY --from=centos-8-builder /rpmbuild/RPMS/ /pkgs/rpm/ diff --git a/docker/ubi-8/Dockerfile b/docker/ubi-8/Dockerfile index 7b2db66ede..1d1e8bdc6e 100644 --- a/docker/ubi-8/Dockerfile +++ b/docker/ubi-8/Dockerfile @@ -16,8 +16,8 @@ RUN dnf install -qy https://dl.fedoraproject.org/pub/epel/epel-release-latest-8. libcap-devel platform-python-devel \ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \ https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-devel-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \ - https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm \ - https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-devel-0.7.0-1.el7.centos.x86_64.rpm + https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm \ + https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-devel-0.8.0-1.el7.x86_64.rpm COPY . /src @@ -60,7 +60,7 @@ RUN rpm --import https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official \ RUN dnf install -qy https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm \ && mkdir -p /pkgs/rpm \ && dnf install --enablerepo=* -qy https://ci1.netdef.org/artifact/LIBYANG-LIBYANGV2/shared/build-2/CentOS-8-x86_64-Packages/libyang2-2.0.0.10.g2eb910e4-1.el8.x86_64.rpm \ - https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-110/CentOS-7-x86_64-Packages/librtr-0.7.0-1.el7.centos.x86_64.rpm + https://ci1.netdef.org/artifact/RPKI-RTRLIB/shared/build-00146/CentOS-7-x86_64-Packages/librtr-0.8.0-1.el7.x86_64.rpm COPY --from=ubi-8-builder /rpmbuild/RPMS/ /pkgs/rpm/ diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index 0753940595..c479a7d4cf 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -774,9 +774,91 @@ sed -i 's/ -M rpki//' %{_sysconfdir}/frr/daemons %changelog -* Tue Nov 4 2021 Martin Winter <mwinter@opensourcerouting.org> - %{version} - -* Tue Feb 1 2022 Donatas Abraitis <donatas.abraitis@gmail.com> - 8.2 +* Tue Mar 1 2022 Martin Winter <mwinter@opensourcerouting.org> - %{version} + +* Tue Mar 1 2022 Jafar Al-Gharaibeh <jafar@atcorp.com> - 8.2 +- The FRRouting community would like to announce FRR Release 8.2. +- This release consists of just over 800 commits from 62 authors. +- Selected features and bug fixes are listed below. +- babeld: +- Fix the checks for truncated packets +- bfdd: +- Correct one spelling error of comment +- Fix detection timeout update +- Fix possibly wrong counter of control packets +- bgpd: +- Add "json" option to a few more show commands +- Add 'show bgp <afi> <safi> json detail' header data +- Add a 6 hour warning to missing policy +- Add an ability to match ipv6 next-hop by prefix-list +- Add autocomplete for access-list under bmp node +- Add autocomplete for as-path filters +- Add autocomplete for set/match community/large/ext lists +- Add long-lived graceful restart capability +- Add peer-groups to neighbor autocomplete +- Adjust symbolic names for cease notifications according to rfc4486 +- Deprecate dpa, advertiser and rcid_path path attributes +- Extended bgp administrative shutdown communication +- Fix crash when using "show bgp vrf all" +- Fix inconsistency of match ip/ipv6 next-hop commands +- Fix missing name of default vrf +- Handle TCP connection errors with connection callbacks for RPKI +- Implement llgr helper mode +- Implement rfc9072 +- Support redirect import more than one route-target ipv6 +- docker: +- Update alpine build enable set own version +- isisd: +- Add link state traffic engineering support +- Fix router capability tlv parsing issues +- Fix running-config for fast-reroute +- Make isis work with default vrf name different than 'default' +- ospf6d +- Add missing vrf parameter to "clear ipv6 ospf6 interface" +- Add prompt for commands with non-exist vrf +- Add support for nssa type-7 address ranges +- Add the ability of specifying router-id/area-id in no debug ospf6 +- Do not originate type-4 lsa when nssa +- Do not send type-5 into stub area +- Fix ecmp inter-area route nexthop update +- Fix memory leak for `show ipv6 ospf6 zebra json` +- ospfd +- Fix wrong comparison of routemap name +- Fix crash on "ospf send-extra-data zebra" +- Fix incorrect detection of topology changes in helper mode +- Fix loss of mixed form in "range" command +- Fix no-form of "graceful-restart" command +- Fix summary-address deletion +- Fix wrong parsing of te subtlv +- pbrd +- Add vlan actions to vty +- Pbr route maps get addr family of nhgs +- Protect from a possible null dereference +- pimd +- Do not allow 224.0.0.0/24 range in igmp join +- Fix igmp user config +- Fix msdp mesh grp with wildcard member addr +- Fix stale forwarding entries left around after join goes away +- Fix FRR drops IGMP packets for TOS value other than 0XC0 +- redhat +- Check if frr.conf already exists +- Logrotate file has typo for staticd +- ripd +- Fix packet send for non primary addresses +- vtysh +- Add missing rpki node when showing config +- Improve startup time by ca. ×6 +- remove `address-family evpn` +- watchfrr +- Allow an integrated config to work within a namespace +- zebra +- Add optional nhg id output to `show ip ro` +- Add resolver flag for nexthop in json +- Add support for json output in srv6 locator detail command +- Don't lose next hop weights while exporting via fpm +- Fix buffer overflow +- Fix netns deletion +- Fix route-map application when when using vrfs * Tue Nov 2 2021 Jafar Al-Gharaibeh <jafar@atcorp.com> - 8.1 - FRR 8.1 brings a long list of enhancements and fixes with 1200 commits from diff --git a/tests/topotests/bgp_gr_notification/__init__.py b/tests/topotests/bgp_gr_notification/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_gr_notification/__init__.py diff --git a/tests/topotests/bgp_gr_notification/r1/bgpd.conf b/tests/topotests/bgp_gr_notification/r1/bgpd.conf new file mode 100644 index 0000000000..6119f67436 --- /dev/null +++ b/tests/topotests/bgp_gr_notification/r1/bgpd.conf @@ -0,0 +1,10 @@ +router bgp 65001 + no bgp ebgp-requires-policy + bgp graceful-restart + neighbor 192.168.255.2 remote-as external + neighbor 192.168.255.2 timers 1 3 + neighbor 192.168.255.2 timers connect 1 + address-family ipv4 + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_gr_notification/r1/zebra.conf b/tests/topotests/bgp_gr_notification/r1/zebra.conf new file mode 100644 index 0000000000..091794f475 --- /dev/null +++ b/tests/topotests/bgp_gr_notification/r1/zebra.conf @@ -0,0 +1,9 @@ +! +interface lo + ip address 172.16.255.1/32 +! +interface r1-eth0 + ip address 192.168.255.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_gr_notification/r2/bgpd.conf b/tests/topotests/bgp_gr_notification/r2/bgpd.conf new file mode 100644 index 0000000000..05e17f0564 --- /dev/null +++ b/tests/topotests/bgp_gr_notification/r2/bgpd.conf @@ -0,0 +1,11 @@ +router bgp 65002 + no bgp ebgp-requires-policy + no bgp hard-administrative-reset + bgp graceful-restart + neighbor 192.168.255.1 remote-as external + neighbor 192.168.255.1 timers 1 3 + neighbor 192.168.255.1 timers connect 1 + address-family ipv4 + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_gr_notification/r2/zebra.conf b/tests/topotests/bgp_gr_notification/r2/zebra.conf new file mode 100644 index 0000000000..1fcccbe161 --- /dev/null +++ b/tests/topotests/bgp_gr_notification/r2/zebra.conf @@ -0,0 +1,9 @@ +! +interface lo + ip address 172.16.255.2/32 +! +interface r2-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py new file mode 100644 index 0000000000..3519e5cc7b --- /dev/null +++ b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python + +# +# bgp_gr_notification.py +# +# Copyright (c) 2022 by +# Donatas Abraitis <donatas@opensourcerouting.org> +# +# 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. +# + +""" +TC1: Disable the link between R1-R2 and wait for HoldTimerExpire notification: + 1) Check if R2 sent HoldTimerExpired notification + 2) Check if the routes are retained at R2 +TC2: Trigger `clear bgp` (Administrative Reset): + `bgp hard-administrative-reset` disabled: + a) Check if Administrative Reset notification was sent from R2 + b) Routes should be retained on R1 +""" + +import os +import sys +import json +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.common_config import step + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + 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(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 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_hold_timer_expired_gr(): + # TC1 + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + def _bgp_converge(): + output = json.loads(r2.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + "192.168.255.1": { + "bgpState": "Established", + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}}, + } + } + return topotest.json_cmp(output, expected) + + def _disable_link_r1_r2(): + r1.cmd_raises("ip link set down dev r1-eth0") + + def _enable_link_r1_r2(): + r1.cmd_raises("ip link set up dev r1-eth0") + + def _bgp_check_hold_timer_expire_reason(): + output = json.loads(r2.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + "192.168.255.1": { + "lastNotificationReason": "Hold Timer Expired", + } + } + return topotest.json_cmp(output, expected) + + def _bgp_check_hold_timer_expire_stale(): + output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast 172.16.255.1/32 json")) + expected = { + "paths": [ + { + "stale": True, + "valid": True, + } + ] + } + return topotest.json_cmp(output, expected) + + step("Initial BGP converge") + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see BGP convergence on R2" + + step("Disable the link between R1-R2") + _disable_link_r1_r2() + + step("Check if R2 sent HoldTimerExpire notification to R1") + test_func = functools.partial(_bgp_check_hold_timer_expire_reason) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see Hold Timer Expired notification from R2 on R1" + + step("Check if the routes are retained at R2") + test_func = functools.partial(_bgp_check_hold_timer_expire_stale) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see retained stale routes on R2" + + step("Enable the link between R1-R2") + _enable_link_r1_r2() + + +def test_bgp_administrative_reset_gr(): + # TC2 + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + def _bgp_converge(): + output = json.loads(r2.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + "192.168.255.1": { + "bgpState": "Established", + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}}, + } + } + return topotest.json_cmp(output, expected) + + def _bgp_check_hard_reset(): + output = json.loads(r1.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json")) + expected = { + "192.168.255.2": { + "lastNotificationReason": "Cease/Administrative Reset", + "lastNotificationHardReset": False, + } + } + return topotest.json_cmp(output, expected) + + def _bgp_check_gr_notification_stale(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 172.16.255.2/32 json")) + expected = { + "paths": [ + { + "stale": True, + "valid": True, + } + ] + } + return topotest.json_cmp(output, expected) + + def _bgp_clear_r1_and_shutdown(): + r2.vtysh_cmd( + """ + clear ip bgp 192.168.255.1 + configure terminal + router bgp + neighbor 192.168.255.1 shutdown + """ + ) + + step("Initial BGP converge") + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see BGP convergence on R2" + + step("Reset and shutdown R1") + _bgp_clear_r1_and_shutdown() + + step("Check if Hard Reset notification wasn't sent from R2") + test_func = functools.partial(_bgp_check_hard_reset) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to send Administrative Reset notification from R2" + + step("Check if stale routes are retained on R1") + test_func = functools.partial(_bgp_check_gr_notification_stale) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see retained stale routes on R1" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/cspf_topo1/reference/sharp-ted.json b/tests/topotests/cspf_topo1/reference/sharp-ted.json index db50260ac7..d3d1f9e406 100644 --- a/tests/topotests/cspf_topo1/reference/sharp-ted.json +++ b/tests/topotests/cspf_topo1/reference/sharp-ted.json @@ -269,7 +269,6 @@ }, "segment-routing":[ { - "adj-sid":5001, "flags":"0xb0", "weight":0 } @@ -666,7 +665,6 @@ }, "segment-routing":[ { - "adj-sid":5000, "flags":"0x30", "weight":0 } diff --git a/tests/topotests/pbr_topo1/test_pbr_topo1.py b/tests/topotests/pbr_topo1/test_pbr_topo1.py index 586d9217d2..8506a15135 100644 --- a/tests/topotests/pbr_topo1/test_pbr_topo1.py +++ b/tests/topotests/pbr_topo1/test_pbr_topo1.py @@ -234,15 +234,23 @@ def test_rule_linux_installation(): logger.info("Checking for installed PBR rules in OS") + def _get_router_rules(router, expected): + actual = topotest.ip_rules(router) + + logger.info(actual) + return topotest.json_cmp(actual, expected) + router_list = tgen.routers().values() for router in router_list: rules_file = "{}/{}/linux-rules.json".format(CWD, router.name) - actual = topotest.ip_rules(router) expected = json.loads(open(rules_file).read()) + test_func = partial(_get_router_rules, router, expected) + + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) assertmsg = "Router {} OS rules mismatch".format(router.name) - assert topotest.json_cmp(actual, expected) is None, assertmsg + assert result is None, assertmsg if __name__ == "__main__": |
