blob: b68e210554842bd705ba67babe61976cf03b1691 [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 Rannsfca0c242017-01-13 07:57:46 -080069 if is_ip6:
Neale Rannsb3b2de72017-03-08 05:17:22 -080070 self.nh_addr = inet_pton(AF_INET6, nh_addr)
Neale Rannsfca0c242017-01-13 07:57:46 -080071 else:
Neale Rannsb3b2de72017-03-08 05:17:22 -080072 self.nh_addr = inet_pton(AF_INET, nh_addr)
Neale Rannsf12a83f2017-04-18 09:09:40 -070073 self.is_resolve_host = is_resolve_host
74 self.is_resolve_attached = is_resolve_attached
Neale Ranns0f26c5a2017-03-01 15:12:11 -080075 self.is_interface_rx = is_interface_rx
76 self.is_rpf_id = 0
77 if rpf_id != 0:
78 self.is_rpf_id = 1
79 self.nh_itf = rpf_id
Neale Ranns177bbdc2016-11-15 09:46:51 +000080
81
Neale Ranns5a8123b2017-01-26 01:18:23 -080082class VppMRoutePath(VppRoutePath):
Neale Ranns32e1c012016-11-22 17:07:28 +000083
84 def __init__(self, nh_sw_if_index, flags):
Neale Ranns5a8123b2017-01-26 01:18:23 -080085 super(VppMRoutePath, self).__init__("0.0.0.0",
86 nh_sw_if_index)
Neale Ranns32e1c012016-11-22 17:07:28 +000087 self.nh_i_flags = flags
88
89
Neale Ranns5a8123b2017-01-26 01:18:23 -080090class VppIpRoute(VppObject):
Neale Ranns177bbdc2016-11-15 09:46:51 +000091 """
92 IP Route
93 """
94
95 def __init__(self, test, dest_addr,
Neale Ranns37be7362017-02-21 17:30:26 -080096 dest_addr_len, paths, table_id=0, is_ip6=0, is_local=0,
97 is_unreach=0, is_prohibit=0):
Neale Ranns177bbdc2016-11-15 09:46:51 +000098 self._test = test
99 self.paths = paths
Neale Ranns177bbdc2016-11-15 09:46:51 +0000100 self.dest_addr_len = dest_addr_len
101 self.table_id = table_id
Neale Rannsfca0c242017-01-13 07:57:46 -0800102 self.is_ip6 = is_ip6
103 self.is_local = is_local
Neale Ranns37be7362017-02-21 17:30:26 -0800104 self.is_unreach = is_unreach
105 self.is_prohibit = is_prohibit
Neale Rannsb3b2de72017-03-08 05:17:22 -0800106 self.dest_addr_p = dest_addr
Neale Rannsfca0c242017-01-13 07:57:46 -0800107 if is_ip6:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800108 self.dest_addr = inet_pton(AF_INET6, dest_addr)
Neale Rannsfca0c242017-01-13 07:57:46 -0800109 else:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800110 self.dest_addr = inet_pton(AF_INET, dest_addr)
Neale Ranns177bbdc2016-11-15 09:46:51 +0000111
Neale Ranns69b7aa42017-03-10 03:04:12 -0800112 def modify(self, paths, is_local=0,
113 is_unreach=0, is_prohibit=0):
114 self.paths = paths
115 self.is_local = is_local
116 self.is_unreach = is_unreach
117 self.is_prohibit = is_prohibit
118
Neale Ranns177bbdc2016-11-15 09:46:51 +0000119 def add_vpp_config(self):
Neale Ranns37be7362017-02-21 17:30:26 -0800120 if self.is_local or self.is_unreach or self.is_prohibit:
Klement Sekerada505f62017-01-04 12:58:53 +0100121 self._test.vapi.ip_add_del_route(
122 self.dest_addr,
123 self.dest_addr_len,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800124 inet_pton(AF_INET6, "::"),
Neale Rannsfca0c242017-01-13 07:57:46 -0800125 0xffffffff,
Neale Ranns37be7362017-02-21 17:30:26 -0800126 is_local=self.is_local,
127 is_unreach=self.is_unreach,
128 is_prohibit=self.is_prohibit,
Klement Sekerada505f62017-01-04 12:58:53 +0100129 table_id=self.table_id,
Neale Rannsfca0c242017-01-13 07:57:46 -0800130 is_ipv6=self.is_ip6)
131 else:
132 for path in self.paths:
133 self._test.vapi.ip_add_del_route(
134 self.dest_addr,
135 self.dest_addr_len,
136 path.nh_addr,
137 path.nh_itf,
138 table_id=self.table_id,
139 next_hop_out_label_stack=path.nh_labels,
140 next_hop_n_out_labels=len(
141 path.nh_labels),
142 next_hop_via_label=path.nh_via_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700143 next_hop_table_id=path.nh_table_id,
144 is_ipv6=self.is_ip6,
145 is_resolve_host=path.is_resolve_host,
146 is_resolve_attached=path.is_resolve_attached,
147 is_multipath=1 if len(self.paths) > 1 else 0)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800148 self._test.registry.register(self, self._test.logger)
Neale Ranns177bbdc2016-11-15 09:46:51 +0000149
150 def remove_vpp_config(self):
Neale Ranns37be7362017-02-21 17:30:26 -0800151 if self.is_local or self.is_unreach or self.is_prohibit:
Neale Rannsfca0c242017-01-13 07:57:46 -0800152 self._test.vapi.ip_add_del_route(
153 self.dest_addr,
154 self.dest_addr_len,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800155 inet_pton(AF_INET6, "::"),
Neale Rannsfca0c242017-01-13 07:57:46 -0800156 0xffffffff,
Neale Ranns37be7362017-02-21 17:30:26 -0800157 is_local=self.is_local,
158 is_unreach=self.is_unreach,
159 is_prohibit=self.is_prohibit,
Neale Rannsfca0c242017-01-13 07:57:46 -0800160 is_add=0,
161 table_id=self.table_id,
162 is_ipv6=self.is_ip6)
163 else:
164 for path in self.paths:
Neale Rannsf12a83f2017-04-18 09:09:40 -0700165 self._test.vapi.ip_add_del_route(
166 self.dest_addr,
167 self.dest_addr_len,
168 path.nh_addr,
169 path.nh_itf,
170 table_id=self.table_id,
171 next_hop_table_id=path.nh_table_id,
172 next_hop_via_label=path.nh_via_label,
173 is_add=0,
174 is_ipv6=self.is_ip6)
Neale Rannsad422ed2016-11-02 14:20:04 +0000175
Neale Ranns5a8123b2017-01-26 01:18:23 -0800176 def query_vpp_config(self):
Neale Rannsb3b2de72017-03-08 05:17:22 -0800177 return find_route(self._test,
178 self.dest_addr_p,
179 self.dest_addr_len,
180 self.table_id,
181 inet=AF_INET6 if self.is_ip6 == 1 else AF_INET)
Neale Rannsad422ed2016-11-02 14:20:04 +0000182
Neale Ranns5a8123b2017-01-26 01:18:23 -0800183 def __str__(self):
184 return self.object_id()
185
186 def object_id(self):
Neale Rannsb3b2de72017-03-08 05:17:22 -0800187 return ("%d:%s/%d"
188 % (self.table_id,
189 self.dest_addr_p,
190 self.dest_addr_len))
Neale Ranns5a8123b2017-01-26 01:18:23 -0800191
192
193class VppIpMRoute(VppObject):
Neale Ranns32e1c012016-11-22 17:07:28 +0000194 """
195 IP Multicast Route
196 """
197
198 def __init__(self, test, src_addr, grp_addr,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800199 grp_addr_len, e_flags, paths, table_id=0,
200 rpf_id=0, is_ip6=0):
Neale Ranns32e1c012016-11-22 17:07:28 +0000201 self._test = test
202 self.paths = paths
203 self.grp_addr_len = grp_addr_len
204 self.table_id = table_id
205 self.e_flags = e_flags
206 self.is_ip6 = is_ip6
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800207 self.rpf_id = rpf_id
Neale Ranns32e1c012016-11-22 17:07:28 +0000208
209 if is_ip6:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800210 self.grp_addr = inet_pton(AF_INET6, grp_addr)
211 self.src_addr = inet_pton(AF_INET6, src_addr)
Neale Ranns32e1c012016-11-22 17:07:28 +0000212 else:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800213 self.grp_addr = inet_pton(AF_INET, grp_addr)
214 self.src_addr = inet_pton(AF_INET, src_addr)
Neale Ranns32e1c012016-11-22 17:07:28 +0000215
216 def add_vpp_config(self):
217 for path in self.paths:
218 self._test.vapi.ip_mroute_add_del(self.src_addr,
219 self.grp_addr,
220 self.grp_addr_len,
221 self.e_flags,
222 path.nh_itf,
223 path.nh_i_flags,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800224 rpf_id=self.rpf_id,
Neale Ranns32e1c012016-11-22 17:07:28 +0000225 table_id=self.table_id,
226 is_ipv6=self.is_ip6)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800227 self._test.registry.register(self, self._test.logger)
Neale Ranns32e1c012016-11-22 17:07:28 +0000228
229 def remove_vpp_config(self):
230 for path in self.paths:
231 self._test.vapi.ip_mroute_add_del(self.src_addr,
232 self.grp_addr,
233 self.grp_addr_len,
234 self.e_flags,
235 path.nh_itf,
236 path.nh_i_flags,
237 table_id=self.table_id,
238 is_add=0,
239 is_ipv6=self.is_ip6)
240
241 def update_entry_flags(self, flags):
242 self.e_flags = flags
243 self._test.vapi.ip_mroute_add_del(self.src_addr,
244 self.grp_addr,
245 self.grp_addr_len,
246 self.e_flags,
247 0xffffffff,
248 0,
249 table_id=self.table_id,
250 is_ipv6=self.is_ip6)
251
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800252 def update_rpf_id(self, rpf_id):
253 self.rpf_id = rpf_id
254 self._test.vapi.ip_mroute_add_del(self.src_addr,
255 self.grp_addr,
256 self.grp_addr_len,
257 self.e_flags,
258 0xffffffff,
259 0,
260 rpf_id=self.rpf_id,
261 table_id=self.table_id,
262 is_ipv6=self.is_ip6)
263
Neale Ranns32e1c012016-11-22 17:07:28 +0000264 def update_path_flags(self, itf, flags):
265 for path in self.paths:
266 if path.nh_itf == itf:
267 path.nh_i_flags = flags
268 break
269 self._test.vapi.ip_mroute_add_del(self.src_addr,
270 self.grp_addr,
271 self.grp_addr_len,
272 self.e_flags,
273 path.nh_itf,
274 path.nh_i_flags,
275 table_id=self.table_id,
276 is_ipv6=self.is_ip6)
277
Neale Ranns5a8123b2017-01-26 01:18:23 -0800278 def query_vpp_config(self):
279 dump = self._test.vapi.ip_fib_dump()
280 for e in dump:
281 if self.grp_addr == e.address \
282 and self.grp_addr_len == e.address_length \
283 and self.table_id == e.table_id:
284 return True
285 return False
Neale Ranns32e1c012016-11-22 17:07:28 +0000286
Neale Ranns5a8123b2017-01-26 01:18:23 -0800287 def __str__(self):
288 return self.object_id()
289
290 def object_id(self):
291 if self.is_ip6:
292 return ("%d:(%s,%s/%d)"
293 % (self.table_id,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800294 inet_ntop(AF_INET6, self.src_addr),
295 inet_ntop(AF_INET6, self.grp_addr),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800296 self.grp_addr_len))
297 else:
298 return ("%d:(%s,%s/%d)"
299 % (self.table_id,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800300 inet_ntop(AF_INET, self.src_addr),
301 inet_ntop(AF_INET, self.grp_addr),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800302 self.grp_addr_len))
303
304
305class VppMFibSignal(object):
Neale Ranns32e1c012016-11-22 17:07:28 +0000306 def __init__(self, test, route, interface, packet):
307 self.route = route
308 self.interface = interface
309 self.packet = packet
310 self.test = test
311
312 def compare(self, signal):
313 self.test.assertEqual(self.interface, signal.sw_if_index)
314 self.test.assertEqual(self.route.table_id, signal.table_id)
315 self.test.assertEqual(self.route.grp_addr_len,
316 signal.grp_address_len)
317 for i in range(self.route.grp_addr_len / 8):
318 self.test.assertEqual(self.route.grp_addr[i],
319 signal.grp_address[i])
320 if (self.route.grp_addr_len > 32):
321 for i in range(4):
322 self.test.assertEqual(self.route.src_addr[i],
323 signal.src_address[i])
324
325
Neale Ranns5a8123b2017-01-26 01:18:23 -0800326class VppMplsIpBind(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000327 """
328 MPLS to IP Binding
329 """
330
Neale Ranns5a8123b2017-01-26 01:18:23 -0800331 def __init__(self, test, local_label, dest_addr, dest_addr_len,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700332 table_id=0, ip_table_id=0, is_ip6=0):
Neale Rannsad422ed2016-11-02 14:20:04 +0000333 self._test = test
Neale Rannsad422ed2016-11-02 14:20:04 +0000334 self.dest_addr_len = dest_addr_len
Neale Rannsf12a83f2017-04-18 09:09:40 -0700335 self.dest_addr = dest_addr
Neale Rannsad422ed2016-11-02 14:20:04 +0000336 self.local_label = local_label
Neale Ranns5a8123b2017-01-26 01:18:23 -0800337 self.table_id = table_id
338 self.ip_table_id = ip_table_id
Neale Rannsf12a83f2017-04-18 09:09:40 -0700339 self.is_ip6 = is_ip6
340 if is_ip6:
341 self.dest_addrn = inet_pton(AF_INET6, dest_addr)
342 else:
343 self.dest_addrn = inet_pton(AF_INET, dest_addr)
Neale Rannsad422ed2016-11-02 14:20:04 +0000344
345 def add_vpp_config(self):
346 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700347 self.dest_addrn,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800348 self.dest_addr_len,
349 table_id=self.table_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700350 ip_table_id=self.ip_table_id,
351 is_ip4=(self.is_ip6 == 0))
Neale Ranns5a8123b2017-01-26 01:18:23 -0800352 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000353
354 def remove_vpp_config(self):
355 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700356 self.dest_addrn,
Neale Rannsad422ed2016-11-02 14:20:04 +0000357 self.dest_addr_len,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700358 table_id=self.table_id,
359 ip_table_id=self.ip_table_id,
360 is_bind=0,
361 is_ip4=(self.is_ip6 == 0))
Neale Rannsad422ed2016-11-02 14:20:04 +0000362
Neale Ranns5a8123b2017-01-26 01:18:23 -0800363 def query_vpp_config(self):
364 dump = self._test.vapi.mpls_fib_dump()
365 for e in dump:
366 if self.local_label == e.label \
Neale Ranns5a8123b2017-01-26 01:18:23 -0800367 and self.table_id == e.table_id:
368 return True
369 return False
Neale Rannsad422ed2016-11-02 14:20:04 +0000370
Neale Ranns5a8123b2017-01-26 01:18:23 -0800371 def __str__(self):
372 return self.object_id()
373
374 def object_id(self):
375 return ("%d:%s binds %d:%s/%d"
376 % (self.table_id,
377 self.local_label,
378 self.ip_table_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700379 self.dest_addr,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800380 self.dest_addr_len))
381
382
383class VppMplsRoute(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000384 """
Neale Ranns5a8123b2017-01-26 01:18:23 -0800385 MPLS Route/LSP
Neale Rannsad422ed2016-11-02 14:20:04 +0000386 """
387
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800388 def __init__(self, test, local_label, eos_bit, paths, table_id=0,
389 is_multicast=0):
Neale Rannsad422ed2016-11-02 14:20:04 +0000390 self._test = test
391 self.paths = paths
392 self.local_label = local_label
393 self.eos_bit = eos_bit
394 self.table_id = table_id
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800395 self.is_multicast = is_multicast
Neale Rannsad422ed2016-11-02 14:20:04 +0000396
397 def add_vpp_config(self):
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800398 is_multipath = len(self.paths) > 1
Neale Rannsad422ed2016-11-02 14:20:04 +0000399 for path in self.paths:
Klement Sekerada505f62017-01-04 12:58:53 +0100400 self._test.vapi.mpls_route_add_del(
401 self.local_label,
402 self.eos_bit,
403 1,
404 path.nh_addr,
405 path.nh_itf,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800406 is_multicast=self.is_multicast,
407 is_multipath=is_multipath,
Klement Sekerada505f62017-01-04 12:58:53 +0100408 table_id=self.table_id,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800409 is_interface_rx=path.is_interface_rx,
410 is_rpf_id=path.is_rpf_id,
Klement Sekerada505f62017-01-04 12:58:53 +0100411 next_hop_out_label_stack=path.nh_labels,
412 next_hop_n_out_labels=len(
413 path.nh_labels),
414 next_hop_via_label=path.nh_via_label,
415 next_hop_table_id=path.nh_table_id)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800416 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000417
418 def remove_vpp_config(self):
419 for path in self.paths:
420 self._test.vapi.mpls_route_add_del(self.local_label,
421 self.eos_bit,
422 1,
423 path.nh_addr,
424 path.nh_itf,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800425 is_rpf_id=path.is_rpf_id,
Neale Rannsad422ed2016-11-02 14:20:04 +0000426 table_id=self.table_id,
427 is_add=0)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800428
429 def query_vpp_config(self):
430 dump = self._test.vapi.mpls_fib_dump()
431 for e in dump:
432 if self.local_label == e.label \
433 and self.eos_bit == e.eos_bit \
434 and self.table_id == e.table_id:
435 return True
436 return False
437
438 def __str__(self):
439 return self.object_id()
440
441 def object_id(self):
442 return ("%d:%s/%d"
443 % (self.table_id,
444 self.local_label,
445 20+self.eos_bit))