]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_path_selection/test_bgp_path_selection.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / bgp_path_selection / test_bgp_path_selection.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # Copyright (c) 2022 by
6 # Louis Scalbert <louis.scalbert@6wind.com>
7 #
8
9 """
10
11 """
12
13 import os
14 import sys
15 import json
16 import pytest
17 import functools
18
19 CWD = os.path.dirname(os.path.realpath(__file__))
20 sys.path.append(os.path.join(CWD, "../"))
21
22 # pylint: disable=C0413
23 from lib import topotest
24 from lib.topogen import Topogen, TopoRouter, get_topogen
25 from lib.common_config import step
26
27 pytestmark = [pytest.mark.bgpd]
28
29
30 def build_topo(tgen):
31 for routern in range(1, 4):
32 tgen.add_router("r{}".format(routern))
33
34 switch = tgen.add_switch("s1")
35 switch.add_link(tgen.gears["r1"])
36 switch.add_link(tgen.gears["r2"])
37
38 switch = tgen.add_switch("s2")
39 switch.add_link(tgen.gears["r1"])
40 switch.add_link(tgen.gears["r3"])
41
42
43 def setup_module(mod):
44 tgen = Topogen(build_topo, mod.__name__)
45 tgen.start_topology()
46
47 router_list = tgen.routers()
48
49 for routern in range(1, 4):
50 tgen.gears["r{}".format(routern)].cmd("ip link add vrf1 type vrf table 10")
51 tgen.gears["r{}".format(routern)].cmd("ip link set vrf1 up")
52 tgen.gears["r{}".format(routern)].cmd("ip address add dev vrf1 {}.{}.{}.{}/32".format(routern, routern, routern,routern))
53 tgen.gears["r2"].cmd("ip address add dev vrf1 192.0.2.8/32")
54 tgen.gears["r3"].cmd("ip address add dev vrf1 192.0.2.8/32")
55
56 for i, (rname, router) in enumerate(router_list.items(), 1):
57 router.load_config(
58 TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
59 )
60 router.load_config(
61 TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
62 )
63 router.load_config(
64 TopoRouter.RD_LDP, os.path.join(CWD, "{}/ldpd.conf".format(rname))
65 )
66
67 tgen.start_router()
68
69 tgen.gears["r1"].cmd("ip route add 192.0.2.2 via 192.168.1.2 metric 20")
70 tgen.gears["r1"].cmd("ip route add 192.0.2.3 via 192.168.2.2 metric 20")
71
72
73 def teardown_module(mod):
74 tgen = get_topogen()
75 tgen.stop_topology()
76
77 def test_bgp_path_selection_ecmp():
78 tgen = get_topogen()
79
80 if tgen.routers_have_failure():
81 pytest.skip(tgen.errors)
82
83 def _bgp_check_path_selection_ecmp():
84 output = json.loads(
85 tgen.gears["r1"].vtysh_cmd("show bgp ipv4 unicast 192.0.2.8/32 json")
86 )
87 expected = {
88 "paths": [
89 {
90 "valid": True,
91 "aspath": {"string": "65002"},
92 "multipath": True,
93 "nexthops": [{"ip": "192.0.2.2", "metric": 20}],
94 },
95 {
96 "valid": True,
97 "aspath": {"string": "65002"},
98 "multipath": True,
99 "nexthops": [{"ip": "192.0.2.3", "metric": 20}],
100 }
101 ]
102 }
103
104 return topotest.json_cmp(output, expected)
105
106 step("Check if two ECMP paths are present")
107 test_func = functools.partial(_bgp_check_path_selection_ecmp)
108 _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
109 assert result is None, "Failed to see BGP prefixes on R1"
110
111
112 def test_bgp_path_selection_vpn_ecmp():
113 tgen = get_topogen()
114
115 if tgen.routers_have_failure():
116 pytest.skip(tgen.errors)
117
118 def _bgp_check_path_selection_vpn_ecmp():
119 output = json.loads(
120 tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv4 unicast 192.0.2.8/32 json")
121 )
122 expected = {
123 "paths": [
124 {
125 "valid": True,
126 "aspath": {"string": "65002"},
127 "multipath": True,
128 "nexthops": [{"ip": "192.0.2.2", "metric": 20}],
129 },
130 {
131 "valid": True,
132 "aspath": {"string": "65002"},
133 "multipath": True,
134 "nexthops": [{"ip": "192.0.2.3", "metric": 20}],
135 }
136 ]
137 }
138
139 return topotest.json_cmp(output, expected)
140
141 step("Check if two ECMP paths are present")
142 test_func = functools.partial(_bgp_check_path_selection_vpn_ecmp)
143 _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
144 assert result is None, "Failed to see BGP prefixes on R1"
145
146
147 def test_bgp_path_selection_metric():
148 tgen = get_topogen()
149
150 if tgen.routers_have_failure():
151 pytest.skip(tgen.errors)
152
153 def _bgp_check_path_selection_metric():
154 output = json.loads(
155 tgen.gears["r1"].vtysh_cmd("show bgp ipv4 unicast 192.0.2.8/32 json")
156 )
157 expected = {
158 "paths": [
159 {
160 "valid": True,
161 "aspath": {"string": "65002"},
162 "nexthops": [{"ip": "192.0.2.2", "metric": 10}],
163 "bestpath":{ "selectionReason":"IGP Metric"},
164 },
165 {
166 "valid": True,
167 "aspath": {"string": "65002"},
168 "nexthops": [{"ip": "192.0.2.3", "metric": 20}],
169 }
170 ]
171 }
172
173 return topotest.json_cmp(output, expected)
174
175 tgen.gears["r1"].cmd("ip route add 192.0.2.2 via 192.168.1.2 metric 10")
176 tgen.gears["r1"].cmd("ip route del 192.0.2.2 via 192.168.1.2 metric 20")
177
178 step("Check if IGP metric best path is selected")
179 test_func = functools.partial(_bgp_check_path_selection_metric)
180 _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
181 assert result is None, "Failed to see BGP prefixes on R1"
182
183
184 def test_bgp_path_selection_vpn_metric():
185 tgen = get_topogen()
186
187 if tgen.routers_have_failure():
188 pytest.skip(tgen.errors)
189
190 def _bgp_check_path_selection_vpn_metric():
191 output = json.loads(
192 tgen.gears["r1"].vtysh_cmd("show bgp vrf vrf1 ipv4 unicast 192.0.2.8/32 json")
193 )
194 expected = {
195 "paths": [
196 {
197 "valid": True,
198 "aspath": {"string": "65002"},
199 "nexthops": [{"ip": "192.0.2.2", "metric": 10}],
200 "bestpath":{ "selectionReason":"IGP Metric"},
201 },
202 {
203 "valid": True,
204 "aspath": {"string": "65002"},
205 "nexthops": [{"ip": "192.0.2.3", "metric": 20}],
206 }
207 ]
208 }
209
210 return topotest.json_cmp(output, expected)
211
212 step("Check if IGP metric best path is selected")
213 test_func = functools.partial(_bgp_check_path_selection_vpn_metric)
214 _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
215 assert result is None, "Failed to see BGP prefixes on R1"
216
217
218 if __name__ == "__main__":
219 args = ["-s"] + sys.argv[1:]
220 sys.exit(pytest.main(args))