]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_gshut/test_bgp_gshut.py
5 # Part of NetDEF Topology Tests
7 # Copyright (c) 2020 by
8 # Vivek Venkatraman <vivek@nvidia.com>
10 # Permission to use, copy, modify, and/or distribute this software
11 # for any purpose with or without fee is hereby granted, provided
12 # that the above copyright notice and this permission notice appear
15 # THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
16 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
18 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
19 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
21 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
26 Test the ability to initiate and stop BGP graceful shutdown.
27 Test both the vrf-specific and global configuration and operation.
37 r2 is UUT and peers with r1 and r3 in default bgp instance and
38 with r4 and r5 in vrf vrf1.
39 r1-r2 peering is iBGP and the other peerings are eBGP.
41 Check r2 initial convergence in default table
42 Define update-delay with max-delay in the default bgp instance on r2
43 Shutdown peering on r1 toward r2 so that delay timers can be exercised
44 Clear bgp neighbors on r2 and then check for the 'in progress' indicator
45 Check that r2 only installs route learned from r4 after the max-delay timer expires
46 Define update-delay with max-delay and estabish-wait and check json output showing set
47 Clear neighbors on r2 and check that r3 installs route from r4 after establish-wait time
48 Remove update-delay timer on r2 to verify that it goes back to normal behavior
49 Clear neighbors on r2 and check that route install time on r2 does not delay
50 Define global bgp update-delay with max-delay and establish-wait on r2
51 Check that r2 default instance and vrf1 have the max-delay and establish set
52 Clear neighbors on r2 and check route-install time is after the establish-wait timer
54 Note that the keepalive/hold times were changed to 3/9 and the connect retry timer
55 to 10 to improve the odds the convergence timing in this test case is useful in the
67 from functools
import partial
69 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
70 sys
.path
.append(os
.path
.join(CWD
, "../"))
72 # pylint: disable=C0413
73 from lib
import topotest
74 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
75 from lib
.topolog
import logger
76 from mininet
.topo
import Topo
78 pytestmark
= [pytest
.mark
.bgpd
]
81 class TemplateTopo(Topo
):
82 def build(self
, *_args
, **_opts
):
83 tgen
= get_topogen(self
)
85 for routern
in range(1, 6):
86 tgen
.add_router("r{}".format(routern
))
88 switch
= tgen
.add_switch("s1")
89 switch
.add_link(tgen
.gears
["r1"])
90 switch
.add_link(tgen
.gears
["r2"])
92 switch
= tgen
.add_switch("s2")
93 switch
.add_link(tgen
.gears
["r2"])
94 switch
.add_link(tgen
.gears
["r3"])
96 switch
= tgen
.add_switch("s3")
97 switch
.add_link(tgen
.gears
["r2"])
98 switch
.add_link(tgen
.gears
["r4"])
100 switch
= tgen
.add_switch("s4")
101 switch
.add_link(tgen
.gears
["r2"])
102 switch
.add_link(tgen
.gears
["r5"])
105 def _run_cmd_and_check(router
, cmd
, results_file
, retries
=100, intvl
=0.5):
106 json_file
= "{}/{}".format(CWD
, results_file
)
107 expected
= json
.loads(open(json_file
).read())
108 test_func
= partial(topotest
.router_json_cmp
, router
, cmd
, expected
)
109 return topotest
.run_and_expect(test_func
, None, retries
, intvl
)
112 def setup_module(mod
):
113 tgen
= Topogen(TemplateTopo
, mod
.__name
__)
114 tgen
.start_topology()
116 router_list
= tgen
.routers()
117 krel
= platform
.release()
118 if topotest
.version_cmp(krel
, "4.5") < 0:
119 tgen
.errors
= "Linux kernel version of at least 4.5 needed for bgp-gshut tests"
120 pytest
.skip(tgen
.errors
)
122 # Configure vrf and its slaves in the kernel on r2
123 r2
= tgen
.gears
["r2"]
124 r2
.run("ip link add vrf1 type vrf table 1000")
125 r2
.run("ip link set vrf1 up")
126 r2
.run("ip link set r2-eth2 master vrf1")
127 r2
.run("ip link set r2-eth3 master vrf1")
129 # Load FRR config and initialize all routers
130 for i
, (rname
, router
) in enumerate(router_list
.items(), 1):
132 TopoRouter
.RD_ZEBRA
, os
.path
.join(CWD
, "{}/zebra.conf".format(rname
))
135 TopoRouter
.RD_BGP
, os
.path
.join(CWD
, "{}/bgpd.conf".format(rname
))
140 # Basic peering test to see if things are ok
141 _
, result
= _run_cmd_and_check(r2
, "show ip bgp summary json", "r2/bgp_sum_1.json")
142 assertmsg
= "R2: Basic sanity test after init failed -- global peerings not up"
143 assert result
is None, assertmsg
145 _
, result
= _run_cmd_and_check(
146 r2
, "show ip bgp vrf vrf1 summary json", "r2/bgp_sum_2.json"
148 assertmsg
= "R2: Basic sanity test after init failed -- VRF peerings not up"
149 assert result
is None, assertmsg
152 def teardown_module(mod
):
157 def test_bgp_gshut():
160 if tgen
.routers_have_failure():
161 pytest
.skip(tgen
.errors
)
163 r1
= tgen
.gears
["r1"]
164 r2
= tgen
.gears
["r2"]
165 r3
= tgen
.gears
["r3"]
166 r4
= tgen
.gears
["r4"]
167 r5
= tgen
.gears
["r5"]
169 # Verify initial route states
170 logger
.info("\nVerify initial route states")
172 _
, result
= _run_cmd_and_check(
173 r1
, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json"
175 assertmsg
= "R1: Route 13.1.1.1/32 not present or has unexpected params"
176 assert result
is None, assertmsg
178 _
, result
= _run_cmd_and_check(
179 r3
, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json"
181 assertmsg
= "R3: Route 11.1.1.1/32 not present or has unexpected params"
182 assert result
is None, assertmsg
184 _
, result
= _run_cmd_and_check(
185 r5
, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_1.json"
187 assertmsg
= "R5: Route 14.1.1.1/32 not present or has unexpected params"
188 assert result
is None, assertmsg
190 logger
.info("\nInitial route states are as expected")
192 # "Test #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers"
194 "\nTest #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers"
200 bgp graceful-shutdown
204 # R1, R3 and R5 should see routes from R2 with GSHUT. In addition,
205 # R1 should see LOCAL_PREF of 0
206 _
, result
= _run_cmd_and_check(
207 r1
, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_2.json"
209 assertmsg
= "R1: Route 13.1.1.1/32 not present or has unexpected params"
210 assert result
is None, assertmsg
212 _
, result
= _run_cmd_and_check(
213 r3
, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_2.json"
215 assertmsg
= "R3: Route 11.1.1.1/32 not present or has unexpected params"
216 assert result
is None, assertmsg
218 _
, result
= _run_cmd_and_check(
219 r5
, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_2.json"
221 assertmsg
= "R5: Route 14.1.1.1/32 not present or has unexpected params"
222 assert result
is None, assertmsg
225 "\nTest #1: Successful, routes have GSHUT and/or LPREF of 0 as expected"
228 # "Test #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers"
230 "\nTest #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers"
236 no bgp graceful-shutdown
240 # R1, R3 and R5 should see routes from R2 with their original attributes
241 _
, result
= _run_cmd_and_check(
242 r1
, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json"
244 assertmsg
= "R1: Route 13.1.1.1/32 not present or has unexpected params"
245 assert result
is None, assertmsg
247 _
, result
= _run_cmd_and_check(
248 r3
, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json"
250 assertmsg
= "R3: Route 11.1.1.1/32 not present or has unexpected params"
251 assert result
is None, assertmsg
253 _
, result
= _run_cmd_and_check(
254 r5
, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_1.json"
256 assertmsg
= "R5: Route 14.1.1.1/32 not present or has unexpected params"
257 assert result
is None, assertmsg
260 "\nTest #2: Successful, routes have their original attributes with default LPREF and without GSHUT"
263 # "Test #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers"
265 "\nTest #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers"
271 router bgp 65001 vrf vrf1
272 bgp graceful-shutdown
276 # R1 and R3 should see no change to their routes
277 _
, result
= _run_cmd_and_check(
278 r1
, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json"
280 assertmsg
= "R1: Route 13.1.1.1/32 not present or has unexpected params"
281 assert result
is None, assertmsg
283 _
, result
= _run_cmd_and_check(
284 r3
, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json"
286 assertmsg
= "R3: Route 11.1.1.1/32 not present or has unexpected params"
287 assert result
is None, assertmsg
289 # R5 should see routes from R2 with GSHUT.
290 _
, result
= _run_cmd_and_check(
291 r5
, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_2.json"
293 assertmsg
= "R5: Route 14.1.1.1/32 not present or has unexpected params"
294 assert result
is None, assertmsg
296 logger
.info("\nTest #3: Successful, only VRF peers like R5 see routes with GSHUT")
298 # "Test #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1"
300 "\nTest #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1"
306 bgp graceful-shutdown
311 assertmsg
= "R2: BGP-wide graceful-shutdown config not rejected even though it is enabled in VRF1"
313 re
.search("global graceful-shutdown not permitted", ret
) is not None
317 "\nTest #4: Successful, BGP-wide graceful-shutdown rejected as it is enabled in VRF"
320 # "Test #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers"
322 "\nTest #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers"
328 router bgp 65001 vrf vrf1
329 no bgp graceful-shutdown
333 # R1 and R3 should see no change to their routes
334 _
, result
= _run_cmd_and_check(
335 r1
, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json"
337 assertmsg
= "R1: Route 13.1.1.1/32 not present or has unexpected params"
338 assert result
is None, assertmsg
340 _
, result
= _run_cmd_and_check(
341 r3
, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json"
343 assertmsg
= "R3: Route 11.1.1.1/32 not present or has unexpected params"
344 assert result
is None, assertmsg
346 # R5 should see routes from R2 with original attributes.
347 _
, result
= _run_cmd_and_check(
348 r5
, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_1.json"
350 assertmsg
= "R5: Route 14.1.1.1/32 not present or has unexpected params"
351 assert result
is None, assertmsg
354 "\nTest #5: Successful, routes have their original attributes with default LPREF and without GSHUT"
360 if __name__
== "__main__":
361 args
= ["-s"] + sys
.argv
[1:]
362 sys
.exit(pytest
.main(args
))