blob: 9b3a138a81c8720b2e5cde77e19ee4e7106d225c [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):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200172 def __init__(self, test, table_id, is_ip6=0, register=True):
Neale Ranns15002542017-09-10 04:39:11 -0700173 self._test = test
174 self.table_id = table_id
175 self.is_ip6 = is_ip6
Neale Ranns256b67b2020-09-02 14:46:53 +0000176 self.register = register
Neale Ranns15002542017-09-10 04:39:11 -0700177
178 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200179 self._test.vapi.ip_table_add_del(
180 is_add=1, table={"is_ip6": self.is_ip6, "table_id": self.table_id}
181 )
Neale Ranns256b67b2020-09-02 14:46:53 +0000182 if self.register:
183 self._test.registry.register(self, self._test.logger)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000184 return self
Neale Ranns15002542017-09-10 04:39:11 -0700185
186 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200187 self._test.vapi.ip_table_add_del(
188 is_add=0, table={"is_ip6": self.is_ip6, "table_id": self.table_id}
189 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000190
191 def replace_begin(self):
192 self._test.vapi.ip_table_replace_begin(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200193 table={"is_ip6": self.is_ip6, "table_id": self.table_id}
194 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000195
196 def replace_end(self):
197 self._test.vapi.ip_table_replace_end(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200198 table={"is_ip6": self.is_ip6, "table_id": self.table_id}
199 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000200
201 def flush(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200202 self._test.vapi.ip_table_flush(
203 table={"is_ip6": self.is_ip6, "table_id": self.table_id}
204 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000205
206 def dump(self):
207 return self._test.vapi.ip_route_dump(self.table_id, self.is_ip6)
208
209 def mdump(self):
210 return self._test.vapi.ip_mroute_dump(self.table_id, self.is_ip6)
Neale Ranns15002542017-09-10 04:39:11 -0700211
212 def query_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700213 if self.table_id == 0:
214 # the default table always exists
215 return False
Neale Ranns15002542017-09-10 04:39:11 -0700216 # find the default route
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200217 return find_route(
218 self._test, "::" if self.is_ip6 else "0.0.0.0", 0, self.table_id
219 )
Neale Ranns15002542017-09-10 04:39:11 -0700220
Neale Ranns15002542017-09-10 04:39:11 -0700221 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200222 return "table-%s-%d" % ("v6" if self.is_ip6 == 1 else "v4", self.table_id)
Neale Ranns15002542017-09-10 04:39:11 -0700223
224
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700225class VppIpInterfaceAddress(VppObject):
Neale Ranns59f71132020-04-08 12:19:38 +0000226 def __init__(self, test, intf, addr, len, bind=None):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700227 self._test = test
228 self.intf = intf
Neale Rannsefd7bc22019-11-11 08:32:34 +0000229 self.addr = addr
230 self.len = len
231 self.prefix = "%s/%d" % (addr, len)
Neale Ranns59f71132020-04-08 12:19:38 +0000232 self.host_len = ip_network(self.prefix, strict=False).max_prefixlen
233 self.table_id = 0
234 if bind:
235 self.table_id = bind.table.table_id
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700236
237 def add_vpp_config(self):
238 self._test.vapi.sw_interface_add_del_address(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200239 sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=1
240 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700241 self._test.registry.register(self, self._test.logger)
Neale Ranns9efcee62019-11-26 19:30:08 +0000242 return self
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700243
244 def remove_vpp_config(self):
245 self._test.vapi.sw_interface_add_del_address(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200246 sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=0
247 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700248
249 def query_vpp_config(self):
Neale Ranns59f71132020-04-08 12:19:38 +0000250 # search for the IP address mapping and the two expected
251 # FIB entries
252 v = ip_address(self.addr).version
253
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200254 if (v == 4 and self.len < 31) or (v == 6 and self.len < 127):
255 return (
256 fib_interface_ip_prefix(
257 self._test, self.addr, self.len, self.intf.sw_if_index
258 )
259 & find_route(
260 self._test,
261 self.addr,
262 self.len,
263 table_id=self.table_id,
264 sw_if_index=self.intf.sw_if_index,
265 )
266 & find_route(
267 self._test,
268 self.addr,
269 self.host_len,
270 table_id=self.table_id,
271 sw_if_index=self.intf.sw_if_index,
272 )
273 )
Neale Ranns59f71132020-04-08 12:19:38 +0000274 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200275 return fib_interface_ip_prefix(
276 self._test, self.addr, self.len, self.intf.sw_if_index
277 ) & find_route(
278 self._test,
279 self.addr,
280 self.host_len,
281 table_id=self.table_id,
282 sw_if_index=self.intf.sw_if_index,
283 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700284
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700285 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200286 return "interface-ip-%s-%d-%s" % (self.intf, self.table_id, self.prefix)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700287
288
Neale Rannsec40a7d2020-04-23 07:36:12 +0000289class VppIp6LinkLocalAddress(VppObject):
Neale Rannsec40a7d2020-04-23 07:36:12 +0000290 def __init__(self, test, intf, addr):
291 self._test = test
292 self.intf = intf
293 self.addr = addr
294
295 def add_vpp_config(self):
296 self._test.vapi.sw_interface_ip6_set_link_local_address(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200297 sw_if_index=self.intf.sw_if_index, ip=self.addr
298 )
Neale Rannsec40a7d2020-04-23 07:36:12 +0000299 self._test.registry.register(self, self._test.logger)
300 return self
301
302 def remove_vpp_config(self):
303 # link locals can't be removed, only changed
304 pass
305
306 def query_vpp_config(self):
307 # no API to query
308 return False
309
310 def object_id(self):
311 return "ip6-link-local-%s-%s" % (self.intf, self.addr)
312
313
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700314class VppIpInterfaceBind(VppObject):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700315 def __init__(self, test, intf, table):
316 self._test = test
317 self.intf = intf
318 self.table = table
319
320 def add_vpp_config(self):
321 if self.table.is_ip6:
322 self.intf.set_table_ip6(self.table.table_id)
323 else:
324 self.intf.set_table_ip4(self.table.table_id)
325 self._test.registry.register(self, self._test.logger)
Neale Ranns59f71132020-04-08 12:19:38 +0000326 return self
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700327
328 def remove_vpp_config(self):
329 if 0 == self.table.table_id:
330 return
331 if self.table.is_ip6:
332 self.intf.set_table_ip6(0)
333 else:
334 self.intf.set_table_ip4(0)
335
336 def query_vpp_config(self):
337 if 0 == self.table.table_id:
338 return False
Klement Sekera77c821c2022-04-14 16:29:07 +0200339 try:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200340 return (
341 self._test.vapi.sw_interface_get_table(
342 self.intf.sw_if_index, self.table.is_ip6
343 ).vrf_id
344 == self.table.table_id
345 )
Klement Sekera77c821c2022-04-14 16:29:07 +0200346 except UnexpectedApiReturnValueError as e:
347 if e.retval == -2: # INVALID_SW_IF_INDEX
348 return False
349 raise
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700350
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700351 def object_id(self):
352 return "interface-bind-%s-%s" % (self.intf, self.table)
353
354
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500355class VppMplsLabel:
Neale Ranns31ed7442018-02-23 05:29:09 -0800356 def __init__(self, value, mode=MplsLspMode.PIPE, ttl=64, exp=0):
357 self.value = value
358 self.mode = mode
359 self.ttl = ttl
360 self.exp = exp
361
362 def encode(self):
363 is_uniform = 0 if self.mode is MplsLspMode.PIPE else 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200364 return {
365 "label": self.value,
366 "ttl": self.ttl,
367 "exp": self.exp,
368 "is_uniform": is_uniform,
369 }
Neale Ranns31ed7442018-02-23 05:29:09 -0800370
Neale Ranns775f73c2018-12-20 03:01:49 -0800371 def __eq__(self, other):
372 if isinstance(other, self.__class__):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200373 return (
374 self.value == other.value
375 and self.ttl == other.ttl
376 and self.exp == other.exp
377 and self.mode == other.mode
378 )
379 elif hasattr(other, "label"):
380 return (
381 self.value == other.label
382 and self.ttl == other.ttl
383 and self.exp == other.exp
384 and (self.mode == MplsLspMode.UNIFORM) == other.is_uniform
385 )
Neale Ranns775f73c2018-12-20 03:01:49 -0800386 else:
387 return False
388
389 def __ne__(self, other):
390 return not (self == other)
391
Neale Ranns31ed7442018-02-23 05:29:09 -0800392
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500393class VppFibPathNextHop:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200394 def __init__(self, addr, via_label=MPLS_LABEL_INVALID, next_hop_id=INVALID_INDEX):
Neale Ranns097fa662018-05-01 05:17:55 -0700395 self.addr = VppIpAddressUnion(addr)
396 self.via_label = via_label
397 self.obj_id = next_hop_id
398
399 def encode(self):
400 if self.via_label is not MPLS_LABEL_INVALID:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200401 return {"via_label": self.via_label}
Neale Ranns097fa662018-05-01 05:17:55 -0700402 if self.obj_id is not INVALID_INDEX:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200403 return {"obj_id": self.obj_id}
Neale Ranns097fa662018-05-01 05:17:55 -0700404 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200405 return {"address": self.addr.encode()}
Neale Ranns097fa662018-05-01 05:17:55 -0700406
407 def proto(self):
408 if self.via_label is MPLS_LABEL_INVALID:
409 return address_proto(self.addr)
410 else:
411 return FibPathProto.FIB_PATH_NH_PROTO_MPLS
412
413 def __eq__(self, other):
414 if not isinstance(other, self.__class__):
415 # try the other instance's __eq__.
416 return NotImplemented
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200417 return (
418 self.addr == other.addr
419 and self.via_label == other.via_label
420 and self.obj_id == other.obj_id
421 )
Neale Ranns097fa662018-05-01 05:17:55 -0700422
423
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500424class VppRoutePath:
Klement Sekerada505f62017-01-04 12:58:53 +0100425 def __init__(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200426 self,
427 nh_addr,
428 nh_sw_if_index,
429 nh_table_id=0,
430 labels=[],
431 nh_via_label=MPLS_LABEL_INVALID,
432 rpf_id=0,
433 next_hop_id=INVALID_INDEX,
434 proto=None,
435 flags=FibPathFlags.FIB_PATH_FLAG_NONE,
436 type=FibPathType.FIB_PATH_TYPE_NORMAL,
437 ):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000438 self.nh_itf = nh_sw_if_index
439 self.nh_table_id = nh_table_id
Neale Rannsad422ed2016-11-02 14:20:04 +0000440 self.nh_labels = labels
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800441 self.weight = 1
442 self.rpf_id = rpf_id
Neale Ranns097fa662018-05-01 05:17:55 -0700443 self.proto = proto
444 self.flags = flags
445 self.type = type
446 self.nh = VppFibPathNextHop(nh_addr, nh_via_label, next_hop_id)
447 if proto is None:
448 self.proto = self.nh.proto()
Neale Ranns31426c62017-05-24 10:32:58 -0700449 else:
Neale Ranns097fa662018-05-01 05:17:55 -0700450 self.proto = proto
Neale Ranns810086d2017-11-05 16:26:46 -0800451 self.next_hop_id = next_hop_id
Neale Ranns177bbdc2016-11-15 09:46:51 +0000452
Neale Ranns097fa662018-05-01 05:17:55 -0700453 def encode_labels(self):
Neale Ranns31ed7442018-02-23 05:29:09 -0800454 lstack = []
455 for l in self.nh_labels:
456 if type(l) == VppMplsLabel:
457 lstack.append(l.encode())
458 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200459 lstack.append({"label": l, "ttl": 255})
460 while len(lstack) < 16:
Neale Ranns097fa662018-05-01 05:17:55 -0700461 lstack.append({})
462
Neale Ranns31ed7442018-02-23 05:29:09 -0800463 return lstack
464
Neale Ranns097fa662018-05-01 05:17:55 -0700465 def encode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200466 return {
467 "weight": 1,
468 "preference": 0,
469 "table_id": self.nh_table_id,
470 "nh": self.nh.encode(),
471 "next_hop_id": self.next_hop_id,
472 "sw_if_index": self.nh_itf,
473 "rpf_id": self.rpf_id,
474 "proto": self.proto,
475 "type": self.type,
476 "flags": self.flags,
477 "n_labels": len(self.nh_labels),
478 "label_stack": self.encode_labels(),
479 }
Neale Ranns2303cb12018-02-21 04:57:17 -0800480
Neale Rannsef90ed02018-09-13 08:45:12 -0700481 def __eq__(self, other):
Neale Ranns775f73c2018-12-20 03:01:49 -0800482 if isinstance(other, self.__class__):
Neale Ranns097fa662018-05-01 05:17:55 -0700483 return self.nh == other.nh
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200484 elif hasattr(other, "sw_if_index"):
Neale Ranns775f73c2018-12-20 03:01:49 -0800485 # vl_api_fib_path_t
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200486 if len(self.nh_labels) != other.n_labels:
Neale Ranns775f73c2018-12-20 03:01:49 -0800487 return False
488 for i in range(len(self.nh_labels)):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200489 if self.nh_labels[i] != other.label_stack[i]:
Neale Ranns775f73c2018-12-20 03:01:49 -0800490 return False
491 return self.nh_itf == other.sw_if_index
492 else:
493 return False
494
495 def __ne__(self, other):
496 return not (self == other)
Neale Rannsef90ed02018-09-13 08:45:12 -0700497
Neale Ranns177bbdc2016-11-15 09:46:51 +0000498
Neale Ranns5a8123b2017-01-26 01:18:23 -0800499class VppMRoutePath(VppRoutePath):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200500 def __init__(
501 self,
502 nh_sw_if_index,
503 flags,
504 nh=None,
505 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
506 type=FibPathType.FIB_PATH_TYPE_NORMAL,
507 bier_imp=INVALID_INDEX,
508 ):
Neale Rannse821ab12017-06-01 07:45:05 -0700509 if not nh:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200510 nh = "::" if proto is FibPathProto.FIB_PATH_NH_PROTO_IP6 else "0.0.0.0"
511 super(VppMRoutePath, self).__init__(
512 nh, nh_sw_if_index, proto=proto, type=type, next_hop_id=bier_imp
513 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000514 self.nh_i_flags = flags
Neale Rannsd792d9c2017-10-21 10:53:20 -0700515 self.bier_imp = bier_imp
Neale Ranns32e1c012016-11-22 17:07:28 +0000516
Neale Ranns097fa662018-05-01 05:17:55 -0700517 def encode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200518 return {
519 "path": super(VppMRoutePath, self).encode(),
520 "itf_flags": self.nh_i_flags,
521 }
Neale Ranns097fa662018-05-01 05:17:55 -0700522
Neale Ranns32e1c012016-11-22 17:07:28 +0000523
Neale Ranns5a8123b2017-01-26 01:18:23 -0800524class VppIpRoute(VppObject):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000525 """
526 IP Route
527 """
528
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200529 def __init__(
530 self, test, dest_addr, dest_addr_len, paths, table_id=0, register=True
531 ):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000532 self._test = test
533 self.paths = paths
Neale Ranns177bbdc2016-11-15 09:46:51 +0000534 self.table_id = table_id
Neale Rannsefd7bc22019-11-11 08:32:34 +0000535 self.prefix = mk_network(dest_addr, dest_addr_len)
Neale Ranns097fa662018-05-01 05:17:55 -0700536 self.register = register
Paul Vinciguerra941da4a2019-06-18 07:57:53 -0400537 self.stats_index = None
Neale Rannsc2ac2352019-07-02 14:33:29 +0000538 self.modified = False
Neale Ranns177bbdc2016-11-15 09:46:51 +0000539
Neale Ranns097fa662018-05-01 05:17:55 -0700540 self.encoded_paths = []
541 for path in self.paths:
542 self.encoded_paths.append(path.encode())
543
544 def __eq__(self, other):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200545 if self.table_id == other.table_id and self.prefix == other.prefix:
Neale Ranns097fa662018-05-01 05:17:55 -0700546 return True
547 return False
548
549 def modify(self, paths):
Neale Ranns69b7aa42017-03-10 03:04:12 -0800550 self.paths = paths
Neale Ranns097fa662018-05-01 05:17:55 -0700551 self.encoded_paths = []
552 for path in self.paths:
553 self.encoded_paths.append(path.encode())
Neale Rannsc2ac2352019-07-02 14:33:29 +0000554 self.modified = True
Neale Ranns097fa662018-05-01 05:17:55 -0700555
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200556 self._test.vapi.ip_route_add_del(
557 route={
558 "table_id": self.table_id,
559 "prefix": self.prefix,
560 "n_paths": len(self.encoded_paths),
561 "paths": self.encoded_paths,
562 },
563 is_add=1,
564 is_multipath=0,
565 )
Neale Ranns69b7aa42017-03-10 03:04:12 -0800566
Neale Ranns177bbdc2016-11-15 09:46:51 +0000567 def add_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700568 r = self._test.vapi.ip_route_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200569 route={
570 "table_id": self.table_id,
571 "prefix": self.prefix,
572 "n_paths": len(self.encoded_paths),
573 "paths": self.encoded_paths,
574 },
Neale Ranns097fa662018-05-01 05:17:55 -0700575 is_add=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200576 is_multipath=0,
577 )
Neale Ranns008dbe12018-09-07 09:32:36 -0700578 self.stats_index = r.stats_index
Neale Ranns097fa662018-05-01 05:17:55 -0700579 if self.register:
580 self._test.registry.register(self, self._test.logger)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000581 return self
Neale Ranns177bbdc2016-11-15 09:46:51 +0000582
583 def remove_vpp_config(self):
Neale Rannsc2ac2352019-07-02 14:33:29 +0000584 # there's no need to issue different deletes for modified routes
585 # we do this only to test the two different ways to delete routes
586 # eiter by passing all the paths to remove and mutlipath=1 or
587 # passing no paths and multipath=0
588 if self.modified:
589 self._test.vapi.ip_route_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200590 route={
591 "table_id": self.table_id,
592 "prefix": self.prefix,
593 "n_paths": len(self.encoded_paths),
594 "paths": self.encoded_paths,
595 },
Neale Rannsc2ac2352019-07-02 14:33:29 +0000596 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200597 is_multipath=1,
598 )
Neale Rannsc2ac2352019-07-02 14:33:29 +0000599 else:
600 self._test.vapi.ip_route_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200601 route={"table_id": self.table_id, "prefix": self.prefix, "n_paths": 0},
Neale Rannsc2ac2352019-07-02 14:33:29 +0000602 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200603 is_multipath=0,
604 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000605
Neale Ranns5a8123b2017-01-26 01:18:23 -0800606 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200607 return find_route(
608 self._test,
609 self.prefix.network_address,
610 self.prefix.prefixlen,
611 self.table_id,
Maxime Peimb0d43392024-04-09 09:08:00 +0200612 ignore_default_route=True,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200613 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000614
Neale Ranns5a8123b2017-01-26 01:18:23 -0800615 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200616 return "%s:table-%d-%s" % (
617 "ip6-route" if self.prefix.version == 6 else "ip-route",
618 self.table_id,
619 self.prefix,
620 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800621
Neale Ranns008dbe12018-09-07 09:32:36 -0700622 def get_stats_to(self):
623 c = self._test.statistics.get_counter("/net/route/to")
624 return c[0][self.stats_index]
625
626 def get_stats_via(self):
627 c = self._test.statistics.get_counter("/net/route/via")
628 return c[0][self.stats_index]
629
Neale Ranns5a8123b2017-01-26 01:18:23 -0800630
Neale Ranns976b2592019-12-04 06:11:00 +0000631class VppIpRouteV2(VppObject):
632 """
633 IP Route V2
634 """
635
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200636 def __init__(
637 self, test, dest_addr, dest_addr_len, paths, table_id=0, register=True, src=0
638 ):
Neale Ranns976b2592019-12-04 06:11:00 +0000639 self._test = test
640 self.paths = paths
641 self.table_id = table_id
642 self.prefix = mk_network(dest_addr, dest_addr_len)
643 self.register = register
644 self.stats_index = None
645 self.modified = False
646 self.src = src
647
648 self.encoded_paths = []
649 for path in self.paths:
650 self.encoded_paths.append(path.encode())
651
652 def __eq__(self, other):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200653 if self.table_id == other.table_id and self.prefix == other.prefix:
Neale Ranns976b2592019-12-04 06:11:00 +0000654 return True
655 return False
656
657 def modify(self, paths):
658 self.paths = paths
659 self.encoded_paths = []
660 for path in self.paths:
661 self.encoded_paths.append(path.encode())
662 self.modified = True
663
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200664 self._test.vapi.ip_route_add_del_v2(
665 route={
666 "table_id": self.table_id,
667 "prefix": self.prefix,
668 "src": self.src,
669 "n_paths": len(self.encoded_paths),
670 "paths": self.encoded_paths,
671 },
672 is_add=1,
673 is_multipath=0,
674 )
Neale Ranns976b2592019-12-04 06:11:00 +0000675
676 def add_vpp_config(self):
677 r = self._test.vapi.ip_route_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200678 route={
679 "table_id": self.table_id,
680 "prefix": self.prefix,
681 "n_paths": len(self.encoded_paths),
682 "paths": self.encoded_paths,
683 "src": self.src,
684 },
Neale Ranns976b2592019-12-04 06:11:00 +0000685 is_add=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200686 is_multipath=0,
687 )
Neale Ranns976b2592019-12-04 06:11:00 +0000688 self.stats_index = r.stats_index
689 if self.register:
690 self._test.registry.register(self, self._test.logger)
691 return self
692
693 def remove_vpp_config(self):
694 # there's no need to issue different deletes for modified routes
695 # we do this only to test the two different ways to delete routes
696 # eiter by passing all the paths to remove and mutlipath=1 or
697 # passing no paths and multipath=0
698 if self.modified:
699 self._test.vapi.ip_route_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200700 route={
701 "table_id": self.table_id,
702 "prefix": self.prefix,
703 "src": self.src,
704 "n_paths": len(self.encoded_paths),
705 "paths": self.encoded_paths,
706 },
Neale Ranns976b2592019-12-04 06:11:00 +0000707 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200708 is_multipath=1,
709 )
Neale Ranns976b2592019-12-04 06:11:00 +0000710 else:
711 self._test.vapi.ip_route_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200712 route={
713 "table_id": self.table_id,
714 "prefix": self.prefix,
715 "src": self.src,
716 "n_paths": 0,
717 },
Neale Ranns976b2592019-12-04 06:11:00 +0000718 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200719 is_multipath=0,
720 )
Neale Ranns976b2592019-12-04 06:11:00 +0000721
722 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200723 return find_route(
724 self._test,
725 self.prefix.network_address,
726 self.prefix.prefixlen,
727 self.table_id,
Maxime Peimb0d43392024-04-09 09:08:00 +0200728 ignore_default_route=True,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200729 )
Neale Ranns976b2592019-12-04 06:11:00 +0000730
731 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200732 return "%s:table-%d-%s" % (
733 "ip6-route" if self.prefix.version == 6 else "ip-route",
734 self.table_id,
735 self.prefix,
736 )
Neale Ranns976b2592019-12-04 06:11:00 +0000737
738 def get_stats_to(self):
739 c = self._test.statistics.get_counter("/net/route/to")
740 return c[0][self.stats_index]
741
742 def get_stats_via(self):
743 c = self._test.statistics.get_counter("/net/route/via")
744 return c[0][self.stats_index]
745
746
Neale Ranns5a8123b2017-01-26 01:18:23 -0800747class VppIpMRoute(VppObject):
Neale Ranns32e1c012016-11-22 17:07:28 +0000748 """
749 IP Multicast Route
750 """
751
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200752 def __init__(
753 self,
754 test,
755 src_addr,
756 grp_addr,
757 grp_addr_len,
758 e_flags,
759 paths,
760 table_id=0,
761 rpf_id=0,
762 ):
Neale Ranns32e1c012016-11-22 17:07:28 +0000763 self._test = test
764 self.paths = paths
Neale Ranns32e1c012016-11-22 17:07:28 +0000765 self.table_id = table_id
766 self.e_flags = e_flags
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800767 self.rpf_id = rpf_id
Neale Ranns32e1c012016-11-22 17:07:28 +0000768
Neale Ranns097fa662018-05-01 05:17:55 -0700769 self.prefix = VppIpMPrefix(src_addr, grp_addr, grp_addr_len)
770 self.encoded_paths = []
771 for path in self.paths:
772 self.encoded_paths.append(path.encode())
Neale Ranns32e1c012016-11-22 17:07:28 +0000773
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400774 def encode(self, paths=None):
775 _paths = self.encoded_paths if paths is None else paths
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200776 return {
777 "table_id": self.table_id,
778 "entry_flags": self.e_flags,
779 "rpf_id": self.rpf_id,
780 "prefix": self.prefix.encode(),
781 "n_paths": len(_paths),
782 "paths": _paths,
783 }
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400784
Neale Ranns32e1c012016-11-22 17:07:28 +0000785 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200786 r = self._test.vapi.ip_mroute_add_del(
787 route=self.encode(), is_multipath=1, is_add=1
788 )
Neale Ranns097fa662018-05-01 05:17:55 -0700789 self.stats_index = r.stats_index
Neale Ranns5a8123b2017-01-26 01:18:23 -0800790 self._test.registry.register(self, self._test.logger)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000791 return self
Neale Ranns32e1c012016-11-22 17:07:28 +0000792
793 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200794 self._test.vapi.ip_mroute_add_del(route=self.encode(), is_multipath=1, is_add=0)
Neale Ranns32e1c012016-11-22 17:07:28 +0000795
796 def update_entry_flags(self, flags):
797 self.e_flags = flags
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200798 self._test.vapi.ip_mroute_add_del(
799 route=self.encode(paths=[]), is_multipath=1, is_add=1
800 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000801
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800802 def update_rpf_id(self, rpf_id):
803 self.rpf_id = rpf_id
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 Ranns0f26c5a2017-03-01 15:12:11 -0800807
Neale Ranns32e1c012016-11-22 17:07:28 +0000808 def update_path_flags(self, itf, flags):
Neale Ranns097fa662018-05-01 05:17:55 -0700809 for p in range(len(self.paths)):
810 if self.paths[p].nh_itf == itf:
811 self.paths[p].nh_i_flags = flags
Paul Vinciguerra6230b9d2020-04-28 11:23:31 -0400812 self.encoded_paths[p] = self.paths[p].encode()
813 break
Neale Ranns097fa662018-05-01 05:17:55 -0700814
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400815 self._test.vapi.ip_mroute_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200816 route=self.encode(paths=[self.encoded_paths[p]]), is_add=1, is_multipath=0
817 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000818
Neale Ranns5a8123b2017-01-26 01:18:23 -0800819 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200820 return find_mroute(
821 self._test,
822 self.prefix.gaddr,
823 self.prefix.saddr,
824 self.prefix.length,
825 self.table_id,
826 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000827
Neale Ranns5a8123b2017-01-26 01:18:23 -0800828 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200829 return "%d:(%s,%s/%d)" % (
830 self.table_id,
831 self.prefix.saddr,
832 self.prefix.gaddr,
833 self.prefix.length,
834 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800835
Neale Ranns28c142e2018-09-07 09:37:07 -0700836 def get_stats(self):
837 c = self._test.statistics.get_counter("/net/mroute")
838 return c[0][self.stats_index]
839
Neale Ranns5a8123b2017-01-26 01:18:23 -0800840
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500841class VppMFibSignal:
Neale Ranns32e1c012016-11-22 17:07:28 +0000842 def __init__(self, test, route, interface, packet):
843 self.route = route
844 self.interface = interface
845 self.packet = packet
846 self.test = test
847
848 def compare(self, signal):
849 self.test.assertEqual(self.interface, signal.sw_if_index)
850 self.test.assertEqual(self.route.table_id, signal.table_id)
Neale Ranns097fa662018-05-01 05:17:55 -0700851 self.test.assertEqual(self.route.prefix, signal.prefix)
Neale Ranns32e1c012016-11-22 17:07:28 +0000852
853
Neale Ranns5a8123b2017-01-26 01:18:23 -0800854class VppMplsIpBind(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000855 """
856 MPLS to IP Binding
857 """
858
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200859 def __init__(
860 self,
861 test,
862 local_label,
863 dest_addr,
864 dest_addr_len,
865 table_id=0,
866 ip_table_id=0,
867 is_ip6=0,
868 ):
Neale Rannsad422ed2016-11-02 14:20:04 +0000869 self._test = test
Neale Rannsad422ed2016-11-02 14:20:04 +0000870 self.dest_addr_len = dest_addr_len
Neale Rannsf12a83f2017-04-18 09:09:40 -0700871 self.dest_addr = dest_addr
Neale Ranns097fa662018-05-01 05:17:55 -0700872 self.ip_addr = ip_address(text_type(dest_addr))
Neale Rannsad422ed2016-11-02 14:20:04 +0000873 self.local_label = local_label
Neale Ranns5a8123b2017-01-26 01:18:23 -0800874 self.table_id = table_id
875 self.ip_table_id = ip_table_id
Neale Rannsefd7bc22019-11-11 08:32:34 +0000876 self.prefix = mk_network(dest_addr, dest_addr_len)
Neale Rannsad422ed2016-11-02 14:20:04 +0000877
878 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200879 self._test.vapi.mpls_ip_bind_unbind(
880 self.local_label,
881 self.prefix,
882 table_id=self.table_id,
883 ip_table_id=self.ip_table_id,
884 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800885 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000886
887 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200888 self._test.vapi.mpls_ip_bind_unbind(
889 self.local_label,
890 self.prefix,
891 table_id=self.table_id,
892 ip_table_id=self.ip_table_id,
893 is_bind=0,
894 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000895
Neale Ranns5a8123b2017-01-26 01:18:23 -0800896 def query_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700897 dump = self._test.vapi.mpls_route_dump(self.table_id)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800898 for e in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200899 if (
900 self.local_label == e.mr_route.mr_label
901 and self.table_id == e.mr_route.mr_table_id
902 ):
Neale Ranns5a8123b2017-01-26 01:18:23 -0800903 return True
904 return False
Neale Rannsad422ed2016-11-02 14:20:04 +0000905
Neale Ranns5a8123b2017-01-26 01:18:23 -0800906 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200907 return "%d:%s binds %d:%s/%d" % (
908 self.table_id,
909 self.local_label,
910 self.ip_table_id,
911 self.dest_addr,
912 self.dest_addr_len,
913 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800914
915
Neale Ranns15002542017-09-10 04:39:11 -0700916class VppMplsTable(VppObject):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200917 def __init__(self, test, table_id):
Neale Ranns15002542017-09-10 04:39:11 -0700918 self._test = test
919 self.table_id = table_id
920
921 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200922 self._test.vapi.mpls_table_add_del(self.table_id, is_add=1)
Neale Ranns15002542017-09-10 04:39:11 -0700923 self._test.registry.register(self, self._test.logger)
924
925 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200926 self._test.vapi.mpls_table_add_del(self.table_id, is_add=0)
Neale Ranns15002542017-09-10 04:39:11 -0700927
928 def query_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700929 dump = self._test.vapi.mpls_table_dump()
930 for d in dump:
931 if d.mt_table.mt_table_id == self.table_id:
932 return True
Neale Ranns15002542017-09-10 04:39:11 -0700933 return False
934
Neale Ranns15002542017-09-10 04:39:11 -0700935 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200936 return "table-mpls-%d" % (self.table_id)
Neale Ranns15002542017-09-10 04:39:11 -0700937
938
Neale Ranns5a8123b2017-01-26 01:18:23 -0800939class VppMplsRoute(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000940 """
Neale Ranns5a8123b2017-01-26 01:18:23 -0800941 MPLS Route/LSP
Neale Rannsad422ed2016-11-02 14:20:04 +0000942 """
943
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200944 def __init__(
945 self,
946 test,
947 local_label,
948 eos_bit,
949 paths,
950 table_id=0,
951 is_multicast=0,
952 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
953 ):
Neale Rannsad422ed2016-11-02 14:20:04 +0000954 self._test = test
955 self.paths = paths
956 self.local_label = local_label
957 self.eos_bit = eos_bit
Neale Ranns097fa662018-05-01 05:17:55 -0700958 self.eos_proto = eos_proto
Neale Rannsad422ed2016-11-02 14:20:04 +0000959 self.table_id = table_id
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800960 self.is_multicast = is_multicast
Neale Rannsad422ed2016-11-02 14:20:04 +0000961
962 def add_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700963 paths = []
Neale Rannsad422ed2016-11-02 14:20:04 +0000964 for path in self.paths:
Neale Ranns097fa662018-05-01 05:17:55 -0700965 paths.append(path.encode())
Neale Ranns31ed7442018-02-23 05:29:09 -0800966
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200967 r = self._test.vapi.mpls_route_add_del(
968 self.table_id,
969 self.local_label,
970 self.eos_bit,
971 self.eos_proto,
972 self.is_multicast,
973 paths,
974 1,
975 0,
976 )
Neale Ranns008dbe12018-09-07 09:32:36 -0700977 self.stats_index = r.stats_index
Neale Ranns5a8123b2017-01-26 01:18:23 -0800978 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000979
980 def remove_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700981 paths = []
Neale Rannsad422ed2016-11-02 14:20:04 +0000982 for path in self.paths:
Neale Ranns097fa662018-05-01 05:17:55 -0700983 paths.append(path.encode())
984
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200985 self._test.vapi.mpls_route_add_del(
986 self.table_id,
987 self.local_label,
988 self.eos_bit,
989 self.eos_proto,
990 self.is_multicast,
991 paths,
992 0,
993 0,
994 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800995
996 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200997 return find_mpls_route(
998 self._test, self.table_id, self.local_label, self.eos_bit
999 )
Neale Ranns5a8123b2017-01-26 01:18:23 -08001000
Neale Ranns5a8123b2017-01-26 01:18:23 -08001001 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +02001002 return "mpls-route-%d:%s/%d" % (
1003 self.table_id,
1004 self.local_label,
1005 20 + self.eos_bit,
1006 )
Neale Ranns008dbe12018-09-07 09:32:36 -07001007
1008 def get_stats_to(self):
1009 c = self._test.statistics.get_counter("/net/route/to")
1010 return c[0][self.stats_index]
1011
1012 def get_stats_via(self):
1013 c = self._test.statistics.get_counter("/net/route/via")
1014 return c[0][self.stats_index]