make test: fix missing log/packet messages
[vpp.git] / test / vpp_papi_provider.py
1 import os
2 import array
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 need_swap = True if os.sys.byteorder == 'little' else False
25
26 class VppPapiProvider(object):
27     """VPP-api provider using vpp-papi
28
29     @property hook: hook object providing before and after api/cli hooks
30
31
32     """
33
34     def __init__(self, name, shm_prefix, test_class):
35         self.hook = Hook("vpp-papi-provider")
36         self.name = name
37         self.shm_prefix = shm_prefix
38         self.test_class = test_class
39
40     def register_hook(self, hook):
41         """Replace hook registration with new hook
42
43         :param hook:
44
45         """
46         self.hook = hook
47
48     def connect(self):
49         """Connect the API to VPP"""
50         vpp_papi.connect(self.name, self.shm_prefix)
51
52     def disconnect(self):
53         """Disconnect the API from VPP"""
54         vpp_papi.disconnect()
55
56     def api(self, api_fn, api_args, expected_retval=0):
57         """Call API function and check it's return value
58         Call the appropriate hooks before and after the API call
59
60         :param api_fn: API function to call
61         :param api_args: tuple of API function arguments
62         :param expected_retval: Expected return value (Default value = 0)
63         :returns: reply from the API
64
65         """
66         self.hook.before_api(api_fn.__name__, api_args)
67         reply = api_fn(*api_args)
68         if hasattr(reply, 'retval') and reply.retval != expected_retval:
69             msg = "API call failed, expected retval == %d, got %s" % (
70                 expected_retval, repr(reply))
71             self.test_class.test_instance.logger.error(msg)
72             raise Exception(msg)
73         self.hook.after_api(api_fn.__name__, api_args)
74         return reply
75
76     def cli(self, cli):
77         """
78         Execute a CLI, calling the before/after hooks appropriately.
79
80         :param cli: CLI to execute
81         :returns: CLI output
82
83         """
84         self.hook.before_cli(cli)
85         cli += '\n'
86         r = vpp_papi.cli_inband(len(cli), cli)
87         self.hook.after_cli(cli)
88         if hasattr(r, 'reply'):
89             return r.reply[0].decode().rstrip('\x00')
90
91     def ppcli(self, cli):
92         """
93         Helping method to print CLI command in case of info logging level.
94
95         :param cli: CLI to execute
96         :returns: CLI output
97         """
98         return cli + "\n" + str(self.cli(cli))
99
100     def _convert_mac(self, mac):
101         return int(mac.replace(":", ""), 16) << 16
102
103     def show_version(self):
104         """ """
105         return vpp_papi.show_version()
106
107     def pg_create_interface(self, pg_index):
108         """
109
110         :param pg_index:
111
112         """
113         return self.api(vpp_papi.pg_create_interface, (pg_index, ))
114
115     def sw_interface_dump(self, filter=None):
116         """
117
118         :param filter:  (Default value = None)
119
120         """
121         if filter is not None:
122             args = (1, filter)
123         else:
124             args = (0, b'')
125         return self.api(vpp_papi.sw_interface_dump, args)
126
127     def sw_interface_set_table(self, sw_if_index, is_ipv6, table_id):
128         """
129           Set the IPvX Table-id for the Interface
130
131         :param sw_if_index:
132         :param is_ipv6:
133         :param table_id:
134
135         """
136         return self.api(vpp_papi.sw_interface_set_table,
137                         (sw_if_index, is_ipv6, table_id))
138
139     def sw_interface_add_del_address(self, sw_if_index, addr, addr_len,
140                                      is_ipv6=0, is_add=1, del_all=0):
141         """
142
143         :param addr: param is_ipv6:  (Default value = 0)
144         :param sw_if_index:
145         :param addr_len:
146         :param is_ipv6:  (Default value = 0)
147         :param is_add:  (Default value = 1)
148         :param del_all:  (Default value = 0)
149
150         """
151         return self.api(vpp_papi.sw_interface_add_del_address,
152                         (sw_if_index, is_add, is_ipv6, del_all, addr_len, addr))
153
154     def sw_interface_enable_disable_mpls(self, sw_if_index,
155                                          is_enable=1):
156         """
157         Enable/Disable MPLS on the interface
158         :param sw_if_index:
159         :param is_enable:  (Default value = 1)
160
161         """
162         return self.api(vpp_papi.sw_interface_set_mpls_enable,
163                         (sw_if_index, is_enable))
164
165     def sw_interface_ra_suppress(self, sw_if_index):
166         suppress = 1
167         managed = 0
168         other = 0
169         ll_option = 0
170         send_unicast = 0
171         cease = 0
172         is_no = 0
173         default_router = 0
174         max_interval = 0
175         min_interval = 0
176         lifetime = 0
177         initial_count = 0
178         initial_interval = 0
179         async = False
180         return self.api(vpp_papi.sw_interface_ip6nd_ra_config,
181                         (sw_if_index, suppress, managed, other,
182                          ll_option, send_unicast, cease, is_no,
183                          default_router, max_interval, min_interval,
184                          lifetime, initial_count, initial_interval, async))
185
186     def vxlan_add_del_tunnel(
187             self,
188             src_addr,
189             dst_addr,
190             mcast_sw_if_index=0xFFFFFFFF,
191             is_add=1,
192             is_ipv6=0,
193             encap_vrf_id=0,
194             decap_next_index=0xFFFFFFFF,
195             vni=0):
196         """
197
198         :param dst_addr:
199         :param src_addr:
200         :param is_add:  (Default value = 1)
201         :param is_ipv6:  (Default value = 0)
202         :param encap_vrf_id:  (Default value = 0)
203         :param decap_next_index:  (Default value = 0xFFFFFFFF)
204         :param mcast_sw_if_index:  (Default value = 0xFFFFFFFF)
205         :param vni:  (Default value = 0)
206
207         """
208         return self.api(vpp_papi.vxlan_add_del_tunnel,
209                         (is_add, is_ipv6, src_addr, dst_addr, mcast_sw_if_index,
210                          encap_vrf_id, decap_next_index, vni))
211
212     def bridge_domain_add_del(self, bd_id, flood=1, uu_flood=1, forward=1,
213                               learn=1, arp_term=0, is_add=1):
214         """Create/delete bridge domain.
215
216         :param int bd_id: Bridge domain index.
217         :param int flood: Enable/disable bcast/mcast flooding in the BD.
218             (Default value = 1)
219         :param int uu_flood: Enable/disable unknown unicast flood in the BD.
220             (Default value = 1)
221         :param int forward: Enable/disable forwarding on all interfaces in
222             the BD. (Default value = 1)
223         :param int learn: Enable/disable learning on all interfaces in the BD.
224             (Default value = 1)
225         :param int arp_term: Enable/disable arp termination in the BD.
226             (Default value = 1)
227         :param int is_add: Add or delete flag. (Default value = 1)
228         """
229         return self.api(vpp_papi.bridge_domain_add_del,
230                         (bd_id, flood, uu_flood, forward, learn, arp_term,
231                          is_add))
232
233     def l2fib_add_del(self, mac, bd_id, sw_if_index, is_add=1, static_mac=0,
234                       filter_mac=0, bvi_mac=0):
235         """Create/delete L2 FIB entry.
236
237         :param str mac: MAC address to create FIB entry for.
238         :param int bd_id: Bridge domain index.
239         :param int sw_if_index: Software interface index of the interface.
240         :param int is_add: Add or delete flag. (Default value = 1)
241         :param int static_mac: Set to 1 to create static MAC entry.
242             (Default value = 0)
243         :param int filter_mac: Set to 1 to drop packet that's source or
244             destination MAC address contains defined MAC address.
245             (Default value = 0)
246         :param int bvi_mac: Set to 1 to create entry that points to BVI
247             interface. (Default value = 0)
248         """
249         return self.api(vpp_papi.l2fib_add_del,
250                         (self._convert_mac(mac), bd_id, sw_if_index, is_add,
251                          static_mac, filter_mac, bvi_mac))
252
253     def sw_interface_set_l2_bridge(self, sw_if_index, bd_id,
254                                    shg=0, bvi=0, enable=1):
255         """Add/remove interface to/from bridge domain.
256
257         :param int sw_if_index: Software interface index of the interface.
258         :param int bd_id: Bridge domain index.
259         :param int shg: Split-horizon group index. (Default value = 0)
260         :param int bvi: Set interface as a bridge group virtual interface.
261             (Default value = 0)
262         :param int enable: Add or remove interface. (Default value = 1)
263         """
264         return self.api(vpp_papi.sw_interface_set_l2_bridge,
265                         (sw_if_index, bd_id, shg, bvi, enable))
266
267     def bridge_flags(self, bd_id, is_set, feature_bitmap):
268         """Enable/disable required feature of the bridge domain with defined ID.
269
270         :param int bd_id: Bridge domain ID.
271         :param int is_set: Set to 1 to enable, set to 0 to disable the feature.
272         :param int feature_bitmap: Bitmap value of the feature to be set:
273             - learn (1 << 0),
274             - forward (1 << 1),
275             - flood (1 << 2),
276             - uu-flood (1 << 3) or
277             - arp-term (1 << 4).
278         """
279         return self.api(vpp_papi.bridge_flags, (bd_id, is_set, feature_bitmap))
280
281     def bridge_domain_dump(self, bd_id=0):
282         """
283
284         :param int bd_id: Bridge domain ID. (Default value = 0 => dump of all
285             existing bridge domains returned)
286         :return: Dictionary of bridge domain(s) data.
287         """
288         return self.api(vpp_papi.bridge_domain_dump, (bd_id, ))
289
290     def sw_interface_set_l2_xconnect(self, rx_sw_if_index, tx_sw_if_index,
291                                      enable):
292         """Create or delete unidirectional cross-connect from Tx interface to
293         Rx interface.
294
295         :param int rx_sw_if_index: Software interface index of Rx interface.
296         :param int tx_sw_if_index: Software interface index of Tx interface.
297         :param int enable: Create cross-connect if equal to 1, delete
298             cross-connect if equal to 0.
299
300         """
301         return self.api(vpp_papi.sw_interface_set_l2_xconnect,
302                         (rx_sw_if_index, tx_sw_if_index, enable))
303
304     def sw_interface_set_l2_tag_rewrite(self, sw_if_index, vtr_oper, push=0, tag1=0, tag2=0):
305         """L2 interface vlan tag rewrite configure request
306         :param client_index - opaque cookie to identify the sender
307         :param context - sender context, to match reply w/ request
308         :param sw_if_index - interface the operation is applied to
309         :param vtr_op - Choose from l2_vtr_op_t enum values
310         :param push_dot1q - first pushed flag dot1q id set, else dot1ad
311         :param tag1 - Needed for any push or translate vtr op
312         :param tag2 - Needed for any push 2 or translate x-2 vtr ops
313
314         """
315         return self.api(vpp_papi.l2_interface_vlan_tag_rewrite,
316                         (sw_if_index, vtr_oper, push, tag1, tag2))
317
318     def sw_interface_set_flags(self, sw_if_index, admin_up_down,
319                                link_up_down=0, deleted=0):
320         """
321
322         :param admin_up_down:
323         :param sw_if_index:
324         :param link_up_down:  (Default value = 0)
325         :param deleted:  (Default value = 0)
326
327         """
328         return self.api(vpp_papi.sw_interface_set_flags,
329                         (sw_if_index, admin_up_down, link_up_down, deleted))
330
331     def create_subif(self, sw_if_index, sub_id, outer_vlan, inner_vlan,
332                      no_tags=0, one_tag=0, two_tags=0, dot1ad=0, exact_match=0,
333                      default_sub=0, outer_vlan_id_any=0, inner_vlan_id_any=0):
334         """Create subinterface
335         from vpe.api: set dot1ad = 0 for dot1q, set dot1ad = 1 for dot1ad
336
337         :param sub_id: param inner_vlan:
338         :param sw_if_index:
339         :param outer_vlan:
340         :param inner_vlan:
341         :param no_tags:  (Default value = 0)
342         :param one_tag:  (Default value = 0)
343         :param two_tags:  (Default value = 0)
344         :param dot1ad:  (Default value = 0)
345         :param exact_match:  (Default value = 0)
346         :param default_sub:  (Default value = 0)
347         :param outer_vlan_id_any:  (Default value = 0)
348         :param inner_vlan_id_any:  (Default value = 0)
349
350         """
351         return self.api(
352             vpp_papi.create_subif,
353             (sw_if_index,
354              sub_id,
355              no_tags,
356              one_tag,
357              two_tags,
358              dot1ad,
359              exact_match,
360              default_sub,
361              outer_vlan_id_any,
362              inner_vlan_id_any,
363              outer_vlan,
364              inner_vlan))
365
366     def delete_subif(self, sw_if_index):
367         """Delete subinterface
368
369         :param sw_if_index:
370         """
371         return self.api(vpp_papi.delete_subif, ([sw_if_index]))
372
373     def create_vlan_subif(self, sw_if_index, vlan):
374         """
375
376         :param vlan:
377         :param sw_if_index:
378
379         """
380         return self.api(vpp_papi.create_vlan_subif, (sw_if_index, vlan))
381
382     def create_loopback(self, mac=''):
383         """
384
385         :param mac: (Optional)
386         """
387         return self.api(vpp_papi.create_loopback, (mac,))
388
389     def ip_add_del_route(
390             self,
391             dst_address,
392             dst_address_length,
393             next_hop_address,
394             next_hop_sw_if_index=0xFFFFFFFF,
395             table_id=0,
396             next_hop_table_id=0,
397             next_hop_weight=1,
398             next_hop_n_out_labels = 0,
399             next_hop_out_label_stack = [],
400             next_hop_via_label = MPLS_LABEL_INVALID,
401             create_vrf_if_needed=0,
402             is_resolve_host=0,
403             is_resolve_attached=0,
404             classify_table_index=0xFFFFFFFF,
405             is_add=1,
406             is_drop=0,
407             is_unreach=0,
408             is_prohibit=0,
409             is_ipv6=0,
410             is_local=0,
411             is_classify=0,
412             is_multipath=0,
413             not_last=0):
414         """
415
416         :param dst_address_length:
417         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
418         :param dst_address:
419         :param next_hop_address:
420         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
421         :param vrf_id:  (Default value = 0)
422         :param lookup_in_vrf:  (Default value = 0)
423         :param classify_table_index:  (Default value = 0xFFFFFFFF)
424         :param create_vrf_if_needed:  (Default value = 0)
425         :param is_add:  (Default value = 1)
426         :param is_drop:  (Default value = 0)
427         :param is_ipv6:  (Default value = 0)
428         :param is_local:  (Default value = 0)
429         :param is_classify:  (Default value = 0)
430         :param is_multipath:  (Default value = 0)
431         :param is_resolve_host:  (Default value = 0)
432         :param is_resolve_attached:  (Default value = 0)
433         :param not_last:  (Default value = 0)
434         :param next_hop_weight:  (Default value = 1)
435
436         """
437         stack = array.array('I', next_hop_out_label_stack)
438         if need_swap:
439             stack.byteswap()
440         stack = stack.tostring()
441
442         return self.api(
443             vpp_papi.ip_add_del_route,
444             (next_hop_sw_if_index,
445              table_id,
446              classify_table_index,
447              next_hop_table_id,
448              create_vrf_if_needed,
449              is_add,
450              is_drop,
451              is_unreach,
452              is_prohibit,
453              is_ipv6,
454              is_local,
455              is_classify,
456              is_multipath,
457              is_resolve_host,
458              is_resolve_attached,
459              not_last,
460              next_hop_weight,
461              dst_address_length,
462              dst_address,
463              next_hop_address,
464              next_hop_n_out_labels,
465              next_hop_via_label,
466              stack))
467
468     def ip_neighbor_add_del(self,
469                             sw_if_index,
470                             mac_address,
471                             dst_address,
472                             vrf_id=0,
473                             is_add=1,
474                             is_ipv6=0,
475                             is_static=0,
476                             ):
477         """ Add neighbor MAC to IPv4 or IPv6 address.
478
479         :param sw_if_index:
480         :param mac_address:
481         :param dst_address:
482         :param vrf_id:  (Default value = 0)
483         :param is_add:  (Default value = 1)
484         :param is_ipv6:  (Default value = 0)
485         :param is_static:  (Default value = 0)
486         """
487
488         return self.api(
489             vpp_papi.ip_neighbor_add_del,
490             (vrf_id,
491              sw_if_index,
492              is_add,
493              is_ipv6,
494              is_static,
495              mac_address,
496              dst_address
497              )
498         )
499
500     def sw_interface_span_enable_disable(
501             self, sw_if_index_from, sw_if_index_to, enable=1):
502         """
503
504         :param sw_if_index_from:
505         :param sw_if_index_to:
506         :param enable
507
508         """
509         return self.api(vpp_papi.sw_interface_span_enable_disable, (sw_if_index_from, sw_if_index_to, enable ))
510
511     def gre_tunnel_add_del(self,
512                            src_address,
513                            dst_address,
514                            outer_fib_id=0,
515                            is_teb=0,
516                            is_add=1,
517                            is_ip6=0):
518         """ Add a GRE tunnel
519
520         :param src_address:
521         :param dst_address:
522         :param outer_fib_id:  (Default value = 0)
523         :param is_add:  (Default value = 1)
524         :param is_ipv6:  (Default value = 0)
525         :param is_teb:  (Default value = 0)
526         """
527
528         return self.api(
529             vpp_papi.gre_add_del_tunnel,
530             (is_add,
531              is_ip6,
532              is_teb,
533              src_address,
534              dst_address,
535              outer_fib_id)
536         )
537
538     def mpls_route_add_del(
539             self,
540             label,
541             eos,
542             next_hop_proto_is_ip4,
543             next_hop_address,
544             next_hop_sw_if_index=0xFFFFFFFF,
545             table_id=0,
546             next_hop_table_id=0,
547             next_hop_weight=1,
548             next_hop_n_out_labels = 0,
549             next_hop_out_label_stack = [],
550             next_hop_via_label = MPLS_LABEL_INVALID,
551             create_vrf_if_needed=0,
552             is_resolve_host=0,
553             is_resolve_attached=0,
554             is_add=1,
555             is_drop=0,
556             is_multipath=0,
557             classify_table_index=0xFFFFFFFF,
558             is_classify=0,
559             not_last=0):
560         """
561
562         :param dst_address_length:
563         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
564         :param dst_address:
565         :param next_hop_address:
566         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
567         :param vrf_id:  (Default value = 0)
568         :param lookup_in_vrf:  (Default value = 0)
569         :param classify_table_index:  (Default value = 0xFFFFFFFF)
570         :param create_vrf_if_needed:  (Default value = 0)
571         :param is_add:  (Default value = 1)
572         :param is_drop:  (Default value = 0)
573         :param is_ipv6:  (Default value = 0)
574         :param is_local:  (Default value = 0)
575         :param is_classify:  (Default value = 0)
576         :param is_multipath:  (Default value = 0)
577         :param is_resolve_host:  (Default value = 0)
578         :param is_resolve_attached:  (Default value = 0)
579         :param not_last:  (Default value = 0)
580         :param next_hop_weight:  (Default value = 1)
581
582         """
583         stack = array.array('I', next_hop_out_label_stack)
584         if need_swap:
585             stack.byteswap()
586         stack = stack.tostring()
587
588         return self.api(
589             vpp_papi.mpls_route_add_del,
590             (label,
591              eos,
592              table_id,
593              classify_table_index,
594              create_vrf_if_needed,
595              is_add,
596              is_classify,
597              is_multipath,
598              is_resolve_host,
599              is_resolve_attached,
600              next_hop_proto_is_ip4,
601              next_hop_weight,
602              next_hop_address,
603              next_hop_n_out_labels,
604              next_hop_sw_if_index,
605              next_hop_table_id,
606              next_hop_via_label,
607              stack))
608
609     def mpls_ip_bind_unbind(
610             self,
611             label,
612             dst_address,
613             dst_address_length,
614             table_id=0,
615             ip_table_id=0,
616             is_ip4=1,
617             create_vrf_if_needed=0,
618             is_bind=1):
619         """
620         """
621         return self.api(
622             vpp_papi.mpls_ip_bind_unbind,
623             (table_id,
624              label,
625              ip_table_id,
626              create_vrf_if_needed,
627              is_bind,
628              is_ip4,
629              dst_address_length,
630              dst_address))
631
632     def mpls_tunnel_add_del(
633             self,
634             tun_sw_if_index,
635             next_hop_proto_is_ip4,
636             next_hop_address,
637             next_hop_sw_if_index=0xFFFFFFFF,
638             next_hop_table_id=0,
639             next_hop_weight=1,
640             next_hop_n_out_labels = 0,
641             next_hop_out_label_stack = [],
642             next_hop_via_label = MPLS_LABEL_INVALID,
643             create_vrf_if_needed=0,
644             is_add=1,
645             l2_only=0):
646         """
647
648         :param dst_address_length:
649         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
650         :param dst_address:
651         :param next_hop_address:
652         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
653         :param vrf_id:  (Default value = 0)
654         :param lookup_in_vrf:  (Default value = 0)
655         :param classify_table_index:  (Default value = 0xFFFFFFFF)
656         :param create_vrf_if_needed:  (Default value = 0)
657         :param is_add:  (Default value = 1)
658         :param is_drop:  (Default value = 0)
659         :param is_ipv6:  (Default value = 0)
660         :param is_local:  (Default value = 0)
661         :param is_classify:  (Default value = 0)
662         :param is_multipath:  (Default value = 0)
663         :param is_resolve_host:  (Default value = 0)
664         :param is_resolve_attached:  (Default value = 0)
665         :param not_last:  (Default value = 0)
666         :param next_hop_weight:  (Default value = 1)
667
668         """
669         stack = array.array('I', next_hop_out_label_stack)
670         if need_swap:
671             stack.byteswap()
672         stack = stack.tostring()
673
674         return self.api(
675             vpp_papi.mpls_tunnel_add_del,
676             (tun_sw_if_index,
677              is_add,
678              l2_only,
679              next_hop_proto_is_ip4,
680              next_hop_weight,
681              next_hop_address,
682              next_hop_n_out_labels,
683              next_hop_sw_if_index,
684              next_hop_table_id,
685              stack))
686
687         return self.api(vpp_papi.sw_interface_span_enable_disable,
688                         (sw_if_index_from, sw_if_index_to, enable))