blob: 31aab3a03ee2457cc29549e0018c50f754a4e86a [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
Paul Vinciguerraa279d9c2019-02-28 09:00:09 -08007from vpp_object import VppObject
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02008from vpp_ip import DpoProto, INVALID_INDEX, VppIpAddressUnion, VppIpMPrefix
Neale Ranns59f71132020-04-08 12:19:38 +00009from ipaddress import ip_network, ip_address, IPv4Network, IPv6Network
Klement Sekera77c821c2022-04-14 16:29:07 +020010from vpp_papi_exceptions import UnexpectedApiReturnValueError
Neale Ranns177bbdc2016-11-15 09:46:51 +000011
Neale Rannsad422ed2016-11-02 14:20:04 +000012# from vnet/vnet/mpls/mpls_types.h
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020013MPLS_IETF_MAX_LABEL = 0xFFFFF
Neale Rannsad422ed2016-11-02 14:20:04 +000014MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
Neale Ranns177bbdc2016-11-15 09:46:51 +000015
Neale Ranns097fa662018-05-01 05:17:55 -070016try:
17 text_type = unicode
18except NameError:
19 text_type = str
20
Neale Ranns177bbdc2016-11-15 09:46:51 +000021
Neale Ranns097fa662018-05-01 05:17:55 -070022class FibPathProto:
23 FIB_PATH_NH_PROTO_IP4 = 0
24 FIB_PATH_NH_PROTO_IP6 = 1
25 FIB_PATH_NH_PROTO_MPLS = 2
26 FIB_PATH_NH_PROTO_ETHERNET = 3
27 FIB_PATH_NH_PROTO_BIER = 4
28 FIB_PATH_NH_PROTO_NSH = 5
29
30
31class FibPathType:
32 FIB_PATH_TYPE_NORMAL = 0
33 FIB_PATH_TYPE_LOCAL = 1
34 FIB_PATH_TYPE_DROP = 2
35 FIB_PATH_TYPE_UDP_ENCAP = 3
36 FIB_PATH_TYPE_BIER_IMP = 4
37 FIB_PATH_TYPE_ICMP_UNREACH = 5
38 FIB_PATH_TYPE_ICMP_PROHIBIT = 6
39 FIB_PATH_TYPE_SOURCE_LOOKUP = 7
40 FIB_PATH_TYPE_DVR = 8
41 FIB_PATH_TYPE_INTERFACE_RX = 9
42 FIB_PATH_TYPE_CLASSIFY = 10
43
44
45class FibPathFlags:
46 FIB_PATH_FLAG_NONE = 0
47 FIB_PATH_FLAG_RESOLVE_VIA_ATTACHED = 1
48 FIB_PATH_FLAG_RESOLVE_VIA_HOST = 2
Neale Ranns1dbcf302019-07-19 11:44:53 +000049 FIB_PATH_FLAG_POP_PW_CW = 4
Neale Ranns097fa662018-05-01 05:17:55 -070050
51
Neale Ranns31ed7442018-02-23 05:29:09 -080052class MplsLspMode:
53 PIPE = 0
54 UNIFORM = 1
55
56
Neale Rannsefd7bc22019-11-11 08:32:34 +000057def mk_network(addr, len):
58 if ip_address(text_type(addr)).version == 4:
59 return IPv4Network("%s/%d" % (addr, len), strict=False)
60 else:
61 return IPv6Network("%s/%d" % (addr, len), strict=False)
62
63
Neale Ranns93cc3ee2018-10-10 07:22:51 -070064def ip_to_dpo_proto(addr):
Paul Vinciguerrabeded852019-03-01 10:35:55 -080065 if addr.version == 6:
Neale Ranns93cc3ee2018-10-10 07:22:51 -070066 return DpoProto.DPO_PROTO_IP6
67 else:
68 return DpoProto.DPO_PROTO_IP4
69
70
Neale Ranns097fa662018-05-01 05:17:55 -070071def address_proto(ip_addr):
Ole Troan6e6ad642020-02-04 13:28:13 +010072 if ip_addr.ip_addr.version == 4:
Neale Ranns097fa662018-05-01 05:17:55 -070073 return FibPathProto.FIB_PATH_NH_PROTO_IP4
Neale Rannsb3b2de72017-03-08 05:17:22 -080074 else:
Neale Ranns097fa662018-05-01 05:17:55 -070075 return FibPathProto.FIB_PATH_NH_PROTO_IP6
Neale Rannsb3b2de72017-03-08 05:17:22 -080076
Neale Ranns097fa662018-05-01 05:17:55 -070077
Maxime Peimb0d43392024-04-09 09:08:00 +020078def find_route(
79 test, addr, len, table_id=0, sw_if_index=None, ignore_default_route=False
80):
Neale Rannsefd7bc22019-11-11 08:32:34 +000081 prefix = mk_network(addr, len)
Neale Ranns097fa662018-05-01 05:17:55 -070082
Ole Troan6e6ad642020-02-04 13:28:13 +010083 if 4 == prefix.version:
Neale Ranns097fa662018-05-01 05:17:55 -070084 routes = test.vapi.ip_route_dump(table_id, False)
Neale Ranns097fa662018-05-01 05:17:55 -070085 else:
86 routes = test.vapi.ip_route_dump(table_id, True)
Neale Ranns097fa662018-05-01 05:17:55 -070087
Neale Rannsb3b2de72017-03-08 05:17:22 -080088 for e in routes:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020089 if table_id == e.route.table_id and str(e.route.prefix) == str(prefix):
Neale Ranns59f71132020-04-08 12:19:38 +000090 if not sw_if_index:
Maxime Peimb0d43392024-04-09 09:08:00 +020091 # if the route is a default one of the table:
92 # 0.0.0.0/0, 0.0.0.0/32, 240.0.0.0/4, 255.255.255.255/32
93 return not (
94 ignore_default_route
95 and e.route.n_paths == 1
96 and e.route.paths[0].type == FibPathType.FIB_PATH_TYPE_DROP
97 )
Neale Ranns59f71132020-04-08 12:19:38 +000098 else:
99 # should be only one path if the user is looking
100 # for the interface the route is reachable through
101 if e.route.n_paths != 1:
102 return False
103 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200104 return e.route.paths[0].sw_if_index == sw_if_index
Neale Ranns59f71132020-04-08 12:19:38 +0000105
Neale Rannsb3b2de72017-03-08 05:17:22 -0800106 return False
107
108
Neale Ranns9db6ada2019-11-08 12:42:31 +0000109def find_route_in_dump(dump, route, table):
110 for r in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200111 if table.table_id == r.route.table_id and route.prefix == r.route.prefix:
Neale Ranns9db6ada2019-11-08 12:42:31 +0000112 if len(route.paths) == r.route.n_paths:
113 return True
114 return False
115
116
117def find_mroute_in_dump(dump, route, table):
118 for r in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200119 if table.table_id == r.route.table_id and route.prefix == r.route.prefix:
Neale Ranns9db6ada2019-11-08 12:42:31 +0000120 return True
121 return False
122
123
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200124def find_mroute(test, grp_addr, src_addr, grp_addr_len, table_id=0):
125 ip_mprefix = VppIpMPrefix(text_type(src_addr), text_type(grp_addr), grp_addr_len)
Neale Ranns097fa662018-05-01 05:17:55 -0700126
Ole Troan6e6ad642020-02-04 13:28:13 +0100127 if 4 == ip_mprefix.version:
Neale Ranns097fa662018-05-01 05:17:55 -0700128 routes = test.vapi.ip_mroute_dump(table_id, False)
Neale Ranns947ea622018-06-07 23:48:20 -0700129 else:
Neale Ranns097fa662018-05-01 05:17:55 -0700130 routes = test.vapi.ip_mroute_dump(table_id, True)
131
Neale Ranns947ea622018-06-07 23:48:20 -0700132 for e in routes:
Neale Ranns097fa662018-05-01 05:17:55 -0700133 if table_id == e.route.table_id and ip_mprefix == e.route.prefix:
Neale Ranns947ea622018-06-07 23:48:20 -0700134 return True
135 return False
136
137
Neale Ranns775f73c2018-12-20 03:01:49 -0800138def find_mpls_route(test, table_id, label, eos_bit, paths=None):
Neale Ranns097fa662018-05-01 05:17:55 -0700139 dump = test.vapi.mpls_route_dump(table_id)
Neale Ranns775f73c2018-12-20 03:01:49 -0800140 for e in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200141 if (
142 label == e.mr_route.mr_label
143 and eos_bit == e.mr_route.mr_eos
144 and table_id == e.mr_route.mr_table_id
145 ):
Neale Ranns775f73c2018-12-20 03:01:49 -0800146 if not paths:
147 return True
148 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200149 if len(paths) != len(e.mr_route.mr_paths):
Neale Ranns775f73c2018-12-20 03:01:49 -0800150 return False
151 for i in range(len(paths)):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200152 if paths[i] != e.mr_route.mr_paths[i]:
Neale Ranns775f73c2018-12-20 03:01:49 -0800153 return False
154 return True
155 return False
156
157
Neale Rannsefd7bc22019-11-11 08:32:34 +0000158def fib_interface_ip_prefix(test, addr, len, sw_if_index):
159 # can't use python net here since we need the host bits in the prefix
160 prefix = "%s/%d" % (addr, len)
161 addrs = test.vapi.ip_address_dump(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200162 sw_if_index, is_ipv6=(6 == ip_address(addr).version)
163 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700164
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700165 for a in addrs:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200166 if a.sw_if_index == sw_if_index and str(a.prefix) == prefix:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700167 return True
168 return False
169
170
Neale Ranns15002542017-09-10 04:39:11 -0700171class VppIpTable(VppObject):
Benoît Ganneff570d32024-04-16 09:36:05 +0200172 def __init__(
173 self, test, table_id, is_ip6=0, register=True, name="", create_mfib=True
174 ):
Neale Ranns15002542017-09-10 04:39:11 -0700175 self._test = test
Maxime Peimf13534e2024-04-05 14:16:39 +0200176 self.name = name
Neale Ranns15002542017-09-10 04:39:11 -0700177 self.table_id = table_id
178 self.is_ip6 = is_ip6
Neale Ranns256b67b2020-09-02 14:46:53 +0000179 self.register = register
Benoît Ganneff570d32024-04-16 09:36:05 +0200180 self.create_mfib = True
Neale Ranns15002542017-09-10 04:39:11 -0700181
182 def add_vpp_config(self):
Benoît Ganneff570d32024-04-16 09:36:05 +0200183 self._test.vapi.ip_table_add_del_v2(
Maxime Peimf13534e2024-04-05 14:16:39 +0200184 is_add=1,
Benoît Ganneff570d32024-04-16 09:36:05 +0200185 create_mfib=self.create_mfib,
Maxime Peimf13534e2024-04-05 14:16:39 +0200186 table={"is_ip6": self.is_ip6, "table_id": self.table_id, "name": self.name},
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200187 )
Neale Ranns256b67b2020-09-02 14:46:53 +0000188 if self.register:
189 self._test.registry.register(self, self._test.logger)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000190 return self
Neale Ranns15002542017-09-10 04:39:11 -0700191
192 def remove_vpp_config(self):
Benoît Ganneff570d32024-04-16 09:36:05 +0200193 self._test.vapi.ip_table_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200194 is_add=0, table={"is_ip6": self.is_ip6, "table_id": self.table_id}
195 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000196
197 def replace_begin(self):
198 self._test.vapi.ip_table_replace_begin(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200199 table={"is_ip6": self.is_ip6, "table_id": self.table_id}
200 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000201
202 def replace_end(self):
203 self._test.vapi.ip_table_replace_end(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200204 table={"is_ip6": self.is_ip6, "table_id": self.table_id}
205 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000206
207 def flush(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200208 self._test.vapi.ip_table_flush(
209 table={"is_ip6": self.is_ip6, "table_id": self.table_id}
210 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000211
212 def dump(self):
213 return self._test.vapi.ip_route_dump(self.table_id, self.is_ip6)
214
215 def mdump(self):
216 return self._test.vapi.ip_mroute_dump(self.table_id, self.is_ip6)
Neale Ranns15002542017-09-10 04:39:11 -0700217
218 def query_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700219 if self.table_id == 0:
220 # the default table always exists
221 return False
Neale Ranns15002542017-09-10 04:39:11 -0700222 # find the default route
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200223 return find_route(
224 self._test, "::" if self.is_ip6 else "0.0.0.0", 0, self.table_id
225 )
Neale Ranns15002542017-09-10 04:39:11 -0700226
Neale Ranns15002542017-09-10 04:39:11 -0700227 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200228 return "table-%s-%d" % ("v6" if self.is_ip6 == 1 else "v4", self.table_id)
Neale Ranns15002542017-09-10 04:39:11 -0700229
230
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700231class VppIpInterfaceAddress(VppObject):
Neale Ranns59f71132020-04-08 12:19:38 +0000232 def __init__(self, test, intf, addr, len, bind=None):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700233 self._test = test
234 self.intf = intf
Neale Rannsefd7bc22019-11-11 08:32:34 +0000235 self.addr = addr
236 self.len = len
237 self.prefix = "%s/%d" % (addr, len)
Neale Ranns59f71132020-04-08 12:19:38 +0000238 self.host_len = ip_network(self.prefix, strict=False).max_prefixlen
239 self.table_id = 0
240 if bind:
241 self.table_id = bind.table.table_id
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700242
243 def add_vpp_config(self):
244 self._test.vapi.sw_interface_add_del_address(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200245 sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=1
246 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700247 self._test.registry.register(self, self._test.logger)
Neale Ranns9efcee62019-11-26 19:30:08 +0000248 return self
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700249
250 def remove_vpp_config(self):
251 self._test.vapi.sw_interface_add_del_address(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200252 sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=0
253 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700254
255 def query_vpp_config(self):
Neale Ranns59f71132020-04-08 12:19:38 +0000256 # search for the IP address mapping and the two expected
257 # FIB entries
258 v = ip_address(self.addr).version
259
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200260 if (v == 4 and self.len < 31) or (v == 6 and self.len < 127):
261 return (
262 fib_interface_ip_prefix(
263 self._test, self.addr, self.len, self.intf.sw_if_index
264 )
265 & find_route(
266 self._test,
267 self.addr,
268 self.len,
269 table_id=self.table_id,
270 sw_if_index=self.intf.sw_if_index,
271 )
272 & find_route(
273 self._test,
274 self.addr,
275 self.host_len,
276 table_id=self.table_id,
277 sw_if_index=self.intf.sw_if_index,
278 )
279 )
Neale Ranns59f71132020-04-08 12:19:38 +0000280 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200281 return fib_interface_ip_prefix(
282 self._test, self.addr, self.len, self.intf.sw_if_index
283 ) & find_route(
284 self._test,
285 self.addr,
286 self.host_len,
287 table_id=self.table_id,
288 sw_if_index=self.intf.sw_if_index,
289 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700290
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700291 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200292 return "interface-ip-%s-%d-%s" % (self.intf, self.table_id, self.prefix)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700293
294
Neale Rannsec40a7d2020-04-23 07:36:12 +0000295class VppIp6LinkLocalAddress(VppObject):
Neale Rannsec40a7d2020-04-23 07:36:12 +0000296 def __init__(self, test, intf, addr):
297 self._test = test
298 self.intf = intf
299 self.addr = addr
300
301 def add_vpp_config(self):
302 self._test.vapi.sw_interface_ip6_set_link_local_address(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200303 sw_if_index=self.intf.sw_if_index, ip=self.addr
304 )
Neale Rannsec40a7d2020-04-23 07:36:12 +0000305 self._test.registry.register(self, self._test.logger)
306 return self
307
308 def remove_vpp_config(self):
309 # link locals can't be removed, only changed
310 pass
311
312 def query_vpp_config(self):
313 # no API to query
314 return False
315
316 def object_id(self):
317 return "ip6-link-local-%s-%s" % (self.intf, self.addr)
318
319
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700320class VppIpInterfaceBind(VppObject):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700321 def __init__(self, test, intf, table):
322 self._test = test
323 self.intf = intf
324 self.table = table
325
326 def add_vpp_config(self):
327 if self.table.is_ip6:
328 self.intf.set_table_ip6(self.table.table_id)
329 else:
330 self.intf.set_table_ip4(self.table.table_id)
331 self._test.registry.register(self, self._test.logger)
Neale Ranns59f71132020-04-08 12:19:38 +0000332 return self
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700333
334 def remove_vpp_config(self):
335 if 0 == self.table.table_id:
336 return
337 if self.table.is_ip6:
338 self.intf.set_table_ip6(0)
339 else:
340 self.intf.set_table_ip4(0)
341
342 def query_vpp_config(self):
343 if 0 == self.table.table_id:
344 return False
Klement Sekera77c821c2022-04-14 16:29:07 +0200345 try:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200346 return (
347 self._test.vapi.sw_interface_get_table(
348 self.intf.sw_if_index, self.table.is_ip6
349 ).vrf_id
350 == self.table.table_id
351 )
Klement Sekera77c821c2022-04-14 16:29:07 +0200352 except UnexpectedApiReturnValueError as e:
353 if e.retval == -2: # INVALID_SW_IF_INDEX
354 return False
355 raise
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700356
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700357 def object_id(self):
358 return "interface-bind-%s-%s" % (self.intf, self.table)
359
360
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500361class VppMplsLabel:
Neale Ranns31ed7442018-02-23 05:29:09 -0800362 def __init__(self, value, mode=MplsLspMode.PIPE, ttl=64, exp=0):
363 self.value = value
364 self.mode = mode
365 self.ttl = ttl
366 self.exp = exp
367
368 def encode(self):
369 is_uniform = 0 if self.mode is MplsLspMode.PIPE else 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200370 return {
371 "label": self.value,
372 "ttl": self.ttl,
373 "exp": self.exp,
374 "is_uniform": is_uniform,
375 }
Neale Ranns31ed7442018-02-23 05:29:09 -0800376
Neale Ranns775f73c2018-12-20 03:01:49 -0800377 def __eq__(self, other):
378 if isinstance(other, self.__class__):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200379 return (
380 self.value == other.value
381 and self.ttl == other.ttl
382 and self.exp == other.exp
383 and self.mode == other.mode
384 )
385 elif hasattr(other, "label"):
386 return (
387 self.value == other.label
388 and self.ttl == other.ttl
389 and self.exp == other.exp
390 and (self.mode == MplsLspMode.UNIFORM) == other.is_uniform
391 )
Neale Ranns775f73c2018-12-20 03:01:49 -0800392 else:
393 return False
394
395 def __ne__(self, other):
396 return not (self == other)
397
Neale Ranns31ed7442018-02-23 05:29:09 -0800398
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500399class VppFibPathNextHop:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200400 def __init__(self, addr, via_label=MPLS_LABEL_INVALID, next_hop_id=INVALID_INDEX):
Neale Ranns097fa662018-05-01 05:17:55 -0700401 self.addr = VppIpAddressUnion(addr)
402 self.via_label = via_label
403 self.obj_id = next_hop_id
404
405 def encode(self):
406 if self.via_label is not MPLS_LABEL_INVALID:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200407 return {"via_label": self.via_label}
Neale Ranns097fa662018-05-01 05:17:55 -0700408 if self.obj_id is not INVALID_INDEX:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200409 return {"obj_id": self.obj_id}
Neale Ranns097fa662018-05-01 05:17:55 -0700410 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200411 return {"address": self.addr.encode()}
Neale Ranns097fa662018-05-01 05:17:55 -0700412
413 def proto(self):
414 if self.via_label is MPLS_LABEL_INVALID:
415 return address_proto(self.addr)
416 else:
417 return FibPathProto.FIB_PATH_NH_PROTO_MPLS
418
419 def __eq__(self, other):
420 if not isinstance(other, self.__class__):
421 # try the other instance's __eq__.
422 return NotImplemented
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200423 return (
424 self.addr == other.addr
425 and self.via_label == other.via_label
426 and self.obj_id == other.obj_id
427 )
Neale Ranns097fa662018-05-01 05:17:55 -0700428
429
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500430class VppRoutePath:
Klement Sekerada505f62017-01-04 12:58:53 +0100431 def __init__(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200432 self,
433 nh_addr,
434 nh_sw_if_index,
435 nh_table_id=0,
436 labels=[],
437 nh_via_label=MPLS_LABEL_INVALID,
438 rpf_id=0,
439 next_hop_id=INVALID_INDEX,
440 proto=None,
441 flags=FibPathFlags.FIB_PATH_FLAG_NONE,
442 type=FibPathType.FIB_PATH_TYPE_NORMAL,
443 ):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000444 self.nh_itf = nh_sw_if_index
445 self.nh_table_id = nh_table_id
Neale Rannsad422ed2016-11-02 14:20:04 +0000446 self.nh_labels = labels
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800447 self.weight = 1
448 self.rpf_id = rpf_id
Neale Ranns097fa662018-05-01 05:17:55 -0700449 self.proto = proto
450 self.flags = flags
451 self.type = type
452 self.nh = VppFibPathNextHop(nh_addr, nh_via_label, next_hop_id)
453 if proto is None:
454 self.proto = self.nh.proto()
Neale Ranns31426c62017-05-24 10:32:58 -0700455 else:
Neale Ranns097fa662018-05-01 05:17:55 -0700456 self.proto = proto
Neale Ranns810086d2017-11-05 16:26:46 -0800457 self.next_hop_id = next_hop_id
Neale Ranns177bbdc2016-11-15 09:46:51 +0000458
Neale Ranns097fa662018-05-01 05:17:55 -0700459 def encode_labels(self):
Neale Ranns31ed7442018-02-23 05:29:09 -0800460 lstack = []
461 for l in self.nh_labels:
462 if type(l) == VppMplsLabel:
463 lstack.append(l.encode())
464 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200465 lstack.append({"label": l, "ttl": 255})
466 while len(lstack) < 16:
Neale Ranns097fa662018-05-01 05:17:55 -0700467 lstack.append({})
468
Neale Ranns31ed7442018-02-23 05:29:09 -0800469 return lstack
470
Neale Ranns097fa662018-05-01 05:17:55 -0700471 def encode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200472 return {
473 "weight": 1,
474 "preference": 0,
475 "table_id": self.nh_table_id,
476 "nh": self.nh.encode(),
477 "next_hop_id": self.next_hop_id,
478 "sw_if_index": self.nh_itf,
479 "rpf_id": self.rpf_id,
480 "proto": self.proto,
481 "type": self.type,
482 "flags": self.flags,
483 "n_labels": len(self.nh_labels),
484 "label_stack": self.encode_labels(),
485 }
Neale Ranns2303cb12018-02-21 04:57:17 -0800486
Neale Rannsef90ed02018-09-13 08:45:12 -0700487 def __eq__(self, other):
Neale Ranns775f73c2018-12-20 03:01:49 -0800488 if isinstance(other, self.__class__):
Neale Ranns097fa662018-05-01 05:17:55 -0700489 return self.nh == other.nh
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200490 elif hasattr(other, "sw_if_index"):
Neale Ranns775f73c2018-12-20 03:01:49 -0800491 # vl_api_fib_path_t
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200492 if len(self.nh_labels) != other.n_labels:
Neale Ranns775f73c2018-12-20 03:01:49 -0800493 return False
494 for i in range(len(self.nh_labels)):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200495 if self.nh_labels[i] != other.label_stack[i]:
Neale Ranns775f73c2018-12-20 03:01:49 -0800496 return False
497 return self.nh_itf == other.sw_if_index
498 else:
499 return False
500
501 def __ne__(self, other):
502 return not (self == other)
Neale Rannsef90ed02018-09-13 08:45:12 -0700503
Neale Ranns177bbdc2016-11-15 09:46:51 +0000504
Neale Ranns5a8123b2017-01-26 01:18:23 -0800505class VppMRoutePath(VppRoutePath):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200506 def __init__(
507 self,
508 nh_sw_if_index,
509 flags,
510 nh=None,
511 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
512 type=FibPathType.FIB_PATH_TYPE_NORMAL,
513 bier_imp=INVALID_INDEX,
514 ):
Neale Rannse821ab12017-06-01 07:45:05 -0700515 if not nh:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200516 nh = "::" if proto is FibPathProto.FIB_PATH_NH_PROTO_IP6 else "0.0.0.0"
517 super(VppMRoutePath, self).__init__(
518 nh, nh_sw_if_index, proto=proto, type=type, next_hop_id=bier_imp
519 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000520 self.nh_i_flags = flags
Neale Rannsd792d9c2017-10-21 10:53:20 -0700521 self.bier_imp = bier_imp
Neale Ranns32e1c012016-11-22 17:07:28 +0000522
Neale Ranns097fa662018-05-01 05:17:55 -0700523 def encode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200524 return {
525 "path": super(VppMRoutePath, self).encode(),
526 "itf_flags": self.nh_i_flags,
527 }
Neale Ranns097fa662018-05-01 05:17:55 -0700528
Neale Ranns32e1c012016-11-22 17:07:28 +0000529
Neale Ranns5a8123b2017-01-26 01:18:23 -0800530class VppIpRoute(VppObject):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000531 """
532 IP Route
533 """
534
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200535 def __init__(
536 self, test, dest_addr, dest_addr_len, paths, table_id=0, register=True
537 ):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000538 self._test = test
539 self.paths = paths
Neale Ranns177bbdc2016-11-15 09:46:51 +0000540 self.table_id = table_id
Neale Rannsefd7bc22019-11-11 08:32:34 +0000541 self.prefix = mk_network(dest_addr, dest_addr_len)
Neale Ranns097fa662018-05-01 05:17:55 -0700542 self.register = register
Paul Vinciguerra941da4a2019-06-18 07:57:53 -0400543 self.stats_index = None
Neale Rannsc2ac2352019-07-02 14:33:29 +0000544 self.modified = False
Neale Ranns177bbdc2016-11-15 09:46:51 +0000545
Neale Ranns097fa662018-05-01 05:17:55 -0700546 self.encoded_paths = []
547 for path in self.paths:
548 self.encoded_paths.append(path.encode())
549
550 def __eq__(self, other):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200551 if self.table_id == other.table_id and self.prefix == other.prefix:
Neale Ranns097fa662018-05-01 05:17:55 -0700552 return True
553 return False
554
555 def modify(self, paths):
Neale Ranns69b7aa42017-03-10 03:04:12 -0800556 self.paths = paths
Neale Ranns097fa662018-05-01 05:17:55 -0700557 self.encoded_paths = []
558 for path in self.paths:
559 self.encoded_paths.append(path.encode())
Neale Rannsc2ac2352019-07-02 14:33:29 +0000560 self.modified = True
Neale Ranns097fa662018-05-01 05:17:55 -0700561
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200562 self._test.vapi.ip_route_add_del(
563 route={
564 "table_id": self.table_id,
565 "prefix": self.prefix,
566 "n_paths": len(self.encoded_paths),
567 "paths": self.encoded_paths,
568 },
569 is_add=1,
570 is_multipath=0,
571 )
Neale Ranns69b7aa42017-03-10 03:04:12 -0800572
Neale Ranns177bbdc2016-11-15 09:46:51 +0000573 def add_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700574 r = self._test.vapi.ip_route_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200575 route={
576 "table_id": self.table_id,
577 "prefix": self.prefix,
578 "n_paths": len(self.encoded_paths),
579 "paths": self.encoded_paths,
580 },
Neale Ranns097fa662018-05-01 05:17:55 -0700581 is_add=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200582 is_multipath=0,
583 )
Neale Ranns008dbe12018-09-07 09:32:36 -0700584 self.stats_index = r.stats_index
Neale Ranns097fa662018-05-01 05:17:55 -0700585 if self.register:
586 self._test.registry.register(self, self._test.logger)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000587 return self
Neale Ranns177bbdc2016-11-15 09:46:51 +0000588
589 def remove_vpp_config(self):
Neale Rannsc2ac2352019-07-02 14:33:29 +0000590 # there's no need to issue different deletes for modified routes
591 # we do this only to test the two different ways to delete routes
592 # eiter by passing all the paths to remove and mutlipath=1 or
593 # passing no paths and multipath=0
594 if self.modified:
595 self._test.vapi.ip_route_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200596 route={
597 "table_id": self.table_id,
598 "prefix": self.prefix,
599 "n_paths": len(self.encoded_paths),
600 "paths": self.encoded_paths,
601 },
Neale Rannsc2ac2352019-07-02 14:33:29 +0000602 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200603 is_multipath=1,
604 )
Neale Rannsc2ac2352019-07-02 14:33:29 +0000605 else:
606 self._test.vapi.ip_route_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200607 route={"table_id": self.table_id, "prefix": self.prefix, "n_paths": 0},
Neale Rannsc2ac2352019-07-02 14:33:29 +0000608 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200609 is_multipath=0,
610 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000611
Neale Ranns5a8123b2017-01-26 01:18:23 -0800612 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200613 return find_route(
614 self._test,
615 self.prefix.network_address,
616 self.prefix.prefixlen,
617 self.table_id,
Maxime Peimb0d43392024-04-09 09:08:00 +0200618 ignore_default_route=True,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200619 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000620
Neale Ranns5a8123b2017-01-26 01:18:23 -0800621 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200622 return "%s:table-%d-%s" % (
623 "ip6-route" if self.prefix.version == 6 else "ip-route",
624 self.table_id,
625 self.prefix,
626 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800627
Neale Ranns008dbe12018-09-07 09:32:36 -0700628 def get_stats_to(self):
629 c = self._test.statistics.get_counter("/net/route/to")
630 return c[0][self.stats_index]
631
632 def get_stats_via(self):
633 c = self._test.statistics.get_counter("/net/route/via")
634 return c[0][self.stats_index]
635
Neale Ranns5a8123b2017-01-26 01:18:23 -0800636
Neale Ranns976b2592019-12-04 06:11:00 +0000637class VppIpRouteV2(VppObject):
638 """
639 IP Route V2
640 """
641
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200642 def __init__(
643 self, test, dest_addr, dest_addr_len, paths, table_id=0, register=True, src=0
644 ):
Neale Ranns976b2592019-12-04 06:11:00 +0000645 self._test = test
646 self.paths = paths
647 self.table_id = table_id
648 self.prefix = mk_network(dest_addr, dest_addr_len)
649 self.register = register
650 self.stats_index = None
651 self.modified = False
652 self.src = src
653
654 self.encoded_paths = []
655 for path in self.paths:
656 self.encoded_paths.append(path.encode())
657
658 def __eq__(self, other):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200659 if self.table_id == other.table_id and self.prefix == other.prefix:
Neale Ranns976b2592019-12-04 06:11:00 +0000660 return True
661 return False
662
663 def modify(self, paths):
664 self.paths = paths
665 self.encoded_paths = []
666 for path in self.paths:
667 self.encoded_paths.append(path.encode())
668 self.modified = True
669
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200670 self._test.vapi.ip_route_add_del_v2(
671 route={
672 "table_id": self.table_id,
673 "prefix": self.prefix,
674 "src": self.src,
675 "n_paths": len(self.encoded_paths),
676 "paths": self.encoded_paths,
677 },
678 is_add=1,
679 is_multipath=0,
680 )
Neale Ranns976b2592019-12-04 06:11:00 +0000681
682 def add_vpp_config(self):
683 r = self._test.vapi.ip_route_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200684 route={
685 "table_id": self.table_id,
686 "prefix": self.prefix,
687 "n_paths": len(self.encoded_paths),
688 "paths": self.encoded_paths,
689 "src": self.src,
690 },
Neale Ranns976b2592019-12-04 06:11:00 +0000691 is_add=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200692 is_multipath=0,
693 )
Neale Ranns976b2592019-12-04 06:11:00 +0000694 self.stats_index = r.stats_index
695 if self.register:
696 self._test.registry.register(self, self._test.logger)
697 return self
698
699 def remove_vpp_config(self):
700 # there's no need to issue different deletes for modified routes
701 # we do this only to test the two different ways to delete routes
702 # eiter by passing all the paths to remove and mutlipath=1 or
703 # passing no paths and multipath=0
704 if self.modified:
705 self._test.vapi.ip_route_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200706 route={
707 "table_id": self.table_id,
708 "prefix": self.prefix,
709 "src": self.src,
710 "n_paths": len(self.encoded_paths),
711 "paths": self.encoded_paths,
712 },
Neale Ranns976b2592019-12-04 06:11:00 +0000713 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200714 is_multipath=1,
715 )
Neale Ranns976b2592019-12-04 06:11:00 +0000716 else:
717 self._test.vapi.ip_route_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200718 route={
719 "table_id": self.table_id,
720 "prefix": self.prefix,
721 "src": self.src,
722 "n_paths": 0,
723 },
Neale Ranns976b2592019-12-04 06:11:00 +0000724 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200725 is_multipath=0,
726 )
Neale Ranns976b2592019-12-04 06:11:00 +0000727
728 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200729 return find_route(
730 self._test,
731 self.prefix.network_address,
732 self.prefix.prefixlen,
733 self.table_id,
Maxime Peimb0d43392024-04-09 09:08:00 +0200734 ignore_default_route=True,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200735 )
Neale Ranns976b2592019-12-04 06:11:00 +0000736
737 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200738 return "%s:table-%d-%s" % (
739 "ip6-route" if self.prefix.version == 6 else "ip-route",
740 self.table_id,
741 self.prefix,
742 )
Neale Ranns976b2592019-12-04 06:11:00 +0000743
744 def get_stats_to(self):
745 c = self._test.statistics.get_counter("/net/route/to")
746 return c[0][self.stats_index]
747
748 def get_stats_via(self):
749 c = self._test.statistics.get_counter("/net/route/via")
750 return c[0][self.stats_index]
751
752
Neale Ranns5a8123b2017-01-26 01:18:23 -0800753class VppIpMRoute(VppObject):
Neale Ranns32e1c012016-11-22 17:07:28 +0000754 """
755 IP Multicast Route
756 """
757
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200758 def __init__(
759 self,
760 test,
761 src_addr,
762 grp_addr,
763 grp_addr_len,
764 e_flags,
765 paths,
766 table_id=0,
767 rpf_id=0,
768 ):
Neale Ranns32e1c012016-11-22 17:07:28 +0000769 self._test = test
770 self.paths = paths
Neale Ranns32e1c012016-11-22 17:07:28 +0000771 self.table_id = table_id
772 self.e_flags = e_flags
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800773 self.rpf_id = rpf_id
Neale Ranns32e1c012016-11-22 17:07:28 +0000774
Neale Ranns097fa662018-05-01 05:17:55 -0700775 self.prefix = VppIpMPrefix(src_addr, grp_addr, grp_addr_len)
776 self.encoded_paths = []
777 for path in self.paths:
778 self.encoded_paths.append(path.encode())
Neale Ranns32e1c012016-11-22 17:07:28 +0000779
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400780 def encode(self, paths=None):
781 _paths = self.encoded_paths if paths is None else paths
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200782 return {
783 "table_id": self.table_id,
784 "entry_flags": self.e_flags,
785 "rpf_id": self.rpf_id,
786 "prefix": self.prefix.encode(),
787 "n_paths": len(_paths),
788 "paths": _paths,
789 }
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400790
Neale Ranns32e1c012016-11-22 17:07:28 +0000791 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200792 r = self._test.vapi.ip_mroute_add_del(
793 route=self.encode(), is_multipath=1, is_add=1
794 )
Neale Ranns097fa662018-05-01 05:17:55 -0700795 self.stats_index = r.stats_index
Neale Ranns5a8123b2017-01-26 01:18:23 -0800796 self._test.registry.register(self, self._test.logger)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000797 return self
Neale Ranns32e1c012016-11-22 17:07:28 +0000798
799 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200800 self._test.vapi.ip_mroute_add_del(route=self.encode(), is_multipath=1, is_add=0)
Neale Ranns32e1c012016-11-22 17:07:28 +0000801
802 def update_entry_flags(self, flags):
803 self.e_flags = flags
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200804 self._test.vapi.ip_mroute_add_del(
805 route=self.encode(paths=[]), is_multipath=1, is_add=1
806 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000807
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800808 def update_rpf_id(self, rpf_id):
809 self.rpf_id = rpf_id
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200810 self._test.vapi.ip_mroute_add_del(
811 route=self.encode(paths=[]), is_multipath=1, is_add=1
812 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800813
Neale Ranns32e1c012016-11-22 17:07:28 +0000814 def update_path_flags(self, itf, flags):
Neale Ranns097fa662018-05-01 05:17:55 -0700815 for p in range(len(self.paths)):
816 if self.paths[p].nh_itf == itf:
817 self.paths[p].nh_i_flags = flags
Paul Vinciguerra6230b9d2020-04-28 11:23:31 -0400818 self.encoded_paths[p] = self.paths[p].encode()
819 break
Neale Ranns097fa662018-05-01 05:17:55 -0700820
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400821 self._test.vapi.ip_mroute_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200822 route=self.encode(paths=[self.encoded_paths[p]]), is_add=1, is_multipath=0
823 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000824
Neale Ranns5a8123b2017-01-26 01:18:23 -0800825 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200826 return find_mroute(
827 self._test,
828 self.prefix.gaddr,
829 self.prefix.saddr,
830 self.prefix.length,
831 self.table_id,
832 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000833
Neale Ranns5a8123b2017-01-26 01:18:23 -0800834 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200835 return "%d:(%s,%s/%d)" % (
836 self.table_id,
837 self.prefix.saddr,
838 self.prefix.gaddr,
839 self.prefix.length,
840 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800841
Neale Ranns28c142e2018-09-07 09:37:07 -0700842 def get_stats(self):
843 c = self._test.statistics.get_counter("/net/mroute")
844 return c[0][self.stats_index]
845
Neale Ranns5a8123b2017-01-26 01:18:23 -0800846
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500847class VppMFibSignal:
Neale Ranns32e1c012016-11-22 17:07:28 +0000848 def __init__(self, test, route, interface, packet):
849 self.route = route
850 self.interface = interface
851 self.packet = packet
852 self.test = test
853
854 def compare(self, signal):
855 self.test.assertEqual(self.interface, signal.sw_if_index)
856 self.test.assertEqual(self.route.table_id, signal.table_id)
Neale Ranns097fa662018-05-01 05:17:55 -0700857 self.test.assertEqual(self.route.prefix, signal.prefix)
Neale Ranns32e1c012016-11-22 17:07:28 +0000858
859
Neale Ranns5a8123b2017-01-26 01:18:23 -0800860class VppMplsIpBind(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000861 """
862 MPLS to IP Binding
863 """
864
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200865 def __init__(
866 self,
867 test,
868 local_label,
869 dest_addr,
870 dest_addr_len,
871 table_id=0,
872 ip_table_id=0,
873 is_ip6=0,
874 ):
Neale Rannsad422ed2016-11-02 14:20:04 +0000875 self._test = test
Neale Rannsad422ed2016-11-02 14:20:04 +0000876 self.dest_addr_len = dest_addr_len
Neale Rannsf12a83f2017-04-18 09:09:40 -0700877 self.dest_addr = dest_addr
Neale Ranns097fa662018-05-01 05:17:55 -0700878 self.ip_addr = ip_address(text_type(dest_addr))
Neale Rannsad422ed2016-11-02 14:20:04 +0000879 self.local_label = local_label
Neale Ranns5a8123b2017-01-26 01:18:23 -0800880 self.table_id = table_id
881 self.ip_table_id = ip_table_id
Neale Rannsefd7bc22019-11-11 08:32:34 +0000882 self.prefix = mk_network(dest_addr, dest_addr_len)
Neale Rannsad422ed2016-11-02 14:20:04 +0000883
884 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200885 self._test.vapi.mpls_ip_bind_unbind(
886 self.local_label,
887 self.prefix,
888 table_id=self.table_id,
889 ip_table_id=self.ip_table_id,
890 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800891 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000892
893 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200894 self._test.vapi.mpls_ip_bind_unbind(
895 self.local_label,
896 self.prefix,
897 table_id=self.table_id,
898 ip_table_id=self.ip_table_id,
899 is_bind=0,
900 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000901
Neale Ranns5a8123b2017-01-26 01:18:23 -0800902 def query_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700903 dump = self._test.vapi.mpls_route_dump(self.table_id)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800904 for e in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200905 if (
906 self.local_label == e.mr_route.mr_label
907 and self.table_id == e.mr_route.mr_table_id
908 ):
Neale Ranns5a8123b2017-01-26 01:18:23 -0800909 return True
910 return False
Neale Rannsad422ed2016-11-02 14:20:04 +0000911
Neale Ranns5a8123b2017-01-26 01:18:23 -0800912 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200913 return "%d:%s binds %d:%s/%d" % (
914 self.table_id,
915 self.local_label,
916 self.ip_table_id,
917 self.dest_addr,
918 self.dest_addr_len,
919 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800920
921
Neale Ranns15002542017-09-10 04:39:11 -0700922class VppMplsTable(VppObject):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200923 def __init__(self, test, table_id):
Neale Ranns15002542017-09-10 04:39:11 -0700924 self._test = test
925 self.table_id = table_id
926
927 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200928 self._test.vapi.mpls_table_add_del(self.table_id, is_add=1)
Neale Ranns15002542017-09-10 04:39:11 -0700929 self._test.registry.register(self, self._test.logger)
930
931 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200932 self._test.vapi.mpls_table_add_del(self.table_id, is_add=0)
Neale Ranns15002542017-09-10 04:39:11 -0700933
934 def query_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700935 dump = self._test.vapi.mpls_table_dump()
936 for d in dump:
937 if d.mt_table.mt_table_id == self.table_id:
938 return True
Neale Ranns15002542017-09-10 04:39:11 -0700939 return False
940
Neale Ranns15002542017-09-10 04:39:11 -0700941 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200942 return "table-mpls-%d" % (self.table_id)
Neale Ranns15002542017-09-10 04:39:11 -0700943
944
Neale Ranns5a8123b2017-01-26 01:18:23 -0800945class VppMplsRoute(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000946 """
Neale Ranns5a8123b2017-01-26 01:18:23 -0800947 MPLS Route/LSP
Neale Rannsad422ed2016-11-02 14:20:04 +0000948 """
949
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200950 def __init__(
951 self,
952 test,
953 local_label,
954 eos_bit,
955 paths,
956 table_id=0,
957 is_multicast=0,
958 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
959 ):
Neale Rannsad422ed2016-11-02 14:20:04 +0000960 self._test = test
961 self.paths = paths
962 self.local_label = local_label
963 self.eos_bit = eos_bit
Neale Ranns097fa662018-05-01 05:17:55 -0700964 self.eos_proto = eos_proto
Neale Rannsad422ed2016-11-02 14:20:04 +0000965 self.table_id = table_id
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800966 self.is_multicast = is_multicast
Neale Rannsad422ed2016-11-02 14:20:04 +0000967
968 def add_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700969 paths = []
Neale Rannsad422ed2016-11-02 14:20:04 +0000970 for path in self.paths:
Neale Ranns097fa662018-05-01 05:17:55 -0700971 paths.append(path.encode())
Neale Ranns31ed7442018-02-23 05:29:09 -0800972
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200973 r = self._test.vapi.mpls_route_add_del(
974 self.table_id,
975 self.local_label,
976 self.eos_bit,
977 self.eos_proto,
978 self.is_multicast,
979 paths,
980 1,
981 0,
982 )
Neale Ranns008dbe12018-09-07 09:32:36 -0700983 self.stats_index = r.stats_index
Neale Ranns5a8123b2017-01-26 01:18:23 -0800984 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000985
986 def remove_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700987 paths = []
Neale Rannsad422ed2016-11-02 14:20:04 +0000988 for path in self.paths:
Neale Ranns097fa662018-05-01 05:17:55 -0700989 paths.append(path.encode())
990
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200991 self._test.vapi.mpls_route_add_del(
992 self.table_id,
993 self.local_label,
994 self.eos_bit,
995 self.eos_proto,
996 self.is_multicast,
997 paths,
998 0,
999 0,
1000 )
Neale Ranns5a8123b2017-01-26 01:18:23 -08001001
1002 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001003 return find_mpls_route(
1004 self._test, self.table_id, self.local_label, self.eos_bit
1005 )
Neale Ranns5a8123b2017-01-26 01:18:23 -08001006
Neale Ranns5a8123b2017-01-26 01:18:23 -08001007 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001008 return "mpls-route-%d:%s/%d" % (
1009 self.table_id,
1010 self.local_label,
1011 20 + self.eos_bit,
1012 )
Neale Ranns008dbe12018-09-07 09:32:36 -07001013
1014 def get_stats_to(self):
1015 c = self._test.statistics.get_counter("/net/route/to")
1016 return c[0][self.stats_index]
1017
1018 def get_stats_via(self):
1019 c = self._test.statistics.get_counter("/net/route/via")
1020 return c[0][self.stats_index]