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