blob: badb310275221bc8043f5540b27e1111691debb1 [file] [log] [blame]
Neale Ranns177bbdc2016-11-15 09:46:51 +00001"""
2 IP Routes
3
4 object abstractions for representing IP routes in VPP
5"""
6
Neale Ranns5a8123b2017-01-26 01:18:23 -08007from vpp_object import *
Neale Rannsb3b2de72017-03-08 05:17:22 -08008from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
Neale Ranns177bbdc2016-11-15 09:46:51 +00009
Neale Rannsad422ed2016-11-02 14:20:04 +000010# from vnet/vnet/mpls/mpls_types.h
11MPLS_IETF_MAX_LABEL = 0xfffff
12MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
Neale Ranns177bbdc2016-11-15 09:46:51 +000013
Neale Ranns177bbdc2016-11-15 09:46:51 +000014
Neale Ranns180279b2017-03-16 15:49:09 -040015class MRouteItfFlags:
16 MFIB_ITF_FLAG_NONE = 0
17 MFIB_ITF_FLAG_NEGATE_SIGNAL = 1
18 MFIB_ITF_FLAG_ACCEPT = 2
19 MFIB_ITF_FLAG_FORWARD = 4
20 MFIB_ITF_FLAG_SIGNAL_PRESENT = 8
21 MFIB_ITF_FLAG_INTERNAL_COPY = 16
22
23
24class MRouteEntryFlags:
25 MFIB_ENTRY_FLAG_NONE = 0
26 MFIB_ENTRY_FLAG_SIGNAL = 1
27 MFIB_ENTRY_FLAG_DROP = 2
28 MFIB_ENTRY_FLAG_CONNECTED = 4
29 MFIB_ENTRY_FLAG_INHERIT_ACCEPT = 8
30
31
Neale Rannsb3b2de72017-03-08 05:17:22 -080032def find_route(test, ip_addr, len, table_id=0, inet=AF_INET):
33 if inet == AF_INET:
34 s = 4
35 routes = test.vapi.ip_fib_dump()
36 else:
37 s = 16
38 routes = test.vapi.ip6_fib_dump()
39
40 route_addr = inet_pton(inet, ip_addr)
41 for e in routes:
42 if route_addr == e.address[:s] \
43 and len == e.address_length \
44 and table_id == e.table_id:
45 return True
46 return False
47
48
Neale Ranns5a8123b2017-01-26 01:18:23 -080049class VppRoutePath(object):
Neale Rannsad422ed2016-11-02 14:20:04 +000050
Klement Sekerada505f62017-01-04 12:58:53 +010051 def __init__(
52 self,
53 nh_addr,
54 nh_sw_if_index,
55 nh_table_id=0,
56 labels=[],
Neale Rannsfca0c242017-01-13 07:57:46 -080057 nh_via_label=MPLS_LABEL_INVALID,
Neale Ranns0f26c5a2017-03-01 15:12:11 -080058 is_ip6=0,
59 rpf_id=0,
Neale Rannsf12a83f2017-04-18 09:09:40 -070060 is_interface_rx=0,
61 is_resolve_host=0,
62 is_resolve_attached=0):
Neale Ranns177bbdc2016-11-15 09:46:51 +000063 self.nh_itf = nh_sw_if_index
64 self.nh_table_id = nh_table_id
Neale Rannsad422ed2016-11-02 14:20:04 +000065 self.nh_via_label = nh_via_label
66 self.nh_labels = labels
Neale Ranns0f26c5a2017-03-01 15:12:11 -080067 self.weight = 1
68 self.rpf_id = rpf_id
Neale Ranns31426c62017-05-24 10:32:58 -070069 self.is_ip4 = 1 if is_ip6 == 0 else 0
70 if self.is_ip4:
Neale Rannsb3b2de72017-03-08 05:17:22 -080071 self.nh_addr = inet_pton(AF_INET, nh_addr)
Neale Ranns31426c62017-05-24 10:32:58 -070072 else:
73 self.nh_addr = inet_pton(AF_INET6, nh_addr)
Neale Rannsf12a83f2017-04-18 09:09:40 -070074 self.is_resolve_host = is_resolve_host
75 self.is_resolve_attached = is_resolve_attached
Neale Ranns0f26c5a2017-03-01 15:12:11 -080076 self.is_interface_rx = is_interface_rx
77 self.is_rpf_id = 0
78 if rpf_id != 0:
79 self.is_rpf_id = 1
80 self.nh_itf = rpf_id
Neale Ranns177bbdc2016-11-15 09:46:51 +000081
82
Neale Ranns5a8123b2017-01-26 01:18:23 -080083class VppMRoutePath(VppRoutePath):
Neale Ranns32e1c012016-11-22 17:07:28 +000084
85 def __init__(self, nh_sw_if_index, flags):
Neale Ranns5a8123b2017-01-26 01:18:23 -080086 super(VppMRoutePath, self).__init__("0.0.0.0",
87 nh_sw_if_index)
Neale Ranns32e1c012016-11-22 17:07:28 +000088 self.nh_i_flags = flags
89
90
Neale Ranns5a8123b2017-01-26 01:18:23 -080091class VppIpRoute(VppObject):
Neale Ranns177bbdc2016-11-15 09:46:51 +000092 """
93 IP Route
94 """
95
96 def __init__(self, test, dest_addr,
Neale Ranns37be7362017-02-21 17:30:26 -080097 dest_addr_len, paths, table_id=0, is_ip6=0, is_local=0,
98 is_unreach=0, is_prohibit=0):
Neale Ranns177bbdc2016-11-15 09:46:51 +000099 self._test = test
100 self.paths = paths
Neale Ranns177bbdc2016-11-15 09:46:51 +0000101 self.dest_addr_len = dest_addr_len
102 self.table_id = table_id
Neale Rannsfca0c242017-01-13 07:57:46 -0800103 self.is_ip6 = is_ip6
104 self.is_local = is_local
Neale Ranns37be7362017-02-21 17:30:26 -0800105 self.is_unreach = is_unreach
106 self.is_prohibit = is_prohibit
Neale Rannsb3b2de72017-03-08 05:17:22 -0800107 self.dest_addr_p = dest_addr
Neale Rannsfca0c242017-01-13 07:57:46 -0800108 if is_ip6:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800109 self.dest_addr = inet_pton(AF_INET6, dest_addr)
Neale Rannsfca0c242017-01-13 07:57:46 -0800110 else:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800111 self.dest_addr = inet_pton(AF_INET, dest_addr)
Neale Ranns177bbdc2016-11-15 09:46:51 +0000112
Neale Ranns69b7aa42017-03-10 03:04:12 -0800113 def modify(self, paths, is_local=0,
114 is_unreach=0, is_prohibit=0):
115 self.paths = paths
116 self.is_local = is_local
117 self.is_unreach = is_unreach
118 self.is_prohibit = is_prohibit
119
Neale Ranns177bbdc2016-11-15 09:46:51 +0000120 def add_vpp_config(self):
Neale Ranns37be7362017-02-21 17:30:26 -0800121 if self.is_local or self.is_unreach or self.is_prohibit:
Klement Sekerada505f62017-01-04 12:58:53 +0100122 self._test.vapi.ip_add_del_route(
123 self.dest_addr,
124 self.dest_addr_len,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800125 inet_pton(AF_INET6, "::"),
Neale Rannsfca0c242017-01-13 07:57:46 -0800126 0xffffffff,
Neale Ranns37be7362017-02-21 17:30:26 -0800127 is_local=self.is_local,
128 is_unreach=self.is_unreach,
129 is_prohibit=self.is_prohibit,
Klement Sekerada505f62017-01-04 12:58:53 +0100130 table_id=self.table_id,
Neale Rannsfca0c242017-01-13 07:57:46 -0800131 is_ipv6=self.is_ip6)
132 else:
133 for path in self.paths:
134 self._test.vapi.ip_add_del_route(
135 self.dest_addr,
136 self.dest_addr_len,
137 path.nh_addr,
138 path.nh_itf,
139 table_id=self.table_id,
140 next_hop_out_label_stack=path.nh_labels,
141 next_hop_n_out_labels=len(
142 path.nh_labels),
143 next_hop_via_label=path.nh_via_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700144 next_hop_table_id=path.nh_table_id,
145 is_ipv6=self.is_ip6,
146 is_resolve_host=path.is_resolve_host,
147 is_resolve_attached=path.is_resolve_attached,
148 is_multipath=1 if len(self.paths) > 1 else 0)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800149 self._test.registry.register(self, self._test.logger)
Neale Ranns177bbdc2016-11-15 09:46:51 +0000150
151 def remove_vpp_config(self):
Neale Ranns37be7362017-02-21 17:30:26 -0800152 if self.is_local or self.is_unreach or self.is_prohibit:
Neale Rannsfca0c242017-01-13 07:57:46 -0800153 self._test.vapi.ip_add_del_route(
154 self.dest_addr,
155 self.dest_addr_len,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800156 inet_pton(AF_INET6, "::"),
Neale Rannsfca0c242017-01-13 07:57:46 -0800157 0xffffffff,
Neale Ranns37be7362017-02-21 17:30:26 -0800158 is_local=self.is_local,
159 is_unreach=self.is_unreach,
160 is_prohibit=self.is_prohibit,
Neale Rannsfca0c242017-01-13 07:57:46 -0800161 is_add=0,
162 table_id=self.table_id,
163 is_ipv6=self.is_ip6)
164 else:
165 for path in self.paths:
Neale Rannsf12a83f2017-04-18 09:09:40 -0700166 self._test.vapi.ip_add_del_route(
167 self.dest_addr,
168 self.dest_addr_len,
169 path.nh_addr,
170 path.nh_itf,
171 table_id=self.table_id,
172 next_hop_table_id=path.nh_table_id,
173 next_hop_via_label=path.nh_via_label,
174 is_add=0,
175 is_ipv6=self.is_ip6)
Neale Rannsad422ed2016-11-02 14:20:04 +0000176
Neale Ranns5a8123b2017-01-26 01:18:23 -0800177 def query_vpp_config(self):
Neale Rannsb3b2de72017-03-08 05:17:22 -0800178 return find_route(self._test,
179 self.dest_addr_p,
180 self.dest_addr_len,
181 self.table_id,
182 inet=AF_INET6 if self.is_ip6 == 1 else AF_INET)
Neale Rannsad422ed2016-11-02 14:20:04 +0000183
Neale Ranns5a8123b2017-01-26 01:18:23 -0800184 def __str__(self):
185 return self.object_id()
186
187 def object_id(self):
Neale Rannsb3b2de72017-03-08 05:17:22 -0800188 return ("%d:%s/%d"
189 % (self.table_id,
190 self.dest_addr_p,
191 self.dest_addr_len))
Neale Ranns5a8123b2017-01-26 01:18:23 -0800192
193
194class VppIpMRoute(VppObject):
Neale Ranns32e1c012016-11-22 17:07:28 +0000195 """
196 IP Multicast Route
197 """
198
199 def __init__(self, test, src_addr, grp_addr,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800200 grp_addr_len, e_flags, paths, table_id=0,
201 rpf_id=0, is_ip6=0):
Neale Ranns32e1c012016-11-22 17:07:28 +0000202 self._test = test
203 self.paths = paths
204 self.grp_addr_len = grp_addr_len
205 self.table_id = table_id
206 self.e_flags = e_flags
207 self.is_ip6 = is_ip6
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800208 self.rpf_id = rpf_id
Neale Ranns32e1c012016-11-22 17:07:28 +0000209
210 if is_ip6:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800211 self.grp_addr = inet_pton(AF_INET6, grp_addr)
212 self.src_addr = inet_pton(AF_INET6, src_addr)
Neale Ranns32e1c012016-11-22 17:07:28 +0000213 else:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800214 self.grp_addr = inet_pton(AF_INET, grp_addr)
215 self.src_addr = inet_pton(AF_INET, src_addr)
Neale Ranns32e1c012016-11-22 17:07:28 +0000216
217 def add_vpp_config(self):
218 for path in self.paths:
219 self._test.vapi.ip_mroute_add_del(self.src_addr,
220 self.grp_addr,
221 self.grp_addr_len,
222 self.e_flags,
223 path.nh_itf,
224 path.nh_i_flags,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800225 rpf_id=self.rpf_id,
Neale Ranns32e1c012016-11-22 17:07:28 +0000226 table_id=self.table_id,
227 is_ipv6=self.is_ip6)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800228 self._test.registry.register(self, self._test.logger)
Neale Ranns32e1c012016-11-22 17:07:28 +0000229
230 def remove_vpp_config(self):
231 for path in self.paths:
232 self._test.vapi.ip_mroute_add_del(self.src_addr,
233 self.grp_addr,
234 self.grp_addr_len,
235 self.e_flags,
236 path.nh_itf,
237 path.nh_i_flags,
238 table_id=self.table_id,
239 is_add=0,
240 is_ipv6=self.is_ip6)
241
242 def update_entry_flags(self, flags):
243 self.e_flags = flags
244 self._test.vapi.ip_mroute_add_del(self.src_addr,
245 self.grp_addr,
246 self.grp_addr_len,
247 self.e_flags,
248 0xffffffff,
249 0,
250 table_id=self.table_id,
251 is_ipv6=self.is_ip6)
252
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800253 def update_rpf_id(self, rpf_id):
254 self.rpf_id = rpf_id
255 self._test.vapi.ip_mroute_add_del(self.src_addr,
256 self.grp_addr,
257 self.grp_addr_len,
258 self.e_flags,
259 0xffffffff,
260 0,
261 rpf_id=self.rpf_id,
262 table_id=self.table_id,
263 is_ipv6=self.is_ip6)
264
Neale Ranns32e1c012016-11-22 17:07:28 +0000265 def update_path_flags(self, itf, flags):
266 for path in self.paths:
267 if path.nh_itf == itf:
268 path.nh_i_flags = flags
269 break
270 self._test.vapi.ip_mroute_add_del(self.src_addr,
271 self.grp_addr,
272 self.grp_addr_len,
273 self.e_flags,
274 path.nh_itf,
275 path.nh_i_flags,
276 table_id=self.table_id,
277 is_ipv6=self.is_ip6)
278
Neale Ranns5a8123b2017-01-26 01:18:23 -0800279 def query_vpp_config(self):
280 dump = self._test.vapi.ip_fib_dump()
281 for e in dump:
282 if self.grp_addr == e.address \
283 and self.grp_addr_len == e.address_length \
284 and self.table_id == e.table_id:
285 return True
286 return False
Neale Ranns32e1c012016-11-22 17:07:28 +0000287
Neale Ranns5a8123b2017-01-26 01:18:23 -0800288 def __str__(self):
289 return self.object_id()
290
291 def object_id(self):
292 if self.is_ip6:
293 return ("%d:(%s,%s/%d)"
294 % (self.table_id,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800295 inet_ntop(AF_INET6, self.src_addr),
296 inet_ntop(AF_INET6, self.grp_addr),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800297 self.grp_addr_len))
298 else:
299 return ("%d:(%s,%s/%d)"
300 % (self.table_id,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800301 inet_ntop(AF_INET, self.src_addr),
302 inet_ntop(AF_INET, self.grp_addr),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800303 self.grp_addr_len))
304
305
306class VppMFibSignal(object):
Neale Ranns32e1c012016-11-22 17:07:28 +0000307 def __init__(self, test, route, interface, packet):
308 self.route = route
309 self.interface = interface
310 self.packet = packet
311 self.test = test
312
313 def compare(self, signal):
314 self.test.assertEqual(self.interface, signal.sw_if_index)
315 self.test.assertEqual(self.route.table_id, signal.table_id)
316 self.test.assertEqual(self.route.grp_addr_len,
317 signal.grp_address_len)
318 for i in range(self.route.grp_addr_len / 8):
319 self.test.assertEqual(self.route.grp_addr[i],
320 signal.grp_address[i])
321 if (self.route.grp_addr_len > 32):
322 for i in range(4):
323 self.test.assertEqual(self.route.src_addr[i],
324 signal.src_address[i])
325
326
Neale Ranns5a8123b2017-01-26 01:18:23 -0800327class VppMplsIpBind(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000328 """
329 MPLS to IP Binding
330 """
331
Neale Ranns5a8123b2017-01-26 01:18:23 -0800332 def __init__(self, test, local_label, dest_addr, dest_addr_len,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700333 table_id=0, ip_table_id=0, is_ip6=0):
Neale Rannsad422ed2016-11-02 14:20:04 +0000334 self._test = test
Neale Rannsad422ed2016-11-02 14:20:04 +0000335 self.dest_addr_len = dest_addr_len
Neale Rannsf12a83f2017-04-18 09:09:40 -0700336 self.dest_addr = dest_addr
Neale Rannsad422ed2016-11-02 14:20:04 +0000337 self.local_label = local_label
Neale Ranns5a8123b2017-01-26 01:18:23 -0800338 self.table_id = table_id
339 self.ip_table_id = ip_table_id
Neale Rannsf12a83f2017-04-18 09:09:40 -0700340 self.is_ip6 = is_ip6
341 if is_ip6:
342 self.dest_addrn = inet_pton(AF_INET6, dest_addr)
343 else:
344 self.dest_addrn = inet_pton(AF_INET, dest_addr)
Neale Rannsad422ed2016-11-02 14:20:04 +0000345
346 def add_vpp_config(self):
347 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700348 self.dest_addrn,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800349 self.dest_addr_len,
350 table_id=self.table_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700351 ip_table_id=self.ip_table_id,
352 is_ip4=(self.is_ip6 == 0))
Neale Ranns5a8123b2017-01-26 01:18:23 -0800353 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000354
355 def remove_vpp_config(self):
356 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700357 self.dest_addrn,
Neale Rannsad422ed2016-11-02 14:20:04 +0000358 self.dest_addr_len,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700359 table_id=self.table_id,
360 ip_table_id=self.ip_table_id,
361 is_bind=0,
362 is_ip4=(self.is_ip6 == 0))
Neale Rannsad422ed2016-11-02 14:20:04 +0000363
Neale Ranns5a8123b2017-01-26 01:18:23 -0800364 def query_vpp_config(self):
365 dump = self._test.vapi.mpls_fib_dump()
366 for e in dump:
367 if self.local_label == e.label \
Neale Ranns5a8123b2017-01-26 01:18:23 -0800368 and self.table_id == e.table_id:
369 return True
370 return False
Neale Rannsad422ed2016-11-02 14:20:04 +0000371
Neale Ranns5a8123b2017-01-26 01:18:23 -0800372 def __str__(self):
373 return self.object_id()
374
375 def object_id(self):
376 return ("%d:%s binds %d:%s/%d"
377 % (self.table_id,
378 self.local_label,
379 self.ip_table_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700380 self.dest_addr,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800381 self.dest_addr_len))
382
383
384class VppMplsRoute(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000385 """
Neale Ranns5a8123b2017-01-26 01:18:23 -0800386 MPLS Route/LSP
Neale Rannsad422ed2016-11-02 14:20:04 +0000387 """
388
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800389 def __init__(self, test, local_label, eos_bit, paths, table_id=0,
390 is_multicast=0):
Neale Rannsad422ed2016-11-02 14:20:04 +0000391 self._test = test
392 self.paths = paths
393 self.local_label = local_label
394 self.eos_bit = eos_bit
395 self.table_id = table_id
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800396 self.is_multicast = is_multicast
Neale Rannsad422ed2016-11-02 14:20:04 +0000397
398 def add_vpp_config(self):
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800399 is_multipath = len(self.paths) > 1
Neale Rannsad422ed2016-11-02 14:20:04 +0000400 for path in self.paths:
Klement Sekerada505f62017-01-04 12:58:53 +0100401 self._test.vapi.mpls_route_add_del(
402 self.local_label,
403 self.eos_bit,
Neale Ranns31426c62017-05-24 10:32:58 -0700404 path.is_ip4,
Klement Sekerada505f62017-01-04 12:58:53 +0100405 path.nh_addr,
406 path.nh_itf,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800407 is_multicast=self.is_multicast,
408 is_multipath=is_multipath,
Klement Sekerada505f62017-01-04 12:58:53 +0100409 table_id=self.table_id,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800410 is_interface_rx=path.is_interface_rx,
411 is_rpf_id=path.is_rpf_id,
Klement Sekerada505f62017-01-04 12:58:53 +0100412 next_hop_out_label_stack=path.nh_labels,
413 next_hop_n_out_labels=len(
414 path.nh_labels),
415 next_hop_via_label=path.nh_via_label,
416 next_hop_table_id=path.nh_table_id)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800417 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000418
419 def remove_vpp_config(self):
420 for path in self.paths:
421 self._test.vapi.mpls_route_add_del(self.local_label,
422 self.eos_bit,
423 1,
424 path.nh_addr,
425 path.nh_itf,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800426 is_rpf_id=path.is_rpf_id,
Neale Rannsad422ed2016-11-02 14:20:04 +0000427 table_id=self.table_id,
428 is_add=0)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800429
430 def query_vpp_config(self):
431 dump = self._test.vapi.mpls_fib_dump()
432 for e in dump:
433 if self.local_label == e.label \
434 and self.eos_bit == e.eos_bit \
435 and self.table_id == e.table_id:
436 return True
437 return False
438
439 def __str__(self):
440 return self.object_id()
441
442 def object_id(self):
443 return ("%d:%s/%d"
444 % (self.table_id,
445 self.local_label,
446 20+self.eos_bit))