5721b6b92adf1af36a1e1978d77e41a021e8d27b
[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
22 class VppPapiProvider(object):
23     """VPP-api provider using vpp-papi
24
25     @property hook: hook object providing before and after api/cli hooks
26
27
28     """
29
30     def __init__(self, name, shm_prefix):
31         self.hook = Hook("vpp-papi-provider")
32         self.name = name
33         self.shm_prefix = shm_prefix
34
35     def register_hook(self, hook):
36         """Replace hook registration with new hook
37
38         :param hook:
39
40         """
41         self.hook = hook
42
43     def connect(self):
44         """Connect the API to VPP"""
45         vpp_papi.connect(self.name, self.shm_prefix)
46
47     def disconnect(self):
48         """Disconnect the API from VPP"""
49         vpp_papi.disconnect()
50
51     def api(self, api_fn, api_args, expected_retval=0):
52         """Call API function and check it's return value
53         Call the appropriate hooks before and after the API call
54
55         :param api_fn: API function to call
56         :param api_args: tuple of API function arguments
57         :param expected_retval: Expected return value (Default value = 0)
58         :returns: reply from the API
59
60         """
61         self.hook.before_api(api_fn.__name__, api_args)
62         reply = api_fn(*api_args)
63         if hasattr(reply, 'retval') and reply.retval != expected_retval:
64             msg = "API call failed, expected retval == %d, got %s" % (
65                 expected_retval, repr(reply))
66             error(msg)
67             raise Exception(msg)
68         self.hook.after_api(api_fn.__name__, api_args)
69         return reply
70
71     def cli(self, cli):
72         """
73         Execute a CLI, calling the before/after hooks appropriately.
74
75         :param cli: CLI to execute
76         :returns: CLI output
77
78         """
79         self.hook.before_cli(cli)
80         cli += '\n'
81         r = vpp_papi.cli_inband(len(cli), cli)
82         self.hook.after_cli(cli)
83         if hasattr(r, 'reply'):
84             return r.reply[0].decode().rstrip('\x00')
85
86     def ppcli(self, cli):
87         """
88         Helping method to print CLI command in case of info logging level.
89
90         :param cli: CLI to execute
91         :returns: CLI output
92         """
93         return cli + "\n" + self.cli(cli)
94
95     def show_version(self):
96         """ """
97         return vpp_papi.show_version()
98
99     def pg_create_interface(self, pg_index):
100         """
101
102         :param pg_index:
103
104         """
105         return self.api(vpp_papi.pg_create_interface, (pg_index, ))
106
107     def sw_interface_dump(self, filter=None):
108         """
109
110         :param filter:  (Default value = None)
111
112         """
113         if filter is not None:
114             args = (1, filter)
115         else:
116             args = (0, b'')
117         return self.api(vpp_papi.sw_interface_dump, args)
118
119     def sw_interface_set_table(self, sw_if_index, is_ipv6, table_id):
120         """
121           Set the IPvX Table-id for the Interface
122
123         :param sw_if_index:
124         :param is_ipv6:
125         :param table_id:
126
127         """
128         return self.api(vpp_papi.sw_interface_set_table,
129                         (sw_if_index, is_ipv6, table_id))
130
131     def sw_interface_add_del_address(self, sw_if_index, addr, addr_len,
132                                      is_ipv6=0, is_add=1, del_all=0):
133         """
134
135         :param addr: param is_ipv6:  (Default value = 0)
136         :param sw_if_index:
137         :param addr_len:
138         :param is_ipv6:  (Default value = 0)
139         :param is_add:  (Default value = 1)
140         :param del_all:  (Default value = 0)
141
142         """
143         return self.api(vpp_papi.sw_interface_add_del_address,
144                         (sw_if_index, is_add, is_ipv6, del_all, addr_len, addr))
145
146     def sw_interface_enable_disable_mpls(self, sw_if_index,
147                                          is_enable=1):
148         """
149         Enable/Disable MPLS on the interface
150         :param sw_if_index:
151         :param is_enable:  (Default value = 1)
152
153         """
154         return self.api(vpp_papi.sw_interface_set_mpls_enable,
155                         (sw_if_index, is_enable))
156
157     def sw_interface_ra_suppress(self, sw_if_index):
158         suppress = 1
159         managed = 0
160         other = 0
161         ll_option = 0
162         send_unicast = 0
163         cease = 0
164         is_no = 0
165         default_router = 0
166         max_interval = 0
167         min_interval = 0
168         lifetime = 0
169         initial_count = 0
170         initial_interval = 0
171         async = False
172         return self.api(vpp_papi.sw_interface_ip6nd_ra_config,
173                         (sw_if_index, suppress, managed, other,
174                          ll_option, send_unicast, cease, is_no,
175                          default_router, max_interval, min_interval,
176                          lifetime, initial_count, initial_interval, async))
177
178     def vxlan_add_del_tunnel(
179             self,
180             src_addr,
181             dst_addr,
182             is_add=1,
183             is_ipv6=0,
184             encap_vrf_id=0,
185             decap_next_index=0xFFFFFFFF,
186             vni=0):
187         """
188
189         :param dst_addr:
190         :param src_addr:
191         :param is_add:  (Default value = 1)
192         :param is_ipv6:  (Default value = 0)
193         :param encap_vrf_id:  (Default value = 0)
194         :param decap_next_index:  (Default value = 0xFFFFFFFF)
195         :param vni:  (Default value = 0)
196
197         """
198         return self.api(vpp_papi.vxlan_add_del_tunnel,
199                         (is_add, is_ipv6, src_addr, dst_addr, encap_vrf_id,
200                          decap_next_index, vni))
201
202     def sw_interface_set_l2_bridge(self, sw_if_index, bd_id,
203                                    shg=0, bvi=0, enable=1):
204         """
205
206         :param bd_id:
207         :param sw_if_index:
208         :param shg:  (Default value = 0)
209         :param bvi:  (Default value = 0)
210         :param enable:  (Default value = 1)
211
212         """
213         return self.api(vpp_papi.sw_interface_set_l2_bridge,
214                         (sw_if_index, bd_id, shg, bvi, enable))
215
216     def sw_interface_set_l2_xconnect(self, rx_sw_if_index, tx_sw_if_index,
217                                      enable):
218         """Create or delete unidirectional cross-connect from Tx interface to
219         Rx interface.
220
221         :param rx_sw_if_index: Software interface index of Rx interface.
222         :param tx_sw_if_index: Software interface index of Tx interface.
223         :param enable: Create cross-connect if equal to 1, delete cross-connect
224                        if equal to 0.
225         :type rx_sw_if_index: str or int
226         :type rx_sw_if_index: str or int
227         :type enable: int
228
229         """
230         return self.api(vpp_papi.sw_interface_set_l2_xconnect,
231                         (rx_sw_if_index, tx_sw_if_index, enable))
232
233     def sw_interface_set_flags(self, sw_if_index, admin_up_down,
234                                link_up_down=0, deleted=0):
235         """
236
237         :param admin_up_down:
238         :param sw_if_index:
239         :param link_up_down:  (Default value = 0)
240         :param deleted:  (Default value = 0)
241
242         """
243         return self.api(vpp_papi.sw_interface_set_flags,
244                         (sw_if_index, admin_up_down, link_up_down, deleted))
245
246     def create_subif(self, sw_if_index, sub_id, outer_vlan, inner_vlan,
247                      no_tags=0, one_tag=0, two_tags=0, dot1ad=0, exact_match=0,
248                      default_sub=0, outer_vlan_id_any=0, inner_vlan_id_any=0):
249         """Create subinterface
250         from vpe.api: set dot1ad = 0 for dot1q, set dot1ad = 1 for dot1ad
251
252         :param sub_id: param inner_vlan:
253         :param sw_if_index:
254         :param outer_vlan:
255         :param inner_vlan:
256         :param no_tags:  (Default value = 0)
257         :param one_tag:  (Default value = 0)
258         :param two_tags:  (Default value = 0)
259         :param dot1ad:  (Default value = 0)
260         :param exact_match:  (Default value = 0)
261         :param default_sub:  (Default value = 0)
262         :param outer_vlan_id_any:  (Default value = 0)
263         :param inner_vlan_id_any:  (Default value = 0)
264
265         """
266         return self.api(
267             vpp_papi.create_subif,
268             (sw_if_index,
269              sub_id,
270              no_tags,
271              one_tag,
272              two_tags,
273              dot1ad,
274              exact_match,
275              default_sub,
276              outer_vlan_id_any,
277              inner_vlan_id_any,
278              outer_vlan,
279              inner_vlan))
280
281     def create_vlan_subif(self, sw_if_index, vlan):
282         """
283
284         :param vlan:
285         :param sw_if_index:
286
287         """
288         return self.api(vpp_papi.create_vlan_subif, (sw_if_index, vlan))
289
290     def create_loopback(self, mac=''):
291         """
292
293         :param mac: (Optional)
294         """
295         return self.api(vpp_papi.create_loopback, (mac,))
296
297     def ip_add_del_route(
298             self,
299             dst_address,
300             dst_address_length,
301             next_hop_address,
302             next_hop_sw_if_index=0xFFFFFFFF,
303             table_id=0,
304             resolve_attempts=0,
305             classify_table_index=0xFFFFFFFF,
306             next_hop_out_label=MPLS_LABEL_INVALID,
307             next_hop_table_id=0,
308             create_vrf_if_needed=0,
309             resolve_if_needed=0,
310             is_add=1,
311             is_drop=0,
312             is_unreach=0,
313             is_prohibit=0,
314             is_ipv6=0,
315             is_local=0,
316             is_classify=0,
317             is_multipath=0,
318             is_resolve_host=0,
319             is_resolve_attached=0,
320             not_last=0,
321             next_hop_weight=1):
322         """
323
324         :param dst_address_length:
325         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
326         :param dst_address:
327         :param next_hop_address:
328         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
329         :param vrf_id:  (Default value = 0)
330         :param lookup_in_vrf:  (Default value = 0)
331         :param resolve_attempts:  (Default value = 0)
332         :param classify_table_index:  (Default value = 0xFFFFFFFF)
333         :param create_vrf_if_needed:  (Default value = 0)
334         :param resolve_if_needed:  (Default value = 0)
335         :param is_add:  (Default value = 1)
336         :param is_drop:  (Default value = 0)
337         :param is_ipv6:  (Default value = 0)
338         :param is_local:  (Default value = 0)
339         :param is_classify:  (Default value = 0)
340         :param is_multipath:  (Default value = 0)
341         :param is_resolve_host:  (Default value = 0)
342         :param is_resolve_attached:  (Default value = 0)
343         :param not_last:  (Default value = 0)
344         :param next_hop_weight:  (Default value = 1)
345
346         """
347         return self.api(
348             vpp_papi.ip_add_del_route,
349             (next_hop_sw_if_index,
350              table_id,
351              resolve_attempts,
352              classify_table_index,
353              next_hop_out_label,
354              next_hop_table_id,
355              create_vrf_if_needed,
356              resolve_if_needed,
357              is_add,
358              is_drop,
359              is_unreach,
360              is_prohibit,
361              is_ipv6,
362              is_local,
363              is_classify,
364              is_multipath,
365              is_resolve_host,
366              is_resolve_attached,
367              not_last,
368              next_hop_weight,
369              dst_address_length,
370              dst_address,
371              next_hop_address))
372
373     def ip_neighbor_add_del(self,
374                             sw_if_index,
375                             mac_address,
376                             dst_address,
377                             vrf_id=0,
378                             is_add=1,
379                             is_ipv6=0,
380                             is_static=0,
381                             ):
382         """ Add neighbor MAC to IPv4 or IPv6 address.
383
384         :param sw_if_index:
385         :param mac_address:
386         :param dst_address:
387         :param vrf_id:  (Default value = 0)
388         :param is_add:  (Default value = 1)
389         :param is_ipv6:  (Default value = 0)
390         :param is_static:  (Default value = 0)
391         """
392
393         return self.api(
394             vpp_papi.ip_neighbor_add_del,
395             (vrf_id,
396              sw_if_index,
397              is_add,
398              is_ipv6,
399              is_static,
400              mac_address,
401              dst_address
402              )
403         )