blob: 9e5c53184e34618b489237da9ff0ab6bfd304ca1 [file] [log] [blame]
Neale Ranns177bbdc2016-11-15 09:46:51 +00001"""
2 IP Routes
3
4 object abstractions for representing IP routes in VPP
5"""
6
Neale Ranns5a8123b2017-01-26 01:18:23 -08007from vpp_object import *
Neale Rannsb3b2de72017-03-08 05:17:22 -08008from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
Neale Ranns177bbdc2016-11-15 09:46:51 +00009
Neale Rannsad422ed2016-11-02 14:20:04 +000010# from vnet/vnet/mpls/mpls_types.h
11MPLS_IETF_MAX_LABEL = 0xfffff
12MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
Neale Ranns177bbdc2016-11-15 09:46:51 +000013
Neale Ranns177bbdc2016-11-15 09:46:51 +000014
Neale Ranns180279b2017-03-16 15:49:09 -040015class MRouteItfFlags:
16 MFIB_ITF_FLAG_NONE = 0
17 MFIB_ITF_FLAG_NEGATE_SIGNAL = 1
18 MFIB_ITF_FLAG_ACCEPT = 2
19 MFIB_ITF_FLAG_FORWARD = 4
20 MFIB_ITF_FLAG_SIGNAL_PRESENT = 8
21 MFIB_ITF_FLAG_INTERNAL_COPY = 16
22
23
24class MRouteEntryFlags:
25 MFIB_ENTRY_FLAG_NONE = 0
26 MFIB_ENTRY_FLAG_SIGNAL = 1
27 MFIB_ENTRY_FLAG_DROP = 2
28 MFIB_ENTRY_FLAG_CONNECTED = 4
29 MFIB_ENTRY_FLAG_INHERIT_ACCEPT = 8
30
31
Neale Rannsda78f952017-05-24 09:15:43 -070032class DpoProto:
33 DPO_PROTO_IP4 = 0
34 DPO_PROTO_IP6 = 1
35 DPO_PROTO_MPLS = 2
36 DPO_PROTO_ETHERNET = 3
Neale Rannsd792d9c2017-10-21 10:53:20 -070037 DPO_PROTO_BIER = 4
38 DPO_PROTO_NSH = 5
Neale Rannsda78f952017-05-24 09:15:43 -070039
40
Neale Ranns31ed7442018-02-23 05:29:09 -080041class MplsLspMode:
42 PIPE = 0
43 UNIFORM = 1
44
45
Neale Rannsb3b2de72017-03-08 05:17:22 -080046def find_route(test, ip_addr, len, table_id=0, inet=AF_INET):
47 if inet == AF_INET:
48 s = 4
49 routes = test.vapi.ip_fib_dump()
50 else:
51 s = 16
52 routes = test.vapi.ip6_fib_dump()
53
54 route_addr = inet_pton(inet, ip_addr)
55 for e in routes:
56 if route_addr == e.address[:s] \
57 and len == e.address_length \
58 and table_id == e.table_id:
59 return True
60 return False
61
62
Neale Ranns947ea622018-06-07 23:48:20 -070063def find_mroute(test, grp_addr, src_addr, grp_addr_len,
64 table_id=0, inet=AF_INET):
65 if inet == AF_INET:
66 s = 4
67 routes = test.vapi.ip_mfib_dump()
68 else:
69 s = 16
70 routes = test.vapi.ip6_mfib_dump()
71 gaddr = inet_pton(inet, grp_addr)
72 saddr = inet_pton(inet, src_addr)
73 for e in routes:
74 if gaddr == e.grp_address[:s] \
75 and grp_addr_len == e.address_length \
76 and saddr == e.src_address[:s] \
77 and table_id == e.table_id:
78 return True
79 return False
80
81
Neale Ranns15002542017-09-10 04:39:11 -070082class VppIpTable(VppObject):
83
84 def __init__(self,
85 test,
86 table_id,
87 is_ip6=0):
88 self._test = test
89 self.table_id = table_id
90 self.is_ip6 = is_ip6
91
92 def add_vpp_config(self):
93 self._test.vapi.ip_table_add_del(
94 self.table_id,
95 is_ipv6=self.is_ip6,
96 is_add=1)
97 self._test.registry.register(self, self._test.logger)
98
99 def remove_vpp_config(self):
100 self._test.vapi.ip_table_add_del(
101 self.table_id,
102 is_ipv6=self.is_ip6,
103 is_add=0)
104
105 def query_vpp_config(self):
106 # find the default route
107 return find_route(self._test,
108 "::" if self.is_ip6 else "0.0.0.0",
109 0,
110 self.table_id,
111 inet=AF_INET6 if self.is_ip6 == 1 else AF_INET)
112
113 def __str__(self):
114 return self.object_id()
115
116 def object_id(self):
117 return ("table-%s-%d" %
118 ("v6" if self.is_ip6 == 1 else "v4",
119 self.table_id))
120
121
Neale Ranns31ed7442018-02-23 05:29:09 -0800122class VppMplsLabel(object):
123 def __init__(self, value, mode=MplsLspMode.PIPE, ttl=64, exp=0):
124 self.value = value
125 self.mode = mode
126 self.ttl = ttl
127 self.exp = exp
128
129 def encode(self):
130 is_uniform = 0 if self.mode is MplsLspMode.PIPE else 1
131 return {'label': self.value,
132 'ttl': self.ttl,
133 'exp': self.exp,
134 'is_uniform': is_uniform}
135
136
Neale Ranns5a8123b2017-01-26 01:18:23 -0800137class VppRoutePath(object):
Neale Rannsad422ed2016-11-02 14:20:04 +0000138
Klement Sekerada505f62017-01-04 12:58:53 +0100139 def __init__(
140 self,
141 nh_addr,
142 nh_sw_if_index,
143 nh_table_id=0,
144 labels=[],
Neale Rannsfca0c242017-01-13 07:57:46 -0800145 nh_via_label=MPLS_LABEL_INVALID,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800146 rpf_id=0,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700147 is_interface_rx=0,
148 is_resolve_host=0,
Neale Rannsda78f952017-05-24 09:15:43 -0700149 is_resolve_attached=0,
Neale Ranns054c03a2017-10-13 05:15:07 -0700150 is_source_lookup=0,
Neale Ranns810086d2017-11-05 16:26:46 -0800151 is_udp_encap=0,
Neale Rannsf068c3e2018-01-03 04:18:48 -0800152 is_dvr=0,
Neale Ranns810086d2017-11-05 16:26:46 -0800153 next_hop_id=0xffffffff,
Neale Rannsda78f952017-05-24 09:15:43 -0700154 proto=DpoProto.DPO_PROTO_IP4):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000155 self.nh_itf = nh_sw_if_index
156 self.nh_table_id = nh_table_id
Neale Rannsad422ed2016-11-02 14:20:04 +0000157 self.nh_via_label = nh_via_label
158 self.nh_labels = labels
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800159 self.weight = 1
160 self.rpf_id = rpf_id
Neale Rannsda78f952017-05-24 09:15:43 -0700161 self.proto = proto
162 if self.proto is DpoProto.DPO_PROTO_IP6:
163 self.nh_addr = inet_pton(AF_INET6, nh_addr)
164 elif self.proto is DpoProto.DPO_PROTO_IP4:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800165 self.nh_addr = inet_pton(AF_INET, nh_addr)
Neale Ranns31426c62017-05-24 10:32:58 -0700166 else:
Neale Rannsda78f952017-05-24 09:15:43 -0700167 self.nh_addr = inet_pton(AF_INET6, "::")
Neale Rannsf12a83f2017-04-18 09:09:40 -0700168 self.is_resolve_host = is_resolve_host
169 self.is_resolve_attached = is_resolve_attached
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800170 self.is_interface_rx = is_interface_rx
Neale Ranns054c03a2017-10-13 05:15:07 -0700171 self.is_source_lookup = is_source_lookup
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800172 self.is_rpf_id = 0
173 if rpf_id != 0:
174 self.is_rpf_id = 1
175 self.nh_itf = rpf_id
Neale Ranns810086d2017-11-05 16:26:46 -0800176 self.is_udp_encap = is_udp_encap
177 self.next_hop_id = next_hop_id
Neale Rannsf068c3e2018-01-03 04:18:48 -0800178 self.is_dvr = is_dvr
Neale Ranns177bbdc2016-11-15 09:46:51 +0000179
Neale Ranns31ed7442018-02-23 05:29:09 -0800180 def encode_labels(self):
181 lstack = []
182 for l in self.nh_labels:
183 if type(l) == VppMplsLabel:
184 lstack.append(l.encode())
185 else:
186 lstack.append({'label': l,
187 'ttl': 255})
188 return lstack
189
Neale Ranns2303cb12018-02-21 04:57:17 -0800190 def encode(self):
191 return {'next_hop': self.nh_addr,
192 'weight': 1,
193 'afi': 0,
194 'preference': 0,
195 'table_id': self.nh_table_id,
196 'next_hop_id': self.next_hop_id,
197 'sw_if_index': self.nh_itf,
198 'afi': self.proto,
199 'is_udp_encap': self.is_udp_encap,
200 'n_labels': len(self.nh_labels),
201 'label_stack': self.encode_labels()}
202
Neale Ranns177bbdc2016-11-15 09:46:51 +0000203
Neale Ranns5a8123b2017-01-26 01:18:23 -0800204class VppMRoutePath(VppRoutePath):
Neale Ranns32e1c012016-11-22 17:07:28 +0000205
Neale Rannsd792d9c2017-10-21 10:53:20 -0700206 def __init__(self, nh_sw_if_index, flags,
Neale Rannse821ab12017-06-01 07:45:05 -0700207 nh=None,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700208 proto=DpoProto.DPO_PROTO_IP4,
209 bier_imp=0):
Neale Rannse821ab12017-06-01 07:45:05 -0700210 if not nh:
211 nh = "::" if proto is DpoProto.DPO_PROTO_IP6 else "0.0.0.0"
212 super(VppMRoutePath, self).__init__(nh,
213 nh_sw_if_index,
214 proto=proto)
Neale Ranns32e1c012016-11-22 17:07:28 +0000215 self.nh_i_flags = flags
Neale Rannsd792d9c2017-10-21 10:53:20 -0700216 self.bier_imp = bier_imp
Neale Ranns32e1c012016-11-22 17:07:28 +0000217
218
Neale Ranns5a8123b2017-01-26 01:18:23 -0800219class VppIpRoute(VppObject):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000220 """
221 IP Route
222 """
223
224 def __init__(self, test, dest_addr,
Neale Ranns37be7362017-02-21 17:30:26 -0800225 dest_addr_len, paths, table_id=0, is_ip6=0, is_local=0,
226 is_unreach=0, is_prohibit=0):
Neale Ranns177bbdc2016-11-15 09:46:51 +0000227 self._test = test
228 self.paths = paths
Neale Ranns177bbdc2016-11-15 09:46:51 +0000229 self.dest_addr_len = dest_addr_len
230 self.table_id = table_id
Neale Rannsfca0c242017-01-13 07:57:46 -0800231 self.is_ip6 = is_ip6
232 self.is_local = is_local
Neale Ranns37be7362017-02-21 17:30:26 -0800233 self.is_unreach = is_unreach
234 self.is_prohibit = is_prohibit
Neale Rannsb3b2de72017-03-08 05:17:22 -0800235 self.dest_addr_p = dest_addr
Neale Rannsfca0c242017-01-13 07:57:46 -0800236 if is_ip6:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800237 self.dest_addr = inet_pton(AF_INET6, dest_addr)
Neale Rannsfca0c242017-01-13 07:57:46 -0800238 else:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800239 self.dest_addr = inet_pton(AF_INET, dest_addr)
Neale Ranns177bbdc2016-11-15 09:46:51 +0000240
Neale Ranns69b7aa42017-03-10 03:04:12 -0800241 def modify(self, paths, is_local=0,
242 is_unreach=0, is_prohibit=0):
243 self.paths = paths
244 self.is_local = is_local
245 self.is_unreach = is_unreach
246 self.is_prohibit = is_prohibit
247
Neale Ranns177bbdc2016-11-15 09:46:51 +0000248 def add_vpp_config(self):
Neale Ranns37be7362017-02-21 17:30:26 -0800249 if self.is_local or self.is_unreach or self.is_prohibit:
Klement Sekerada505f62017-01-04 12:58:53 +0100250 self._test.vapi.ip_add_del_route(
251 self.dest_addr,
252 self.dest_addr_len,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800253 inet_pton(AF_INET6, "::"),
Neale Rannsfca0c242017-01-13 07:57:46 -0800254 0xffffffff,
Neale Ranns37be7362017-02-21 17:30:26 -0800255 is_local=self.is_local,
256 is_unreach=self.is_unreach,
257 is_prohibit=self.is_prohibit,
Klement Sekerada505f62017-01-04 12:58:53 +0100258 table_id=self.table_id,
Neale Rannsfca0c242017-01-13 07:57:46 -0800259 is_ipv6=self.is_ip6)
260 else:
261 for path in self.paths:
Neale Ranns31ed7442018-02-23 05:29:09 -0800262 lstack = path.encode_labels()
263
Neale Rannsfca0c242017-01-13 07:57:46 -0800264 self._test.vapi.ip_add_del_route(
265 self.dest_addr,
266 self.dest_addr_len,
267 path.nh_addr,
268 path.nh_itf,
269 table_id=self.table_id,
Neale Ranns31ed7442018-02-23 05:29:09 -0800270 next_hop_out_label_stack=lstack,
271 next_hop_n_out_labels=len(lstack),
Neale Rannsfca0c242017-01-13 07:57:46 -0800272 next_hop_via_label=path.nh_via_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700273 next_hop_table_id=path.nh_table_id,
Neale Ranns810086d2017-11-05 16:26:46 -0800274 next_hop_id=path.next_hop_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700275 is_ipv6=self.is_ip6,
Neale Rannsf068c3e2018-01-03 04:18:48 -0800276 is_dvr=path.is_dvr,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700277 is_resolve_host=path.is_resolve_host,
278 is_resolve_attached=path.is_resolve_attached,
Neale Ranns054c03a2017-10-13 05:15:07 -0700279 is_source_lookup=path.is_source_lookup,
Neale Ranns810086d2017-11-05 16:26:46 -0800280 is_udp_encap=path.is_udp_encap,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700281 is_multipath=1 if len(self.paths) > 1 else 0)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800282 self._test.registry.register(self, self._test.logger)
Neale Ranns177bbdc2016-11-15 09:46:51 +0000283
284 def remove_vpp_config(self):
Neale Ranns37be7362017-02-21 17:30:26 -0800285 if self.is_local or self.is_unreach or self.is_prohibit:
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
329
330class VppIpMRoute(VppObject):
Neale Ranns32e1c012016-11-22 17:07:28 +0000331 """
332 IP Multicast Route
333 """
334
335 def __init__(self, test, src_addr, grp_addr,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800336 grp_addr_len, e_flags, paths, table_id=0,
337 rpf_id=0, is_ip6=0):
Neale Ranns32e1c012016-11-22 17:07:28 +0000338 self._test = test
339 self.paths = paths
340 self.grp_addr_len = grp_addr_len
341 self.table_id = table_id
342 self.e_flags = e_flags
343 self.is_ip6 = is_ip6
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800344 self.rpf_id = rpf_id
Neale Ranns32e1c012016-11-22 17:07:28 +0000345
Neale Ranns947ea622018-06-07 23:48:20 -0700346 self.grp_addr_p = grp_addr
347 self.src_addr_p = src_addr
Neale Ranns32e1c012016-11-22 17:07:28 +0000348 if is_ip6:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800349 self.grp_addr = inet_pton(AF_INET6, grp_addr)
350 self.src_addr = inet_pton(AF_INET6, src_addr)
Neale Ranns32e1c012016-11-22 17:07:28 +0000351 else:
Neale Rannsb3b2de72017-03-08 05:17:22 -0800352 self.grp_addr = inet_pton(AF_INET, grp_addr)
353 self.src_addr = inet_pton(AF_INET, src_addr)
Neale Ranns32e1c012016-11-22 17:07:28 +0000354
355 def add_vpp_config(self):
356 for path in self.paths:
357 self._test.vapi.ip_mroute_add_del(self.src_addr,
358 self.grp_addr,
359 self.grp_addr_len,
360 self.e_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700361 path.proto,
Neale Ranns32e1c012016-11-22 17:07:28 +0000362 path.nh_itf,
Neale Rannse821ab12017-06-01 07:45:05 -0700363 path.nh_addr,
Neale Ranns32e1c012016-11-22 17:07:28 +0000364 path.nh_i_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700365 bier_imp=path.bier_imp,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800366 rpf_id=self.rpf_id,
Neale Ranns32e1c012016-11-22 17:07:28 +0000367 table_id=self.table_id,
368 is_ipv6=self.is_ip6)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800369 self._test.registry.register(self, self._test.logger)
Neale Ranns32e1c012016-11-22 17:07:28 +0000370
371 def remove_vpp_config(self):
372 for path in self.paths:
373 self._test.vapi.ip_mroute_add_del(self.src_addr,
374 self.grp_addr,
375 self.grp_addr_len,
376 self.e_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700377 path.proto,
Neale Ranns32e1c012016-11-22 17:07:28 +0000378 path.nh_itf,
Neale Rannse821ab12017-06-01 07:45:05 -0700379 path.nh_addr,
Neale Ranns32e1c012016-11-22 17:07:28 +0000380 path.nh_i_flags,
381 table_id=self.table_id,
Neale Rannseea537a2018-01-09 04:11:28 -0800382 bier_imp=path.bier_imp,
Neale Ranns32e1c012016-11-22 17:07:28 +0000383 is_add=0,
384 is_ipv6=self.is_ip6)
385
386 def update_entry_flags(self, flags):
387 self.e_flags = flags
388 self._test.vapi.ip_mroute_add_del(self.src_addr,
389 self.grp_addr,
390 self.grp_addr_len,
391 self.e_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700392 0,
Neale Ranns32e1c012016-11-22 17:07:28 +0000393 0xffffffff,
Neale Rannse821ab12017-06-01 07:45:05 -0700394 "",
Neale Ranns32e1c012016-11-22 17:07:28 +0000395 0,
396 table_id=self.table_id,
397 is_ipv6=self.is_ip6)
398
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800399 def update_rpf_id(self, rpf_id):
400 self.rpf_id = rpf_id
401 self._test.vapi.ip_mroute_add_del(self.src_addr,
402 self.grp_addr,
403 self.grp_addr_len,
404 self.e_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700405 0,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800406 0xffffffff,
Neale Rannse821ab12017-06-01 07:45:05 -0700407 "",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800408 0,
409 rpf_id=self.rpf_id,
410 table_id=self.table_id,
411 is_ipv6=self.is_ip6)
412
Neale Ranns32e1c012016-11-22 17:07:28 +0000413 def update_path_flags(self, itf, flags):
414 for path in self.paths:
415 if path.nh_itf == itf:
416 path.nh_i_flags = flags
417 break
418 self._test.vapi.ip_mroute_add_del(self.src_addr,
419 self.grp_addr,
420 self.grp_addr_len,
421 self.e_flags,
Neale Rannsd792d9c2017-10-21 10:53:20 -0700422 path.proto,
Neale Ranns32e1c012016-11-22 17:07:28 +0000423 path.nh_itf,
Neale Rannse821ab12017-06-01 07:45:05 -0700424 path.nh_addr,
Neale Ranns32e1c012016-11-22 17:07:28 +0000425 path.nh_i_flags,
426 table_id=self.table_id,
427 is_ipv6=self.is_ip6)
428
Neale Ranns5a8123b2017-01-26 01:18:23 -0800429 def query_vpp_config(self):
Neale Ranns947ea622018-06-07 23:48:20 -0700430 return find_mroute(self._test,
431 self.grp_addr_p,
432 self.src_addr_p,
433 self.grp_addr_len,
434 self.table_id,
435 inet=AF_INET6 if self.is_ip6 == 1 else AF_INET)
Neale Ranns32e1c012016-11-22 17:07:28 +0000436
Neale Ranns5a8123b2017-01-26 01:18:23 -0800437 def __str__(self):
438 return self.object_id()
439
440 def object_id(self):
441 if self.is_ip6:
442 return ("%d:(%s,%s/%d)"
443 % (self.table_id,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800444 inet_ntop(AF_INET6, self.src_addr),
445 inet_ntop(AF_INET6, self.grp_addr),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800446 self.grp_addr_len))
447 else:
448 return ("%d:(%s,%s/%d)"
449 % (self.table_id,
Neale Rannsb3b2de72017-03-08 05:17:22 -0800450 inet_ntop(AF_INET, self.src_addr),
451 inet_ntop(AF_INET, self.grp_addr),
Neale Ranns5a8123b2017-01-26 01:18:23 -0800452 self.grp_addr_len))
453
454
455class VppMFibSignal(object):
Neale Ranns32e1c012016-11-22 17:07:28 +0000456 def __init__(self, test, route, interface, packet):
457 self.route = route
458 self.interface = interface
459 self.packet = packet
460 self.test = test
461
462 def compare(self, signal):
463 self.test.assertEqual(self.interface, signal.sw_if_index)
464 self.test.assertEqual(self.route.table_id, signal.table_id)
465 self.test.assertEqual(self.route.grp_addr_len,
466 signal.grp_address_len)
467 for i in range(self.route.grp_addr_len / 8):
468 self.test.assertEqual(self.route.grp_addr[i],
469 signal.grp_address[i])
470 if (self.route.grp_addr_len > 32):
471 for i in range(4):
472 self.test.assertEqual(self.route.src_addr[i],
473 signal.src_address[i])
474
475
Neale Ranns5a8123b2017-01-26 01:18:23 -0800476class VppMplsIpBind(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000477 """
478 MPLS to IP Binding
479 """
480
Neale Ranns5a8123b2017-01-26 01:18:23 -0800481 def __init__(self, test, local_label, dest_addr, dest_addr_len,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700482 table_id=0, ip_table_id=0, is_ip6=0):
Neale Rannsad422ed2016-11-02 14:20:04 +0000483 self._test = test
Neale Rannsad422ed2016-11-02 14:20:04 +0000484 self.dest_addr_len = dest_addr_len
Neale Rannsf12a83f2017-04-18 09:09:40 -0700485 self.dest_addr = dest_addr
Neale Rannsad422ed2016-11-02 14:20:04 +0000486 self.local_label = local_label
Neale Ranns5a8123b2017-01-26 01:18:23 -0800487 self.table_id = table_id
488 self.ip_table_id = ip_table_id
Neale Rannsf12a83f2017-04-18 09:09:40 -0700489 self.is_ip6 = is_ip6
490 if is_ip6:
491 self.dest_addrn = inet_pton(AF_INET6, dest_addr)
492 else:
493 self.dest_addrn = inet_pton(AF_INET, dest_addr)
Neale Rannsad422ed2016-11-02 14:20:04 +0000494
495 def add_vpp_config(self):
496 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700497 self.dest_addrn,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800498 self.dest_addr_len,
499 table_id=self.table_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700500 ip_table_id=self.ip_table_id,
501 is_ip4=(self.is_ip6 == 0))
Neale Ranns5a8123b2017-01-26 01:18:23 -0800502 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000503
504 def remove_vpp_config(self):
505 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700506 self.dest_addrn,
Neale Rannsad422ed2016-11-02 14:20:04 +0000507 self.dest_addr_len,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700508 table_id=self.table_id,
509 ip_table_id=self.ip_table_id,
510 is_bind=0,
511 is_ip4=(self.is_ip6 == 0))
Neale Rannsad422ed2016-11-02 14:20:04 +0000512
Neale Ranns5a8123b2017-01-26 01:18:23 -0800513 def query_vpp_config(self):
514 dump = self._test.vapi.mpls_fib_dump()
515 for e in dump:
516 if self.local_label == e.label \
Neale Ranns5a8123b2017-01-26 01:18:23 -0800517 and self.table_id == e.table_id:
518 return True
519 return False
Neale Rannsad422ed2016-11-02 14:20:04 +0000520
Neale Ranns5a8123b2017-01-26 01:18:23 -0800521 def __str__(self):
522 return self.object_id()
523
524 def object_id(self):
525 return ("%d:%s binds %d:%s/%d"
526 % (self.table_id,
527 self.local_label,
528 self.ip_table_id,
Neale Rannsf12a83f2017-04-18 09:09:40 -0700529 self.dest_addr,
Neale Ranns5a8123b2017-01-26 01:18:23 -0800530 self.dest_addr_len))
531
532
Neale Ranns15002542017-09-10 04:39:11 -0700533class VppMplsTable(VppObject):
534
535 def __init__(self,
536 test,
537 table_id):
538 self._test = test
539 self.table_id = table_id
540
541 def add_vpp_config(self):
542 self._test.vapi.mpls_table_add_del(
543 self.table_id,
544 is_add=1)
545 self._test.registry.register(self, self._test.logger)
546
547 def remove_vpp_config(self):
548 self._test.vapi.mpls_table_add_del(
549 self.table_id,
550 is_add=0)
551
552 def query_vpp_config(self):
553 # find the default route
554 dump = self._test.vapi.mpls_fib_dump()
555 if len(dump):
556 return True
557 return False
558
559 def __str__(self):
560 return self.object_id()
561
562 def object_id(self):
563 return ("table-mpls-%d" % (self.table_id))
564
565
Neale Ranns5a8123b2017-01-26 01:18:23 -0800566class VppMplsRoute(VppObject):
Neale Rannsad422ed2016-11-02 14:20:04 +0000567 """
Neale Ranns5a8123b2017-01-26 01:18:23 -0800568 MPLS Route/LSP
Neale Rannsad422ed2016-11-02 14:20:04 +0000569 """
570
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800571 def __init__(self, test, local_label, eos_bit, paths, table_id=0,
572 is_multicast=0):
Neale Rannsad422ed2016-11-02 14:20:04 +0000573 self._test = test
574 self.paths = paths
575 self.local_label = local_label
576 self.eos_bit = eos_bit
577 self.table_id = table_id
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800578 self.is_multicast = is_multicast
Neale Rannsad422ed2016-11-02 14:20:04 +0000579
580 def add_vpp_config(self):
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800581 is_multipath = len(self.paths) > 1
Neale Rannsad422ed2016-11-02 14:20:04 +0000582 for path in self.paths:
Neale Ranns31ed7442018-02-23 05:29:09 -0800583 lstack = path.encode_labels()
584
Klement Sekerada505f62017-01-04 12:58:53 +0100585 self._test.vapi.mpls_route_add_del(
586 self.local_label,
587 self.eos_bit,
Neale Rannsda78f952017-05-24 09:15:43 -0700588 path.proto,
Klement Sekerada505f62017-01-04 12:58:53 +0100589 path.nh_addr,
590 path.nh_itf,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800591 is_multicast=self.is_multicast,
592 is_multipath=is_multipath,
Klement Sekerada505f62017-01-04 12:58:53 +0100593 table_id=self.table_id,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800594 is_interface_rx=path.is_interface_rx,
595 is_rpf_id=path.is_rpf_id,
Neale Ranns31ed7442018-02-23 05:29:09 -0800596 next_hop_out_label_stack=lstack,
597 next_hop_n_out_labels=len(lstack),
Klement Sekerada505f62017-01-04 12:58:53 +0100598 next_hop_via_label=path.nh_via_label,
599 next_hop_table_id=path.nh_table_id)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800600 self._test.registry.register(self, self._test.logger)
Neale Rannsad422ed2016-11-02 14:20:04 +0000601
602 def remove_vpp_config(self):
603 for path in self.paths:
604 self._test.vapi.mpls_route_add_del(self.local_label,
605 self.eos_bit,
Neale Rannsda78f952017-05-24 09:15:43 -0700606 path.proto,
Neale Rannsad422ed2016-11-02 14:20:04 +0000607 path.nh_addr,
608 path.nh_itf,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800609 is_rpf_id=path.is_rpf_id,
Neale Rannsad422ed2016-11-02 14:20:04 +0000610 table_id=self.table_id,
611 is_add=0)
Neale Ranns5a8123b2017-01-26 01:18:23 -0800612
613 def query_vpp_config(self):
614 dump = self._test.vapi.mpls_fib_dump()
615 for e in dump:
616 if self.local_label == e.label \
617 and self.eos_bit == e.eos_bit \
618 and self.table_id == e.table_id:
619 return True
620 return False
621
622 def __str__(self):
623 return self.object_id()
624
625 def object_id(self):
626 return ("%d:%s/%d"
627 % (self.table_id,
628 self.local_label,
629 20+self.eos_bit))