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