blob: 00a79f442329f43b6fe05ea1427607b93efd7fe4 [file] [log] [blame]
Neale Ranns177bbdc2016-11-15 09:46:51 +00001"""
2 IP Routes
3
4 object abstractions for representing IP routes in VPP
5"""
6
Neale Ranns5a8123b2017-01-26 01:18:23 -08007from vpp_object import *
Neale Rannsb3b2de72017-03-08 05:17:22 -08008from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
Neale Rannsc0a93142018-09-05 15:42:26 -07009from vpp_ip import *
Neale Ranns177bbdc2016-11-15 09:46:51 +000010
Neale Rannsad422ed2016-11-02 14:20:04 +000011# from vnet/vnet/mpls/mpls_types.h
12MPLS_IETF_MAX_LABEL = 0xfffff
13MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
Neale Ranns177bbdc2016-11-15 09:46:51 +000014
Neale Ranns177bbdc2016-11-15 09:46:51 +000015
Neale Ranns180279b2017-03-16 15:49:09 -040016class MRouteItfFlags:
17 MFIB_ITF_FLAG_NONE = 0
18 MFIB_ITF_FLAG_NEGATE_SIGNAL = 1
19 MFIB_ITF_FLAG_ACCEPT = 2
20 MFIB_ITF_FLAG_FORWARD = 4
21 MFIB_ITF_FLAG_SIGNAL_PRESENT = 8
22 MFIB_ITF_FLAG_INTERNAL_COPY = 16
23
24
25class MRouteEntryFlags:
26 MFIB_ENTRY_FLAG_NONE = 0
27 MFIB_ENTRY_FLAG_SIGNAL = 1
28 MFIB_ENTRY_FLAG_DROP = 2
29 MFIB_ENTRY_FLAG_CONNECTED = 4
30 MFIB_ENTRY_FLAG_INHERIT_ACCEPT = 8
31
32
Neale Ranns31ed7442018-02-23 05:29:09 -080033class MplsLspMode:
34 PIPE = 0
35 UNIFORM = 1
36
37
Neale Rannsb3b2de72017-03-08 05:17:22 -080038def find_route(test, ip_addr, len, table_id=0, inet=AF_INET):
39 if inet == AF_INET:
40 s = 4
41 routes = test.vapi.ip_fib_dump()
42 else:
43 s = 16
44 routes = test.vapi.ip6_fib_dump()
45
46 route_addr = inet_pton(inet, ip_addr)
47 for e in routes:
48 if route_addr == e.address[:s] \
49 and len == e.address_length \
50 and table_id == e.table_id:
51 return True
52 return False
53
54
Neale Ranns947ea622018-06-07 23:48:20 -070055def find_mroute(test, grp_addr, src_addr, grp_addr_len,
56 table_id=0, inet=AF_INET):
57 if inet == AF_INET:
58 s = 4
59 routes = test.vapi.ip_mfib_dump()
60 else:
61 s = 16
62 routes = test.vapi.ip6_mfib_dump()
63 gaddr = inet_pton(inet, grp_addr)
64 saddr = inet_pton(inet, src_addr)
65 for e in routes:
66 if gaddr == e.grp_address[:s] \
67 and grp_addr_len == e.address_length \
68 and saddr == e.src_address[:s] \
69 and table_id == e.table_id:
70 return True
71 return False
72
73
Neale Ranns15002542017-09-10 04:39:11 -070074class VppIpTable(VppObject):
75
76 def __init__(self,
77 test,
78 table_id,
79 is_ip6=0):
80 self._test = test
81 self.table_id = table_id
82 self.is_ip6 = is_ip6
83
84 def add_vpp_config(self):
85 self._test.vapi.ip_table_add_del(
86 self.table_id,
87 is_ipv6=self.is_ip6,
88 is_add=1)
89 self._test.registry.register(self, self._test.logger)
90
91 def remove_vpp_config(self):
92 self._test.vapi.ip_table_add_del(
93 self.table_id,
94 is_ipv6=self.is_ip6,
95 is_add=0)
96
97 def query_vpp_config(self):
98 # find the default route
99 return find_route(self._test,
100 "::" if self.is_ip6 else "0.0.0.0",
101 0,
102 self.table_id,
103 inet=AF_INET6 if self.is_ip6 == 1 else AF_INET)
104
105 def __str__(self):
106 return self.object_id()
107
108 def object_id(self):
109 return ("table-%s-%d" %
110 ("v6" if self.is_ip6 == 1 else "v4",
111 self.table_id))
112
113
Neale Ranns31ed7442018-02-23 05:29:09 -0800114class VppMplsLabel(object):
115 def __init__(self, value, mode=MplsLspMode.PIPE, ttl=64, exp=0):
116 self.value = value
117 self.mode = mode
118 self.ttl = ttl
119 self.exp = exp
120
121 def encode(self):
122 is_uniform = 0 if self.mode is MplsLspMode.PIPE else 1
123 return {'label': self.value,
124 'ttl': self.ttl,
125 'exp': self.exp,
126 'is_uniform': is_uniform}
127
128
Neale Ranns5a8123b2017-01-26 01:18:23 -0800129class VppRoutePath(object):
Neale Rannsad422ed2016-11-02 14:20:04 +0000130
Klement Sekerada505f62017-01-04 12:58:53 +0100131 def __init__(
132 self,
133 nh_addr,
134 nh_sw_if_index,
135 nh_table_id=0,
136 labels=[],
Neale Rannsfca0c242017-01-13 07:57:46 -0800137 nh_via_label=MPLS_LABEL_INVALID,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800138 rpf_id=0,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700139 is_interface_rx=0,
140 is_resolve_host=0,
Neale Rannsda78f952017-05-24 09:15:43 -0700141 is_resolve_attached=0,
Neale Ranns054c03a2017-10-13 05:15:07 -0700142 is_source_lookup=0,
Neale Ranns810086d2017-11-05 16:26:46 -0800143 is_udp_encap=0,
Neale Rannsf068c3e2018-01-03 04:18:48 -0800144 is_dvr=0,
Neale Ranns810086d2017-11-05 16:26:46 -0800145 next_hop_id=0xffffffff,
Neale Rannsda78f952017-05-24 09:15:43 -0700146 proto=DpoProto.DPO_PROTO_IP4):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000147 self.nh_itf = nh_sw_if_index
148 self.nh_table_id = nh_table_id
Neale Rannsad422ed2016-11-02 14:20:04 +0000149 self.nh_via_label = nh_via_label
150 self.nh_labels = labels
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800151 self.weight = 1
152 self.rpf_id = rpf_id
Neale Rannsda78f952017-05-24 09:15:43 -0700153 self.proto = proto
154 if self.proto is DpoProto.DPO_PROTO_IP6:
155 self.nh_addr = inet_pton(AF_INET6, nh_addr)
156 elif self.proto is DpoProto.DPO_PROTO_IP4:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800157 self.nh_addr = inet_pton(AF_INET, nh_addr)
Neale Ranns31426c62017-05-24 10:32:58 -0700158 else:
Neale Rannsda78f952017-05-24 09:15:43 -0700159 self.nh_addr = inet_pton(AF_INET6, "::")
Neale Rannsf12a83f2017-04-18 09:09:40 -0700160 self.is_resolve_host = is_resolve_host
161 self.is_resolve_attached = is_resolve_attached
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800162 self.is_interface_rx = is_interface_rx
Neale Ranns054c03a2017-10-13 05:15:07 -0700163 self.is_source_lookup = is_source_lookup
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800164 self.is_rpf_id = 0
165 if rpf_id != 0:
166 self.is_rpf_id = 1
167 self.nh_itf = rpf_id
Neale Ranns810086d2017-11-05 16:26:46 -0800168 self.is_udp_encap = is_udp_encap
169 self.next_hop_id = next_hop_id
Neale Rannsf068c3e2018-01-03 04:18:48 -0800170 self.is_dvr = is_dvr
Neale Ranns177bbdc2016-11-15 09:46:51 +0000171
Neale Ranns31ed7442018-02-23 05:29:09 -0800172 def encode_labels(self):
173 lstack = []
174 for l in self.nh_labels:
175 if type(l) == VppMplsLabel:
176 lstack.append(l.encode())
177 else:
178 lstack.append({'label': l,
179 'ttl': 255})
180 return lstack
181
Neale Ranns2303cb12018-02-21 04:57:17 -0800182 def encode(self):
183 return {'next_hop': self.nh_addr,
184 'weight': 1,
185 'afi': 0,
186 'preference': 0,
187 'table_id': self.nh_table_id,
188 'next_hop_id': self.next_hop_id,
189 'sw_if_index': self.nh_itf,
190 'afi': self.proto,
191 'is_udp_encap': self.is_udp_encap,
192 'n_labels': len(self.nh_labels),
193 'label_stack': self.encode_labels()}
194
Neale Rannsef90ed02018-09-13 08:45:12 -0700195 def __eq__(self, other):
196 return self.nh_addr == other.nh_addr
197
Neale Ranns177bbdc2016-11-15 09:46:51 +0000198
Neale Ranns5a8123b2017-01-26 01:18:23 -0800199class VppMRoutePath(VppRoutePath):
Neale Ranns32e1c012016-11-22 17:07:28 +0000200
Neale Rannsd792d9c2017-10-21 10:53:20 -0700201 def __init__(self, nh_sw_if_index, flags,
Neale Rannse821ab12017-06-01 07:45:05 -0700202 nh=None,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700203 proto=DpoProto.DPO_PROTO_IP4,
204 bier_imp=0):
Neale Rannse821ab12017-06-01 07:45:05 -0700205 if not nh:
206 nh = "::" if proto is DpoProto.DPO_PROTO_IP6 else "0.0.0.0"
207 super(VppMRoutePath, self).__init__(nh,
208 nh_sw_if_index,
209 proto=proto)
Neale Ranns32e1c012016-11-22 17:07:28 +0000210 self.nh_i_flags = flags
Neale Rannsd792d9c2017-10-21 10:53:20 -0700211 self.bier_imp = bier_imp
Neale Ranns32e1c012016-11-22 17:07:28 +0000212
213
Neale Ranns5a8123b2017-01-26 01:18:23 -0800214class VppIpRoute(VppObject):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000215 """
216 IP Route
217 """
218
219 def __init__(self, test, dest_addr,
Neale Ranns37be7362017-02-21 17:30:26 -0800220 dest_addr_len, paths, table_id=0, is_ip6=0, is_local=0,
Neale Ranns3b93be52018-09-07 01:48:54 -0700221 is_unreach=0, is_prohibit=0, is_drop=0):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000222 self._test = test
223 self.paths = paths
Neale Ranns177bbdc2016-11-15 09:46:51 +0000224 self.dest_addr_len = dest_addr_len
225 self.table_id = table_id
Neale Rannsfca0c242017-01-13 07:57:46 -0800226 self.is_ip6 = is_ip6
227 self.is_local = is_local
Neale Ranns37be7362017-02-21 17:30:26 -0800228 self.is_unreach = is_unreach
229 self.is_prohibit = is_prohibit
Neale Ranns3b93be52018-09-07 01:48:54 -0700230 self.is_drop = is_drop
Neale Rannsb3b2de72017-03-08 05:17:22 -0800231 self.dest_addr_p = dest_addr
Neale Rannsfca0c242017-01-13 07:57:46 -0800232 if is_ip6:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800233 self.dest_addr = inet_pton(AF_INET6, dest_addr)
Neale Rannsfca0c242017-01-13 07:57:46 -0800234 else:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800235 self.dest_addr = inet_pton(AF_INET, dest_addr)
Neale Ranns177bbdc2016-11-15 09:46:51 +0000236
Neale Ranns69b7aa42017-03-10 03:04:12 -0800237 def modify(self, paths, is_local=0,
238 is_unreach=0, is_prohibit=0):
239 self.paths = paths
240 self.is_local = is_local
241 self.is_unreach = is_unreach
242 self.is_prohibit = is_prohibit
243
Neale Ranns177bbdc2016-11-15 09:46:51 +0000244 def add_vpp_config(self):
Neale Ranns3b93be52018-09-07 01:48:54 -0700245 if self.is_local or self.is_unreach or \
246 self.is_prohibit or self.is_drop:
Neale Ranns008dbe12018-09-07 09:32:36 -0700247 r = self._test.vapi.ip_add_del_route(
Klement Sekerada505f62017-01-04 12:58:53 +0100248 self.dest_addr,
249 self.dest_addr_len,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800250 inet_pton(AF_INET6, "::"),
Neale Rannsfca0c242017-01-13 07:57:46 -0800251 0xffffffff,
Neale Ranns37be7362017-02-21 17:30:26 -0800252 is_local=self.is_local,
253 is_unreach=self.is_unreach,
254 is_prohibit=self.is_prohibit,
Neale Ranns3b93be52018-09-07 01:48:54 -0700255 is_drop=self.is_drop,
Klement Sekerada505f62017-01-04 12:58:53 +0100256 table_id=self.table_id,
Neale Rannsfca0c242017-01-13 07:57:46 -0800257 is_ipv6=self.is_ip6)
258 else:
259 for path in self.paths:
Neale Ranns31ed7442018-02-23 05:29:09 -0800260 lstack = path.encode_labels()
261
Neale Ranns008dbe12018-09-07 09:32:36 -0700262 r = self._test.vapi.ip_add_del_route(
Neale Rannsfca0c242017-01-13 07:57:46 -0800263 self.dest_addr,
264 self.dest_addr_len,
265 path.nh_addr,
266 path.nh_itf,
267 table_id=self.table_id,
Neale Ranns31ed7442018-02-23 05:29:09 -0800268 next_hop_out_label_stack=lstack,
269 next_hop_n_out_labels=len(lstack),
Neale Rannsfca0c242017-01-13 07:57:46 -0800270 next_hop_via_label=path.nh_via_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700271 next_hop_table_id=path.nh_table_id,
Neale Ranns810086d2017-11-05 16:26:46 -0800272 next_hop_id=path.next_hop_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700273 is_ipv6=self.is_ip6,
Neale Rannsf068c3e2018-01-03 04:18:48 -0800274 is_dvr=path.is_dvr,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700275 is_resolve_host=path.is_resolve_host,
276 is_resolve_attached=path.is_resolve_attached,
Neale Ranns054c03a2017-10-13 05:15:07 -0700277 is_source_lookup=path.is_source_lookup,
Neale Ranns810086d2017-11-05 16:26:46 -0800278 is_udp_encap=path.is_udp_encap,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700279 is_multipath=1 if len(self.paths) > 1 else 0)
Neale Ranns008dbe12018-09-07 09:32:36 -0700280 self.stats_index = r.stats_index
Neale Ranns5a8123b2017-01-26 01:18:23 -0800281 self._test.registry.register(self, self._test.logger)
Neale Ranns177bbdc2016-11-15 09:46:51 +0000282
283 def remove_vpp_config(self):
Neale Ranns3b93be52018-09-07 01:48:54 -0700284 if self.is_local or self.is_unreach or \
285 self.is_prohibit or self.is_drop:
Neale Rannsfca0c242017-01-13 07:57:46 -0800286 self._test.vapi.ip_add_del_route(
287 self.dest_addr,
288 self.dest_addr_len,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800289 inet_pton(AF_INET6, "::"),
Neale Rannsfca0c242017-01-13 07:57:46 -0800290 0xffffffff,
Neale Ranns37be7362017-02-21 17:30:26 -0800291 is_local=self.is_local,
292 is_unreach=self.is_unreach,
293 is_prohibit=self.is_prohibit,
Neale Rannsfca0c242017-01-13 07:57:46 -0800294 is_add=0,
295 table_id=self.table_id,
296 is_ipv6=self.is_ip6)
297 else:
298 for path in self.paths:
Neale Rannsf12a83f2017-04-18 09:09:40 -0700299 self._test.vapi.ip_add_del_route(
300 self.dest_addr,
301 self.dest_addr_len,
302 path.nh_addr,
303 path.nh_itf,
304 table_id=self.table_id,
305 next_hop_table_id=path.nh_table_id,
306 next_hop_via_label=path.nh_via_label,
Neale Ranns810086d2017-11-05 16:26:46 -0800307 next_hop_id=path.next_hop_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700308 is_add=0,
Neale Ranns810086d2017-11-05 16:26:46 -0800309 is_udp_encap=path.is_udp_encap,
Neale Rannsf068c3e2018-01-03 04:18:48 -0800310 is_ipv6=self.is_ip6,
311 is_dvr=path.is_dvr)
Neale Rannsad422ed2016-11-02 14:20:04 +0000312
Neale Ranns5a8123b2017-01-26 01:18:23 -0800313 def query_vpp_config(self):
Neale Rannsb3b2de72017-03-08 05:17:22 -0800314 return find_route(self._test,
315 self.dest_addr_p,
316 self.dest_addr_len,
317 self.table_id,
318 inet=AF_INET6 if self.is_ip6 == 1 else AF_INET)
Neale Rannsad422ed2016-11-02 14:20:04 +0000319
Neale Ranns5a8123b2017-01-26 01:18:23 -0800320 def __str__(self):
321 return self.object_id()
322
323 def object_id(self):
Neale Rannsb3b2de72017-03-08 05:17:22 -0800324 return ("%d:%s/%d"
325 % (self.table_id,
326 self.dest_addr_p,
327 self.dest_addr_len))
Neale Ranns5a8123b2017-01-26 01:18:23 -0800328
Neale Ranns008dbe12018-09-07 09:32:36 -0700329 def get_stats_to(self):
330 c = self._test.statistics.get_counter("/net/route/to")
331 return c[0][self.stats_index]
332
333 def get_stats_via(self):
334 c = self._test.statistics.get_counter("/net/route/via")
335 return c[0][self.stats_index]
336
Neale Ranns5a8123b2017-01-26 01:18:23 -0800337
338class VppIpMRoute(VppObject):
Neale Ranns32e1c012016-11-22 17:07:28 +0000339 """
340 IP Multicast Route
341 """
342
343 def __init__(self, test, src_addr, grp_addr,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800344 grp_addr_len, e_flags, paths, table_id=0,
345 rpf_id=0, is_ip6=0):
Neale Ranns32e1c012016-11-22 17:07:28 +0000346 self._test = test
347 self.paths = paths
348 self.grp_addr_len = grp_addr_len
349 self.table_id = table_id
350 self.e_flags = e_flags
351 self.is_ip6 = is_ip6
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800352 self.rpf_id = rpf_id
Neale Ranns32e1c012016-11-22 17:07:28 +0000353
Neale Ranns947ea622018-06-07 23:48:20 -0700354 self.grp_addr_p = grp_addr
355 self.src_addr_p = src_addr
Neale Ranns32e1c012016-11-22 17:07:28 +0000356 if is_ip6:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800357 self.grp_addr = inet_pton(AF_INET6, grp_addr)
358 self.src_addr = inet_pton(AF_INET6, src_addr)
Neale Ranns32e1c012016-11-22 17:07:28 +0000359 else:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800360 self.grp_addr = inet_pton(AF_INET, grp_addr)
361 self.src_addr = inet_pton(AF_INET, src_addr)
Neale Ranns32e1c012016-11-22 17:07:28 +0000362
363 def add_vpp_config(self):
364 for path in self.paths:
Neale Ranns28c142e2018-09-07 09:37:07 -0700365 r = self._test.vapi.ip_mroute_add_del(self.src_addr,
366 self.grp_addr,
367 self.grp_addr_len,
368 self.e_flags,
369 path.proto,
370 path.nh_itf,
371 path.nh_addr,
372 path.nh_i_flags,
373 bier_imp=path.bier_imp,
374 rpf_id=self.rpf_id,
375 table_id=self.table_id,
376 is_ipv6=self.is_ip6)
377 self.stats_index = r.stats_index
Neale Ranns5a8123b2017-01-26 01:18:23 -0800378 self._test.registry.register(self, self._test.logger)
Neale Ranns32e1c012016-11-22 17:07:28 +0000379
380 def remove_vpp_config(self):
381 for path in self.paths:
382 self._test.vapi.ip_mroute_add_del(self.src_addr,
383 self.grp_addr,
384 self.grp_addr_len,
385 self.e_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700386 path.proto,
Neale Ranns32e1c012016-11-22 17:07:28 +0000387 path.nh_itf,
Neale Rannse821ab12017-06-01 07:45:05 -0700388 path.nh_addr,
Neale Ranns32e1c012016-11-22 17:07:28 +0000389 path.nh_i_flags,
390 table_id=self.table_id,
Neale Rannseea537a2018-01-09 04:11:28 -0800391 bier_imp=path.bier_imp,
Neale Ranns32e1c012016-11-22 17:07:28 +0000392 is_add=0,
393 is_ipv6=self.is_ip6)
394
395 def update_entry_flags(self, flags):
396 self.e_flags = flags
397 self._test.vapi.ip_mroute_add_del(self.src_addr,
398 self.grp_addr,
399 self.grp_addr_len,
400 self.e_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700401 0,
Neale Ranns32e1c012016-11-22 17:07:28 +0000402 0xffffffff,
Neale Rannse821ab12017-06-01 07:45:05 -0700403 "",
Neale Ranns32e1c012016-11-22 17:07:28 +0000404 0,
405 table_id=self.table_id,
406 is_ipv6=self.is_ip6)
407
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800408 def update_rpf_id(self, rpf_id):
409 self.rpf_id = rpf_id
410 self._test.vapi.ip_mroute_add_del(self.src_addr,
411 self.grp_addr,
412 self.grp_addr_len,
413 self.e_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700414 0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800415 0xffffffff,
Neale Rannse821ab12017-06-01 07:45:05 -0700416 "",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800417 0,
418 rpf_id=self.rpf_id,
419 table_id=self.table_id,
420 is_ipv6=self.is_ip6)
421
Neale Ranns32e1c012016-11-22 17:07:28 +0000422 def update_path_flags(self, itf, flags):
423 for path in self.paths:
424 if path.nh_itf == itf:
425 path.nh_i_flags = flags
426 break
427 self._test.vapi.ip_mroute_add_del(self.src_addr,
428 self.grp_addr,
429 self.grp_addr_len,
430 self.e_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700431 path.proto,
Neale Ranns32e1c012016-11-22 17:07:28 +0000432 path.nh_itf,
Neale Rannse821ab12017-06-01 07:45:05 -0700433 path.nh_addr,
Neale Ranns32e1c012016-11-22 17:07:28 +0000434 path.nh_i_flags,
435 table_id=self.table_id,
436 is_ipv6=self.is_ip6)
437
Neale Ranns5a8123b2017-01-26 01:18:23 -0800438 def query_vpp_config(self):
Neale Ranns947ea622018-06-07 23:48:20 -0700439 return find_mroute(self._test,
440 self.grp_addr_p,
441 self.src_addr_p,
442 self.grp_addr_len,
443 self.table_id,
444 inet=AF_INET6 if self.is_ip6 == 1 else AF_INET)
Neale Ranns32e1c012016-11-22 17:07:28 +0000445
Neale Ranns5a8123b2017-01-26 01:18:23 -0800446 def __str__(self):
447 return self.object_id()
448
449 def object_id(self):
450 if self.is_ip6:
451 return ("%d:(%s,%s/%d)"
452 % (self.table_id,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800453 inet_ntop(AF_INET6, self.src_addr),
454 inet_ntop(AF_INET6, self.grp_addr),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800455 self.grp_addr_len))
456 else:
457 return ("%d:(%s,%s/%d)"
458 % (self.table_id,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800459 inet_ntop(AF_INET, self.src_addr),
460 inet_ntop(AF_INET, self.grp_addr),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800461 self.grp_addr_len))
462
Neale Ranns28c142e2018-09-07 09:37:07 -0700463 def get_stats(self):
464 c = self._test.statistics.get_counter("/net/mroute")
465 return c[0][self.stats_index]
466
Neale Ranns5a8123b2017-01-26 01:18:23 -0800467
468class VppMFibSignal(object):
Neale Ranns32e1c012016-11-22 17:07:28 +0000469 def __init__(self, test, route, interface, packet):
470 self.route = route
471 self.interface = interface
472 self.packet = packet
473 self.test = test
474
475 def compare(self, signal):
476 self.test.assertEqual(self.interface, signal.sw_if_index)
477 self.test.assertEqual(self.route.table_id, signal.table_id)
478 self.test.assertEqual(self.route.grp_addr_len,
479 signal.grp_address_len)
480 for i in range(self.route.grp_addr_len / 8):
481 self.test.assertEqual(self.route.grp_addr[i],
482 signal.grp_address[i])
483 if (self.route.grp_addr_len > 32):
484 for i in range(4):
485 self.test.assertEqual(self.route.src_addr[i],
486 signal.src_address[i])
487
488
Neale Ranns5a8123b2017-01-26 01:18:23 -0800489class VppMplsIpBind(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000490 """
491 MPLS to IP Binding
492 """
493
Neale Ranns5a8123b2017-01-26 01:18:23 -0800494 def __init__(self, test, local_label, dest_addr, dest_addr_len,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700495 table_id=0, ip_table_id=0, is_ip6=0):
Neale Rannsad422ed2016-11-02 14:20:04 +0000496 self._test = test
Neale Rannsad422ed2016-11-02 14:20:04 +0000497 self.dest_addr_len = dest_addr_len
Neale Rannsf12a83f2017-04-18 09:09:40 -0700498 self.dest_addr = dest_addr
Neale Rannsad422ed2016-11-02 14:20:04 +0000499 self.local_label = local_label
Neale Ranns5a8123b2017-01-26 01:18:23 -0800500 self.table_id = table_id
501 self.ip_table_id = ip_table_id
Neale Rannsf12a83f2017-04-18 09:09:40 -0700502 self.is_ip6 = is_ip6
503 if is_ip6:
504 self.dest_addrn = inet_pton(AF_INET6, dest_addr)
505 else:
506 self.dest_addrn = inet_pton(AF_INET, dest_addr)
Neale Rannsad422ed2016-11-02 14:20:04 +0000507
508 def add_vpp_config(self):
509 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700510 self.dest_addrn,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800511 self.dest_addr_len,
512 table_id=self.table_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700513 ip_table_id=self.ip_table_id,
514 is_ip4=(self.is_ip6 == 0))
Neale Ranns5a8123b2017-01-26 01:18:23 -0800515 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000516
517 def remove_vpp_config(self):
518 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700519 self.dest_addrn,
Neale Rannsad422ed2016-11-02 14:20:04 +0000520 self.dest_addr_len,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700521 table_id=self.table_id,
522 ip_table_id=self.ip_table_id,
523 is_bind=0,
524 is_ip4=(self.is_ip6 == 0))
Neale Rannsad422ed2016-11-02 14:20:04 +0000525
Neale Ranns5a8123b2017-01-26 01:18:23 -0800526 def query_vpp_config(self):
527 dump = self._test.vapi.mpls_fib_dump()
528 for e in dump:
529 if self.local_label == e.label \
Neale Ranns5a8123b2017-01-26 01:18:23 -0800530 and self.table_id == e.table_id:
531 return True
532 return False
Neale Rannsad422ed2016-11-02 14:20:04 +0000533
Neale Ranns5a8123b2017-01-26 01:18:23 -0800534 def __str__(self):
535 return self.object_id()
536
537 def object_id(self):
538 return ("%d:%s binds %d:%s/%d"
539 % (self.table_id,
540 self.local_label,
541 self.ip_table_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700542 self.dest_addr,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800543 self.dest_addr_len))
544
545
Neale Ranns15002542017-09-10 04:39:11 -0700546class VppMplsTable(VppObject):
547
548 def __init__(self,
549 test,
550 table_id):
551 self._test = test
552 self.table_id = table_id
553
554 def add_vpp_config(self):
555 self._test.vapi.mpls_table_add_del(
556 self.table_id,
557 is_add=1)
558 self._test.registry.register(self, self._test.logger)
559
560 def remove_vpp_config(self):
561 self._test.vapi.mpls_table_add_del(
562 self.table_id,
563 is_add=0)
564
565 def query_vpp_config(self):
566 # find the default route
567 dump = self._test.vapi.mpls_fib_dump()
568 if len(dump):
569 return True
570 return False
571
572 def __str__(self):
573 return self.object_id()
574
575 def object_id(self):
576 return ("table-mpls-%d" % (self.table_id))
577
578
Neale Ranns5a8123b2017-01-26 01:18:23 -0800579class VppMplsRoute(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000580 """
Neale Ranns5a8123b2017-01-26 01:18:23 -0800581 MPLS Route/LSP
Neale Rannsad422ed2016-11-02 14:20:04 +0000582 """
583
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800584 def __init__(self, test, local_label, eos_bit, paths, table_id=0,
585 is_multicast=0):
Neale Rannsad422ed2016-11-02 14:20:04 +0000586 self._test = test
587 self.paths = paths
588 self.local_label = local_label
589 self.eos_bit = eos_bit
590 self.table_id = table_id
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800591 self.is_multicast = is_multicast
Neale Rannsad422ed2016-11-02 14:20:04 +0000592
593 def add_vpp_config(self):
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800594 is_multipath = len(self.paths) > 1
Neale Rannsad422ed2016-11-02 14:20:04 +0000595 for path in self.paths:
Neale Ranns31ed7442018-02-23 05:29:09 -0800596 lstack = path.encode_labels()
597
Neale Ranns008dbe12018-09-07 09:32:36 -0700598 r = self._test.vapi.mpls_route_add_del(
Klement Sekerada505f62017-01-04 12:58:53 +0100599 self.local_label,
600 self.eos_bit,
Neale Rannsda78f952017-05-24 09:15:43 -0700601 path.proto,
Klement Sekerada505f62017-01-04 12:58:53 +0100602 path.nh_addr,
603 path.nh_itf,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800604 is_multicast=self.is_multicast,
605 is_multipath=is_multipath,
Klement Sekerada505f62017-01-04 12:58:53 +0100606 table_id=self.table_id,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800607 is_interface_rx=path.is_interface_rx,
608 is_rpf_id=path.is_rpf_id,
Neale Ranns31ed7442018-02-23 05:29:09 -0800609 next_hop_out_label_stack=lstack,
610 next_hop_n_out_labels=len(lstack),
Klement Sekerada505f62017-01-04 12:58:53 +0100611 next_hop_via_label=path.nh_via_label,
612 next_hop_table_id=path.nh_table_id)
Neale Ranns008dbe12018-09-07 09:32:36 -0700613 self.stats_index = r.stats_index
Neale Ranns5a8123b2017-01-26 01:18:23 -0800614 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000615
616 def remove_vpp_config(self):
617 for path in self.paths:
618 self._test.vapi.mpls_route_add_del(self.local_label,
619 self.eos_bit,
Neale Rannsda78f952017-05-24 09:15:43 -0700620 path.proto,
Neale Rannsad422ed2016-11-02 14:20:04 +0000621 path.nh_addr,
622 path.nh_itf,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800623 is_rpf_id=path.is_rpf_id,
Neale Rannsad422ed2016-11-02 14:20:04 +0000624 table_id=self.table_id,
625 is_add=0)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800626
627 def query_vpp_config(self):
628 dump = self._test.vapi.mpls_fib_dump()
629 for e in dump:
630 if self.local_label == e.label \
631 and self.eos_bit == e.eos_bit \
632 and self.table_id == e.table_id:
633 return True
634 return False
635
636 def __str__(self):
637 return self.object_id()
638
639 def object_id(self):
640 return ("%d:%s/%d"
641 % (self.table_id,
642 self.local_label,
643 20+self.eos_bit))
Neale Ranns008dbe12018-09-07 09:32:36 -0700644
645 def get_stats_to(self):
646 c = self._test.statistics.get_counter("/net/route/to")
647 return c[0][self.stats_index]
648
649 def get_stats_via(self):
650 c = self._test.statistics.get_counter("/net/route/via")
651 return c[0][self.stats_index]