]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py
Merge pull request #9292 from mobash-rasool/ospfv3-bug2
[mirror_frr.git] / tests / topotests / bgp_gr_functionality_topo1 / test_bgp_gr_functionality_topo1-2.py
1 #!/usr/bin/env python
2 #
3 # Copyright (c) 2019 by VMware, Inc. ("VMware")
4 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF")
5 # in this file.
6 #
7 # Permission to use, copy, modify, and/or distribute this software
8 # for any purpose with or without fee is hereby granted, provided
9 # that the above copyright notice and this permission notice appear
10 # in all copies.
11 #
12 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
13 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
15 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
16 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
17 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
18 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
19 # OF THIS SOFTWARE.
20 #
21
22 """
23 Following tests are covered to test BGP Gracefull Restart functionality.
24 Basic Common Test steps for all the test case below :
25 - Create topology (setup module)
26 Creating 2 routers topology, r1, r2 in IBGP
27 - Bring up topology
28 - Verify for bgp to converge
29 - Configure BGP Garceful Restart on both the routers.
30
31 1. Transition from Peer-level helper to Global Restarting
32 2. Transition from Peer-level helper to Global inherit helper
33 3. Transition from Peer-level restarting to Global inherit helper
34 4. Default GR functional mode is Helper.
35 5. Verify that the restarting node sets "R" bit while sending the
36 BGP open messages after the node restart, only if GR is enabled.
37 6. Verify if restarting node resets R bit in BGP open message
38 during normal BGP session flaps as well, even when GR restarting
39 mode is enabled. Here link flap happen due to interface UP/DOWN.
40 7. Verify if restarting node resets R bit in BGP
41 open message during normal BGP session flaps when GR is disabled.
42 8. Verify that restarting nodes set "F" bit while sending
43 the BGP open messages after it restarts, only when BGP GR is enabled.
44 9. Verify that only GR helper routers keep the stale
45 route entries, not any GR disabled router.
46 10. Verify that GR helper routers keeps all the routes received
47 from restarting node if both the routers are configured as
48 GR restarting node.
49 11. Verify that GR helper routers delete all the routes
50 received from a node if both the routers are configured as GR
51 helper node.
52 12. After BGP neighborship is established and GR capability is exchanged,
53 transition restarting router to disabled state and vice versa.
54 13. After BGP neighborship is established and GR capability is exchanged,
55 transition restarting router to disabled state and vice versa.
56 14. Verify that restarting nodes reset "F" bit while sending
57 the BGP open messages after it's restarts, when BGP GR is **NOT** enabled.
58 15. Verify that only GR helper routers keep the stale
59 route entries, not any GR disabled router.
60 16. Transition from Global Restarting to Disable and then Global
61 Disable to Restarting.
62 17. Transition from Global Helper to Disable and then Global
63 Disable to Helper.
64 18. Transition from Global Restart to Helper and then Global
65 Helper to Restart, Global Mode : GR Restarting
66 PerPeer Mode : GR Helper
67 GR Mode effective : GR Helper
68 19. Transition from Peer-level helper to Global Restarting,
69 Global Mode : GR Restarting
70 PerPeer Mode : GR Restarting
71 GR Mode effective : GR Restarting
72 20. Transition from Peer-level restart to Global Restart
73 Global Mode : GR Restarting
74 PerPeer Mode : GR Restarting
75 GR Mode effective : GR Restarting
76 21. Transition from Peer-level disabled to Global Restart
77 Global Mode : GR Restarting
78 PerPeer Mode : GR Disabled
79 GR Mode effective : GR Disabled
80 22. Peer-level inherit from Global Restarting
81 Global Mode : GR Restart
82 PerPeer Mode : None
83 GR Mode effective : GR Restart
84 23. Transition from Peer-level disbale to Global inherit helper
85 Global Mode : None
86 PerPeer Mode : GR Disable
87 GR Mode effective : GR Disable
88
89 These tests have been broken up into 4 sub python scripts because
90 the totality of this run was fairly significant.
91 """
92
93 import os
94 import sys
95 import time
96 import pytest
97
98 # Save the Current Working Directory to find configuration files.
99 CWD = os.path.dirname(os.path.realpath(__file__))
100 sys.path.append(os.path.join("../"))
101 sys.path.append(os.path.join("../lib/"))
102
103 # pylint: disable=C0413
104 # Import topogen and topotest helpers
105 from lib.topogen import Topogen, get_topogen
106 from lib.topolog import logger
107
108 # Required to instantiate the topology builder class.
109
110 # Import topoJson from lib, to create topology and initial configuration
111 from lib.topojson import build_config_from_json
112 from lib.bgp import (
113 clear_bgp,
114 verify_bgp_rib,
115 verify_graceful_restart,
116 create_router_bgp,
117 verify_r_bit,
118 verify_f_bit,
119 verify_bgp_convergence,
120 verify_bgp_convergence_from_running_config,
121 )
122
123 from lib.common_config import (
124 write_test_header,
125 reset_config_on_routers,
126 start_topology,
127 kill_router_daemons,
128 start_router_daemons,
129 verify_rib,
130 check_address_types,
131 write_test_footer,
132 check_router_status,
133 shutdown_bringup_interface,
134 step,
135 get_frr_ipv6_linklocal,
136 required_linux_kernel_version,
137 )
138
139 pytestmark = [pytest.mark.bgpd]
140
141
142 # Global variables
143 NEXT_HOP_IP = {"ipv4": "192.168.1.10", "ipv6": "fd00:0:0:1::10"}
144 NEXT_HOP_IP_1 = {"ipv4": "192.168.0.1", "ipv6": "fd00::1"}
145 NEXT_HOP_IP_2 = {"ipv4": "192.168.0.2", "ipv6": "fd00::2"}
146 BGP_CONVERGENCE = False
147 GR_RESTART_TIMER = 20
148 PREFERRED_NEXT_HOP = "link_local"
149
150
151 def setup_module(mod):
152 """
153 Sets up the pytest environment
154
155 * `mod`: module name
156 """
157
158 global ADDR_TYPES
159
160 # Required linux kernel version for this suite to run.
161 result = required_linux_kernel_version("4.16")
162 if result is not True:
163 pytest.skip("Kernel requirements are not met")
164
165 testsuite_run_time = time.asctime(time.localtime(time.time()))
166 logger.info("Testsuite start time: {}".format(testsuite_run_time))
167 logger.info("=" * 40)
168
169 logger.info("Running setup_module to create topology")
170
171 # This function initiates the topology build with Topogen...
172 json_file = "{}/bgp_gr_topojson_topo1.json".format(CWD)
173 tgen = Topogen(json_file, mod.__name__)
174 global topo
175 topo = tgen.json_topo
176 # ... and here it calls Mininet initialization functions.
177
178 # Starting topology, create tmp files which are loaded to routers
179 # to start deamons and then start routers
180 start_topology(tgen)
181
182 # Creating configuration from JSON
183 build_config_from_json(tgen, topo)
184
185 # Don't run this test if we have any failure.
186 if tgen.routers_have_failure():
187 pytest.skip(tgen.errors)
188
189 # Api call verify whether BGP is converged
190 ADDR_TYPES = check_address_types()
191
192 BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
193 assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format(
194 BGP_CONVERGENCE
195 )
196
197 logger.info("Running setup_module() done")
198
199
200 def teardown_module(mod):
201 """
202 Teardown the pytest environment
203
204 * `mod`: module name
205 """
206
207 logger.info("Running teardown_module to delete topology")
208
209 tgen = get_topogen()
210
211 # Stop toplogy and Remove tmp files
212 tgen.stop_topology()
213
214 logger.info(
215 "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
216 )
217 logger.info("=" * 40)
218
219
220 def configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut, peer):
221 """
222 This function groups the repetitive function calls into one function.
223 """
224
225 result = create_router_bgp(tgen, topo, input_dict)
226 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
227
228 for addr_type in ADDR_TYPES:
229 neighbor = topo["routers"][peer]["links"]["r1-link1"][addr_type].split("/")[0]
230 clear_bgp(tgen, addr_type, dut, neighbor=neighbor)
231
232 for addr_type in ADDR_TYPES:
233 neighbor = topo["routers"][dut]["links"]["r2-link1"][addr_type].split("/")[0]
234 clear_bgp(tgen, addr_type, peer, neighbor=neighbor)
235
236 result = verify_bgp_convergence_from_running_config(tgen)
237 assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
238
239 return True
240
241
242 def next_hop_per_address_family(
243 tgen, dut, peer, addr_type, next_hop_dict, preferred_next_hop=PREFERRED_NEXT_HOP
244 ):
245 """
246 This function returns link_local or global next_hop per address-family
247 """
248
249 intferface = topo["routers"][peer]["links"]["{}-link1".format(dut)]["interface"]
250 if addr_type == "ipv6" and "link_local" in preferred_next_hop:
251 next_hop = get_frr_ipv6_linklocal(tgen, peer, intf=intferface)
252 else:
253 next_hop = next_hop_dict[addr_type]
254
255 return next_hop
256
257
258 def test_BGP_GR_TC_8_p1(request):
259 """
260 Test Objective : Verify that restarting nodes set "F" bit while sending
261 the BGP open messages after it restarts, only when BGP GR is enabled.
262 """
263
264 tgen = get_topogen()
265 tc_name = request.node.name
266 write_test_header(tc_name)
267
268 # Check router status
269 check_router_status(tgen)
270
271 # Don't run this test if we have any failure.
272 if tgen.routers_have_failure():
273 pytest.skip(tgen.errors)
274
275 # Creating configuration from JSON
276 reset_config_on_routers(tgen)
277
278 logger.info(
279 "[Phase 1] : Test Setup" " [Restart Mode]R1-----R2[Restart Mode] initialized "
280 )
281
282 # Configure graceful-restart
283 input_dict = {
284 "r1": {
285 "bgp": {
286 "graceful-restart": {"preserve-fw-state": True},
287 "address_family": {
288 "ipv4": {
289 "unicast": {
290 "neighbor": {
291 "r2": {
292 "dest_link": {
293 "r1-link1": {"graceful-restart": True}
294 }
295 }
296 }
297 }
298 },
299 "ipv6": {
300 "unicast": {
301 "neighbor": {
302 "r2": {
303 "dest_link": {
304 "r1-link1": {"graceful-restart": True}
305 }
306 }
307 }
308 }
309 },
310 },
311 }
312 },
313 "r2": {
314 "bgp": {
315 "address_family": {
316 "ipv4": {
317 "unicast": {
318 "neighbor": {
319 "r1": {
320 "dest_link": {
321 "r2-link1": {"graceful-restart": True}
322 }
323 }
324 }
325 }
326 },
327 "ipv6": {
328 "unicast": {
329 "neighbor": {
330 "r1": {
331 "dest_link": {
332 "r2-link1": {"graceful-restart": True}
333 }
334 }
335 }
336 }
337 },
338 }
339 }
340 },
341 }
342
343 configure_gr_followed_by_clear(tgen, topo, input_dict, tc_name, dut="r1", peer="r2")
344
345 for addr_type in ADDR_TYPES:
346 result = verify_graceful_restart(
347 tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
348 )
349 assert result is True, "Testcase {} : Failed \n Error {}".format(
350 tc_name, result
351 )
352
353 # Verifying BGP RIB routes
354 dut = "r1"
355 peer = "r2"
356 next_hop = next_hop_per_address_family(
357 tgen, dut, peer, addr_type, NEXT_HOP_IP_2
358 )
359 input_topo = {key: topo["routers"][key] for key in ["r2"]}
360 result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop)
361 assert result is True, "Testcase {} : Failed \n Error {}".format(
362 tc_name, result
363 )
364
365 # Verifying RIB routes
366 protocol = "bgp"
367 result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol)
368 assert result is True, "Testcase {} : Failed \n Error {}".format(
369 tc_name, result
370 )
371
372 logger.info("[Phase 2] : R1 goes for reload ")
373
374 kill_router_daemons(tgen, "r1", ["bgpd"])
375
376 logger.info("[Phase 3] : R1 is about to come up now ")
377 start_router_daemons(tgen, "r1", ["bgpd"])
378
379 logger.info("[Phase 4] : R2 is UP now, so time to collect GR stats ")
380
381 for addr_type in ADDR_TYPES:
382 result = verify_graceful_restart(
383 tgen, topo, addr_type, input_dict, dut="r1", peer="r2"
384 )
385 assert result is True, "Testcase {} : Failed \n Error {}".format(
386 tc_name, result
387 )
388
389 result = verify_r_bit(tgen, topo, addr_type, input_dict, dut="r2", peer="r1")
390 assert result is True, "Testcase {} : Failed \n Error {}".format(
391 tc_name, result
392 )
393
394 result = verify_f_bit(tgen, topo, addr_type, input_dict, dut="r2", peer="r1")
395 assert result is True, "Testcase {} : Failed \n Error {}".format(
396 tc_name, result
397 )
398
399 write_test_footer(tc_name)
400
401
402 if __name__ == "__main__":
403 args = ["-s"] + sys.argv[1:]
404 sys.exit(pytest.main(args))