]> git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py
Merge pull request #5288 from SumitAgarwal123/bfd_docs
[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/Quagga 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 re
78 import pytest
79 import platform
80
81 # pylint: disable=C0413
82 # Import topogen and topotest helpers
83 from lib import topotest
84 from lib.topogen import Topogen, TopoRouter, get_topogen
85 from lib.topolog import logger
86 from lib.ltemplate import ltemplateRtrCmd
87
88 # Required to instantiate the topology builder class.
89 from mininet.topo import Topo
90
91 import shutil
92 CWD = os.path.dirname(os.path.realpath(__file__))
93 # test name based on directory
94 TEST = os.path.basename(CWD)
95
96 class ThisTestTopo(Topo):
97 "Test topology builder"
98 def build(self, *_args, **_opts):
99 "Build function"
100 tgen = get_topogen(self)
101
102 # This function only purpose is to define allocation and relationship
103 # between routers, switches and hosts.
104 #
105 # Create P/PE routers
106 #check for mpls
107 tgen.add_router('r1')
108 if tgen.hasmpls != True:
109 logger.info('MPLS not available, tests will be skipped')
110 return
111 mach = platform.machine()
112 krel = platform.release()
113 if mach[:1] == 'a' and topotest.version_cmp(krel, '4.11') < 0:
114 logger.info('Need Kernel version 4.11 to run on arm processor')
115 return
116 for routern in range(2, 5):
117 tgen.add_router('r{}'.format(routern))
118 # Create CE routers
119 for routern in range(1, 5):
120 tgen.add_router('ce{}'.format(routern))
121
122 #CE/PE links
123 tgen.add_link(tgen.gears['ce1'], tgen.gears['r1'], 'ce1-eth0', 'r1-eth4')
124 tgen.add_link(tgen.gears['ce2'], tgen.gears['r3'], 'ce2-eth0', 'r3-eth4')
125 tgen.add_link(tgen.gears['ce3'], tgen.gears['r4'], 'ce3-eth0', 'r4-eth4')
126 tgen.add_link(tgen.gears['ce4'], tgen.gears['r4'], 'ce4-eth0', 'r4-eth5')
127
128 # Create a switch with just one router connected to it to simulate a
129 # empty network.
130 switch = {}
131 switch[0] = tgen.add_switch('sw0')
132 switch[0].add_link(tgen.gears['r1'], nodeif='r1-eth0')
133 switch[0].add_link(tgen.gears['r2'], nodeif='r2-eth0')
134
135 switch[1] = tgen.add_switch('sw1')
136 switch[1].add_link(tgen.gears['r2'], nodeif='r2-eth1')
137 switch[1].add_link(tgen.gears['r3'], nodeif='r3-eth0')
138 switch[1].add_link(tgen.gears['r4'], nodeif='r4-eth0')
139
140 switch[1] = tgen.add_switch('sw2')
141 switch[1].add_link(tgen.gears['r2'], nodeif='r2-eth2')
142 switch[1].add_link(tgen.gears['r3'], nodeif='r3-eth1')
143
144 l3mdev_accept = 0
145
146 def ltemplatePreRouterStartHook():
147 global l3mdev_accept
148 cc = ltemplateRtrCmd()
149 krel = platform.release()
150 tgen = get_topogen()
151 logger.info('pre router-start hook, kernel=' + krel)
152
153 if topotest.version_cmp(krel, '4.15') >= 0 and \
154 topotest.version_cmp(krel, '4.18') <= 0:
155 l3mdev_accept = 1
156 else:
157 l3mdev_accept = 0
158 logger.info('setting net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept))
159 #check for mpls
160 if tgen.hasmpls != True:
161 logger.info('MPLS not available, skipping setup')
162 return False
163 #check for normal init
164 if len(tgen.net) == 1:
165 logger.info('Topology not configured, skipping setup')
166 return False
167 #trace errors/unexpected output
168 cc.resetCounts()
169 #configure r2 mpls interfaces
170 intfs = ['lo', 'r2-eth0', 'r2-eth1', 'r2-eth2']
171 for intf in intfs:
172 cc.doCmd(tgen, 'r2', 'echo 1 > /proc/sys/net/mpls/conf/{}/input'.format(intf))
173
174 #configure cust1 VRFs & MPLS
175 rtrs = ['r1', 'r3', 'r4']
176 cmds = ['ip link add {0}-cust1 type vrf table 10',
177 'ip ru add oif {0}-cust1 table 10',
178 'ip ru add iif {0}-cust1 table 10',
179 'ip link set dev {0}-cust1 up',
180 'sysctl -w net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept)]
181 for rtr in rtrs:
182 router = tgen.gears[rtr]
183 for cmd in cmds:
184 cc.doCmd(tgen, rtr, cmd.format(rtr))
185 cc.doCmd(tgen, rtr, 'ip link set dev {0}-eth4 master {0}-cust1'.format(rtr))
186 intfs = [rtr+'-cust1', 'lo', rtr+'-eth0', rtr+'-eth4']
187 for intf in intfs:
188 cc.doCmd(tgen, rtr, 'echo 1 > /proc/sys/net/mpls/conf/{}/input'.format(intf))
189 logger.info('setup {0} vrf {0}-cust1, {0}-eth4. enabled mpls input.'.format(rtr))
190 #configure cust2 VRFs & MPLS
191 rtrs = ['r4']
192 cmds = ['ip link add {0}-cust2 type vrf table 20',
193 'ip ru add oif {0}-cust2 table 20',
194 'ip ru add iif {0}-cust2 table 20',
195 'ip link set dev {0}-cust2 up']
196 for rtr in rtrs:
197 for cmd in cmds:
198 cc.doCmd(tgen, rtr, cmd.format(rtr))
199 cc.doCmd(tgen, rtr, 'ip link set dev {0}-eth5 master {0}-cust2'.format(rtr))
200 intfs = [rtr+'-cust2', rtr+'-eth5']
201 for intf in intfs:
202 cc.doCmd(tgen, rtr, 'echo 1 > /proc/sys/net/mpls/conf/{}/input'.format(intf))
203 logger.info('setup {0} vrf {0}-cust2, {0}-eth5. enabled mpls input.'.format(rtr))
204 #put ce4-eth0 into a VRF (no default instance!)
205 rtrs = ['ce4']
206 cmds = ['ip link add {0}-cust2 type vrf table 20',
207 'ip ru add oif {0}-cust2 table 20',
208 'ip ru add iif {0}-cust2 table 20',
209 'ip link set dev {0}-cust2 up',
210 'sysctl -w net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept)]
211 for rtr in rtrs:
212 for cmd in cmds:
213 cc.doCmd(tgen, rtr, cmd.format(rtr))
214 cc.doCmd(tgen, rtr, 'ip link set dev {0}-eth0 master {0}-cust2'.format(rtr))
215 if cc.getOutput() != 4:
216 InitSuccess = False
217 logger.info('Unexpected output seen ({} times, tests will be skipped'.format(cc.getOutput()))
218 else:
219 InitSuccess = True
220 logger.info('VRF config successful!')
221 return InitSuccess
222
223 def ltemplatePostRouterStartHook():
224 logger.info('post router-start hook')
225 return True