tests: tests for bgpd listing on multiple addresses

* Added a new topotest to test bgpd listening on multiple addresses.
* Updated the existing bgpd tests according to the parameter added to
bgp_master_init.

Signed-off-by: "Adriano Marto Reis" <adrianomarto@gmail.com>
This commit is contained in:
Adriano Marto Reis 2021-01-03 15:02:29 +10:00
parent d1aed873ca
commit 733367c04e
8 changed files with 321 additions and 6 deletions

View File

@ -1265,7 +1265,8 @@ int main(void)
{
int i = 0;
qobj_init();
bgp_master_init(thread_master_create(NULL), BGP_SOCKET_SNDBUF_SIZE);
bgp_master_init(thread_master_create(NULL), BGP_SOCKET_SNDBUF_SIZE,
list_new());
master = bm->master;
bgp_option_set(BGP_OPT_NO_LISTEN);
bgp_attr_init();

View File

@ -912,7 +912,7 @@ int main(void)
qobj_init();
master = thread_master_create(NULL);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);

View File

@ -1086,7 +1086,7 @@ int main(void)
cmd_init(0);
bgp_vty_init();
master = thread_master_create("test mp attr");
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);
bgp_attr_init();

View File

@ -393,7 +393,7 @@ static int global_test_init(void)
qobj_init();
master = thread_master_create(NULL);
zclient = zclient_new(master, &zclient_options_default);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);

View File

@ -59,7 +59,7 @@ int main(int argc, char *argv[])
qobj_init();
bgp_attr_init();
master = thread_master_create(NULL);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
vrf_init(NULL, NULL, NULL, NULL, NULL);
bgp_option_set(BGP_OPT_NO_LISTEN);

View File

@ -1399,7 +1399,7 @@ static void bgp_startup(void)
master = thread_master_create(NULL);
yang_init(true);
nb_init(master, bgpd_yang_modules, array_size(bgpd_yang_modules), false);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE, list_new());
bgp_option_set(BGP_OPT_NO_LISTEN);
vrf_init(NULL, NULL, NULL, NULL, NULL);
frr_pthread_init();

View File

