diff options
| -rw-r--r-- | bgpd/bgp_open.c | 1 | ||||
| -rw-r--r-- | bgpd/bgp_packet.c | 99 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 27 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 3 | ||||
| -rw-r--r-- | doc/developer/logging.rst | 14 | ||||
| -rw-r--r-- | lib/printf/README | 1 | ||||
| -rw-r--r-- | lib/printf/printflocal.h | 1 | ||||
| -rw-r--r-- | lib/printf/vfprintf.c | 44 | ||||
| -rw-r--r-- | tests/lib/test_printfrr.c | 12 | ||||
| -rw-r--r-- | tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_addpath.py | 42 | ||||
| -rw-r--r-- | tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_fqdn.py | 122 | ||||
| -rw-r--r-- | tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_graceful_restart.py | 36 | ||||
| -rw-r--r-- | tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_orf.py | 45 | ||||
| -rw-r--r-- | tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_role.py | 37 | ||||
| -rw-r--r-- | tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py | 37 |
15 files changed, 458 insertions, 63 deletions
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index aa1d81362b..15738e673b 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -2039,7 +2039,6 @@ uint16_t bgp_open_capability(struct stream *s, struct peer *peer, * or disable its use, and that switch MUST be off by default. */ if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_SOFT_VERSION) || - CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SOFT_VERSION_CAPABILITY) || peer->sort == BGP_PEER_IBGP || peer->sub_sort == BGP_PEER_EBGP_OAD) { SET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_ADV); stream_putc(s, BGP_OPEN_OPT_CAP); diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 55d3efde23..8a36a3f4c8 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1240,7 +1240,6 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, /* Encode MP_EXT capability. */ switch (capability_code) { case CAPABILITY_CODE_SOFT_VERSION: - SET_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_ADV); stream_putc(s, action); stream_putc(s, CAPABILITY_CODE_SOFT_VERSION); cap_len = stream_get_endp(s); @@ -1271,6 +1270,9 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, : "Removing", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); + + COND_FLAG(peer->cap, PEER_CAP_SOFT_VERSION_ADV, + action == CAPABILITY_ACTION_SET); break; case CAPABILITY_CODE_MP: stream_putc(s, action); @@ -1290,11 +1292,6 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, iana_safi2str(pkt_safi)); break; case CAPABILITY_CODE_RESTART: - if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART) && - !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) - return; - - SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV); stream_putc(s, action); stream_putc(s, CAPABILITY_CODE_RESTART); cap_len = stream_get_endp(s); @@ -1343,13 +1340,10 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); + COND_FLAG(peer->cap, PEER_CAP_RESTART_ADV, + action == CAPABILITY_ACTION_SET); break; case CAPABILITY_CODE_LLGR: - if (!CHECK_FLAG(peer->cap, PEER_CAP_RESTART_ADV)) - return; - - SET_FLAG(peer->cap, PEER_CAP_LLGR_ADV); - stream_putc(s, action); stream_putc(s, CAPABILITY_CODE_LLGR); cap_len = stream_get_endp(s); @@ -1381,10 +1375,11 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, : "Removing", capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); + + COND_FLAG(peer->cap, PEER_CAP_LLGR_ADV, + action == CAPABILITY_ACTION_SET); break; case CAPABILITY_CODE_ADDPATH: - SET_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV); - FOREACH_AFI_SAFI (afi, safi) { if (peer->afc[afi][safi]) { addpath_afi_safi_count++; @@ -1462,10 +1457,10 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, capability, iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); + COND_FLAG(peer->cap, PEER_CAP_ADDPATH_ADV, + action == CAPABILITY_ACTION_SET); break; case CAPABILITY_CODE_PATHS_LIMIT: - SET_FLAG(peer->cap, PEER_CAP_PATHS_LIMIT_ADV); - FOREACH_AFI_SAFI (afi, safi) { if (!peer->afc[afi][safi]) continue; @@ -1505,6 +1500,8 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, .send); } + COND_FLAG(peer->cap, PEER_CAP_PATHS_LIMIT_ADV, + action == CAPABILITY_ACTION_SET); break; case CAPABILITY_CODE_ORF: /* Convert AFI, SAFI to values for packet. */ @@ -1578,43 +1575,42 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, iana_safi2str(pkt_safi)); break; case CAPABILITY_CODE_FQDN: - if (CHECK_FLAG(peer->flags, PEER_FLAG_CAPABILITY_FQDN) && - hostname) { - SET_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV); - stream_putc(s, action); - stream_putc(s, CAPABILITY_CODE_FQDN); - cap_len = stream_get_endp(s); - stream_putc(s, 0); /* Capability Length */ - - len = strlen(hostname); + stream_putc(s, action); + stream_putc(s, CAPABILITY_CODE_FQDN); + cap_len = stream_get_endp(s); + stream_putc(s, 0); /* Capability Length */ + + len = strlen(hostname); + if (len > BGP_MAX_HOSTNAME) + len = BGP_MAX_HOSTNAME; + + stream_putc(s, len); + stream_put(s, hostname, len); + + if (domainname) { + len = strlen(domainname); if (len > BGP_MAX_HOSTNAME) len = BGP_MAX_HOSTNAME; stream_putc(s, len); - stream_put(s, hostname, len); - - if (domainname) { - len = strlen(domainname); - if (len > BGP_MAX_HOSTNAME) - len = BGP_MAX_HOSTNAME; + stream_put(s, domainname, len); + } else + stream_putc(s, 0); - stream_putc(s, len); - stream_put(s, domainname, len); - } else - stream_putc(s, 0); + len = stream_get_endp(s) - cap_len - 1; + stream_putc_at(s, cap_len, len); - len = stream_get_endp(s) - cap_len - 1; - stream_putc_at(s, cap_len, len); + if (bgp_debug_neighbor_events(peer)) + zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s", + peer, + action == CAPABILITY_ACTION_SET + ? "Advertising" + : "Removing", + capability, iana_afi2str(pkt_afi), + iana_safi2str(pkt_safi)); - if (bgp_debug_neighbor_events(peer)) - zlog_debug("%pBP sending CAPABILITY has %s %s for afi/safi: %s/%s", - peer, - action == CAPABILITY_ACTION_SET - ? "Advertising" - : "Removing", - capability, iana_afi2str(pkt_afi), - iana_safi2str(pkt_safi)); - } + COND_FLAG(peer->cap, PEER_CAP_HOSTNAME_ADV, + action == CAPABILITY_ACTION_SET); break; case CAPABILITY_CODE_REFRESH: case CAPABILITY_CODE_AS4: @@ -1624,13 +1620,12 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, case CAPABILITY_CODE_EXT_MESSAGE: break; case CAPABILITY_CODE_ROLE: - if (peer->local_role != ROLE_UNDEFINED) { - SET_FLAG(peer->cap, PEER_CAP_ROLE_ADV); - stream_putc(s, action); - stream_putc(s, CAPABILITY_CODE_ROLE); - stream_putc(s, CAPABILITY_CODE_ROLE_LEN); - stream_putc(s, peer->local_role); - } + stream_putc(s, action); + stream_putc(s, CAPABILITY_CODE_ROLE); + stream_putc(s, CAPABILITY_CODE_ROLE_LEN); + stream_putc(s, peer->local_role); + COND_FLAG(peer->cap, PEER_CAP_ROLE_ADV, + action == CAPABILITY_ACTION_SET); break; default: break; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index efc71bc8a7..2920405780 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -3260,6 +3260,8 @@ DEFUN (bgp_graceful_restart_disable, GR_DISABLE) { int ret = BGP_GR_FAILURE; + struct listnode *node, *nnode; + struct peer *peer; if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) zlog_debug( @@ -3278,6 +3280,15 @@ DEFUN (bgp_graceful_restart_disable, vty_out(vty, "Graceful restart configuration changed, reset all peers to take effect\n"); + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_RESTART, + CAPABILITY_ACTION_UNSET); + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_LLGR, + CAPABILITY_ACTION_UNSET); + } + return bgp_vty_return(vty, ret); } @@ -18416,9 +18427,19 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, } /* capability software-version */ - if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_SOFT_VERSION)) - vty_out(vty, " neighbor %s capability software-version\n", - addr); + if (CHECK_FLAG(bgp->flags, BGP_FLAG_SOFT_VERSION_CAPABILITY)) { + if (!peergroup_flag_check(peer, + PEER_FLAG_CAPABILITY_SOFT_VERSION)) + vty_out(vty, + " no neighbor %s capability software-version\n", + addr); + } else { + if (peergroup_flag_check(peer, + PEER_FLAG_CAPABILITY_SOFT_VERSION)) + vty_out(vty, + " neighbor %s capability software-version\n", + addr); + } /* dont-capability-negotiation */ if (peergroup_flag_check(peer, PEER_FLAG_DONT_CAPABILITY)) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index e7712f0f3e..be816c3361 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1541,6 +1541,9 @@ struct peer *peer_new(struct bgp *bgp) if (CHECK_FLAG(bgp->flags, BGP_FLAG_ENFORCE_FIRST_AS)) SET_FLAG(peer->flags, PEER_FLAG_ENFORCE_FIRST_AS); + if (CHECK_FLAG(bgp->flags, BGP_FLAG_SOFT_VERSION_CAPABILITY)) + SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_SOFT_VERSION); + SET_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_FQDN); SET_FLAG(peer->flags, PEER_FLAG_CAPABILITY_FQDN); diff --git a/doc/developer/logging.rst b/doc/developer/logging.rst index 52653d3768..6058b8c0fc 100644 --- a/doc/developer/logging.rst +++ b/doc/developer/logging.rst @@ -77,7 +77,14 @@ are available: .. note:: - ``printfrr()`` does not support the ``%n`` format. + ``printfrr()`` does not support the ``%n`` format. It does support ISO C23 + ``%b``, ``%w99d`` and ``%wf99d`` additions, but the latter two are not + supported by the ``frr-format`` plugin yet, and all 3 aren't supported by + the older compilers still in use on some supported platforms. + + ``%b`` can be used with ``FMT_NSTD``, but ``%w99d`` and ``%wf99d`` require + work in the ``frr-format`` plugin before they are really usable. + AS-Safety ^^^^^^^^^ @@ -557,8 +564,9 @@ Integer formats cause compiler warnings when used without the plugin. Use with :c:macro:`FMT_NSTD` if necessary. - It is possible ISO C23 may introduce another format for these, possibly - ``%w64d`` discussed in `JTC 1/SC 22/WG 14/N2680 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2680.pdf>`_. + As anticipated, ISO C23 has introduced new modifiers for this, specifically + ``%w64d`` (= ``%Ld``) and ``%w64u`` (= ``%Lu``). Unfortunately, these new + modifiers are not supported by ``frr-format`` yet. .. frrfmt:: %Lu (uint64_t) diff --git a/lib/printf/README b/lib/printf/README index 46d51cec6a..3c3ef74ca8 100644 --- a/lib/printf/README +++ b/lib/printf/README @@ -1,6 +1,7 @@ This is the printf implementation from FreeBSD. The history of this code is: - imported on 2019-05-12, from SVN revision 347514 - resynced on 2023-09-03, to pick up `%b` implementation +- resynced on 2024-03-10, to pick up `%w[f](8|16|32|64)d` implementation Please don't reindent or otherwise mangle the files to make importing fixes easy (not that there are significant changes likely to happen...) diff --git a/lib/printf/printflocal.h b/lib/printf/printflocal.h index 4b030912fe..93318c8fdb 100644 --- a/lib/printf/printflocal.h +++ b/lib/printf/printflocal.h @@ -52,6 +52,7 @@ #define PTRDIFFT 0x800 /* ptrdiff_t */ #define INTMAXT 0x1000 /* intmax_t */ #define CHARINT 0x2000 /* print char using int format */ +#define FASTINT 0x4000 /* int_fastN_t */ /* * Macros for converting digits to letters and vice versa diff --git a/lib/printf/vfprintf.c b/lib/printf/vfprintf.c index 2083642d5e..3f6700c838 100644 --- a/lib/printf/vfprintf.c +++ b/lib/printf/vfprintf.c @@ -416,6 +416,49 @@ reswitch: switch (ch) { case 't': flags |= PTRDIFFT; goto rflag; + case 'w': + /* + * Fixed-width integer types. On all platforms we + * support, int8_t is equivalent to char, int16_t + * is equivalent to short, int32_t is equivalent + * to int, int64_t is equivalent to long long int. + * Furthermore, int_fast8_t, int_fast16_t and + * int_fast32_t are equivalent to int, and + * int_fast64_t is equivalent to long long int. + */ + flags &= ~(CHARINT|SHORTINT|LONGINT|LLONGINT|INTMAXT); + if (fmt[0] == 'f') { + flags |= FASTINT; + fmt++; + } else { + flags &= ~FASTINT; + } + if (fmt[0] == '8') { + if (!(flags & FASTINT)) + flags |= CHARINT; + else + (void) 0; /* no flag set = 32 */ + fmt += 1; + } else if (fmt[0] == '1' && fmt[1] == '6') { + if (!(flags & FASTINT)) + flags |= SHORTINT; + else + (void) 0; /* no flag set = 32 */ + fmt += 2; + } else if (fmt[0] == '3' && fmt[1] == '2') { + /* no flag set = 32 */ + fmt += 2; + } else if (fmt[0] == '6' && fmt[1] == '4') { + flags |= LLONGINT; + fmt += 2; + } else { + if (flags & FASTINT) { + flags &= ~FASTINT; + fmt--; + } + goto invalid; + } + goto rflag; case 'z': flags |= SIZET; goto rflag; @@ -684,6 +727,7 @@ number: if ((dprec = prec) >= 0) default: /* "%?" prints ?, unless ? is NUL */ if (ch == '\0') goto done; +invalid: /* pretend it was %c with argument ch */ buf[0] = ch; cp = buf; diff --git a/tests/lib/test_printfrr.c b/tests/lib/test_printfrr.c index 66699ec7c0..cefa07ec73 100644 --- a/tests/lib/test_printfrr.c +++ b/tests/lib/test_printfrr.c @@ -143,6 +143,8 @@ int main(int argc, char **argv) NAN, }; uint64_t ui64 = 0xfeed1278cafef00d; + uint16_t i16 = -23456; + int_fast8_t if8 = 123; struct in_addr ip; char *p; char buf[256]; @@ -169,6 +171,16 @@ int main(int argc, char **argv) FMT_NSTD(printchk("11110000000011111010010111000011", "%b", 0xf00fa5c3)); FMT_NSTD(printchk("0b01011010", "%#010b", 0x5a)); +/* FMT_NSTD is conditional on the frr-format plugin being NOT enabled. + * However, the frr-format plugin does not support %wd/%wfd yet, so this needs + * to be unconditional. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" + printchk("123 -23456 feed1278cafef00d 9876", "%wf8d %w16d %w64x %d", + if8, i16, ui64, 9876); +#pragma GCC diagnostic pop + inet_aton("192.168.1.2", &ip); printchk("192.168.1.2", "%pI4", &ip); printchk(" 192.168.1.2", "%20pI4", &ip); diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_addpath.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_addpath.py index f83ee2971c..5202f51e28 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_addpath.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_addpath.py @@ -135,7 +135,7 @@ def test_bgp_dynamic_capability_addpath(): step("Disable Addpath capability RX and check if it's exchanged dynamically") # Clear message stats to check if we receive a notification or not after we - # change the settings fo LLGR. + # disable addpath-rx. r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") r2.vtysh_cmd( """ @@ -174,6 +174,46 @@ def test_bgp_dynamic_capability_addpath(): _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, "Session was reset after disabling Addpath RX flags" + # Clear message stats to check if we receive a notification or not after we + # disable Addpath capability. + r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") + r1.vtysh_cmd( + """ + configure terminal + router bgp + address-family ipv4 unicast + no neighbor 192.168.1.2 addpath-tx-all-paths + """ + ) + + def _bgp_check_if_addpath_capability_is_absent(): + output = json.loads(r1.vtysh_cmd("show bgp neighbor json")) + expected = { + "192.168.1.2": { + "bgpState": "Established", + "neighborCapabilities": { + "dynamic": "advertisedAndReceived", + "addPath": { + "ipv4Unicast": { + "txAdvertisedAndReceived": None, + "txAdvertised": None, + "rxAdvertised": True, + } + }, + }, + "messageStats": { + "notificationsRecv": 0, + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_if_addpath_capability_is_absent, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Failed to disable Addpath capability" + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_fqdn.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_fqdn.py new file mode 100644 index 0000000000..338886d5f4 --- /dev/null +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_fqdn.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 by +# Donatas Abraitis <donatas@opensourcerouting.org> +# + +""" +Test if fqdn capability is exchanged dynamically. +""" + +import os +import re +import sys +import json +import pytest +import functools + +pytestmark = pytest.mark.bgpd + +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 setup_module(mod): + topodef = {"s1": ("r1", "r2")} + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_dynamic_capability_fqdn(): + 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(r1.vtysh_cmd("show bgp neighbor json")) + expected = { + "192.168.1.2": { + "bgpState": "Established", + "neighborCapabilities": { + "dynamic": "advertisedAndReceived", + "hostName": { + "advHostName": "r1", + "rcvHostName": "r2", + }, + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_converge, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't converge" + + step("Disable fqdn capability and check if it's exchanged dynamically") + + # Clear message stats to check if we receive a notification or not after we + # disable fqdn capability. + r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") + r1.vtysh_cmd( + """ + configure terminal + router bgp + no neighbor 192.168.1.2 capability fqdn + """ + ) + + def _bgp_check_if_fqdn_capability_is_absent(): + output = json.loads(r1.vtysh_cmd("show bgp neighbor json")) + expected = { + "192.168.1.2": { + "bgpState": "Established", + "neighborCapabilities": { + "dynamic": "advertisedAndReceived", + "hostName": { + "advHostName": None, + "rcvHostName": "r2", + }, + }, + "messageStats": { + "notificationsRecv": 0, + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_if_fqdn_capability_is_absent, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Failed to disable fqdn capability" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_graceful_restart.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_graceful_restart.py index b7e2090eee..4644ef3293 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_graceful_restart.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_graceful_restart.py @@ -159,7 +159,7 @@ def test_bgp_dynamic_capability_graceful_restart(): ) # Clear message stats to check if we receive a notification or not after we - # change the settings fo LLGR. + # disable graceful-restart notification support. r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") r2.vtysh_cmd( """ @@ -207,6 +207,40 @@ def test_bgp_dynamic_capability_graceful_restart(): result is None ), "Session was reset after changing Graceful-Restart notification support" + # Clear message stats to check if we receive a notification or not after we + # disable GR. + r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") + r1.vtysh_cmd( + """ + configure terminal + router bgp + bgp graceful-restart-disable + """ + ) + + def _bgp_check_if_gr_llgr_capability_is_absent(): + output = json.loads(r1.vtysh_cmd("show bgp neighbor json")) + expected = { + "192.168.1.2": { + "bgpState": "Established", + "neighborCapabilities": { + "dynamic": "advertisedAndReceived", + "gracefulRestartCapability": "received", + "longLivedGracefulRestart": "received", + }, + "messageStats": { + "notificationsRecv": 0, + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_if_gr_llgr_capability_is_absent, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Failed to disable GR/LLGR capabilities" + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_orf.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_orf.py index f1ad74c05c..ba95bd1614 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_orf.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_orf.py @@ -172,6 +172,51 @@ def test_bgp_dynamic_capability_orf(): result is None ), "Only 10.10.10.20/32 SHOULD be advertised due to ORF filtering" + # Clear message stats to check if we receive a notification or not after we + # disable ORF capability. + r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") + r1.vtysh_cmd( + """ + configure terminal + router bgp + address-family ipv4 unicast + no neighbor 192.168.1.2 capability orf prefix-list both + """ + ) + + def _bgp_check_if_orf_capability_is_absent(): + output = json.loads(r1.vtysh_cmd("show bgp neighbor json")) + expected = { + "192.168.1.2": { + "bgpState": "Established", + "neighborCapabilities": { + "dynamic": "advertisedAndReceived", + }, + "messageStats": { + "notificationsRecv": 0, + "notificationsSent": 0, + }, + "addressFamilyInfo": { + "ipv4Unicast": { + "acceptedPrefixCounter": 1, + "afDependentCap": { + "orfPrefixList": { + "sendMode": "received", + "recvMode": "received", + } + }, + } + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_if_orf_capability_is_absent, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Failed to disable ORF capability" + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_role.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_role.py index 700d4c130d..aa9ad5f0e8 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_role.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_role.py @@ -84,7 +84,7 @@ def test_bgp_dynamic_capability_role(): step("Set local-role and check if it's exchanged dynamically") # Clear message stats to check if we receive a notification or not after we - # change the settings fo LLGR. + # change the role. r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") r1.vtysh_cmd( """ @@ -132,6 +132,41 @@ def test_bgp_dynamic_capability_role(): _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, "Session was reset after setting role capability" + # Clear message stats to check if we receive a notification or not after we + # change the role. + r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") + r1.vtysh_cmd( + """ + configure terminal + router bgp + no neighbor 192.168.1.2 local-role customer + """ + ) + + def _bgp_check_if_role_capability_is_absent(): + output = json.loads(r1.vtysh_cmd("show bgp neighbor json")) + expected = { + "192.168.1.2": { + "bgpState": "Established", + "localRole": "undefined", + "remoteRole": "provider", + "neighborCapabilities": { + "dynamic": "advertisedAndReceived", + "role": "received", + }, + "messageStats": { + "notificationsRecv": 0, + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_if_role_capability_is_absent, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Failed to disable role capability" + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py index 11840b4c61..737e694701 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py @@ -86,7 +86,7 @@ def test_bgp_dynamic_capability_software_version(): step("Enable software version capability and check if it's exchanged dynamically") # Clear message stats to check if we receive a notification or not after we - # change the settings fo LLGR. + # enable software-version capability. r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") r1.vtysh_cmd( """ @@ -155,6 +155,41 @@ def test_bgp_dynamic_capability_software_version(): result is None ), "Session was reset after enabling software version capability" + # Clear message stats to check if we receive a notification or not after we + # disable software-version capability. + r1.vtysh_cmd("clear bgp 192.168.1.2 message-stats") + r1.vtysh_cmd( + """ + configure terminal + router bgp + no neighbor 192.168.1.2 capability software-version + """ + ) + + def _bgp_check_if_software_version_capability_is_absent(): + output = json.loads(r1.vtysh_cmd("show bgp neighbor json")) + expected = { + "192.168.1.2": { + "bgpState": "Established", + "neighborCapabilities": { + "dynamic": "advertisedAndReceived", + "softwareVersion": { + "advertisedSoftwareVersion": None, + }, + }, + "messageStats": { + "notificationsRecv": 0, + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_if_software_version_capability_is_absent, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Failed to disable software version capability" + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] |
