3 # Copyright (c) 2019 by VMware, Inc. ("VMware")
4 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc. ("NetDEF")
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
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
23 Following tests are covered to test BGP Graceful Restart functionality.
24 Basic Common Test steps for all the test case below :
25 - Create topology (setup module)
26 Creating 7 routers topology
28 - Verify for bgp to converge
29 - Configure BGP Graceful Restart on both the routers.
32 Verify that EOR message is sent out only after initial convergence
33 Verify whether EOR message is received from all the peers after restart
35 Verify the selection deferral timer functionality when EOR is not sent
38 Verify that selection-deferral timer sets the maximum time to
39 avoid deadlock during which the best-path
41 Test Objective : Test GR scenarios on helper router by enabling
42 Graceful Restart for multiple address families.
44 Test Objective : Test GR scenarios by enabling Graceful Restart
45 for multiple address families..
47 Test Objective : Verify BGP-GR feature when restarting node
48 is a transit router for it's iBGP peers.
50 Test Objective : Verify that GR helper router deletes stale routes
51 received from restarting node, if GR capability is not present in
53 Test Objective : Verify that GR routers keeps all the routes
54 received from restarting node if both the routers are
56 Test Objective : Test GR scenarios on helper router by enabling
57 Graceful Restart for multiple address families.
59 Test Objective : Verify if helper node goes down before restarting
60 node comes up online, helper node sets the R-bit to avoid dead-lock
62 Test Objective : Change timers on the fly, and
63 verify if it takes immediate effect.
65 Test Objective : Helper router receives same prefixes from two
66 different routers (GR-restarting and GR-disabled). Keeps the
68 Test Objective : Restarting node doesn't preserve forwarding
69 state, helper router should not keep the stale entries.
71 Test Objective : Restarting node doesn't preserve the forwarding
72 state verify the behaviour on helper node, if it still keeps the
74 Test Objective : Restarting node is connected to multiple helper
75 nodes, one of them doesn't send EOR to restarting router. Verify
77 Test Objective : Verify if helper node restarts before sending the
78 EOR message, restarting node doesn't wait until stale path timer
80 Test Objective : Restarting node removes stale routes from Zebra
81 after receiving an EOR from helper router.
89 from time
import sleep
91 # Save the Current Working Directory to find configuration files.
92 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
93 sys
.path
.append(os
.path
.join("../"))
94 sys
.path
.append(os
.path
.join("../lib/"))
96 # pylint: disable=C0413
97 # Import topogen and topotest helpers
98 from lib
.topogen
import Topogen
, get_topogen
99 from lib
.topolog
import logger
101 # Required to instantiate the topology builder class.
103 # Import topoJson from lib, to create topology and initial configuration
104 from lib
.topojson
import build_config_from_json
105 from lib
.bgp
import (
108 verify_graceful_restart
,
113 verify_bgp_convergence
,
114 verify_gr_address_family
,
115 modify_bgp_config_when_bgpd_down
,
116 verify_graceful_restart_timers
,
117 verify_bgp_convergence_from_running_config
,
120 from lib
.common_config
import (
122 reset_config_on_routers
,
125 start_router_daemons
,
131 get_frr_ipv6_linklocal
,
132 required_linux_kernel_version
,
135 pytestmark
= [pytest
.mark
.bgpd
]
139 BGP_CONVERGENCE
= False
141 GR_SELECT_DEFER_TIMER
= 5
142 GR_STALEPATH_TIMER
= 5
143 PREFERRED_NEXT_HOP
= "link_local"
144 NEXT_HOP_4
= ["192.168.1.1", "192.168.4.2"]
145 NEXT_HOP_6
= ["fd00:0:0:1::1", "fd00:0:0:4::2"]
148 def setup_module(mod
):
150 Sets up the pytest environment
155 # Required linux kernel version for this suite to run.
156 result
= required_linux_kernel_version("4.16")
157 if result
is not True:
158 pytest
.skip("Kernel requirements are not met")
162 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
163 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
164 logger
.info("=" * 40)
166 logger
.info("Running setup_module to create topology")
168 # This function initiates the topology build with Topogen...
169 json_file
= "{}/bgp_gr_topojson_topo2.json".format(CWD
)
170 tgen
= Topogen(json_file
, mod
.__name
__)
172 topo
= tgen
.json_topo
173 # ... and here it calls Mininet initialization functions.
175 # Starting topology, create tmp files which are loaded to routers
176 # to start daemons and then start routers
179 # Creating configuration from JSON
180 build_config_from_json(tgen
, topo
)
182 # Api call verify whether BGP is converged
183 ADDR_TYPES
= check_address_types()
185 for addr_type
in ADDR_TYPES
:
186 BGP_CONVERGENCE
= verify_bgp_convergence(tgen
, topo
)
187 assert BGP_CONVERGENCE
is True, "setup_module : Failed \n Error:" " {}".format(
191 logger
.info("Running setup_module() done")
194 def teardown_module(mod
):
196 Teardown the pytest environment
201 logger
.info("Running teardown_module to delete topology")
205 # Stop toplogy and Remove tmp files
209 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
211 logger
.info("=" * 40)
214 def configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
, peer
):
216 This function groups the repetitive function calls into one function.
219 logger
.info("configure_gr_followed_by_clear: dut %s peer %s", dut
, peer
)
221 result
= create_router_bgp(tgen
, topo
, input_dict
)
222 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
224 for addr_type
in ADDR_TYPES
:
225 neighbor
= topo
["routers"][peer
]["links"][dut
][addr_type
].split("/")[0]
226 clear_bgp(tgen
, addr_type
, dut
, neighbor
=neighbor
)
228 for addr_type
in ADDR_TYPES
:
229 neighbor
= topo
["routers"][dut
]["links"][peer
][addr_type
].split("/")[0]
230 clear_bgp(tgen
, addr_type
, peer
, neighbor
=neighbor
)
232 result
= verify_bgp_convergence_from_running_config(tgen
)
233 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
238 def next_hop_per_address_family(tgen
, dut
, peer
, addr_type
, next_hop_dict
):
240 This function returns link_local or global next_hop per address-family
243 intferface
= topo
["routers"][peer
]["links"]["{}-link1".format(dut
)]["interface"]
244 if addr_type
== "ipv6" and "link_local" in PREFERRED_NEXT_HOP
:
245 next_hop
= get_frr_ipv6_linklocal(tgen
, peer
, intf
=intferface
)
247 next_hop
= next_hop_dict
[addr_type
]
252 def test_BGP_GR_26_p2(request
):
254 Test Objective : Test GR scenarios on helper router by enabling
255 Graceful Restart for multiple address families.
259 tc_name
= request
.node
.name
260 write_test_header(tc_name
)
262 # Check router status
263 check_router_status(tgen
)
265 # Don't run this test if we have any failure.
266 if tgen
.routers_have_failure():
267 pytest
.skip(tgen
.errors
)
269 # Creating configuration from JSON
270 reset_config_on_routers(tgen
)
273 "[Step 1] : Test Setup " "[Helper Mode]R3-----R1[Restart Mode] initialized"
276 # Configure graceful-restart
287 "graceful-restart": True,
288 "next_hop_self": True,
302 "graceful-restart": True,
303 "next_hop_self": True,
323 "graceful-restart-helper": True,
337 "graceful-restart-helper": True,
350 configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
="r1", peer
="r3")
352 for addr_type
in ADDR_TYPES
:
353 result
= verify_graceful_restart(
354 tgen
, topo
, addr_type
, input_dict
, dut
="r3", peer
="r1"
356 assert result
is True, "Testcase {} : Failed \n Error {}".format(
360 # Verifying BGP RIB routes
362 input_topo
= {key
: topo
["routers"][key
] for key
in ["r1"]}
363 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_topo
)
364 assert result
is True, "Testcase {} : Failed \n Error {}".format(
368 # Verifying RIB routes before shutting down BGPd daemon
369 result
= verify_rib(tgen
, addr_type
, dut
, input_topo
)
370 assert result
is True, "Testcase {} : Failed \n Error {}".format(
374 # Kill BGPd daemon on R1
375 kill_router_daemons(tgen
, "r1", ["bgpd"])
377 for addr_type
in ADDR_TYPES
:
378 # Verifying BGP RIB routes
379 input_topo
= {key
: topo
["routers"][key
] for key
in ["r1"]}
380 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_topo
)
381 assert result
is True, "Testcase {} : Failed \n Error {}".format(
385 # Verifying RIB routes before shutting down BGPd daemon
386 result
= verify_rib(tgen
, addr_type
, dut
, input_topo
)
387 assert result
is True, "Testcase {} : Failed \n Error {}".format(
391 # Start BGPd daemon on R1
392 start_router_daemons(tgen
, "r1", ["bgpd"])
394 for addr_type
in ADDR_TYPES
:
395 # Verifying BGP RIB routes
396 input_topo
= {key
: topo
["routers"][key
] for key
in ["r1"]}
397 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_topo
)
398 assert result
is True, "Testcase {} : Failed \n Error {}".format(
402 # Verifying RIB routes before shutting down BGPd daemon
403 result
= verify_rib(tgen
, addr_type
, dut
, input_topo
)
404 assert result
is True, "Testcase {} : Failed \n Error {}".format(
408 # verify multi address family
409 result
= verify_gr_address_family(
417 assert result
is True, "Testcase {} : Failed \n Error {}".format(
421 # verify multi address family
422 result
= verify_gr_address_family(
430 assert result
is True, "Testcase {} : Failed \n Error {}".format(
434 # verify multi address family
435 result
= verify_gr_address_family(
443 assert result
is True, "Testcase {} : Failed \n Error {}".format(
447 # verify multi address family
448 result
= verify_gr_address_family(
456 assert result
is True, "Testcase {} : Failed \n Error {}".format(
460 write_test_footer(tc_name
)
463 def test_BGP_GR_chaos_28_p1(request
):
465 Test Objective : Verify if helper node goes down before restarting
466 node comes up online, helper node sets the R-bit to avoid dead-lock
471 tc_name
= request
.node
.name
472 write_test_header(tc_name
)
474 # Check router status
475 check_router_status(tgen
)
477 # Don't run this test if we have any failure.
478 if tgen
.routers_have_failure():
479 pytest
.skip(tgen
.errors
)
481 # Creating configuration from JSON
482 reset_config_on_routers(tgen
)
485 "Test Case: test_BGP_GR_chaos_28 :"
486 "[Helper Mode]R3-----R1[Restart Mode] initialized"
489 # Configure graceful-restart
497 "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
504 "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
519 "r3": {"graceful-restart-helper": True}
530 "r3": {"graceful-restart-helper": True}
541 configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
="r1", peer
="r3")
543 for addr_type
in ADDR_TYPES
:
544 result
= verify_graceful_restart(
545 tgen
, topo
, addr_type
, input_dict
, dut
="r1", peer
="r3"
547 assert result
is True, "Testcase {} : Failed \n Error {}".format(
551 logger
.info("[Step 1] : Kill BGPd daemon on R1..")
553 # Kill BGPd daemon on R1
554 kill_router_daemons(tgen
, "r1", ["bgpd"])
556 logger
.info("[Step 2] : Kill BGPd daemon on R3..")
558 # Kill BGPd daemon on R3
559 kill_router_daemons(tgen
, "r3", ["bgpd"])
561 logger
.info("[Step 3] : Start BGPd daemon on R1..")
563 # Start BGPd daemon on R1
564 start_router_daemons(tgen
, "r1", ["bgpd"])
566 logger
.info("[Step 4] : Start BGPd daemon on R3..")
568 # Start BGPd daemon on R3
569 start_router_daemons(tgen
, "r3", ["bgpd"])
572 for addr_type
in ADDR_TYPES
:
573 result
= verify_r_bit(tgen
, topo
, addr_type
, input_dict
, dut
="r3", peer
="r1")
574 assert result
is True, "Testcase {} : Failed \n Error {}".format(
578 write_test_footer(tc_name
)
581 def test_BGP_GR_chaos_29_p1(request
):
583 Test Objective : Change timers on the fly, and
584 verify if it takes immediate effect.
588 tc_name
= request
.node
.name
589 write_test_header(tc_name
)
591 # Check router status
592 check_router_status(tgen
)
594 # Don't run this test if we have any failure.
595 if tgen
.routers_have_failure():
596 pytest
.skip(tgen
.errors
)
598 # Creating configuration from JSON
599 reset_config_on_routers(tgen
)
602 " Test Case : test_BGP_GR_chaos_29"
603 " BGP GR [Helper Mode]R3-----R1[Restart Mode]"
604 " and [restart-time 150]R1 initialized"
607 # Configure graceful-restart and timers
611 "graceful-restart": {"timer": {"restart-time": GR_RESTART_TIMER
}},
616 "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
623 "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
638 "r3": {"graceful-restart-helper": True}
649 "r3": {"graceful-restart-helper": True}
660 configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
="r1", peer
="r3")
662 for addr_type
in ADDR_TYPES
:
663 result
= verify_graceful_restart(
664 tgen
, topo
, addr_type
, input_dict
, dut
="r1", peer
="r3"
666 assert result
is True, "Testcase {} : Failed \n Error {}".format(
670 # Verify graceful-restart timers
674 "graceful-restart": {"timer": {"restart-time": GR_RESTART_TIMER
+ 5}}
679 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
680 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
682 for addr_type
in ADDR_TYPES
:
686 "graceful-restart": {"timer": {"restart-time": GR_RESTART_TIMER
}}
691 result
= verify_graceful_restart_timers(
692 tgen
, topo
, addr_type
, input_dict_2
, dut
="r3", peer
="r1"
694 assert result
is True, "Testcase {} : Failed \n Error {}".format(
698 for addr_type
in ADDR_TYPES
:
699 # Verifying BGP RIB routes before shutting down BGPd daemon
701 input_dict
= {key
: topo
["routers"][key
] for key
in ["r1"]}
702 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_dict
)
703 assert result
is True, "Testcase {} : Failed \n Error {}".format(
707 # Verifying RIB routes before shutting down BGPd daemon
708 result
= verify_rib(tgen
, addr_type
, dut
, input_dict
)
709 assert result
is True, "Testcase {} : Failed \n Error {}".format(
713 logger
.info("[Step 2] : Kill BGPd daemon on R1..")
715 # Kill BGPd daemon on R1
716 kill_router_daemons(tgen
, "r1", ["bgpd"])
718 logger
.info("[Step 3] : Wait for {} seconds..".format(GR_RESTART_TIMER
))
720 # Waiting for GR_RESTART_TIMER
721 sleep(GR_RESTART_TIMER
)
723 for addr_type
in ADDR_TYPES
:
724 # Verifying BGP RIB routes before shutting down BGPd daemon
725 input_dict
= {key
: topo
["routers"][key
] for key
in ["r1"]}
726 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_dict
, expected
=False)
727 assert result
is not True, (
728 "Testcase {} : Failed \n "
729 "r3: routes are still present in BGP RIB\n Error: {}".format(
733 logger
.info(" Expected behavior: {}".format(result
))
735 # Verifying RIB routes before shutting down BGPd daemon
736 result
= verify_rib(tgen
, addr_type
, dut
, input_dict
, expected
=False)
737 assert result
is not True, (
738 "Testcase {} : Failed \n "
739 "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name
, result
)
741 logger
.info(" Expected behavior: {}".format(result
))
743 logger
.info("[Step 4] : Start BGPd daemon on R1..")
745 # Start BGPd daemon on R1
746 start_router_daemons(tgen
, "r1", ["bgpd"])
748 write_test_footer(tc_name
)
751 def test_BGP_GR_chaos_33_p1(request
):
753 Test Objective : Helper router receives same prefixes from two
754 different routers (GR-restarting and GR-disabled). Keeps the
755 stale entry only for GR-restarting node(next-hop is correct).
759 tc_name
= request
.node
.name
760 write_test_header(tc_name
)
762 # Check router status
763 check_router_status(tgen
)
765 # Don't run this test if we have any failure.
766 if tgen
.routers_have_failure():
767 pytest
.skip(tgen
.errors
)
769 # Creating configuration from JSON
770 reset_config_on_routers(tgen
)
773 " Test Case : test_BGP_GR_chaos_33 "
775 "[Restart Mode]R1--R3[Helper Mode]--R4[Disabled Mode]"
778 # Configure graceful-restart
786 "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
793 "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
808 "r3": {"graceful-restart-helper": True}
819 "r3": {"graceful-restart-helper": True}
836 "r4": {"graceful-restart-disable": True}
847 "r4": {"graceful-restart-disable": True}
858 configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
="r1", peer
="r3")
860 for addr_type
in ADDR_TYPES
:
861 result
= verify_graceful_restart(
862 tgen
, topo
, addr_type
, input_dict
, dut
="r1", peer
="r3"
864 assert result
is True, "Testcase {} : Failed \n Error {}".format(
868 logger
.info("[Step 2] : Advertise same networks from R1 and R4..")
870 # Api call to delete advertised networks
877 "advertise_networks": [
879 "network": "200.0.20.1/32",
887 "advertise_networks": [
888 {"network": "2001::1/128", "no_of_network": 2}
900 "advertise_networks": [
901 {"network": "200.0.20.1/32", "no_of_network": 2}
907 "advertise_networks": [
908 {"network": "2001::1/128", "no_of_network": 2}
917 result
= create_router_bgp(tgen
, topo
, input_dict_2
)
918 assert result
is True, "Testcase {} : Failed \n Error: {}".format(tc_name
, result
)
920 for addr_type
in ADDR_TYPES
:
921 # Verifying RIB routes
925 intf1
= topo
["routers"][peer1
]["links"][dut
]["interface"]
926 intf2
= topo
["routers"][peer2
]["links"][dut
]["interface"]
928 if addr_type
== "ipv4":
929 next_hop_4
= NEXT_HOP_4
930 result
= verify_rib(tgen
, addr_type
, dut
, input_dict_2
, next_hop_4
)
931 assert result
is True, "Testcase {} : Failed \n Error {}".format(
935 if addr_type
== "ipv6":
936 if "link_local" in PREFERRED_NEXT_HOP
:
937 next_hop1
= get_frr_ipv6_linklocal(tgen
, peer1
, intf
=intf1
)
938 next_hop2
= get_frr_ipv6_linklocal(tgen
, peer2
, intf
=intf2
)
940 next_hop_6
= [next_hop1
, next_hop2
]
942 next_hop_6
= NEXT_HOP_6
944 result
= verify_rib(tgen
, addr_type
, dut
, input_dict_2
, next_hop_6
)
945 assert result
is True, "Testcase {} : Failed \n Error {}".format(
949 logger
.info("[Step 3] : Kill BGPd daemon on R1 and R4..")
951 # Kill BGPd daemon on R1
952 kill_router_daemons(tgen
, "r1", ["bgpd"])
954 # Kill BGPd daemon on R4
955 kill_router_daemons(tgen
, "r4", ["bgpd"])
957 for addr_type
in ADDR_TYPES
:
958 # Verifying RIB routes
959 next_hop_6
= ["fd00:0:0:1::1"]
960 if addr_type
== "ipv4":
961 next_hop_4
= NEXT_HOP_4
[0]
963 result
= verify_rib(tgen
, addr_type
, dut
, input_dict_2
, next_hop_4
)
964 assert result
is True, "Testcase {} : Failed \n Error {}".format(
968 if addr_type
== "ipv6":
969 if "link_local" in PREFERRED_NEXT_HOP
:
970 next_hop_6
= get_frr_ipv6_linklocal(tgen
, peer1
, intf
=intf1
)
972 next_hop_6
= NEXT_HOP_6
[0]
974 result
= verify_rib(tgen
, addr_type
, dut
, input_dict_2
, next_hop_6
)
976 # Verifying RIB routes
977 if addr_type
== "ipv4":
978 next_hop_4
= NEXT_HOP_4
[1]
980 tgen
, addr_type
, dut
, input_dict_2
, next_hop_4
, expected
=False
982 assert result
is not True, (
983 "Testcase {} : Failed \n "
984 "r3: routes are still present in BGP RIB\n Error: {}".format(
988 logger
.info(" Expected behavior: {}".format(result
))
990 if addr_type
== "ipv6":
991 if "link_local" in PREFERRED_NEXT_HOP
:
992 next_hop_6
= get_frr_ipv6_linklocal(tgen
, peer2
, intf
=intf2
)
994 next_hop_6
= NEXT_HOP_6
[1]
997 tgen
, addr_type
, dut
, input_dict_2
, next_hop_6
, expected
=False
999 assert result
is not True, (
1000 "Testcase {} : Failed \n "
1001 "r3: routes are still present in ZEBRA\n Error: {}".format(
1005 logger
.info(" Expected behavior: {}".format(result
))
1007 logger
.info("[Step 4] : Start BGPd daemon on R1 and R4..")
1009 # Start BGPd daemon on R1
1010 start_router_daemons(tgen
, "r1", ["bgpd"])
1012 # Start BGPd daemon on R4
1013 start_router_daemons(tgen
, "r4", ["bgpd"])
1015 write_test_footer(tc_name
)
1018 def test_BGP_GR_chaos_34_2_p1(request
):
1020 Test Objective : Restarting node doesn't preserve the forwarding
1021 state verify the behaviour on helper node, if it still keeps the
1025 tgen
= get_topogen()
1026 tc_name
= request
.node
.name
1027 write_test_header(tc_name
)
1029 # Check router status
1030 check_router_status(tgen
)
1032 # Don't run this test if we have any failure.
1033 if tgen
.routers_have_failure():
1034 pytest
.skip(tgen
.errors
)
1036 # Creating configuration from JSON
1037 reset_config_on_routers(tgen
)
1040 " Test Case : test_BGP_GR_chaos_34 "
1042 "[Restart Mode]R1---R3[Helper Mode]"
1045 logger
.info("[Step 1] : Configure restarting" " router R1 to prevent ")
1046 logger
.info("[Step 2] : Reset the session" " between R1 and R3..")
1048 # Configure graceful-restart
1052 "graceful-restart": {"preserve-fw-state": True, "disable-eor": True},
1057 "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
1064 "r3": {"dest_link": {"r1": {"graceful-restart": True}}}
1079 "r3": {"graceful-restart-helper": True}
1090 "r3": {"graceful-restart-helper": True}
1101 configure_gr_followed_by_clear(tgen
, topo
, input_dict
, tc_name
, dut
="r1", peer
="r3")
1103 for addr_type
in ADDR_TYPES
:
1104 result
= verify_graceful_restart(
1105 tgen
, topo
, addr_type
, input_dict
, dut
="r1", peer
="r3"
1107 assert result
is True, "Testcase {} : Failed \n Error {}".format(
1111 # Verify f-bit before killing BGPd daemon
1112 result
= verify_f_bit(tgen
, topo
, addr_type
, input_dict
, "r3", "r1")
1113 assert result
is True, "Testcase {} : Failed \n Error {}".format(
1117 # Verifying BGP RIB routes after starting BGPd daemon
1119 input_dict_1
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1120 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_dict_1
)
1121 assert result
is True, "Testcase {} : Failed \n Error {}".format(
1125 # Verifying RIB routes
1126 result
= verify_rib(tgen
, addr_type
, dut
, input_dict_1
)
1127 assert result
is True, "Testcase {} : Failed \n Error {}".format(
1131 logger
.info("[Step 3] : Kill BGPd daemon on R1..")
1133 # Kill BGPd daemon on R1
1134 kill_router_daemons(tgen
, "r1", ["bgpd"])
1136 logger
.info("[Step 4] : Withdraw/delete the prefixes " "originated from R1..")
1138 # Api call to delete advertised networks
1139 network
= {"ipv4": "101.0.20.1/32", "ipv6": "1::1/128"}
1140 for addr_type
in ADDR_TYPES
:
1147 "advertise_networks": [
1149 "network": network
[addr_type
],
1161 result
= modify_bgp_config_when_bgpd_down(tgen
, topo
, input_dict_2
)
1162 assert result
is True, "Testcase {} : Failed \n Error {}".format(
1166 logger
.info("[Step 5] : Remove the CLI from R1's config to " "set the F-bit..")
1168 # Modify graceful-restart config not to set f-bit
1169 # and write to /etc/frr
1170 input_dict_2
= {"r1": {"bgp": {"graceful-restart": {"preserve-fw-state": False}}}}
1172 result
= modify_bgp_config_when_bgpd_down(tgen
, topo
, input_dict_2
)
1173 assert result
is True, "Testcase {} : Failed \n Error {}".format(tc_name
, result
)
1175 logger
.info("[Step 6] : Bring up the BGPd daemon on R1 again..")
1177 # Start BGPd daemon on R1
1178 start_router_daemons(tgen
, "r1", ["bgpd"])
1180 for addr_type
in ADDR_TYPES
:
1181 # Verify f-bit after starting BGPd daemon
1182 result
= verify_f_bit(
1183 tgen
, topo
, addr_type
, input_dict
, "r3", "r1", expected
=False
1187 ), "Testcase {} : Failed \n " "r3: F-bit is set to True\n Error: {}".format(
1190 logger
.info(" Expected behavior: {}".format(result
))
1192 # Verifying BGP RIB routes after starting BGPd daemon
1193 input_dict_1
= {key
: topo
["routers"][key
] for key
in ["r1"]}
1194 result
= verify_bgp_rib(tgen
, addr_type
, dut
, input_dict_1
, expected
=False)
1195 assert result
is not True, (
1196 "Testcase {} : Failed \n "
1197 "r3: routes are still present in BGP RIB\n Error: {}".format(
1201 logger
.info(" Expected behavior: {}".format(result
))
1203 # Verifying RIB routes
1204 result
= verify_rib(tgen
, addr_type
, dut
, input_dict_1
, expected
=False)
1205 assert result
is not True, (
1206 "Testcase {} : Failed \n "
1207 "r3: routes are still present in ZEBRA\n Error: {}".format(tc_name
, result
)
1209 logger
.info(" Expected behavior: {}".format(result
))
1211 write_test_footer(tc_name
)
1214 if __name__
== "__main__":
1215 args
= ["-s"] + sys
.argv
[1:]
1216 sys
.exit(pytest
.main(args
))