]> git.proxmox.com Git - mirror_frr.git/blame - tests/topotests/pbr_topo1/test_pbr_topo1.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / pbr_topo1 / test_pbr_topo1.py
CommitLineData
b1ab2bd2 1#!/usr/bin/env python
acddc0ed 2# SPDX-License-Identifier: ISC
b1ab2bd2
DS
3
4#
5# test_pbr_topo1.py
6#
7# Copyright (c) 2020 by
8# Cumulus Networks, Inc.
9# Donald Sharp
10#
b1ab2bd2
DS
11
12"""
13test_pbr_topo1.py: Testing PBR
14
15"""
16
17import os
b1ab2bd2
DS
18import sys
19import pytest
20import json
272ed0af 21import platform
36952a82 22from functools import partial
b1ab2bd2
DS
23
24# Save the Current Working Directory to find configuration files.
25CWD = os.path.dirname(os.path.realpath(__file__))
26sys.path.append(os.path.join(CWD, "../"))
27
28# pylint: disable=C0413
29# Import topogen and topotest helpers
30from lib import topotest
31from lib.topogen import Topogen, TopoRouter, get_topogen
32from lib.topolog import logger
b046dc87 33from lib.common_config import shutdown_bringup_interface
b1ab2bd2
DS
34
35# Required to instantiate the topology builder class.
b1ab2bd2 36
6907ac7e
DS
37pytestmark = [pytest.mark.pbrd]
38
b1ab2bd2
DS
39#####################################################
40##
41## Network Topology Definition
42##
43#####################################################
44
45
e82b531d
CH
46def build_topo(tgen):
47 "Build function"
b1ab2bd2 48
e82b531d
CH
49 # Populate routers
50 for routern in range(1, 2):
51 tgen.add_router("r{}".format(routern))
b1ab2bd2 52
e82b531d
CH
53 # Populate switches
54 for switchn in range(1, 6):
55 switch = tgen.add_switch("sw{}".format(switchn))
56 switch.add_link(tgen.gears["r1"])
b1ab2bd2
DS
57
58
59#####################################################
60##
61## Tests starting
62##
63#####################################################
64
5980ad0a 65
b1ab2bd2
DS
66def setup_module(module):
67 "Setup topology"
e82b531d 68 tgen = Topogen(build_topo, module.__name__)
b1ab2bd2
DS
69 tgen.start_topology()
70
272ed0af
DS
71 krel = platform.release()
72 if topotest.version_cmp(krel, "4.10") < 0:
11761ab0
MS
73 tgen.errors = "Newer kernel than 4.9 needed for pbr tests"
74 pytest.skip(tgen.errors)
272ed0af 75
b1ab2bd2 76 router_list = tgen.routers()
e5f0ed14 77 for rname, router in router_list.items():
11e33e00
WC
78 # Install vrf into the kernel and slave eth3
79 router.run("ip link add vrf-chiyoda type vrf table 1000")
80 router.run("ip link set dev {}-eth3 master vrf-chiyoda".format(rname))
81 router.run("ip link set vrf-chiyoda up")
82
b1ab2bd2
DS
83 router.load_config(
84 TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
85 )
86 router.load_config(
87 TopoRouter.RD_PBRD, os.path.join(CWD, "{}/pbrd.conf".format(rname))
88 )
89
90 tgen.start_router()
38b5ed4b 91
b1ab2bd2
DS
92
93def teardown_module(_mod):
94 "Teardown the pytest environment"
95 tgen = get_topogen()
96
97 # This function tears down the whole topology.
98 tgen.stop_topology()
99
100
101def test_converge_protocols():
102 "Wait for protocol convergence"
103
104 tgen = get_topogen()
105 # Don't run this test if we have any failure.
106 if tgen.routers_have_failure():
107 pytest.skip(tgen.errors)
108
109 topotest.sleep(5, "Waiting for PBR convergence")
110
111
112def test_pbr_data():
113 "Test PBR 'show ip eigrp'"
114
115 tgen = get_topogen()
116 # Don't run this test if we have any failure.
117 if tgen.routers_have_failure():
118 pytest.skip(tgen.errors)
119
120 # Verify PBR Status
121 logger.info("Verifying PBR routes")
122
123 router_list = tgen.routers().values()
124 for router in router_list:
125 intf_file = "{}/{}/pbr-interface.json".format(CWD, router.name)
b1ab2bd2 126 logger.info(intf_file)
38b5ed4b 127
b1ab2bd2
DS
128 # Read expected result from file
129 expected = json.loads(open(intf_file).read())
130
131 # Actual output from router
701a0192 132 test_func = partial(
133 topotest.router_json_cmp, router, "show pbr interface json", expected
134 )
36952a82 135 _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
b1ab2bd2 136 assertmsg = '"show pbr interface" mismatches on {}'.format(router.name)
11761ab0
MS
137 if result is not None:
138 gather_pbr_data_on_error(router)
d9a34de1 139 assert result is None, assertmsg
b1ab2bd2
DS
140
141 map_file = "{}/{}/pbr-map.json".format(CWD, router.name)
142 logger.info(map_file)
38b5ed4b 143
b1ab2bd2
DS
144 # Read expected result from file
145 expected = json.loads(open(map_file).read())
146
147 # Actual output from router
701a0192 148 test_func = partial(
149 topotest.router_json_cmp, router, "show pbr map json", expected
150 )
36952a82 151 _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
b1ab2bd2 152 assertmsg = '"show pbr map" mismatches on {}'.format(router.name)
11761ab0
MS
153 if result is not None:
154 gather_pbr_data_on_error(router)
d9a34de1 155 assert result is None, assertmsg
b1ab2bd2
DS
156
157 nexthop_file = "{}/{}/pbr-nexthop-groups.json".format(CWD, router.name)
38b5ed4b
WC
158 logger.info(nexthop_file)
159
b1ab2bd2
DS
160 # Read expected result from file
161 expected = json.loads(open(nexthop_file).read())
162
163 # Actual output from router
701a0192 164 test_func = partial(
165 topotest.router_json_cmp, router, "show pbr nexthop-groups json", expected
166 )
36952a82 167 _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
b1ab2bd2 168 assertmsg = '"show pbr nexthop-groups" mismatches on {}'.format(router.name)
11761ab0
MS
169 if result is not None:
170 gather_pbr_data_on_error(router)
d9a34de1 171 assert result is None, assertmsg
38b5ed4b 172
701a0192 173
b046dc87
WC
174def test_pbr_flap():
175 "Test PBR interface flapping"
176
177 tgen = get_topogen()
178 # Don't run this test if we have any failure.
179 if tgen.routers_have_failure():
180 pytest.skip(tgen.errors)
181
182 # Verify PBR Status
183 logger.info("Flapping PBR Interfaces")
184
185 router_list = tgen.routers().values()
186 for router in router_list:
187 # Flap interface to see if route-map properties are intact
188 # Shutdown interface
11e33e00 189
b046dc87
WC
190 for i in range(5):
191 intf = "r1-eth{}".format(i)
192
193 # Down and back again
11e33e00
WC
194 shutdown_bringup_interface(tgen, router.name, intf, False)
195 shutdown_bringup_interface(tgen, router.name, intf, True)
b046dc87
WC
196
197 intf_file = "{}/{}/pbr-interface.json".format(CWD, router.name)
198 logger.info(intf_file)
199
200 # Read expected result from file
201 expected = json.loads(open(intf_file).read())
202
203 # Actual output from router
701a0192 204 test_func = partial(
205 topotest.router_json_cmp, router, "show pbr interface json", expected
206 )
36952a82 207 _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
b046dc87 208 assertmsg = '"show pbr interface" mismatches on {}'.format(router.name)
11761ab0
MS
209 if result is not None:
210 gather_pbr_data_on_error(router)
d9a34de1 211 assert result is None, assertmsg
9b7decf2
JU
212
213
214def test_rule_linux_installation():
215 "Ensure that rule is installed in the kernel"
216
217 tgen = get_topogen()
218 # Don't run this test if we have any failure.
219 if tgen.routers_have_failure():
220 pytest.skip(tgen.errors)
221
222 logger.info("Checking for installed PBR rules in OS")
223
2ca90875
DS
224 def _get_router_rules(router, expected):
225 actual = topotest.ip_rules(router)
226
227 logger.info(actual)
228 return topotest.json_cmp(actual, expected)
229
9b7decf2
JU
230 router_list = tgen.routers().values()
231 for router in router_list:
232 rules_file = "{}/{}/linux-rules.json".format(CWD, router.name)
233
9b7decf2
JU
234 expected = json.loads(open(rules_file).read())
235
2ca90875
DS
236 test_func = partial(_get_router_rules, router, expected)
237
238 _, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
9b7decf2 239 assertmsg = "Router {} OS rules mismatch".format(router.name)
2ca90875 240 assert result is None, assertmsg
b046dc87
WC
241
242
b1ab2bd2
DS
243if __name__ == "__main__":
244 args = ["-s"] + sys.argv[1:]
245 sys.exit(pytest.main(args))
d9a34de1
DS
246
247#
248# EXTRA SAUCE
249#
250def gather_pbr_data_on_error(router):
251 logger.info(router.vtysh_cmd("show ip route"))
2cb8bfb2
DS
252 logger.info(router.vtysh_cmd("show ip route vrf vrf-chiyoda"))
253 logger.info(router.vtysh_cmd("show ip nht"))
d9a34de1
DS
254 logger.info(router.vtysh_cmd("show pbr interface"))
255 logger.info(router.vtysh_cmd("show pbr map"))
256 logger.info(router.vtysh_cmd("show pbr nexthop-groups"))
2cb8bfb2
DS
257 logger.info(router.vtysh_cmd("show nexthop-group rib singleton ip"))
258 logger.info(router.vtysh_cmd("show nexthop-group rib singleton ipv6"))
d9a34de1
DS
259 logger.info(router.vtysh_cmd("show nexthop-group rib"))
260 logger.info(router.run("ip nexthop show"))
261 logger.info(router.run("ip route show"))
2cb8bfb2 262 logger.info(router.run("ip route show table 1000"))
d9a34de1 263 logger.info(router.run("ip route show table 10000"))
2cb8bfb2 264 logger.info(router.run("ip -6 route show table 10000"))
d9a34de1 265 logger.info(router.run("ip route show table 10001"))
2cb8bfb2 266 logger.info(router.run("ip -6 route show table 10001"))
d9a34de1 267 logger.info(router.run("ip route show table 10002"))
2cb8bfb2 268 logger.info(router.run("ip -6 route show table 10002"))
d9a34de1 269 logger.info(router.run("ip route show table 10003"))
2cb8bfb2 270 logger.info(router.run("ip -6 route show table 10003"))
d9a34de1 271 logger.info(router.run("ip route show table 10004"))
2cb8bfb2
DS
272 logger.info(router.run("ip -6 route show table 10004"))
273 logger.info(router.run("ip route show table 10005"))
274 logger.info(router.run("ip -6 route show table 10005"))
d9a34de1 275 logger.info(router.run("ip rule show"))