blob: 06a963cfd88b37292edf79a1996da76d36f39dd5 [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
Neale Ranns59f71132020-04-08 12:19:38 +000078def find_route(test, addr, len, table_id=0, sw_if_index=None):
Neale Rannsefd7bc22019-11-11 08:32:34 +000079 prefix = mk_network(addr, len)
Neale Ranns097fa662018-05-01 05:17:55 -070080
Ole Troan6e6ad642020-02-04 13:28:13 +010081 if 4 == prefix.version:
Neale Ranns097fa662018-05-01 05:17:55 -070082 routes = test.vapi.ip_route_dump(table_id, False)
Neale Ranns097fa662018-05-01 05:17:55 -070083 else:
84 routes = test.vapi.ip_route_dump(table_id, True)
Neale Ranns097fa662018-05-01 05:17:55 -070085
Neale Rannsb3b2de72017-03-08 05:17:22 -080086 for e in routes:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020087 if table_id == e.route.table_id and str(e.route.prefix) == str(prefix):
Neale Ranns59f71132020-04-08 12:19:38 +000088 if not sw_if_index:
89 return True
90 else:
91 # should be only one path if the user is looking
92 # for the interface the route is reachable through
93 if e.route.n_paths != 1:
94 return False
95 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020096 return e.route.paths[0].sw_if_index == sw_if_index
Neale Ranns59f71132020-04-08 12:19:38 +000097
Neale Rannsb3b2de72017-03-08 05:17:22 -080098 return False
99
100
Neale Ranns9db6ada2019-11-08 12:42:31 +0000101def find_route_in_dump(dump, route, table):
102 for r in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200103 if table.table_id == r.route.table_id and route.prefix == r.route.prefix:
Neale Ranns9db6ada2019-11-08 12:42:31 +0000104 if len(route.paths) == r.route.n_paths:
105 return True
106 return False
107
108
109def find_mroute_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 return True
113 return False
114
115
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200116def find_mroute(test, grp_addr, src_addr, grp_addr_len, table_id=0):
117 ip_mprefix = VppIpMPrefix(text_type(src_addr), text_type(grp_addr), grp_addr_len)
Neale Ranns097fa662018-05-01 05:17:55 -0700118
Ole Troan6e6ad642020-02-04 13:28:13 +0100119 if 4 == ip_mprefix.version:
Neale Ranns097fa662018-05-01 05:17:55 -0700120 routes = test.vapi.ip_mroute_dump(table_id, False)
Neale Ranns947ea622018-06-07 23:48:20 -0700121 else:
Neale Ranns097fa662018-05-01 05:17:55 -0700122 routes = test.vapi.ip_mroute_dump(table_id, True)
123
Neale Ranns947ea622018-06-07 23:48:20 -0700124 for e in routes:
Neale Ranns097fa662018-05-01 05:17:55 -0700125 if table_id == e.route.table_id and ip_mprefix == e.route.prefix:
Neale Ranns947ea622018-06-07 23:48:20 -0700126 return True
127 return False
128
129
Neale Ranns775f73c2018-12-20 03:01:49 -0800130def find_mpls_route(test, table_id, label, eos_bit, paths=None):
Neale Ranns097fa662018-05-01 05:17:55 -0700131 dump = test.vapi.mpls_route_dump(table_id)
Neale Ranns775f73c2018-12-20 03:01:49 -0800132 for e in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200133 if (
134 label == e.mr_route.mr_label
135 and eos_bit == e.mr_route.mr_eos
136 and table_id == e.mr_route.mr_table_id
137 ):
Neale Ranns775f73c2018-12-20 03:01:49 -0800138 if not paths:
139 return True
140 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200141 if len(paths) != len(e.mr_route.mr_paths):
Neale Ranns775f73c2018-12-20 03:01:49 -0800142 return False
143 for i in range(len(paths)):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200144 if paths[i] != e.mr_route.mr_paths[i]:
Neale Ranns775f73c2018-12-20 03:01:49 -0800145 return False
146 return True
147 return False
148
149
Neale Rannsefd7bc22019-11-11 08:32:34 +0000150def fib_interface_ip_prefix(test, addr, len, sw_if_index):
151 # can't use python net here since we need the host bits in the prefix
152 prefix = "%s/%d" % (addr, len)
153 addrs = test.vapi.ip_address_dump(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200154 sw_if_index, is_ipv6=(6 == ip_address(addr).version)
155 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700156
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700157 for a in addrs:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200158 if a.sw_if_index == sw_if_index and str(a.prefix) == prefix:
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700159 return True
160 return False
161
162
Neale Ranns15002542017-09-10 04:39:11 -0700163class VppIpTable(VppObject):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200164 def __init__(self, test, table_id, is_ip6=0, register=True):
Neale Ranns15002542017-09-10 04:39:11 -0700165 self._test = test
166 self.table_id = table_id
167 self.is_ip6 = is_ip6
Neale Ranns256b67b2020-09-02 14:46:53 +0000168 self.register = register
Neale Ranns15002542017-09-10 04:39:11 -0700169
170 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200171 self._test.vapi.ip_table_add_del(
172 is_add=1, table={"is_ip6": self.is_ip6, "table_id": self.table_id}
173 )
Neale Ranns256b67b2020-09-02 14:46:53 +0000174 if self.register:
175 self._test.registry.register(self, self._test.logger)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000176 return self
Neale Ranns15002542017-09-10 04:39:11 -0700177
178 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200179 self._test.vapi.ip_table_add_del(
180 is_add=0, table={"is_ip6": self.is_ip6, "table_id": self.table_id}
181 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000182
183 def replace_begin(self):
184 self._test.vapi.ip_table_replace_begin(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200185 table={"is_ip6": self.is_ip6, "table_id": self.table_id}
186 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000187
188 def replace_end(self):
189 self._test.vapi.ip_table_replace_end(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200190 table={"is_ip6": self.is_ip6, "table_id": self.table_id}
191 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000192
193 def flush(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200194 self._test.vapi.ip_table_flush(
195 table={"is_ip6": self.is_ip6, "table_id": self.table_id}
196 )
Neale Ranns9db6ada2019-11-08 12:42:31 +0000197
198 def dump(self):
199 return self._test.vapi.ip_route_dump(self.table_id, self.is_ip6)
200
201 def mdump(self):
202 return self._test.vapi.ip_mroute_dump(self.table_id, self.is_ip6)
Neale Ranns15002542017-09-10 04:39:11 -0700203
204 def query_vpp_config(self):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700205 if self.table_id == 0:
206 # the default table always exists
207 return False
Neale Ranns15002542017-09-10 04:39:11 -0700208 # find the default route
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200209 return find_route(
210 self._test, "::" if self.is_ip6 else "0.0.0.0", 0, self.table_id
211 )
Neale Ranns15002542017-09-10 04:39:11 -0700212
Neale Ranns15002542017-09-10 04:39:11 -0700213 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200214 return "table-%s-%d" % ("v6" if self.is_ip6 == 1 else "v4", self.table_id)
Neale Ranns15002542017-09-10 04:39:11 -0700215
216
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700217class VppIpInterfaceAddress(VppObject):
Neale Ranns59f71132020-04-08 12:19:38 +0000218 def __init__(self, test, intf, addr, len, bind=None):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700219 self._test = test
220 self.intf = intf
Neale Rannsefd7bc22019-11-11 08:32:34 +0000221 self.addr = addr
222 self.len = len
223 self.prefix = "%s/%d" % (addr, len)
Neale Ranns59f71132020-04-08 12:19:38 +0000224 self.host_len = ip_network(self.prefix, strict=False).max_prefixlen
225 self.table_id = 0
226 if bind:
227 self.table_id = bind.table.table_id
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700228
229 def add_vpp_config(self):
230 self._test.vapi.sw_interface_add_del_address(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200231 sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=1
232 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700233 self._test.registry.register(self, self._test.logger)
Neale Ranns9efcee62019-11-26 19:30:08 +0000234 return self
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700235
236 def remove_vpp_config(self):
237 self._test.vapi.sw_interface_add_del_address(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200238 sw_if_index=self.intf.sw_if_index, prefix=self.prefix, is_add=0
239 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700240
241 def query_vpp_config(self):
Neale Ranns59f71132020-04-08 12:19:38 +0000242 # search for the IP address mapping and the two expected
243 # FIB entries
244 v = ip_address(self.addr).version
245
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200246 if (v == 4 and self.len < 31) or (v == 6 and self.len < 127):
247 return (
248 fib_interface_ip_prefix(
249 self._test, self.addr, self.len, self.intf.sw_if_index
250 )
251 & find_route(
252 self._test,
253 self.addr,
254 self.len,
255 table_id=self.table_id,
256 sw_if_index=self.intf.sw_if_index,
257 )
258 & find_route(
259 self._test,
260 self.addr,
261 self.host_len,
262 table_id=self.table_id,
263 sw_if_index=self.intf.sw_if_index,
264 )
265 )
Neale Ranns59f71132020-04-08 12:19:38 +0000266 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200267 return fib_interface_ip_prefix(
268 self._test, self.addr, self.len, self.intf.sw_if_index
269 ) & find_route(
270 self._test,
271 self.addr,
272 self.host_len,
273 table_id=self.table_id,
274 sw_if_index=self.intf.sw_if_index,
275 )
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700276
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700277 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200278 return "interface-ip-%s-%d-%s" % (self.intf, self.table_id, self.prefix)
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700279
280
Neale Rannsec40a7d2020-04-23 07:36:12 +0000281class VppIp6LinkLocalAddress(VppObject):
Neale Rannsec40a7d2020-04-23 07:36:12 +0000282 def __init__(self, test, intf, addr):
283 self._test = test
284 self.intf = intf
285 self.addr = addr
286
287 def add_vpp_config(self):
288 self._test.vapi.sw_interface_ip6_set_link_local_address(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200289 sw_if_index=self.intf.sw_if_index, ip=self.addr
290 )
Neale Rannsec40a7d2020-04-23 07:36:12 +0000291 self._test.registry.register(self, self._test.logger)
292 return self
293
294 def remove_vpp_config(self):
295 # link locals can't be removed, only changed
296 pass
297
298 def query_vpp_config(self):
299 # no API to query
300 return False
301
302 def object_id(self):
303 return "ip6-link-local-%s-%s" % (self.intf, self.addr)
304
305
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700306class VppIpInterfaceBind(VppObject):
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700307 def __init__(self, test, intf, table):
308 self._test = test
309 self.intf = intf
310 self.table = table
311
312 def add_vpp_config(self):
313 if self.table.is_ip6:
314 self.intf.set_table_ip6(self.table.table_id)
315 else:
316 self.intf.set_table_ip4(self.table.table_id)
317 self._test.registry.register(self, self._test.logger)
Neale Ranns59f71132020-04-08 12:19:38 +0000318 return self
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700319
320 def remove_vpp_config(self):
321 if 0 == self.table.table_id:
322 return
323 if self.table.is_ip6:
324 self.intf.set_table_ip6(0)
325 else:
326 self.intf.set_table_ip4(0)
327
328 def query_vpp_config(self):
329 if 0 == self.table.table_id:
330 return False
Klement Sekera77c821c2022-04-14 16:29:07 +0200331 try:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200332 return (
333 self._test.vapi.sw_interface_get_table(
334 self.intf.sw_if_index, self.table.is_ip6
335 ).vrf_id
336 == self.table.table_id
337 )
Klement Sekera77c821c2022-04-14 16:29:07 +0200338 except UnexpectedApiReturnValueError as e:
339 if e.retval == -2: # INVALID_SW_IF_INDEX
340 return False
341 raise
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700342
Neale Ranns93cc3ee2018-10-10 07:22:51 -0700343 def object_id(self):
344 return "interface-bind-%s-%s" % (self.intf, self.table)
345
346
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500347class VppMplsLabel:
Neale Ranns31ed7442018-02-23 05:29:09 -0800348 def __init__(self, value, mode=MplsLspMode.PIPE, ttl=64, exp=0):
349 self.value = value
350 self.mode = mode
351 self.ttl = ttl
352 self.exp = exp
353
354 def encode(self):
355 is_uniform = 0 if self.mode is MplsLspMode.PIPE else 1
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200356 return {
357 "label": self.value,
358 "ttl": self.ttl,
359 "exp": self.exp,
360 "is_uniform": is_uniform,
361 }
Neale Ranns31ed7442018-02-23 05:29:09 -0800362
Neale Ranns775f73c2018-12-20 03:01:49 -0800363 def __eq__(self, other):
364 if isinstance(other, self.__class__):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200365 return (
366 self.value == other.value
367 and self.ttl == other.ttl
368 and self.exp == other.exp
369 and self.mode == other.mode
370 )
371 elif hasattr(other, "label"):
372 return (
373 self.value == other.label
374 and self.ttl == other.ttl
375 and self.exp == other.exp
376 and (self.mode == MplsLspMode.UNIFORM) == other.is_uniform
377 )
Neale Ranns775f73c2018-12-20 03:01:49 -0800378 else:
379 return False
380
381 def __ne__(self, other):
382 return not (self == other)
383
Neale Ranns31ed7442018-02-23 05:29:09 -0800384
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500385class VppFibPathNextHop:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200386 def __init__(self, addr, via_label=MPLS_LABEL_INVALID, next_hop_id=INVALID_INDEX):
Neale Ranns097fa662018-05-01 05:17:55 -0700387 self.addr = VppIpAddressUnion(addr)
388 self.via_label = via_label
389 self.obj_id = next_hop_id
390
391 def encode(self):
392 if self.via_label is not MPLS_LABEL_INVALID:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200393 return {"via_label": self.via_label}
Neale Ranns097fa662018-05-01 05:17:55 -0700394 if self.obj_id is not INVALID_INDEX:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200395 return {"obj_id": self.obj_id}
Neale Ranns097fa662018-05-01 05:17:55 -0700396 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200397 return {"address": self.addr.encode()}
Neale Ranns097fa662018-05-01 05:17:55 -0700398
399 def proto(self):
400 if self.via_label is MPLS_LABEL_INVALID:
401 return address_proto(self.addr)
402 else:
403 return FibPathProto.FIB_PATH_NH_PROTO_MPLS
404
405 def __eq__(self, other):
406 if not isinstance(other, self.__class__):
407 # try the other instance's __eq__.
408 return NotImplemented
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200409 return (
410 self.addr == other.addr
411 and self.via_label == other.via_label
412 and self.obj_id == other.obj_id
413 )
Neale Ranns097fa662018-05-01 05:17:55 -0700414
415
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500416class VppRoutePath:
Klement Sekerada505f62017-01-04 12:58:53 +0100417 def __init__(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200418 self,
419 nh_addr,
420 nh_sw_if_index,
421 nh_table_id=0,
422 labels=[],
423 nh_via_label=MPLS_LABEL_INVALID,
424 rpf_id=0,
425 next_hop_id=INVALID_INDEX,
426 proto=None,
427 flags=FibPathFlags.FIB_PATH_FLAG_NONE,
428 type=FibPathType.FIB_PATH_TYPE_NORMAL,
429 ):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000430 self.nh_itf = nh_sw_if_index
431 self.nh_table_id = nh_table_id
Neale Rannsad422ed2016-11-02 14:20:04 +0000432 self.nh_labels = labels
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800433 self.weight = 1
434 self.rpf_id = rpf_id
Neale Ranns097fa662018-05-01 05:17:55 -0700435 self.proto = proto
436 self.flags = flags
437 self.type = type
438 self.nh = VppFibPathNextHop(nh_addr, nh_via_label, next_hop_id)
439 if proto is None:
440 self.proto = self.nh.proto()
Neale Ranns31426c62017-05-24 10:32:58 -0700441 else:
Neale Ranns097fa662018-05-01 05:17:55 -0700442 self.proto = proto
Neale Ranns810086d2017-11-05 16:26:46 -0800443 self.next_hop_id = next_hop_id
Neale Ranns177bbdc2016-11-15 09:46:51 +0000444
Neale Ranns097fa662018-05-01 05:17:55 -0700445 def encode_labels(self):
Neale Ranns31ed7442018-02-23 05:29:09 -0800446 lstack = []
447 for l in self.nh_labels:
448 if type(l) == VppMplsLabel:
449 lstack.append(l.encode())
450 else:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200451 lstack.append({"label": l, "ttl": 255})
452 while len(lstack) < 16:
Neale Ranns097fa662018-05-01 05:17:55 -0700453 lstack.append({})
454
Neale Ranns31ed7442018-02-23 05:29:09 -0800455 return lstack
456
Neale Ranns097fa662018-05-01 05:17:55 -0700457 def encode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200458 return {
459 "weight": 1,
460 "preference": 0,
461 "table_id": self.nh_table_id,
462 "nh": self.nh.encode(),
463 "next_hop_id": self.next_hop_id,
464 "sw_if_index": self.nh_itf,
465 "rpf_id": self.rpf_id,
466 "proto": self.proto,
467 "type": self.type,
468 "flags": self.flags,
469 "n_labels": len(self.nh_labels),
470 "label_stack": self.encode_labels(),
471 }
Neale Ranns2303cb12018-02-21 04:57:17 -0800472
Neale Rannsef90ed02018-09-13 08:45:12 -0700473 def __eq__(self, other):
Neale Ranns775f73c2018-12-20 03:01:49 -0800474 if isinstance(other, self.__class__):
Neale Ranns097fa662018-05-01 05:17:55 -0700475 return self.nh == other.nh
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200476 elif hasattr(other, "sw_if_index"):
Neale Ranns775f73c2018-12-20 03:01:49 -0800477 # vl_api_fib_path_t
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200478 if len(self.nh_labels) != other.n_labels:
Neale Ranns775f73c2018-12-20 03:01:49 -0800479 return False
480 for i in range(len(self.nh_labels)):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200481 if self.nh_labels[i] != other.label_stack[i]:
Neale Ranns775f73c2018-12-20 03:01:49 -0800482 return False
483 return self.nh_itf == other.sw_if_index
484 else:
485 return False
486
487 def __ne__(self, other):
488 return not (self == other)
Neale Rannsef90ed02018-09-13 08:45:12 -0700489
Neale Ranns177bbdc2016-11-15 09:46:51 +0000490
Neale Ranns5a8123b2017-01-26 01:18:23 -0800491class VppMRoutePath(VppRoutePath):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200492 def __init__(
493 self,
494 nh_sw_if_index,
495 flags,
496 nh=None,
497 proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
498 type=FibPathType.FIB_PATH_TYPE_NORMAL,
499 bier_imp=INVALID_INDEX,
500 ):
Neale Rannse821ab12017-06-01 07:45:05 -0700501 if not nh:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200502 nh = "::" if proto is FibPathProto.FIB_PATH_NH_PROTO_IP6 else "0.0.0.0"
503 super(VppMRoutePath, self).__init__(
504 nh, nh_sw_if_index, proto=proto, type=type, next_hop_id=bier_imp
505 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000506 self.nh_i_flags = flags
Neale Rannsd792d9c2017-10-21 10:53:20 -0700507 self.bier_imp = bier_imp
Neale Ranns32e1c012016-11-22 17:07:28 +0000508
Neale Ranns097fa662018-05-01 05:17:55 -0700509 def encode(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200510 return {
511 "path": super(VppMRoutePath, self).encode(),
512 "itf_flags": self.nh_i_flags,
513 }
Neale Ranns097fa662018-05-01 05:17:55 -0700514
Neale Ranns32e1c012016-11-22 17:07:28 +0000515
Neale Ranns5a8123b2017-01-26 01:18:23 -0800516class VppIpRoute(VppObject):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000517 """
518 IP Route
519 """
520
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200521 def __init__(
522 self, test, dest_addr, dest_addr_len, paths, table_id=0, register=True
523 ):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000524 self._test = test
525 self.paths = paths
Neale Ranns177bbdc2016-11-15 09:46:51 +0000526 self.table_id = table_id
Neale Rannsefd7bc22019-11-11 08:32:34 +0000527 self.prefix = mk_network(dest_addr, dest_addr_len)
Neale Ranns097fa662018-05-01 05:17:55 -0700528 self.register = register
Paul Vinciguerra941da4a2019-06-18 07:57:53 -0400529 self.stats_index = None
Neale Rannsc2ac2352019-07-02 14:33:29 +0000530 self.modified = False
Neale Ranns177bbdc2016-11-15 09:46:51 +0000531
Neale Ranns097fa662018-05-01 05:17:55 -0700532 self.encoded_paths = []
533 for path in self.paths:
534 self.encoded_paths.append(path.encode())
535
536 def __eq__(self, other):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200537 if self.table_id == other.table_id and self.prefix == other.prefix:
Neale Ranns097fa662018-05-01 05:17:55 -0700538 return True
539 return False
540
541 def modify(self, paths):
Neale Ranns69b7aa42017-03-10 03:04:12 -0800542 self.paths = paths
Neale Ranns097fa662018-05-01 05:17:55 -0700543 self.encoded_paths = []
544 for path in self.paths:
545 self.encoded_paths.append(path.encode())
Neale Rannsc2ac2352019-07-02 14:33:29 +0000546 self.modified = True
Neale Ranns097fa662018-05-01 05:17:55 -0700547
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200548 self._test.vapi.ip_route_add_del(
549 route={
550 "table_id": self.table_id,
551 "prefix": self.prefix,
552 "n_paths": len(self.encoded_paths),
553 "paths": self.encoded_paths,
554 },
555 is_add=1,
556 is_multipath=0,
557 )
Neale Ranns69b7aa42017-03-10 03:04:12 -0800558
Neale Ranns177bbdc2016-11-15 09:46:51 +0000559 def add_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700560 r = self._test.vapi.ip_route_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200561 route={
562 "table_id": self.table_id,
563 "prefix": self.prefix,
564 "n_paths": len(self.encoded_paths),
565 "paths": self.encoded_paths,
566 },
Neale Ranns097fa662018-05-01 05:17:55 -0700567 is_add=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200568 is_multipath=0,
569 )
Neale Ranns008dbe12018-09-07 09:32:36 -0700570 self.stats_index = r.stats_index
Neale Ranns097fa662018-05-01 05:17:55 -0700571 if self.register:
572 self._test.registry.register(self, self._test.logger)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000573 return self
Neale Ranns177bbdc2016-11-15 09:46:51 +0000574
575 def remove_vpp_config(self):
Neale Rannsc2ac2352019-07-02 14:33:29 +0000576 # there's no need to issue different deletes for modified routes
577 # we do this only to test the two different ways to delete routes
578 # eiter by passing all the paths to remove and mutlipath=1 or
579 # passing no paths and multipath=0
580 if self.modified:
581 self._test.vapi.ip_route_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200582 route={
583 "table_id": self.table_id,
584 "prefix": self.prefix,
585 "n_paths": len(self.encoded_paths),
586 "paths": self.encoded_paths,
587 },
Neale Rannsc2ac2352019-07-02 14:33:29 +0000588 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200589 is_multipath=1,
590 )
Neale Rannsc2ac2352019-07-02 14:33:29 +0000591 else:
592 self._test.vapi.ip_route_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200593 route={"table_id": self.table_id, "prefix": self.prefix, "n_paths": 0},
Neale Rannsc2ac2352019-07-02 14:33:29 +0000594 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200595 is_multipath=0,
596 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000597
Neale Ranns5a8123b2017-01-26 01:18:23 -0800598 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200599 return find_route(
600 self._test,
601 self.prefix.network_address,
602 self.prefix.prefixlen,
603 self.table_id,
604 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000605
Neale Ranns5a8123b2017-01-26 01:18:23 -0800606 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200607 return "%s:table-%d-%s" % (
608 "ip6-route" if self.prefix.version == 6 else "ip-route",
609 self.table_id,
610 self.prefix,
611 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800612
Neale Ranns008dbe12018-09-07 09:32:36 -0700613 def get_stats_to(self):
614 c = self._test.statistics.get_counter("/net/route/to")
615 return c[0][self.stats_index]
616
617 def get_stats_via(self):
618 c = self._test.statistics.get_counter("/net/route/via")
619 return c[0][self.stats_index]
620
Neale Ranns5a8123b2017-01-26 01:18:23 -0800621
Neale Ranns976b2592019-12-04 06:11:00 +0000622class VppIpRouteV2(VppObject):
623 """
624 IP Route V2
625 """
626
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200627 def __init__(
628 self, test, dest_addr, dest_addr_len, paths, table_id=0, register=True, src=0
629 ):
Neale Ranns976b2592019-12-04 06:11:00 +0000630 self._test = test
631 self.paths = paths
632 self.table_id = table_id
633 self.prefix = mk_network(dest_addr, dest_addr_len)
634 self.register = register
635 self.stats_index = None
636 self.modified = False
637 self.src = src
638
639 self.encoded_paths = []
640 for path in self.paths:
641 self.encoded_paths.append(path.encode())
642
643 def __eq__(self, other):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200644 if self.table_id == other.table_id and self.prefix == other.prefix:
Neale Ranns976b2592019-12-04 06:11:00 +0000645 return True
646 return False
647
648 def modify(self, paths):
649 self.paths = paths
650 self.encoded_paths = []
651 for path in self.paths:
652 self.encoded_paths.append(path.encode())
653 self.modified = True
654
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200655 self._test.vapi.ip_route_add_del_v2(
656 route={
657 "table_id": self.table_id,
658 "prefix": self.prefix,
659 "src": self.src,
660 "n_paths": len(self.encoded_paths),
661 "paths": self.encoded_paths,
662 },
663 is_add=1,
664 is_multipath=0,
665 )
Neale Ranns976b2592019-12-04 06:11:00 +0000666
667 def add_vpp_config(self):
668 r = self._test.vapi.ip_route_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200669 route={
670 "table_id": self.table_id,
671 "prefix": self.prefix,
672 "n_paths": len(self.encoded_paths),
673 "paths": self.encoded_paths,
674 "src": self.src,
675 },
Neale Ranns976b2592019-12-04 06:11:00 +0000676 is_add=1,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200677 is_multipath=0,
678 )
Neale Ranns976b2592019-12-04 06:11:00 +0000679 self.stats_index = r.stats_index
680 if self.register:
681 self._test.registry.register(self, self._test.logger)
682 return self
683
684 def remove_vpp_config(self):
685 # there's no need to issue different deletes for modified routes
686 # we do this only to test the two different ways to delete routes
687 # eiter by passing all the paths to remove and mutlipath=1 or
688 # passing no paths and multipath=0
689 if self.modified:
690 self._test.vapi.ip_route_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200691 route={
692 "table_id": self.table_id,
693 "prefix": self.prefix,
694 "src": self.src,
695 "n_paths": len(self.encoded_paths),
696 "paths": self.encoded_paths,
697 },
Neale Ranns976b2592019-12-04 06:11:00 +0000698 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200699 is_multipath=1,
700 )
Neale Ranns976b2592019-12-04 06:11:00 +0000701 else:
702 self._test.vapi.ip_route_add_del_v2(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200703 route={
704 "table_id": self.table_id,
705 "prefix": self.prefix,
706 "src": self.src,
707 "n_paths": 0,
708 },
Neale Ranns976b2592019-12-04 06:11:00 +0000709 is_add=0,
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200710 is_multipath=0,
711 )
Neale Ranns976b2592019-12-04 06:11:00 +0000712
713 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200714 return find_route(
715 self._test,
716 self.prefix.network_address,
717 self.prefix.prefixlen,
718 self.table_id,
719 )
Neale Ranns976b2592019-12-04 06:11:00 +0000720
721 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200722 return "%s:table-%d-%s" % (
723 "ip6-route" if self.prefix.version == 6 else "ip-route",
724 self.table_id,
725 self.prefix,
726 )
Neale Ranns976b2592019-12-04 06:11:00 +0000727
728 def get_stats_to(self):
729 c = self._test.statistics.get_counter("/net/route/to")
730 return c[0][self.stats_index]
731
732 def get_stats_via(self):
733 c = self._test.statistics.get_counter("/net/route/via")
734 return c[0][self.stats_index]
735
736
Neale Ranns5a8123b2017-01-26 01:18:23 -0800737class VppIpMRoute(VppObject):
Neale Ranns32e1c012016-11-22 17:07:28 +0000738 """
739 IP Multicast Route
740 """
741
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200742 def __init__(
743 self,
744 test,
745 src_addr,
746 grp_addr,
747 grp_addr_len,
748 e_flags,
749 paths,
750 table_id=0,
751 rpf_id=0,
752 ):
Neale Ranns32e1c012016-11-22 17:07:28 +0000753 self._test = test
754 self.paths = paths
Neale Ranns32e1c012016-11-22 17:07:28 +0000755 self.table_id = table_id
756 self.e_flags = e_flags
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800757 self.rpf_id = rpf_id
Neale Ranns32e1c012016-11-22 17:07:28 +0000758
Neale Ranns097fa662018-05-01 05:17:55 -0700759 self.prefix = VppIpMPrefix(src_addr, grp_addr, grp_addr_len)
760 self.encoded_paths = []
761 for path in self.paths:
762 self.encoded_paths.append(path.encode())
Neale Ranns32e1c012016-11-22 17:07:28 +0000763
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400764 def encode(self, paths=None):
765 _paths = self.encoded_paths if paths is None else paths
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200766 return {
767 "table_id": self.table_id,
768 "entry_flags": self.e_flags,
769 "rpf_id": self.rpf_id,
770 "prefix": self.prefix.encode(),
771 "n_paths": len(_paths),
772 "paths": _paths,
773 }
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400774
Neale Ranns32e1c012016-11-22 17:07:28 +0000775 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200776 r = self._test.vapi.ip_mroute_add_del(
777 route=self.encode(), is_multipath=1, is_add=1
778 )
Neale Ranns097fa662018-05-01 05:17:55 -0700779 self.stats_index = r.stats_index
Neale Ranns5a8123b2017-01-26 01:18:23 -0800780 self._test.registry.register(self, self._test.logger)
Neale Ranns9db6ada2019-11-08 12:42:31 +0000781 return self
Neale Ranns32e1c012016-11-22 17:07:28 +0000782
783 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200784 self._test.vapi.ip_mroute_add_del(route=self.encode(), is_multipath=1, is_add=0)
Neale Ranns32e1c012016-11-22 17:07:28 +0000785
786 def update_entry_flags(self, flags):
787 self.e_flags = flags
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200788 self._test.vapi.ip_mroute_add_del(
789 route=self.encode(paths=[]), is_multipath=1, is_add=1
790 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000791
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800792 def update_rpf_id(self, rpf_id):
793 self.rpf_id = rpf_id
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200794 self._test.vapi.ip_mroute_add_del(
795 route=self.encode(paths=[]), is_multipath=1, is_add=1
796 )
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800797
Neale Ranns32e1c012016-11-22 17:07:28 +0000798 def update_path_flags(self, itf, flags):
Neale Ranns097fa662018-05-01 05:17:55 -0700799 for p in range(len(self.paths)):
800 if self.paths[p].nh_itf == itf:
801 self.paths[p].nh_i_flags = flags
Paul Vinciguerra6230b9d2020-04-28 11:23:31 -0400802 self.encoded_paths[p] = self.paths[p].encode()
803 break
Neale Ranns097fa662018-05-01 05:17:55 -0700804
Paul Vinciguerrae64e5ff2020-04-28 00:27:38 -0400805 self._test.vapi.ip_mroute_add_del(
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200806 route=self.encode(paths=[self.encoded_paths[p]]), is_add=1, is_multipath=0
807 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000808
Neale Ranns5a8123b2017-01-26 01:18:23 -0800809 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200810 return find_mroute(
811 self._test,
812 self.prefix.gaddr,
813 self.prefix.saddr,
814 self.prefix.length,
815 self.table_id,
816 )
Neale Ranns32e1c012016-11-22 17:07:28 +0000817
Neale Ranns5a8123b2017-01-26 01:18:23 -0800818 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200819 return "%d:(%s,%s/%d)" % (
820 self.table_id,
821 self.prefix.saddr,
822 self.prefix.gaddr,
823 self.prefix.length,
824 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800825
Neale Ranns28c142e2018-09-07 09:37:07 -0700826 def get_stats(self):
827 c = self._test.statistics.get_counter("/net/mroute")
828 return c[0][self.stats_index]
829
Neale Ranns5a8123b2017-01-26 01:18:23 -0800830
Paul Vinciguerrae061dad2020-12-04 14:57:51 -0500831class VppMFibSignal:
Neale Ranns32e1c012016-11-22 17:07:28 +0000832 def __init__(self, test, route, interface, packet):
833 self.route = route
834 self.interface = interface
835 self.packet = packet
836 self.test = test
837
838 def compare(self, signal):
839 self.test.assertEqual(self.interface, signal.sw_if_index)
840 self.test.assertEqual(self.route.table_id, signal.table_id)
Neale Ranns097fa662018-05-01 05:17:55 -0700841 self.test.assertEqual(self.route.prefix, signal.prefix)
Neale Ranns32e1c012016-11-22 17:07:28 +0000842
843
Neale Ranns5a8123b2017-01-26 01:18:23 -0800844class VppMplsIpBind(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000845 """
846 MPLS to IP Binding
847 """
848
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200849 def __init__(
850 self,
851 test,
852 local_label,
853 dest_addr,
854 dest_addr_len,
855 table_id=0,
856 ip_table_id=0,
857 is_ip6=0,
858 ):
Neale Rannsad422ed2016-11-02 14:20:04 +0000859 self._test = test
Neale Rannsad422ed2016-11-02 14:20:04 +0000860 self.dest_addr_len = dest_addr_len
Neale Rannsf12a83f2017-04-18 09:09:40 -0700861 self.dest_addr = dest_addr
Neale Ranns097fa662018-05-01 05:17:55 -0700862 self.ip_addr = ip_address(text_type(dest_addr))
Neale Rannsad422ed2016-11-02 14:20:04 +0000863 self.local_label = local_label
Neale Ranns5a8123b2017-01-26 01:18:23 -0800864 self.table_id = table_id
865 self.ip_table_id = ip_table_id
Neale Rannsefd7bc22019-11-11 08:32:34 +0000866 self.prefix = mk_network(dest_addr, dest_addr_len)
Neale Rannsad422ed2016-11-02 14:20:04 +0000867
868 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200869 self._test.vapi.mpls_ip_bind_unbind(
870 self.local_label,
871 self.prefix,
872 table_id=self.table_id,
873 ip_table_id=self.ip_table_id,
874 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800875 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000876
877 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200878 self._test.vapi.mpls_ip_bind_unbind(
879 self.local_label,
880 self.prefix,
881 table_id=self.table_id,
882 ip_table_id=self.ip_table_id,
883 is_bind=0,
884 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000885
Neale Ranns5a8123b2017-01-26 01:18:23 -0800886 def query_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700887 dump = self._test.vapi.mpls_route_dump(self.table_id)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800888 for e in dump:
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200889 if (
890 self.local_label == e.mr_route.mr_label
891 and self.table_id == e.mr_route.mr_table_id
892 ):
Neale Ranns5a8123b2017-01-26 01:18:23 -0800893 return True
894 return False
Neale Rannsad422ed2016-11-02 14:20:04 +0000895
Neale Ranns5a8123b2017-01-26 01:18:23 -0800896 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200897 return "%d:%s binds %d:%s/%d" % (
898 self.table_id,
899 self.local_label,
900 self.ip_table_id,
901 self.dest_addr,
902 self.dest_addr_len,
903 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800904
905
Neale Ranns15002542017-09-10 04:39:11 -0700906class VppMplsTable(VppObject):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200907 def __init__(self, test, table_id):
Neale Ranns15002542017-09-10 04:39:11 -0700908 self._test = test
909 self.table_id = table_id
910
911 def add_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200912 self._test.vapi.mpls_table_add_del(self.table_id, is_add=1)
Neale Ranns15002542017-09-10 04:39:11 -0700913 self._test.registry.register(self, self._test.logger)
914
915 def remove_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200916 self._test.vapi.mpls_table_add_del(self.table_id, is_add=0)
Neale Ranns15002542017-09-10 04:39:11 -0700917
918 def query_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700919 dump = self._test.vapi.mpls_table_dump()
920 for d in dump:
921 if d.mt_table.mt_table_id == self.table_id:
922 return True
Neale Ranns15002542017-09-10 04:39:11 -0700923 return False
924
Neale Ranns15002542017-09-10 04:39:11 -0700925 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200926 return "table-mpls-%d" % (self.table_id)
Neale Ranns15002542017-09-10 04:39:11 -0700927
928
Neale Ranns5a8123b2017-01-26 01:18:23 -0800929class VppMplsRoute(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000930 """
Neale Ranns5a8123b2017-01-26 01:18:23 -0800931 MPLS Route/LSP
Neale Rannsad422ed2016-11-02 14:20:04 +0000932 """
933
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200934 def __init__(
935 self,
936 test,
937 local_label,
938 eos_bit,
939 paths,
940 table_id=0,
941 is_multicast=0,
942 eos_proto=FibPathProto.FIB_PATH_NH_PROTO_IP4,
943 ):
Neale Rannsad422ed2016-11-02 14:20:04 +0000944 self._test = test
945 self.paths = paths
946 self.local_label = local_label
947 self.eos_bit = eos_bit
Neale Ranns097fa662018-05-01 05:17:55 -0700948 self.eos_proto = eos_proto
Neale Rannsad422ed2016-11-02 14:20:04 +0000949 self.table_id = table_id
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800950 self.is_multicast = is_multicast
Neale Rannsad422ed2016-11-02 14:20:04 +0000951
952 def add_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700953 paths = []
Neale Rannsad422ed2016-11-02 14:20:04 +0000954 for path in self.paths:
Neale Ranns097fa662018-05-01 05:17:55 -0700955 paths.append(path.encode())
Neale Ranns31ed7442018-02-23 05:29:09 -0800956
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200957 r = self._test.vapi.mpls_route_add_del(
958 self.table_id,
959 self.local_label,
960 self.eos_bit,
961 self.eos_proto,
962 self.is_multicast,
963 paths,
964 1,
965 0,
966 )
Neale Ranns008dbe12018-09-07 09:32:36 -0700967 self.stats_index = r.stats_index
Neale Ranns5a8123b2017-01-26 01:18:23 -0800968 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000969
970 def remove_vpp_config(self):
Neale Ranns097fa662018-05-01 05:17:55 -0700971 paths = []
Neale Rannsad422ed2016-11-02 14:20:04 +0000972 for path in self.paths:
Neale Ranns097fa662018-05-01 05:17:55 -0700973 paths.append(path.encode())
974
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200975 self._test.vapi.mpls_route_add_del(
976 self.table_id,
977 self.local_label,
978 self.eos_bit,
979 self.eos_proto,
980 self.is_multicast,
981 paths,
982 0,
983 0,
984 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800985
986 def query_vpp_config(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200987 return find_mpls_route(
988 self._test, self.table_id, self.local_label, self.eos_bit
989 )
Neale Ranns5a8123b2017-01-26 01:18:23 -0800990
Neale Ranns5a8123b2017-01-26 01:18:23 -0800991 def object_id(self):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200992 return "mpls-route-%d:%s/%d" % (
993 self.table_id,
994 self.local_label,
995 20 + self.eos_bit,
996 )
Neale Ranns008dbe12018-09-07 09:32:36 -0700997
998 def get_stats_to(self):
999 c = self._test.statistics.get_counter("/net/route/to")
1000 return c[0][self.stats_index]
1001
1002 def get_stats_via(self):
1003 c = self._test.statistics.get_counter("/net/route/via")
1004 return c[0][self.stats_index]