VXLAN multicast dst (remote) address support
[vpp.git] / test / vpp_papi_provider.py
1 import os
2 from logging import error
3 from hook import Hook
4
5 do_import = True
6 try:
7     no_vpp_papi = os.getenv("NO_VPP_PAPI")
8     if no_vpp_papi == "1":
9         do_import = False
10 except:
11     pass
12
13 if do_import:
14     import vpp_papi
15
16
17 # from vnet/vnet/mpls/mpls_types.h
18 MPLS_IETF_MAX_LABEL = 0xfffff
19 MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
20
21 class L2_VTR_OP:
22     L2_POP_1 = 3
23
24
25 class VppPapiProvider(object):
26     """VPP-api provider using vpp-papi
27
28     @property hook: hook object providing before and after api/cli hooks
29
30
31     """
32
33     def __init__(self, name, shm_prefix):
34         self.hook = Hook("vpp-papi-provider")
35         self.name = name
36         self.shm_prefix = shm_prefix
37
38     def register_hook(self, hook):
39         """Replace hook registration with new hook
40
41         :param hook:
42
43         """
44         self.hook = hook
45
46     def connect(self):
47         """Connect the API to VPP"""
48         vpp_papi.connect(self.name, self.shm_prefix)
49
50     def disconnect(self):
51         """Disconnect the API from VPP"""
52         vpp_papi.disconnect()
53
54     def api(self, api_fn, api_args, expected_retval=0):
55         """Call API function and check it's return value
56         Call the appropriate hooks before and after the API call
57
58         :param api_fn: API function to call
59         :param api_args: tuple of API function arguments
60         :param expected_retval: Expected return value (Default value = 0)
61         :returns: reply from the API
62
63         """
64         self.hook.before_api(api_fn.__name__, api_args)
65         reply = api_fn(*api_args)
66         if hasattr(reply, 'retval') and reply.retval != expected_retval:
67             msg = "API call failed, expected retval == %d, got %s" % (
68                 expected_retval, repr(reply))
69             error(msg)
70             raise Exception(msg)
71         self.hook.after_api(api_fn.__name__, api_args)
72         return reply
73
74     def cli(self, cli):
75         """
76         Execute a CLI, calling the before/after hooks appropriately.
77
78         :param cli: CLI to execute
79         :returns: CLI output
80
81         """
82         self.hook.before_cli(cli)
83         cli += '\n'
84         r = vpp_papi.cli_inband(len(cli), cli)
85         self.hook.after_cli(cli)
86         if hasattr(r, 'reply'):
87             return r.reply[0].decode().rstrip('\x00')
88
89     def ppcli(self, cli):
90         """
91         Helping method to print CLI command in case of info logging level.
92
93         :param cli: CLI to execute
94         :returns: CLI output
95         """
96         return cli + "\n" + str(self.cli(cli))
97
98     def _convert_mac(self, mac):
99         return int(mac.replace(":", ""), 16) << 16
100
101     def show_version(self):
102         """ """
103         return vpp_papi.show_version()
104
105     def pg_create_interface(self, pg_index):
106         """
107
108         :param pg_index:
109
110         """
111         return self.api(vpp_papi.pg_create_interface, (pg_index, ))
112
113     def sw_interface_dump(self, filter=None):
114         """
115
116         :param filter:  (Default value = None)
117
118         """
119         if filter is not None:
120             args = (1, filter)
121         else:
122             args = (0, b'')
123         return self.api(vpp_papi.sw_interface_dump, args)
124
125     def sw_interface_set_table(self, sw_if_index, is_ipv6, table_id):
126         """
127           Set the IPvX Table-id for the Interface
128
129         :param sw_if_index:
130         :param is_ipv6:
131         :param table_id:
132
133         """
134         return self.api(vpp_papi.sw_interface_set_table,
135                         (sw_if_index, is_ipv6, table_id))
136
137     def sw_interface_add_del_address(self, sw_if_index, addr, addr_len,
138                                      is_ipv6=0, is_add=1, del_all=0):
139         """
140
141         :param addr: param is_ipv6:  (Default value = 0)
142         :param sw_if_index:
143         :param addr_len:
144         :param is_ipv6:  (Default value = 0)
145         :param is_add:  (Default value = 1)
146         :param del_all:  (Default value = 0)
147
148         """
149         return self.api(vpp_papi.sw_interface_add_del_address,
150                         (sw_if_index, is_add, is_ipv6, del_all, addr_len, addr))
151
152     def sw_interface_enable_disable_mpls(self, sw_if_index,
153                                          is_enable=1):
154         """
155         Enable/Disable MPLS on the interface
156         :param sw_if_index:
157         :param is_enable:  (Default value = 1)
158
159         """
160         return self.api(vpp_papi.sw_interface_set_mpls_enable,
161                         (sw_if_index, is_enable))
162
163     def sw_interface_ra_suppress(self, sw_if_index):
164         suppress = 1
165         managed = 0
166         other = 0
167         ll_option = 0
168         send_unicast = 0
169         cease = 0
170         is_no = 0
171         default_router = 0
172         max_interval = 0
173         min_interval = 0
174         lifetime = 0
175         initial_count = 0
176         initial_interval = 0
177         async = False
178         return self.api(vpp_papi.sw_interface_ip6nd_ra_config,
179                         (sw_if_index, suppress, managed, other,
180                          ll_option, send_unicast, cease, is_no,
181                          default_router, max_interval, min_interval,
182                          lifetime, initial_count, initial_interval, async))
183
184     def vxlan_add_del_tunnel(
185             self,
186             src_addr,
187             dst_addr,
188             mcast_sw_if_index=0xFFFFFFFF,
189             is_add=1,
190             is_ipv6=0,
191             encap_vrf_id=0,
192             decap_next_index=0xFFFFFFFF,
193             vni=0):
194         """
195
196         :param dst_addr:
197         :param src_addr:
198         :param is_add:  (Default value = 1)
199         :param is_ipv6:  (Default value = 0)
200         :param encap_vrf_id:  (Default value = 0)
201         :param decap_next_index:  (Default value = 0xFFFFFFFF)
202         :param mcast_sw_if_index:  (Default value = 0xFFFFFFFF)
203         :param vni:  (Default value = 0)
204
205         """
206         return self.api(vpp_papi.vxlan_add_del_tunnel,
207                         (is_add, is_ipv6, src_addr, dst_addr, mcast_sw_if_index,
208                          encap_vrf_id, decap_next_index, vni))
209
210     def bridge_domain_add_del(self, bd_id, flood=1, uu_flood=1, forward=1,
211                               learn=1, arp_term=0, is_add=1):
212         """Create/delete bridge domain.
213
214         :param int bd_id: Bridge domain index.
215         :param int flood: Enable/disable bcast/mcast flooding in the BD.
216             (Default value = 1)
217         :param int uu_flood: Enable/disable unknown unicast flood in the BD.
218             (Default value = 1)
219         :param int forward: Enable/disable forwarding on all interfaces in
220             the BD. (Default value = 1)
221         :param int learn: Enable/disable learning on all interfaces in the BD.
222             (Default value = 1)
223         :param int arp_term: Enable/disable arp termination in the BD.
224             (Default value = 1)
225         :param int is_add: Add or delete flag. (Default value = 1)
226         """
227         return self.api(vpp_papi.bridge_domain_add_del,
228                         (bd_id, flood, uu_flood, forward, learn, arp_term,
229                          is_add))
230
231     def l2fib_add_del(self, mac, bd_id, sw_if_index, is_add=1, static_mac=0,
232                       filter_mac=0, bvi_mac=0):
233         """Create/delete L2 FIB entry.
234
235         :param str mac: MAC address to create FIB entry for.
236         :param int bd_id: Bridge domain index.
237         :param int sw_if_index: Software interface index of the interface.
238         :param int is_add: Add or delete flag. (Default value = 1)
239         :param int static_mac: Set to 1 to create static MAC entry.
240             (Default value = 0)
241         :param int filter_mac: Set to 1 to drop packet that's source or
242             destination MAC address contains defined MAC address.
243             (Default value = 0)
244         :param int bvi_mac: Set to 1 to create entry that points to BVI
245             interface. (Default value = 0)
246         """
247         return self.api(vpp_papi.l2fib_add_del,
248                         (self._convert_mac(mac), bd_id, sw_if_index, is_add,
249                          static_mac, filter_mac, bvi_mac))
250
251     def sw_interface_set_l2_bridge(self, sw_if_index, bd_id,
252                                    shg=0, bvi=0, enable=1):
253         """Add/remove interface to/from bridge domain.
254
255         :param int sw_if_index: Software interface index of the interface.
256         :param int bd_id: Bridge domain index.
257         :param int shg: Split-horizon group index. (Default value = 0)
258         :param int bvi: Set interface as a bridge group virtual interface.
259             (Default value = 0)
260         :param int enable: Add or remove interface. (Default value = 1)
261         """
262         return self.api(vpp_papi.sw_interface_set_l2_bridge,
263                         (sw_if_index, bd_id, shg, bvi, enable))
264
265     def sw_interface_set_l2_xconnect(self, rx_sw_if_index, tx_sw_if_index,
266                                      enable):
267         """Create or delete unidirectional cross-connect from Tx interface to
268         Rx interface.
269
270         :param int rx_sw_if_index: Software interface index of Rx interface.
271         :param int tx_sw_if_index: Software interface index of Tx interface.
272         :param int enable: Create cross-connect if equal to 1, delete
273             cross-connect if equal to 0.
274
275         """
276         return self.api(vpp_papi.sw_interface_set_l2_xconnect,
277                         (rx_sw_if_index, tx_sw_if_index, enable))
278
279     def sw_interface_set_l2_tag_rewrite(self, sw_if_index, vtr_oper, push=0, tag1=0, tag2=0):
280         """L2 interface vlan tag rewrite configure request
281         :param client_index - opaque cookie to identify the sender
282         :param context - sender context, to match reply w/ request
283         :param sw_if_index - interface the operation is applied to
284         :param vtr_op - Choose from l2_vtr_op_t enum values
285         :param push_dot1q - first pushed flag dot1q id set, else dot1ad
286         :param tag1 - Needed for any push or translate vtr op
287         :param tag2 - Needed for any push 2 or translate x-2 vtr ops
288
289         """
290         return self.api(vpp_papi.l2_interface_vlan_tag_rewrite,
291                         (sw_if_index, vtr_oper, push, tag1, tag2))
292
293     def sw_interface_set_flags(self, sw_if_index, admin_up_down,
294                                link_up_down=0, deleted=0):
295         """
296
297         :param admin_up_down:
298         :param sw_if_index:
299         :param link_up_down:  (Default value = 0)
300         :param deleted:  (Default value = 0)
301
302         """
303         return self.api(vpp_papi.sw_interface_set_flags,
304                         (sw_if_index, admin_up_down, link_up_down, deleted))
305
306     def create_subif(self, sw_if_index, sub_id, outer_vlan, inner_vlan,
307                      no_tags=0, one_tag=0, two_tags=0, dot1ad=0, exact_match=0,
308                      default_sub=0, outer_vlan_id_any=0, inner_vlan_id_any=0):
309         """Create subinterface
310         from vpe.api: set dot1ad = 0 for dot1q, set dot1ad = 1 for dot1ad
311
312         :param sub_id: param inner_vlan:
313         :param sw_if_index:
314         :param outer_vlan:
315         :param inner_vlan:
316         :param no_tags:  (Default value = 0)
317         :param one_tag:  (Default value = 0)
318         :param two_tags:  (Default value = 0)
319         :param dot1ad:  (Default value = 0)
320         :param exact_match:  (Default value = 0)
321         :param default_sub:  (Default value = 0)
322         :param outer_vlan_id_any:  (Default value = 0)
323         :param inner_vlan_id_any:  (Default value = 0)
324
325         """
326         return self.api(
327             vpp_papi.create_subif,
328             (sw_if_index,
329              sub_id,
330              no_tags,
331              one_tag,
332              two_tags,
333              dot1ad,
334              exact_match,
335              default_sub,
336              outer_vlan_id_any,
337              inner_vlan_id_any,
338              outer_vlan,
339              inner_vlan))
340
341     def delete_subif(self, sw_if_index):
342         """Delete subinterface
343
344         :param sw_if_index:
345         """
346         return self.api(vpp_papi.delete_subif, ([sw_if_index]))
347
348     def create_vlan_subif(self, sw_if_index, vlan):
349         """
350
351         :param vlan:
352         :param sw_if_index:
353
354         """
355         return self.api(vpp_papi.create_vlan_subif, (sw_if_index, vlan))
356
357     def create_loopback(self, mac=''):
358         """
359
360         :param mac: (Optional)
361         """
362         return self.api(vpp_papi.create_loopback, (mac,))
363
364     def ip_add_del_route(
365             self,
366             dst_address,
367             dst_address_length,
368             next_hop_address,
369             next_hop_sw_if_index=0xFFFFFFFF,
370             table_id=0,
371             resolve_attempts=0,
372             classify_table_index=0xFFFFFFFF,
373             next_hop_out_label=MPLS_LABEL_INVALID,
374             next_hop_table_id=0,
375             create_vrf_if_needed=0,
376             resolve_if_needed=0,
377             is_add=1,
378             is_drop=0,
379             is_unreach=0,
380             is_prohibit=0,
381             is_ipv6=0,
382             is_local=0,
383             is_classify=0,
384             is_multipath=0,
385             is_resolve_host=0,
386             is_resolve_attached=0,
387             not_last=0,
388             next_hop_weight=1):
389         """
390
391         :param dst_address_length:
392         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
393         :param dst_address:
394         :param next_hop_address:
395         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
396         :param vrf_id:  (Default value = 0)
397         :param lookup_in_vrf:  (Default value = 0)
398         :param resolve_attempts:  (Default value = 0)
399         :param classify_table_index:  (Default value = 0xFFFFFFFF)
400         :param create_vrf_if_needed:  (Default value = 0)
401         :param resolve_if_needed:  (Default value = 0)
402         :param is_add:  (Default value = 1)
403         :param is_drop:  (Default value = 0)
404         :param is_ipv6:  (Default value = 0)
405         :param is_local:  (Default value = 0)
406         :param is_classify:  (Default value = 0)
407         :param is_multipath:  (Default value = 0)
408         :param is_resolve_host:  (Default value = 0)
409         :param is_resolve_attached:  (Default value = 0)
410         :param not_last:  (Default value = 0)
411         :param next_hop_weight:  (Default value = 1)
412
413         """
414         return self.api(
415             vpp_papi.ip_add_del_route,
416             (next_hop_sw_if_index,
417              table_id,
418              resolve_attempts,
419              classify_table_index,
420              next_hop_out_label,
421              next_hop_table_id,
422              create_vrf_if_needed,
423              resolve_if_needed,
424              is_add,
425              is_drop,
426              is_unreach,
427              is_prohibit,
428              is_ipv6,
429              is_local,
430              is_classify,
431              is_multipath,
432              is_resolve_host,
433              is_resolve_attached,
434              not_last,
435              next_hop_weight,
436              dst_address_length,
437              dst_address,
438              next_hop_address))
439
440     def ip_neighbor_add_del(self,
441                             sw_if_index,
442                             mac_address,
443                             dst_address,
444                             vrf_id=0,
445                             is_add=1,
446                             is_ipv6=0,
447                             is_static=0,
448                             ):
449         """ Add neighbor MAC to IPv4 or IPv6 address.
450
451         :param sw_if_index:
452         :param mac_address:
453         :param dst_address:
454         :param vrf_id:  (Default value = 0)
455         :param is_add:  (Default value = 1)
456         :param is_ipv6:  (Default value = 0)
457         :param is_static:  (Default value = 0)
458         """
459
460         return self.api(
461             vpp_papi.ip_neighbor_add_del,
462             (vrf_id,
463              sw_if_index,
464              is_add,
465              is_ipv6,
466              is_static,
467              mac_address,
468              dst_address
469              )
470         )
471
472     def sw_interface_span_enable_disable(self, sw_if_index_from, sw_if_index_to, enable=1):
473         """
474
475         :param sw_if_index_from:
476         :param sw_if_index_to:
477         :param enable
478
479         """
480         return self.api(vpp_papi.sw_interface_span_enable_disable, (sw_if_index_from, sw_if_index_to, enable ))
481
482     def gre_tunnel_add_del(self,
483                            src_address,
484                            dst_address,
485                            outer_fib_id=0,
486                            is_teb=0,
487                            is_add=1,
488                            is_ip6=0):
489         """ Add a GRE tunnel
490
491         :param src_address:
492         :param dst_address:
493         :param outer_fib_id:  (Default value = 0)
494         :param is_add:  (Default value = 1)
495         :param is_ipv6:  (Default value = 0)
496         :param is_teb:  (Default value = 0)
497         """
498
499         return self.api(
500             vpp_papi.gre_add_del_tunnel,
501             (is_add,
502              is_ip6,
503              is_teb,
504              src_address,
505              dst_address,
506              outer_fib_id)
507         )