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