diff options
Diffstat (limited to 'tests')
37 files changed, 623 insertions, 65 deletions
diff --git a/tests/.gitignore b/tests/.gitignore index 6252cea823..5414cb8cc9 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -45,6 +45,7 @@ /lib/test_timer_performance /lib/test_ttable /lib/test_typelist +/lib/test_versioncmp /lib/test_zlog /lib/test_zmq /ospf6d/test_lsdb diff --git a/tests/bgpd/test_capability.c b/tests/bgpd/test_capability.c index 96e398512b..1b3f90434b 100644 --- a/tests/bgpd/test_capability.c +++ b/tests/bgpd/test_capability.c @@ -923,7 +923,7 @@ int main(void) if (fileno(stdout) >= 0) tty = isatty(fileno(stdout)); - if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT)) + if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT) < 0) return -1; peer = peer_create_accept(bgp); diff --git a/tests/bgpd/test_mp_attr.c b/tests/bgpd/test_mp_attr.c index fbf2a9fed2..af9e5791b7 100644 --- a/tests/bgpd/test_mp_attr.c +++ b/tests/bgpd/test_mp_attr.c @@ -1087,7 +1087,7 @@ int main(void) if (fileno(stdout) >= 0) tty = isatty(fileno(stdout)); - if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT)) + if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT) < 0) return -1; peer = peer_create_accept(bgp); diff --git a/tests/bgpd/test_packet.c b/tests/bgpd/test_packet.c index 7a038fb02e..d2c093fbea 100644 --- a/tests/bgpd/test_packet.c +++ b/tests/bgpd/test_packet.c @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) vrf_init(NULL, NULL, NULL, NULL, NULL); bgp_option_set(BGP_OPT_NO_LISTEN); - if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT)) + if (bgp_get(&bgp, &asn, NULL, BGP_INSTANCE_TYPE_DEFAULT) < 0) return -1; peer = peer_create_accept(bgp); diff --git a/tests/helpers/c/main.c b/tests/helpers/c/main.c index b1dcfcf707..2de29cbdbc 100644 --- a/tests/helpers/c/main.c +++ b/tests/helpers/c/main.c @@ -24,7 +24,7 @@ #include "vty.h" #include "command.h" #include "memory.h" -#include "memory_vty.h" +#include "lib_vty.h" extern void test_init(void); @@ -154,7 +154,7 @@ int main(int argc, char **argv) /* Library inits. */ cmd_init(1); vty_init(master, false); - memory_init(); + lib_cmd_init(); yang_init(); nb_init(master, NULL, 0); diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c index 2071ae08cd..e091372ab8 100644 --- a/tests/lib/cli/common_cli.c +++ b/tests/lib/cli/common_cli.c @@ -25,7 +25,7 @@ #include "vty.h" #include "command.h" #include "memory.h" -#include "memory_vty.h" +#include "lib_vty.h" #include "log.h" #include "common_cli.h" @@ -83,7 +83,7 @@ int main(int argc, char **argv) cmd_domainname_set("test.domain"); vty_init(master, false); - memory_init(); + lib_cmd_init(); yang_init(); nb_init(master, NULL, 0); diff --git a/tests/lib/cxxcompat.c b/tests/lib/cxxcompat.c index 88126e84bc..391ccd9268 100644 --- a/tests/lib/cxxcompat.c +++ b/tests/lib/cxxcompat.c @@ -51,13 +51,13 @@ #include "lib/json.h" #include "lib/keychain.h" #include "lib/lib_errors.h" +#include "lib/lib_vty.h" #include "lib/libfrr.h" #include "lib/libospf.h" #include "lib/linklist.h" #include "lib/log.h" #include "lib/md5.h" #include "lib/memory.h" -#include "lib/memory_vty.h" #include "lib/mlag.h" #include "lib/module.h" #include "lib/monotime.h" diff --git a/tests/lib/northbound/test_oper_data.c b/tests/lib/northbound/test_oper_data.c index 3180f9f9f3..18d3180889 100644 --- a/tests/lib/northbound/test_oper_data.c +++ b/tests/lib/northbound/test_oper_data.c @@ -23,7 +23,7 @@ #include "vty.h" #include "command.h" #include "memory.h" -#include "memory_vty.h" +#include "lib_vty.h" #include "log.h" #include "northbound.h" @@ -271,7 +271,7 @@ const struct frr_yang_module_info frr_test_module_info = { }; /* clang-format on */ -static const struct frr_yang_module_info *modules[] = { +static const struct frr_yang_module_info *const modules[] = { &frr_test_module_info, }; @@ -412,7 +412,7 @@ int main(int argc, char **argv) cmd_init(1); cmd_hostname_set("test"); vty_init(master, false); - memory_init(); + lib_cmd_init(); yang_init(); nb_init(master, modules, array_size(modules)); diff --git a/tests/lib/test_buffer.c b/tests/lib/test_buffer.c index b56cc30cf3..7fb9a769d3 100644 --- a/tests/lib/test_buffer.c +++ b/tests/lib/test_buffer.c @@ -20,7 +20,7 @@ #include <zebra.h> #include <memory.h> -#include <memory_vty.h> +#include <lib_vty.h> #include <buffer.h> struct thread_master *master; @@ -32,7 +32,7 @@ int main(int argc, char **argv) char junk[3]; char c = 'a'; - memory_init(); + lib_cmd_init(); if ((argc != 2) || (sscanf(argv[1], "%d%1s", &n, junk) != 1)) { fprintf(stderr, "Usage: %s <number of chars to simulate>\n", diff --git a/tests/lib/test_privs.c b/tests/lib/test_privs.c index de638bc67a..c06ebbeb38 100644 --- a/tests/lib/test_privs.c +++ b/tests/lib/test_privs.c @@ -22,7 +22,7 @@ #include "getopt.h" #include "privs.h" #include "memory.h" -#include "memory_vty.h" +#include "lib_vty.h" zebra_capabilities_t _caps_p[] = { ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN, ZCAP_DAC_OVERRIDE, @@ -105,7 +105,7 @@ int main(int argc, char **argv) } /* Library inits. */ - memory_init(); + lib_cmd_init(); zprivs_preinit(&test_privs); zprivs_init(&test_privs); diff --git a/tests/lib/test_typelist.h b/tests/lib/test_typelist.h index f20bbc52d9..9039fa8a46 100644 --- a/tests/lib/test_typelist.h +++ b/tests/lib/test_typelist.h @@ -98,12 +98,13 @@ static void ts_hash(const char *text, const char *expect) unsigned i = 0; uint8_t hash[32]; char hashtext[65]; - uint32_t count; + uint32_t swap_count, count; - count = htonl(list_count(&head)); + count = list_count(&head); + swap_count = htonl(count); SHA256_Init(&ctx); - SHA256_Update(&ctx, &count, sizeof(count)); + SHA256_Update(&ctx, &swap_count, sizeof(swap_count)); frr_each (list, &head, item) { struct { @@ -115,7 +116,7 @@ static void ts_hash(const char *text, const char *expect) }; SHA256_Update(&ctx, &hashitem, sizeof(hashitem)); i++; - assert(i < count); + assert(i <= count); } SHA256_Final(hash, &ctx); diff --git a/tests/lib/test_versioncmp.c b/tests/lib/test_versioncmp.c new file mode 100644 index 0000000000..bb819e36f5 --- /dev/null +++ b/tests/lib/test_versioncmp.c @@ -0,0 +1,66 @@ +/* + * frr_version_cmp() tests + * Copyright (C) 2018 David Lamparter for NetDEF, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <zebra.h> +#include <defaults.h> + +static const char *rel(int x) +{ + if (x < 0) + return "<"; + if (x > 0) + return ">"; + return "=="; +} + +static int fail; + +static void compare(const char *a, const char *b, int expect) +{ + int result = frr_version_cmp(a, b); + + if (expect == result) + printf("\"%s\" %s \"%s\"\n", a, rel(result), b); + else { + printf("\"%s\" %s \"%s\", expected %s!\n", a, rel(result), b, + rel(expect)); + fail = 1; + } +} + +int main(int argc, char **argv) +{ + compare("", "", 0); + compare("1", "1", 0); + compare("1.0", "1.00", 0); + compare("10.0", "1", 1); + compare("10.0", "2", 1); + compare("2.1", "10.0", -1); + compare("1.1.1", "1.1.0", 1); + compare("1.0a", "1.0", 1); + compare("1.0a", "1.0b", -1); + compare("1.0a10", "1.0a2", 1); + compare("1.00a2", "1.0a2", 0); + compare("1.00a2", "1.0a3", -1); + compare("1.0-dev", "1.0", 1); + compare("1.0~foo", "1.0", -1); + compare("1.0~1", "1.0~0", 1); + compare("1.00~1", "1.0~0", 1); + printf("final tally: %s\n", fail ? "FAILED" : "ok"); + return fail; +} diff --git a/tests/lib/test_versioncmp.py b/tests/lib/test_versioncmp.py new file mode 100644 index 0000000000..0990757000 --- /dev/null +++ b/tests/lib/test_versioncmp.py @@ -0,0 +1,6 @@ +import frrtest + +class TestVersionCmp(frrtest.TestMultiOut): + program = './test_versioncmp' + +TestVersionCmp.exit_cleanly() diff --git a/tests/subdir.am b/tests/subdir.am index 270c0811b4..d87d348949 100644 --- a/tests/subdir.am +++ b/tests/subdir.am @@ -69,6 +69,7 @@ check_PROGRAMS = \ tests/lib/test_timer_performance \ tests/lib/test_ttable \ tests/lib/test_typelist \ + tests/lib/test_versioncmp \ tests/lib/test_zlog \ tests/lib/test_graph \ tests/lib/cli/test_cli \ @@ -293,6 +294,10 @@ tests_lib_test_typelist_CFLAGS = $(TESTS_CFLAGS) tests_lib_test_typelist_CPPFLAGS = $(TESTS_CPPFLAGS) tests_lib_test_typelist_LDADD = $(ALL_TESTS_LDADD) tests_lib_test_typelist_SOURCES = tests/lib/test_typelist.c tests/helpers/c/prng.c +tests_lib_test_versioncmp_CFLAGS = $(TESTS_CFLAGS) +tests_lib_test_versioncmp_CPPFLAGS = $(TESTS_CPPFLAGS) +tests_lib_test_versioncmp_LDADD = $(ALL_TESTS_LDADD) +tests_lib_test_versioncmp_SOURCES = tests/lib/test_versioncmp.c tests_lib_test_zlog_CFLAGS = $(TESTS_CFLAGS) tests_lib_test_zlog_CPPFLAGS = $(TESTS_CPPFLAGS) tests_lib_test_zlog_LDADD = $(ALL_TESTS_LDADD) @@ -344,6 +349,7 @@ EXTRA_DIST += \ tests/lib/test_ttable.py \ tests/lib/test_ttable.refout \ tests/lib/test_typelist.py \ + tests/lib/test_versioncmp.py \ tests/lib/test_zlog.py \ tests/lib/test_graph.py \ tests/lib/test_graph.refout \ diff --git a/tests/topotests/bgp_distance_change/__init__.py b/tests/topotests/bgp_distance_change/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_distance_change/__init__.py diff --git a/tests/topotests/bgp_distance_change/r1/bgpd.conf b/tests/topotests/bgp_distance_change/r1/bgpd.conf new file mode 100644 index 0000000000..67994702bc --- /dev/null +++ b/tests/topotests/bgp_distance_change/r1/bgpd.conf @@ -0,0 +1,4 @@ +router bgp 65000 + neighbor 192.168.255.2 remote-as 65001 + exit-address-family +! diff --git a/tests/topotests/bgp_distance_change/r1/zebra.conf b/tests/topotests/bgp_distance_change/r1/zebra.conf new file mode 100644 index 0000000000..6e9b0b4a7e --- /dev/null +++ b/tests/topotests/bgp_distance_change/r1/zebra.conf @@ -0,0 +1,6 @@ +! +interface r1-eth0 + ip address 192.168.255.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_distance_change/r2/bgpd.conf b/tests/topotests/bgp_distance_change/r2/bgpd.conf new file mode 100644 index 0000000000..206f626da4 --- /dev/null +++ b/tests/topotests/bgp_distance_change/r2/bgpd.conf @@ -0,0 +1,6 @@ +router bgp 65001 + neighbor 192.168.255.1 remote-as 65000 + address-family ipv4 + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_distance_change/r2/zebra.conf b/tests/topotests/bgp_distance_change/r2/zebra.conf new file mode 100644 index 0000000000..93e3590448 --- /dev/null +++ b/tests/topotests/bgp_distance_change/r2/zebra.conf @@ -0,0 +1,9 @@ +! +interface lo + ip address 172.16.255.254/32 +! +interface r2-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_distance_change/test_bgp_distance_change.py b/tests/topotests/bgp_distance_change/test_bgp_distance_change.py new file mode 100644 index 0000000000..cf95aec098 --- /dev/null +++ b/tests/topotests/bgp_distance_change/test_bgp_distance_change.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python + +# +# bgp_distance_change.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2019 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# 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. +# + +""" +bgp_distance_change.py: + +Test if works the following commands: +router bgp 65031 + address-family ipv4 unicast + distance bgp 123 123 123 + +Changed distance should reflect to RIB after changes. +""" + +import os +import sys +import json +import time +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.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) + + router = tgen.gears['r1'] + + def _bgp_converge(router): + output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json")) + expected = { + '192.168.255.2': { + 'bgpState': 'Established', + 'addressFamilyInfo': { + 'ipv4Unicast': { + 'acceptedPrefixCounter': 2 + } + } + } + } + return topotest.json_cmp(output, expected) + + def _bgp_distance_change(router): + router.vtysh_cmd(""" + configure terminal + router bgp 65000 + address-family ipv4 unicast + distance bgp 123 123 123 + """) + + def _bgp_check_distance_change(router): + output = json.loads(router.vtysh_cmd("show ip route 172.16.255.254/32 json")) + expected = { + '172.16.255.254/32': [ + { + 'protocol': 'bgp', + 'distance': 123 + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge, router) + success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) + + assert result is None, 'Failed to see BGP convergence in "{}"'.format(router) + + _bgp_distance_change(router) + + test_func = functools.partial(_bgp_check_distance_change, router) + success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) + + assert result is None, 'Failed to see applied BGP distance in RIB "{}"'.format(router) + +if __name__ == '__main__': + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf new file mode 100644 index 0000000000..99e6b6818d --- /dev/null +++ b/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf @@ -0,0 +1,5 @@ +router bgp 65000 + neighbor 192.168.255.2 remote-as 65000 + address-family ipv4 unicast + redistribute connected +! diff --git a/tests/topotests/bgp_ebgp_requires_policy/r5/zebra.conf b/tests/topotests/bgp_ebgp_requires_policy/r5/zebra.conf new file mode 100644 index 0000000000..7ef77a6015 --- /dev/null +++ b/tests/topotests/bgp_ebgp_requires_policy/r5/zebra.conf @@ -0,0 +1,9 @@ +! +interface lo + ip address 172.16.255.254/32 +! +interface r5-eth0 + ip address 192.168.255.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf new file mode 100644 index 0000000000..164f975cb7 --- /dev/null +++ b/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf @@ -0,0 +1,3 @@ +router bgp 65000 + bgp ebgp-requires-policy + neighbor 192.168.255.1 remote-as 65000 diff --git a/tests/topotests/bgp_ebgp_requires_policy/r6/zebra.conf b/tests/topotests/bgp_ebgp_requires_policy/r6/zebra.conf new file mode 100644 index 0000000000..1c617c4272 --- /dev/null +++ b/tests/topotests/bgp_ebgp_requires_policy/r6/zebra.conf @@ -0,0 +1,6 @@ +! +interface r6-eth0 + ip address 192.168.255.2/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py index eecacfd00c..6660b4e866 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py +++ b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py @@ -5,7 +5,7 @@ # Part of NetDEF Topology Tests # # Copyright (c) 2019 by -# Network Device Education Foundation, Inc. ("NetDEF") +# Donatas Abraitis <donatas.abraitis@gmail.com> # # Permission to use, copy, modify, and/or distribute this software # for any purpose with or without fee is hereby granted, provided @@ -34,6 +34,7 @@ import sys import json import time import pytest +import functools CWD = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(CWD, '../')) @@ -48,7 +49,7 @@ class TemplateTopo(Topo): def build(self, *_args, **_opts): tgen = get_topogen(self) - for routern in range(1, 5): + for routern in range(1, 7): tgen.add_router('r{}'.format(routern)) switch = tgen.add_switch('s1') @@ -59,6 +60,10 @@ class TemplateTopo(Topo): switch.add_link(tgen.gears['r3']) switch.add_link(tgen.gears['r4']) + switch = tgen.add_switch('s3') + switch.add_link(tgen.gears['r5']) + switch.add_link(tgen.gears['r6']) + def setup_module(mod): tgen = Topogen(TemplateTopo, mod.__name__) tgen.start_topology() @@ -81,32 +86,57 @@ def teardown_module(mod): tgen = get_topogen() tgen.stop_topology() -def test_bgp_remove_private_as(): +def test_ebgp_requires_policy(): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip(tgen.errors) def _bgp_converge(router): - while True: - cmd = "show ip bgp neighbor 192.168.255.1 json" - output = json.loads(tgen.gears[router].vtysh_cmd(cmd)) - if output['192.168.255.1']['bgpState'] == 'Established': - time.sleep(3) - return True - - def _bgp_ebgp_requires_policy(router): - cmd = "show ip bgp 172.16.255.254/32 json" - output = json.loads(tgen.gears[router].vtysh_cmd(cmd)) - if 'prefix' in output: - return True - return False - - if _bgp_converge('r2'): - assert _bgp_ebgp_requires_policy('r2') == True - - if _bgp_converge('r4'): - assert _bgp_ebgp_requires_policy('r4') == False + output = json.loads(tgen.gears[router].vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + '192.168.255.1': { + 'bgpState': 'Established' + } + } + return topotest.json_cmp(output, expected) + + def _bgp_has_routes(router): + output = json.loads(tgen.gears[router].vtysh_cmd("show ip bgp neighbor 192.168.255.1 routes json")) + expected = { + 'routes': { + '172.16.255.254/32': [ + { + 'valid': True + } + ] + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge, 'r2') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'Failed bgp convergence (r2) in "{}"'.format(router) + + test_func = functools.partial(_bgp_has_routes, 'r2') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'eBGP policy is not working (r2) in "{}"'.format(router) + + test_func = functools.partial(_bgp_converge, 'r4') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'Failed bgp convergence (r4) in "{}"'.format(router) + + test_func = functools.partial(_bgp_has_routes, 'r4') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is False, 'eBGP policy is not working (r4) in "{}"'.format(router) + + test_func = functools.partial(_bgp_converge, 'r6') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'Failed bgp convergence (r6) in "{}"'.format(router) + + test_func = functools.partial(_bgp_has_routes, 'r6') + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert success is True, 'eBGP policy is not working (r6) in "{}"'.format(router) if __name__ == '__main__': args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py index 02fba97316..e62d139a0c 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py @@ -153,8 +153,10 @@ def ltemplatePreRouterStartHook(): if topotest.version_cmp(krel, '4.15') >= 0 and \ topotest.version_cmp(krel, '4.18') <= 0: l3mdev_accept = 1 - else: - l3mdev_accept = 0 + + if topotest.version_cmp(krel, '5.0') >= 0: + l3mdev_accept = 1 + logger.info('setting net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept)) #check for mpls if tgen.hasmpls != True: diff --git a/tests/topotests/bgp_reject_as_sets/__init__.py b/tests/topotests/bgp_reject_as_sets/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/__init__.py diff --git a/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf new file mode 100644 index 0000000000..7b24c4bbf9 --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf @@ -0,0 +1,8 @@ +! exit1 +router bgp 65001 + neighbor 192.168.255.1 remote-as 65002 + address-family ipv4 unicast + redistribute connected + exit-address-family + ! +! diff --git a/tests/topotests/bgp_reject_as_sets/r1/zebra.conf b/tests/topotests/bgp_reject_as_sets/r1/zebra.conf new file mode 100644 index 0000000000..9904bb4e16 --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/r1/zebra.conf @@ -0,0 +1,9 @@ +! exit1 +interface lo + ip address 172.16.255.254/32 +! +interface r1-eth0 + ip address 192.168.255.2/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf new file mode 100644 index 0000000000..c991b5bcd8 --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf @@ -0,0 +1,10 @@ +! spine +router bgp 65002 + bgp reject-as-sets + neighbor 192.168.255.2 remote-as 65001 + neighbor 192.168.254.2 remote-as 65003 + address-family ipv4 unicast + aggregate-address 172.16.0.0/16 as-set summary-only + exit-address-family + ! +! diff --git a/tests/topotests/bgp_reject_as_sets/r2/zebra.conf b/tests/topotests/bgp_reject_as_sets/r2/zebra.conf new file mode 100644 index 0000000000..f0d357c5ff --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/r2/zebra.conf @@ -0,0 +1,9 @@ +! spine +interface r2-eth0 + ip address 192.168.255.1/30 +! +interface r2-eth1 + ip address 192.168.254.1/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf new file mode 100644 index 0000000000..bee518c84b --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf @@ -0,0 +1,9 @@ +! exit2 +router bgp 65003 + neighbor 192.168.254.1 remote-as 65002 + address-family ipv4 unicast + neighbor 192.168.254.1 allowas-in + redistribute connected + exit-address-family + ! +! diff --git a/tests/topotests/bgp_reject_as_sets/r3/zebra.conf b/tests/topotests/bgp_reject_as_sets/r3/zebra.conf new file mode 100644 index 0000000000..f490d97afe --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/r3/zebra.conf @@ -0,0 +1,9 @@ +! exit2 +interface lo + ip address 172.16.254.254/32 +! +interface r3-eth0 + ip address 192.168.254.2/30 +! +ip forwarding +! diff --git a/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py b/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py new file mode 100644 index 0000000000..f307edc678 --- /dev/null +++ b/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python + +# +# test_bgp_reject_as_sets.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2019 by +# Donatas Abraitis <donatas.abraitis@gmail.com> +# +# 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 if an aggregated route with AS_SET is not sent to peers. +Addressing draft-ietf-idr-deprecate-as-set-confed-set recommendations. + +BGP speakers conforming to this document (i.e., conformant BGP + speakers) MUST NOT locally generate BGP UPDATE messages containing + AS_SET or AS_CONFED_SET. Conformant BGP speakers SHOULD NOT send BGP + UPDATE messages containing AS_SET or AS_CONFED_SET. Upon receipt of + such messages, conformant BGP speakers SHOULD use the "Treat-as- + withdraw" error handling behavior as per [RFC7606]. +""" + +import os +import sys +import json +import time +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.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, 4): + tgen.add_router('r{}'.format(routern)) + + switch = tgen.add_switch('s1') + switch.add_link(tgen.gears['r1']) + switch.add_link(tgen.gears['r2']) + + switch = tgen.add_switch('s2') + switch.add_link(tgen.gears['r2']) + switch.add_link(tgen.gears['r3']) + +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_reject_as_sets(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + router = tgen.gears['r2'] + + def _bgp_converge(router): + output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.2 json")) + expected = { + '192.168.255.2': { + 'bgpState': 'Established', + 'addressFamilyInfo': { + 'ipv4Unicast': { + 'acceptedPrefixCounter': 2 + } + } + } + } + return topotest.json_cmp(output, expected) + + def _bgp_has_aggregated_route_with_stripped_as_set(router): + output = json.loads(router.vtysh_cmd("show ip bgp 172.16.0.0/16 json")) + expected = { + 'paths': [ + { + 'aspath': { + 'string': 'Local', + 'segments': [ + ], + 'length': 0 + } + } + ] + } + return topotest.json_cmp(output, expected) + + def _bgp_announce_route_without_as_sets(router): + output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.254.2 advertised-routes json")) + expected = { + 'advertisedRoutes': { + '172.16.0.0/16': { + 'asPath': '' + }, + '192.168.254.0/30': { + 'asPath': '65003' + }, + '192.168.255.0/30': { + 'asPath': '65001' + } + }, + 'totalPrefixCounter': 3 + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_converge, router) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Failed bgp convergence in "{}"'.format(router) + + test_func = functools.partial(_bgp_has_aggregated_route_with_stripped_as_set, router) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Failed to see an aggregated route in "{}"'.format(router) + + test_func = functools.partial(_bgp_announce_route_without_as_sets, router) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Route 172.16.0.0/16 should be sent without AS_SET to r3 "{}"'.format(router) + +if __name__ == '__main__': + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) 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 index 59ffd36ef3..f5119468e0 100644 --- 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 @@ -5,7 +5,7 @@ # Part of NetDEF Topology Tests # # Copyright (c) 2019 by -# Network Device Education Foundation, Inc. ("NetDEF") +# Donatas Abraitis <donatas.abraitis@gmail.com> # # Permission to use, copy, modify, and/or distribute this software # for any purpose with or without fee is hereby granted, provided @@ -33,6 +33,7 @@ import sys import json import time import pytest +import functools CWD = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(CWD, '../')) @@ -76,33 +77,40 @@ def teardown_module(mod): tgen = get_topogen() tgen.stop_topology() -def test_bgp_maximum_prefix_invalid(): +def test_bgp_show_ip_bgp_hostname(): 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) + router = tgen.gears['r2'] + + def _bgp_converge(router): + output = json.loads(router.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_show_nexthop_hostname_and_ip(router): + output = json.loads(router.vtysh_cmd("show ip bgp json")) + for nh in output['routes']['172.16.255.253/32'][0]['nexthops']: + if 'hostname' in nh and 'ip' in nh: return True + return False - 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' + test_func = functools.partial(_bgp_converge, router) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - 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' + assert result is None, 'Failed bgp convergence in "{}"'.format(router) + assert _bgp_show_nexthop_hostname_and_ip(router) == True if __name__ == '__main__': args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/test_bgp_vrf_lite_ipv6_rtadv.py b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/test_bgp_vrf_lite_ipv6_rtadv.py index 6b4df78c69..2944b3729c 100644 --- a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/test_bgp_vrf_lite_ipv6_rtadv.py +++ b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/test_bgp_vrf_lite_ipv6_rtadv.py @@ -31,6 +31,7 @@ import sys import json from functools import partial import pytest +import platform # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -68,6 +69,19 @@ def setup_module(mod): router_list = tgen.routers() logger.info('Testing with VRF Lite support') + krel = platform.release() + + # May need to adjust handling of vrf traffic depending on kernel version + l3mdev_accept = 0 + if topotest.version_cmp(krel, '4.15') >= 0 and \ + topotest.version_cmp(krel, '4.18') <= 0: + l3mdev_accept = 1 + + if topotest.version_cmp(krel, '5.0') >= 0: + l3mdev_accept = 1 + + logger.info('krel \'{0}\' setting net.ipv4.tcp_l3mdev_accept={1}'.format( + krel, l3mdev_accept)) cmds = ['ip link add {0}-cust1 type vrf table 1001', 'ip link add loop1 type dummy', @@ -78,6 +92,15 @@ def setup_module(mod): for cmd in cmds: output = tgen.net[rname].cmd(cmd.format(rname)) + output = tgen.net[rname].cmd('sysctl -n net.ipv4.tcp_l3mdev_accept') + logger.info( + 'router {0}: existing tcp_l3mdev_accept was {1}'.format( + rname, output)) + + if l3mdev_accept: + output = tgen.net[rname].cmd( + 'sysctl -w net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept)) + for rname, router in router_list.iteritems(): router.load_config( TopoRouter.RD_ZEBRA, diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index 9f2fef52ea..fc7581b1f2 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -28,6 +28,7 @@ from subprocess import PIPE as SUB_PIPE from subprocess import Popen from functools import wraps from re import search as re_search +from tempfile import mkdtemp import StringIO import os @@ -276,11 +277,19 @@ def reset_config_on_routers(tgen, routerName=None): run_cfg_file = "{}/{}/frr.sav".format(TMPDIR, rname) init_cfg_file = "{}/{}/frr_json_initial.conf".format(TMPDIR, rname) - command = "/usr/lib/frr/frr-reload.py --input {} --test {} > {}". \ - format(run_cfg_file, init_cfg_file, dname) + + tempdir = mkdtemp() + with open(os.path.join(tempdir, 'vtysh.conf'), 'w') as fd: + pass + + command = "/usr/lib/frr/frr-reload.py --confdir {} --input {} --test {} > {}". \ + format(tempdir, run_cfg_file, init_cfg_file, dname) result = call(command, shell=True, stderr=SUB_STDOUT, stdout=SUB_PIPE) + os.unlink(os.path.join(tempdir, 'vtysh.conf')) + os.rmdir(tempdir) + # Assert if command fail if result > 0: logger.error("Delta file creation failed. Command executed %s", |