@ -0,0 +1,154 @@
{
"ipv4base": "10.0.0.0",
"ipv4mask": 24,
"ipv6base": "fd00::",
"ipv6mask": 64,
"link_ip_start": {
"ipv4": "10.0.0.0",
"v4mask": 24,
"ipv6": "fd00::",
"v6mask": 64
},
"lo_prefix": {
"ipv4": "1.0.",
"v4mask": 32,
"ipv6": "2001:DB8:F::",
"v6mask": 128
},
"routers": {
"r1": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r2": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "1000",
"address_family": {
"ipv4": {
"unicast": {
"neighbor": {
"r2": {
"dest_link": {
"r1": {}
}
}
}
}
}
}
}
},
"r2": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r1": {
"ipv4": "auto",
"ipv6": "auto"
},
"r3": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "2000",
"address_family": {
"ipv4": {
"unicast": {
"neighbor": {
"r1": {
"dest_link": {
"r2": {}
}
},
"r3": {
"dest_link": {
"r2": {}
}
}
}
}
}
}
}
},
"r3": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r2": {
"ipv4": "auto",
"ipv6": "auto"
},
"r4": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "2000",
"address_family": {
"ipv4": {
"unicast": {
"neighbor": {
"r2": {
"dest_link": {
"r3": {}
}
},
"r4": {
"dest_link": {
"r3": {}
}
}
}
}
}
}
}
},
"r4": {
"links": {
"lo": {
"ipv4": "auto",
"ipv6": "auto",
"type": "loopback"
},
"r3": {
"ipv4": "auto",
"ipv6": "auto"
}
},
"bgp": {
"local_as": "3000",
"address_family": {
"ipv4": {
"unicast": {
"neighbor": {
"r3": {
"dest_link": {
"r4": {}
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,160 @@
#!/usr/bin/env python
#
# test_bgp_listen_on_multiple_addresses.py
# Part of NetDEF Topology Tests
#
# Copyright (c) 2021 by Boeing Defence Australia
# Adriano Marto Reis
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted, provided
# that the above copyright notice and this permission notice appear
# in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
#
"""
test_bgp_listen_on_multiple_addresses.py: Test BGP daemon listening for
connections on multiple addresses.
+------+ +------+ +------+ +------+
| | | | | | | |
| r1 |--------| r2 |--------| r3 |--------| r4 |
| | | | | | | |
+------+ +------+ +------+ +------+
| | | |
| AS 1000 | AS 2000 | AS 3000 |
| | | |
+------------+--------------------------------+-------------+
"""
import os
import sys
import json
import pytest
# Save the Current Working Directory to find configuration files.
CWD = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(CWD, "../"))
from lib.topogen import Topogen, get_topogen
from lib.topojson import build_topo_from_json, build_config_from_json
from lib.common_config import start_topology
from lib.topotest import router_json_cmp, run_and_expect
from mininet.topo import Topo
from functools import partial
LISTEN_ADDRESSES = {
"r1": ["10.0.0.1"],
"r2": ["10.0.0.2", "10.0.1.1"],
"r3": ["10.0.1.2", "10.0.2.1"],
"r4": ["10.0.2.2"],
}
# Reads data from JSON File for topology and configuration creation.
jsonFile = "{}/bgp_listen_on_multiple_addresses.json".format(CWD)
try:
with open(jsonFile, "r") as topoJson:
topo = json.load(topoJson)
except IOError:
assert False, "Could not read file {}".format(jsonFile)
class TemplateTopo(Topo):
"Topology builder."
def build(self, *_args, **_opts):
"Defines the allocation and relationship between routers and switches."
tgen = get_topogen(self)
build_topo_from_json(tgen, topo)
def setup_module(mod):
"Sets up the test environment."
tgen = Topogen(TemplateTopo, mod.__name__)
# Adds extra parameters to bgpd so they listen for connections on specific
# multiple addresses.
for router_name in tgen.routers().keys():
tgen.net[router_name].daemons_options["bgpd"] = "-l " + " -l ".join(
LISTEN_ADDRESSES[router_name]
)
start_topology(tgen)
build_config_from_json(tgen, topo)
def teardown_module(_mod):
"Tears-down the test environment."
tgen = get_topogen()
tgen.stop_topology()
def test_peering():
"Checks if the routers peer-up."
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
_bgp_converge_initial("r1", "10.0.0.2")
_bgp_converge_initial("r2", "10.0.0.1")
_bgp_converge_initial("r2", "10.0.1.2")
_bgp_converge_initial("r3", "10.0.1.1")
_bgp_converge_initial("r3", "10.0.2.2")
_bgp_converge_initial("r4", "10.0.2.1")
def test_listening_address():
"""
Checks if bgpd is only listening on the specified IP addresses.
"""
tgen = get_topogen()
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
for router in tgen.routers().values():
# bgpd must not be listening on the default address.
output = router.run("netstat -nlt4 | grep 0.0.0.0:179")
assert output == "", "{}: bpgd is listening on 0.0.0.0:179".format(router.name)
# bgpd must be listening on the specified addresses.
for address in LISTEN_ADDRESSES[router.name]:
output = router.run("netstat -nlt4 | grep {}:179".format(address))
assert output != "", "{}: bpgd is not listening on {}:179".format(
router.name, address
)
def _bgp_converge_initial(router_name, peer_address, timeout=180):
"""
Waits for the BGP connection between a given router and a given peer
(specified by its IP address) to be established. If the connection is
not established within a given timeout, then an exception is raised.
"""
tgen = get_topogen()
router = tgen.routers()[router_name]
expected = {"ipv4Unicast": {"peers": {peer_address: {"state": "Established"}}}}
test_func = partial(router_json_cmp, router, "show ip bgp summary json", expected)
_, result = run_and_expect(test_func, None, count=timeout, wait=1)
assert result is None, "{}: Failed to establish connection with {}".format(
router_name, peer_address
)
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))