]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / tests / topotests / bgp_l3vpn_to_bgp_vrf / customize.py
1 #!/usr/bin/env python
2 # SPDX-License-Identifier: ISC
3
4 #
5 # Part of NetDEF Topology Tests
6 #
7 # Copyright (c) 2017 by
8 # Network Device Education Foundation, Inc. ("NetDEF")
9 #
10
11 r"""
12 customize.py: Simple FRR MPLS L3VPN test topology
13
14 |
15 +----+----+
16 | ce1 |
17 | 99.0.0.1| CE Router
18 +----+----+
19 192.168.1. | .2 ce1-eth0
20 | .1 r1-eth4
21 +---------+
22 | r1 |
23 | 1.1.1.1 | PE Router
24 +----+----+
25 | .1 r1-eth0
26 |
27 ~~~~~~~~~~~~~
28 ~~ sw0 ~~
29 ~~ 10.0.1.0/24 ~~
30 ~~~~~~~~~~~~~
31 |10.0.1.0/24
32 |
33 | .2 r2-eth0
34 +----+----+
35 | r2 |
36 | 2.2.2.2 | P router
37 +--+---+--+
38 r2-eth2 .2 | | .2 r2-eth1
39 ______/ \______
40 / \
41 ~~~~~~~~~~~~~ ~~~~~~~~~~~~~
42 ~~ sw2 ~~ ~~ sw1 ~~
43 ~~ 10.0.3.0/24 ~~ ~~ 10.0.2.0/24 ~~
44 ~~~~~~~~~~~~~ ~~~~~~~~~~~~~
45 | / |
46 \ _________/ |
47 \ / \
48 r3-eth1 .3 | | .3 r3-eth0 | .4 r4-eth0
49 +----+--+---+ +----+----+
50 | r3 | | r4 | r4-eth5
51 | 3.3.3.3 | | 4.4.4.4 |-------+ PE Routers
52 +-----------+ +---------+ |
53 192.168.1.1 |r3.eth4 192.168.1.1 | r4-eth4 |192.168.2.1
54 .2 | ceX-eth0 .2 | | .2
55 +-----+-----+ +----+-----+ +----+-----+
56 | ce2 | | ce3 | | ce4 |
57 | 99.0.0.2 | | 99.0.0.3 | | 99.0.0.4 | CE Routers
58 +-----+-----+ +----+-----+ +----+-----+
59 | | |
60
61 """
62
63 import os
64 import platform
65
66 # pylint: disable=C0413
67 # Import topogen and topotest helpers
68 from lib import topotest
69 from lib.topogen import get_topogen
70 from lib.topolog import logger
71 from lib.ltemplate import ltemplateRtrCmd
72
73 # Required to instantiate the topology builder class.
74
75
76 CWD = os.path.dirname(os.path.realpath(__file__))
77 # test name based on directory
78 TEST = os.path.basename(CWD)
79
80
81 def build_topo(tgen):
82 "Build function"
83
84 # This function only purpose is to define allocation and relationship
85 # between routers, switches and hosts.
86 #
87 # Create P/PE routers
88 # check for mpls
89 tgen.add_router("r1")
90 if tgen.hasmpls != True:
91 logger.info("MPLS not available, tests will be skipped")
92 return
93 mach = platform.machine()
94 krel = platform.release()
95 if mach[:1] == "a" and topotest.version_cmp(krel, "4.11") < 0:
96 logger.info("Need Kernel version 4.11 to run on arm processor")
97 return
98 for routern in range(2, 5):
99 tgen.add_router("r{}".format(routern))
100 # Create CE routers
101 for routern in range(1, 5):
102 tgen.add_router("ce{}".format(routern))
103
104 # CE/PE links
105 tgen.add_link(tgen.gears["ce1"], tgen.gears["r1"], "ce1-eth0", "r1-eth4")
106 tgen.add_link(tgen.gears["ce2"], tgen.gears["r3"], "ce2-eth0", "r3-eth4")
107 tgen.add_link(tgen.gears["ce3"], tgen.gears["r4"], "ce3-eth0", "r4-eth4")
108 tgen.add_link(tgen.gears["ce4"], tgen.gears["r4"], "ce4-eth0", "r4-eth5")
109
110 # Create a switch with just one router connected to it to simulate a
111 # empty network.
112 switch = {}
113 switch[0] = tgen.add_switch("sw0")
114 switch[0].add_link(tgen.gears["r1"], nodeif="r1-eth0")
115 switch[0].add_link(tgen.gears["r2"], nodeif="r2-eth0")
116
117 switch[1] = tgen.add_switch("sw1")
118 switch[1].add_link(tgen.gears["r2"], nodeif="r2-eth1")
119 switch[1].add_link(tgen.gears["r3"], nodeif="r3-eth0")
120 switch[1].add_link(tgen.gears["r4"], nodeif="r4-eth0")
121
122 switch[1] = tgen.add_switch("sw2")
123 switch[1].add_link(tgen.gears["r2"], nodeif="r2-eth2")
124 switch[1].add_link(tgen.gears["r3"], nodeif="r3-eth1")
125
126
127 def ltemplatePreRouterStartHook():
128 cc = ltemplateRtrCmd()
129 krel = platform.release()
130 tgen = get_topogen()
131 logger.info("pre router-start hook, kernel=" + krel)
132
133 # check for mpls
134 if tgen.hasmpls != True:
135 logger.info("MPLS not available, skipping setup")
136 return False
137 # trace errors/unexpected output
138 cc.resetCounts()
139 # configure r2 mpls interfaces
140 intfs = ["lo", "r2-eth0", "r2-eth1", "r2-eth2"]
141 for intf in intfs:
142 cc.doCmd(tgen, "r2", "echo 1 > /proc/sys/net/mpls/conf/{}/input".format(intf))
143
144 # configure cust1 VRFs & MPLS
145 rtrs = ["r1", "r3", "r4"]
146 cmds = [
147 "ip link add {0}-cust1 type vrf table 10",
148 "ip ru add oif {0}-cust1 table 10",
149 "ip ru add iif {0}-cust1 table 10",
150 "ip link set dev {0}-cust1 up",
151 ]
152 for rtr in rtrs:
153 for cmd in cmds:
154 cc.doCmd(tgen, rtr, cmd.format(rtr))
155 cc.doCmd(tgen, rtr, "ip link set dev {0}-eth4 master {0}-cust1".format(rtr))
156 intfs = [rtr + "-cust1", "lo", rtr + "-eth0", rtr + "-eth4"]
157 for intf in intfs:
158 cc.doCmd(
159 tgen, rtr, "echo 1 > /proc/sys/net/mpls/conf/{}/input".format(intf)
160 )
161 logger.info(
162 "setup {0} vrf {0}-cust1, {0}-eth4. enabled mpls input.".format(rtr)
163 )
164 # configure cust2 VRFs & MPLS
165 rtrs = ["r4"]
166 cmds = [
167 "ip link add {0}-cust2 type vrf table 20",
168 "ip ru add oif {0}-cust2 table 20",
169 "ip ru add iif {0}-cust2 table 20",
170 "ip link set dev {0}-cust2 up",
171 ]
172 for rtr in rtrs:
173 for cmd in cmds:
174 cc.doCmd(tgen, rtr, cmd.format(rtr))
175 cc.doCmd(tgen, rtr, "ip link set dev {0}-eth5 master {0}-cust2".format(rtr))
176 intfs = [rtr + "-cust2", rtr + "-eth5"]
177 for intf in intfs:
178 cc.doCmd(
179 tgen, rtr, "echo 1 > /proc/sys/net/mpls/conf/{}/input".format(intf)
180 )
181 logger.info(
182 "setup {0} vrf {0}-cust2, {0}-eth5. enabled mpls input.".format(rtr)
183 )
184 # put ce4-eth0 into a VRF (no default instance!)
185 rtrs = ["ce4"]
186 cmds = [
187 "ip link add {0}-cust2 type vrf table 20",
188 "ip ru add oif {0}-cust2 table 20",
189 "ip ru add iif {0}-cust2 table 20",
190 "ip link set dev {0}-cust2 up",
191 ]
192 for rtr in rtrs:
193 for cmd in cmds:
194 cc.doCmd(tgen, rtr, cmd.format(rtr))
195 cc.doCmd(tgen, rtr, "ip link set dev {0}-eth0 master {0}-cust2".format(rtr))
196 if cc.getOutput() != 0:
197 InitSuccess = False
198 logger.info(
199 "Unexpected output seen ({} times, tests will be skipped".format(
200 cc.getOutput()
201 )
202 )
203 else:
204 rtrs = ["r1", "r3", "r4", "ce4"]
205 for rtr in rtrs:
206 logger.info("{} configured".format(rtr))
207 cc.doCmd(tgen, rtr, "ip -d link show type vrf")
208 cc.doCmd(tgen, rtr, "ip link show")
209 InitSuccess = True
210 logger.info("VRF config successful!")
211 return InitSuccess
212
213
214 def ltemplatePostRouterStartHook():
215 logger.info("post router-start hook")
216 return True