4 object abstractions for representing IP routes in VPP
7 from vpp_object import *
8 from socket import inet_pton, inet_ntop, AF_INET, AF_INET6
10 # from vnet/vnet/mpls/mpls_types.h
11 MPLS_IETF_MAX_LABEL = 0xfffff
12 MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
15 def find_route(test, ip_addr, len, table_id=0, inet=AF_INET):
18 routes = test.vapi.ip_fib_dump()
21 routes = test.vapi.ip6_fib_dump()
23 route_addr = inet_pton(inet, ip_addr)
25 if route_addr == e.address[:s] \
26 and len == e.address_length \
27 and table_id == e.table_id:
32 class VppRoutePath(object):
40 nh_via_label=MPLS_LABEL_INVALID,
42 self.nh_itf = nh_sw_if_index
43 self.nh_table_id = nh_table_id
44 self.nh_via_label = nh_via_label
45 self.nh_labels = labels
47 self.nh_addr = inet_pton(AF_INET6, nh_addr)
49 self.nh_addr = inet_pton(AF_INET, nh_addr)
52 class VppMRoutePath(VppRoutePath):
54 def __init__(self, nh_sw_if_index, flags):
55 super(VppMRoutePath, self).__init__("0.0.0.0",
57 self.nh_i_flags = flags
60 class VppIpRoute(VppObject):
65 def __init__(self, test, dest_addr,
66 dest_addr_len, paths, table_id=0, is_ip6=0, is_local=0,
67 is_unreach=0, is_prohibit=0):
70 self.dest_addr_len = dest_addr_len
71 self.table_id = table_id
73 self.is_local = is_local
74 self.is_unreach = is_unreach
75 self.is_prohibit = is_prohibit
76 self.dest_addr_p = dest_addr
78 self.dest_addr = inet_pton(AF_INET6, dest_addr)
80 self.dest_addr = inet_pton(AF_INET, dest_addr)
82 def add_vpp_config(self):
83 if self.is_local or self.is_unreach or self.is_prohibit:
84 self._test.vapi.ip_add_del_route(
87 inet_pton(AF_INET6, "::"),
89 is_local=self.is_local,
90 is_unreach=self.is_unreach,
91 is_prohibit=self.is_prohibit,
92 table_id=self.table_id,
95 for path in self.paths:
96 self._test.vapi.ip_add_del_route(
101 table_id=self.table_id,
102 next_hop_out_label_stack=path.nh_labels,
103 next_hop_n_out_labels=len(
105 next_hop_via_label=path.nh_via_label,
107 self._test.registry.register(self, self._test.logger)
109 def remove_vpp_config(self):
110 if self.is_local or self.is_unreach or self.is_prohibit:
111 self._test.vapi.ip_add_del_route(
114 inet_pton(AF_INET6, "::"),
116 is_local=self.is_local,
117 is_unreach=self.is_unreach,
118 is_prohibit=self.is_prohibit,
120 table_id=self.table_id,
123 for path in self.paths:
124 self._test.vapi.ip_add_del_route(self.dest_addr,
128 table_id=self.table_id,
131 def query_vpp_config(self):
132 return find_route(self._test,
136 inet=AF_INET6 if self.is_ip6 == 1 else AF_INET)
139 return self.object_id()
148 class VppIpMRoute(VppObject):
153 def __init__(self, test, src_addr, grp_addr,
154 grp_addr_len, e_flags, paths, table_id=0, is_ip6=0):
157 self.grp_addr_len = grp_addr_len
158 self.table_id = table_id
159 self.e_flags = e_flags
163 self.grp_addr = inet_pton(AF_INET6, grp_addr)
164 self.src_addr = inet_pton(AF_INET6, src_addr)
166 self.grp_addr = inet_pton(AF_INET, grp_addr)
167 self.src_addr = inet_pton(AF_INET, src_addr)
169 def add_vpp_config(self):
170 for path in self.paths:
171 self._test.vapi.ip_mroute_add_del(self.src_addr,
177 table_id=self.table_id,
179 self._test.registry.register(self, self._test.logger)
181 def remove_vpp_config(self):
182 for path in self.paths:
183 self._test.vapi.ip_mroute_add_del(self.src_addr,
189 table_id=self.table_id,
193 def update_entry_flags(self, flags):
195 self._test.vapi.ip_mroute_add_del(self.src_addr,
201 table_id=self.table_id,
204 def update_path_flags(self, itf, flags):
205 for path in self.paths:
206 if path.nh_itf == itf:
207 path.nh_i_flags = flags
209 self._test.vapi.ip_mroute_add_del(self.src_addr,
215 table_id=self.table_id,
218 def query_vpp_config(self):
219 dump = self._test.vapi.ip_fib_dump()
221 if self.grp_addr == e.address \
222 and self.grp_addr_len == e.address_length \
223 and self.table_id == e.table_id:
228 return self.object_id()
232 return ("%d:(%s,%s/%d)"
234 inet_ntop(AF_INET6, self.src_addr),
235 inet_ntop(AF_INET6, self.grp_addr),
238 return ("%d:(%s,%s/%d)"
240 inet_ntop(AF_INET, self.src_addr),
241 inet_ntop(AF_INET, self.grp_addr),
245 class VppMFibSignal(object):
246 def __init__(self, test, route, interface, packet):
248 self.interface = interface
252 def compare(self, signal):
253 self.test.assertEqual(self.interface, signal.sw_if_index)
254 self.test.assertEqual(self.route.table_id, signal.table_id)
255 self.test.assertEqual(self.route.grp_addr_len,
256 signal.grp_address_len)
257 for i in range(self.route.grp_addr_len / 8):
258 self.test.assertEqual(self.route.grp_addr[i],
259 signal.grp_address[i])
260 if (self.route.grp_addr_len > 32):
262 self.test.assertEqual(self.route.src_addr[i],
263 signal.src_address[i])
266 class VppMplsIpBind(VppObject):
271 def __init__(self, test, local_label, dest_addr, dest_addr_len,
272 table_id=0, ip_table_id=0):
274 self.dest_addr = inet_pton(AF_INET, dest_addr)
275 self.dest_addr_len = dest_addr_len
276 self.local_label = local_label
277 self.table_id = table_id
278 self.ip_table_id = ip_table_id
280 def add_vpp_config(self):
281 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
284 table_id=self.table_id,
285 ip_table_id=self.ip_table_id)
286 self._test.registry.register(self, self._test.logger)
288 def remove_vpp_config(self):
289 self._test.vapi.mpls_ip_bind_unbind(self.local_label,
294 def query_vpp_config(self):
295 dump = self._test.vapi.mpls_fib_dump()
297 if self.local_label == e.label \
298 and self.eos_bit == e.eos_bit \
299 and self.table_id == e.table_id:
304 return self.object_id()
307 return ("%d:%s binds %d:%s/%d"
311 inet_ntop(AF_INET, self.dest_addr),
315 class VppMplsRoute(VppObject):
320 def __init__(self, test, local_label, eos_bit, paths, table_id=0):
323 self.local_label = local_label
324 self.eos_bit = eos_bit
325 self.table_id = table_id
327 def add_vpp_config(self):
328 for path in self.paths:
329 self._test.vapi.mpls_route_add_del(
335 table_id=self.table_id,
336 next_hop_out_label_stack=path.nh_labels,
337 next_hop_n_out_labels=len(
339 next_hop_via_label=path.nh_via_label,
340 next_hop_table_id=path.nh_table_id)
341 self._test.registry.register(self, self._test.logger)
343 def remove_vpp_config(self):
344 for path in self.paths:
345 self._test.vapi.mpls_route_add_del(self.local_label,
350 table_id=self.table_id,
353 def query_vpp_config(self):
354 dump = self._test.vapi.mpls_fib_dump()
356 if self.local_label == e.label \
357 and self.eos_bit == e.eos_bit \
358 and self.table_id == e.table_id:
363 return self.object_id()