test framework: vpp_papi_provider.py - further cleanup
[vpp.git] / test / vpp_papi_provider.py
1 # NB NB NB NB NB NB NB NB NB NB NB
2 #
3 # NOTE: The API binary wrappers in this file are in the process of being
4 # deprecated. DO NOT ADD NEW WRAPPERS HERE. Call the functions using
5 # named arguments directly instead.
6 #
7
8 import os
9 import time
10 from collections import deque
11
12 from six import moves, iteritems
13 from vpp_papi import VPP, mac_pton
14 from hook import Hook
15 from vpp_l2 import L2_PORT_TYPE
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 L2_VTR_OP:
23     L2_DISABLED = 0
24     L2_PUSH_1 = 1
25     L2_PUSH_2 = 2
26     L2_POP_1 = 3
27     L2_POP_2 = 4
28     L2_TRANSLATE_1_1 = 5
29     L2_TRANSLATE_1_2 = 6
30     L2_TRANSLATE_2_1 = 7
31     L2_TRANSLATE_2_2 = 8
32
33
34 class QOS_SOURCE:
35     EXT = 0
36     VLAN = 1
37     MPLS = 2
38     IP = 3
39
40
41 class SYSLOG_SEVERITY:
42     EMERG = 0
43     ALERT = 1
44     CRIT = 2
45     ERR = 3
46     WARN = 4
47     NOTICE = 5
48     INFO = 6
49     DBG = 7
50
51
52 #
53 # Dictionary keyed on message name to override default values for
54 # named parameters
55 #
56 defaultmapping = {
57     'map_add_domain': {'mtu': 1280},
58     'syslog_set_sender': {'collector_port': 514,
59                           'max_msg_size': 480},
60     'acl_interface_add_del': {'is_add': 1, 'is_input': 1},
61     'acl_interface_list_dump': {'sw_if_index': 4294967295, },
62     'app_namespace_add_del': {'sw_if_index': 4294967295, },
63     'bd_ip_mac_add_del': {'is_add': 1, },
64     'bier_disp_entry_add_del': {'next_hop_rpf_id': -1, 'next_hop_is_ip4': 1,
65                                 'is_add': 1, },
66     'bier_disp_table_add_del': {'is_add': 1, },
67     'bier_imp_add': {'is_add': 1, },
68     'bier_route_add_del': {'is_add': 1, },
69     'bier_table_add_del': {'is_add': 1, },
70     'bridge_domain_add_del': {'flood': 1, 'uu_flood': 1, 'forward': 1,
71                               'learn': 1, 'is_add': 1, },
72     'classify_add_del_table': {'match_n_vectors': 1, 'table_index': 4294967295,
73                                'nbuckets': 2, 'memory_size': 2097152,
74                                'next_table_index': 4294967295,
75                                'miss_next_index': 4294967295, },
76     'dhcp6_client_enable_disable': {'enable': 1, },
77     'dhcp6_clients_enable_disable': {'enable': 1, },
78     'dhcp6_pd_client_enable_disable': {'enable': 1, },
79     'dhcp6_send_client_message': {'server_index': 4294967295, 'mrc': 1, },
80     'dhcp_client_config': {'is_add': 1, 'set_broadcast_flag': 1, },
81     'dhcp_proxy_config': {'is_add': 1, },
82     'dhcp_proxy_set_vss': {'vss_type': 255, 'is_add': 1, },
83     'dslite_add_del_pool_addr_range': {'is_add': 1, },
84     'gbp_subnet_add_del': {'sw_if_index': 4294967295, 'epg_id': 65535, },
85     'geneve_add_del_tunnel': {'mcast_sw_if_index': 4294967295, 'is_add': 1,
86                               'decap_next_index': 4294967295, },
87     'gre_add_del_tunnel': {'instance': 4294967295, 'is_add': 1, },
88     'gtpu_add_del_tunnel': {'is_add': 1, 'mcast_sw_if_index': 4294967295,
89                             'decap_next_index': 4294967295, },
90     'input_acl_set_interface': {'ip4_table_index': 4294967295,
91                                 'ip6_table_index': 4294967295,
92                                 'l2_table_index': 4294967295, },
93     'ip6_add_del_address_using_prefix': {'is_add': 1, },
94     'ip6nd_send_router_solicitation': {'irt': 1, 'mrt': 120, },
95     'ip_add_del_route': {'next_hop_sw_if_index': 4294967295,
96                          'next_hop_weight': 1, 'next_hop_via_label': 1048576,
97                          'next_hop_id': 4294967295,
98                          'classify_table_index': 4294967295, 'is_add': 1, },
99     'ip_mroute_add_del': {'is_add': 1, },
100     'ip_neighbor_add_del': {'is_add': 1, },
101     'ip_punt_police': {'is_add': 1, },
102     'ip_punt_redirect': {'is_add': 1, },
103     'ip_table_add_del': {'is_add': 1, },
104     'ip_unnumbered_dump': {'sw_if_index': 4294967295, },
105     'ipip_add_tunnel': {'is_ipv6': 1, 'instance': 4294967295, },
106     'ipsec_interface_add_del_spd': {'is_add': 1, },
107     'ipsec_sad_entry_add_del': {'is_add': 1, },
108     'ipsec_spd_add_del': {'is_add': 1, },
109     'ipsec_spd_dump': {'sa_id': 4294967295, },
110     'ipsec_spd_entry_add_del': {'local_port_stop': 65535,
111                                 'remote_port_stop': 65535, 'priority': 100,
112                                 'is_outbound': 1,
113                                 'is_add': 1, },
114     'ipsec_tunnel_if_add_del': {'is_add': 1, 'anti_replay': 1, },
115     'l2_emulation': {'enable': 1, },
116     'l2fib_add_del': {'is_add': 1, },
117     'lisp_add_del_adjacency': {'is_add': 1, },
118     'lisp_add_del_local_eid': {'is_add': 1, },
119     'lisp_add_del_locator': {'priority': 1, 'weight': 1, 'is_add': 1, },
120     'lisp_add_del_locator_set': {'is_add': 1, },
121     'lisp_add_del_remote_mapping': {'is_add': 1, },
122     'macip_acl_add_replace': {'acl_index': 4294967295, },
123     'macip_acl_dump': {'acl_index': 4294967295, },
124     'macip_acl_interface_add_del': {'is_add': 1, },
125     'mpls_ip_bind_unbind': {'is_ip4': 1, 'is_bind': 1, },
126     'mpls_route_add_del': {'next_hop_sw_if_index': 4294967295,
127                            'next_hop_weight': 1, 'next_hop_via_label': 1048576,
128                            'is_add': 1, 'classify_table_index': 4294967295, },
129     'mpls_table_add_del': {'is_add': 1, },
130     'mpls_tunnel_add_del': {'next_hop_sw_if_index': 4294967295,
131                             'next_hop_weight': 1,
132                             'next_hop_via_label': 1048576,
133                             'is_add': 1, },
134     'mpls_tunnel_dump': {'sw_if_index': 4294967295, },
135     'nat44_add_del_address_range': {'is_add': 1, 'vrf_id': 4294967295, },
136     'nat44_add_del_identity_mapping': {'ip': '0', 'sw_if_index': 4294967295,
137                                        'addr_only': 1, 'is_add': 1, },
138     'nat44_add_del_interface_addr': {'is_add': 1, },
139     'nat44_add_del_lb_static_mapping': {'is_add': 1, },
140     'nat44_add_del_static_mapping': {'external_sw_if_index': 4294967295,
141                                      'addr_only': 1, 'is_add': 1, },
142     'nat44_del_session': {'is_in': 1, },
143     'nat44_interface_add_del_feature': {'is_inside': 1, 'is_add': 1, },
144     'nat44_interface_add_del_output_feature': {'is_inside': 1, 'is_add': 1, },
145     'nat44_lb_static_mapping_add_del_local': {'is_add': 1, },
146     'nat64_add_del_interface': {'is_inside': 1, 'is_add': 1, },
147     'nat64_add_del_interface_addr': {'is_add': 1, },
148     'nat64_add_del_pool_addr_range': {'vrf_id': 4294967295, 'is_add': 1, },
149     'nat64_add_del_prefix': {'is_add': 1, },
150     'nat64_add_del_static_bib': {'is_add': 1, },
151     'nat64_bib_dump': {'protocol': 255, },
152     'nat64_st_dump': {'protocol': 255, },
153     'nat66_add_del_interface': {'is_inside': 1, 'is_add': 1, },
154     'nat66_add_del_static_mapping': {'is_add': 1, },
155     'nat_det_add_del_map': {'is_add': 1, },
156     'nat_ha_resync': {'want_resync_event': 1, },
157     'nat_ha_set_failover': {'refresh': 10, },
158     'nat_ha_set_listener': {'path_mtu': 512, },
159     'nat_ipfix_enable_disable': {'domain_id': 1, 'src_port': 4739,
160                                  'enable': 1, },
161     'nat_set_mss_clamping': {'mss_value': 1500, },
162     'nat_set_reass': {'timeout': 2, 'max_reass': 1024, 'max_frag': 5, },
163     'nat_set_timeouts': {'udp': 300, 'tcp_established': 7440,
164                          'tcp_transitory': 240, 'icmp': 60, },
165     'output_acl_set_interface': {'ip4_table_index': 4294967295,
166                                  'ip6_table_index': 4294967295,
167                                  'l2_table_index': 4294967295, },
168     'pppoe_add_del_session': {'is_add': 1, },
169     'policer_add_del': {'is_add': 1, 'conform_action_type': 1, },
170     'proxy_arp_add_del': {'is_add': 1, },
171     'proxy_arp_intfc_enable_disable': {'is_enable': 1, },
172     'punt_socket_register': {'protocol': 17, 'header_version': 1,
173                              'is_ip4': 1, },
174     'punt_socket_deregister': {'protocol': 17, 'is_ip4': 1, },
175     'punt_socket_dump': {'is_ip6': 1, },
176     'set_ip_flow_hash': {'src': 1, 'dst': 1, 'sport': 1, 'dport': 1,
177                          'proto': 1, },
178     'set_ipfix_exporter': {'collector_port': 4739, },
179     'sr_localsid_add_del': {'sw_if_index': 4294967295, },
180     'sr_policy_add': {'weight': 1, 'is_encap': 1, },
181     'svs_enable_disable': {'is_enable': 1, },
182     'svs_route_add_del': {'is_add': 1, },
183     'svs_table_add_del': {'is_add': 1, },
184     'sw_interface_add_del_address': {'is_add': 1, },
185     'sw_interface_ip6nd_ra_prefix': {'val_lifetime': 4294967295,
186                                      'pref_lifetime': 4294967295, },
187     'sw_interface_set_ip_directed_broadcast': {'enable': 1, },
188     'sw_interface_set_l2_bridge': {'enable': 1, },
189     'sw_interface_set_mpls_enable': {'enable': 1, },
190     'sw_interface_set_mtu': {'mtu': [0, 0, 0, 0], },
191     'sw_interface_set_unnumbered': {'is_add': 1, },
192     'sw_interface_span_enable_disable': {'state': 1, },
193     'vxlan_add_del_tunnel': {'mcast_sw_if_index': 4294967295, 'is_add': 1,
194                              'decap_next_index': 4294967295,
195                              'instance': 4294967295, },
196     'vxlan_gbp_tunnel_add_del': {'mcast_sw_if_index': 4294967295, 'is_add': 1,
197                                  'instance': 4294967295, },
198     'vxlan_gbp_tunnel_dump': {'sw_if_index': 4294967295, },
199     'vxlan_gpe_add_del_tunnel': {'mcast_sw_if_index': 4294967295, 'is_add': 1,
200                                  'protocol': 3, },
201     'want_bfd_events': {'enable_disable': 1, },
202     'want_dhcp6_pd_reply_events': {'enable_disable': 1, },
203     'want_dhcp6_reply_events': {'enable_disable': 1, },
204     'want_igmp_events': {'enable': 1, },
205     'want_interface_events': {'enable_disable': 1, },
206     'want_ip4_arp_events': {'enable_disable': 1, 'ip': '0.0.0.0', },
207     'want_ip6_nd_events': {'enable_disable': 1, 'ip': '::', },
208     'want_ip6_ra_events': {'enable_disable': 1, },
209     'want_l2_macs_events': {'enable_disable': 1, },
210 }
211
212
213 class UnexpectedApiReturnValueError(Exception):
214     """ exception raised when the API return value is unexpected """
215     pass
216
217
218 class VppPapiProvider(object):
219     """VPP-api provider using vpp-papi
220
221     @property hook: hook object providing before and after api/cli hooks
222     """
223
224     _zero, _negative = range(2)
225
226     def __init__(self, name, shm_prefix, test_class, read_timeout):
227         self.hook = Hook(test_class)
228         self.name = name
229         self.shm_prefix = shm_prefix
230         self.test_class = test_class
231         self._expect_api_retval = self._zero
232         self._expect_stack = []
233
234         install_dir = os.getenv('VPP_INSTALL_PATH')
235
236         # Vapi requires 'VPP_API_DIR', not set when run from Makefile.
237         if 'VPP_API_DIR' not in os.environ:
238             os.environ['VPP_API_DIR'] = os.getenv('VPP_INSTALL_PATH')
239
240         self.vpp = VPP(logger=test_class.logger,
241                        read_timeout=read_timeout)
242         self._events = deque()
243
244     def __enter__(self):
245         return self
246
247     def assert_negative_api_retval(self):
248         """ Expect API failure - used with with, e.g.:
249             with self.vapi.assert_negative_api_retval():
250                 self.vapi.<api call expected to fail>
251         """
252         self._expect_stack.append(self._expect_api_retval)
253         self._expect_api_retval = self._negative
254         return self
255
256     def assert_zero_api_retval(self):
257         """ Expect API success - used with with, e.g.:
258             with self.vapi.assert_negative_api_retval():
259                 self.vapi.<api call expected to succeed>
260
261             note: this is useful only inside another with block
262                   as success is the default expected value
263         """
264         self._expect_stack.append(self._expect_api_retval)
265         self._expect_api_retval = self._zero
266         return self
267
268     def __exit__(self, exc_type, exc_value, traceback):
269         self._expect_api_retval = self._expect_stack.pop()
270
271     def register_hook(self, hook):
272         """Replace hook registration with new hook
273
274         :param hook:
275
276         """
277         self.hook = hook
278
279     def collect_events(self):
280         """ Collect all events from the internal queue and clear the queue. """
281         e = self._events
282         self._events = deque()
283         return e
284
285     def wait_for_event(self, timeout, name=None):
286         """ Wait for and return next event. """
287         if name:
288             self.test_class.logger.debug("Expecting event '%s' within %ss",
289                                          name, timeout)
290         else:
291             self.test_class.logger.debug("Expecting event within %ss",
292                                          timeout)
293         if self._events:
294             self.test_class.logger.debug("Not waiting, event already queued")
295         limit = time.time() + timeout
296         while time.time() < limit:
297             if self._events:
298                 e = self._events.popleft()
299                 if name and type(e).__name__ != name:
300                     raise Exception(
301                         "Unexpected event received: %s, expected: %s" %
302                         (type(e).__name__, name))
303                 self.test_class.logger.debug("Returning event %s:%s" %
304                                              (name, e))
305                 return e
306             time.sleep(0)  # yield
307         raise Exception("Event did not occur within timeout")
308
309     def __call__(self, name, event):
310         """ Enqueue event in the internal event queue. """
311         # FIXME use the name instead of relying on type(e).__name__ ?
312         # FIXME #2 if this throws, it is eaten silently, Ole?
313         self.test_class.logger.debug("New event: %s: %s" % (name, event))
314         self._events.append(event)
315
316     def factory(self, name, apifn):
317         def f(*a, **ka):
318             fields = apifn._func.msg.fields
319
320             # add positional and kw arguments
321             d = ka
322             for i, o in enumerate(fields[3:]):
323                 try:
324                     d[o] = a[i]
325                 except:
326                     break
327
328             # Default override
329             if name in defaultmapping:
330                 for k, v in iteritems(defaultmapping[name]):
331                     if k in d:
332                         continue
333                     d[k] = v
334             return self.api(apifn, d)
335
336         return f
337
338     def __getattribute__(self, name):
339         try:
340             method = super(VppPapiProvider, self).__getattribute__(name)
341         except AttributeError:
342             method = self.factory(name, getattr(self.papi, name))
343             # lazily load the method so we don't need to call factory
344             # again for this name.
345             setattr(self, name, method)
346         return method
347
348     def connect(self):
349         """Connect the API to VPP"""
350         self.vpp.connect(self.name, self.shm_prefix)
351         self.papi = self.vpp.api
352         self.vpp.register_event_callback(self)
353
354     def disconnect(self):
355         """Disconnect the API from VPP"""
356         self.vpp.disconnect()
357
358     def api(self, api_fn, api_args, expected_retval=0):
359         """ Call API function and check it's return value.
360         Call the appropriate hooks before and after the API call
361
362         :param api_fn: API function to call
363         :param api_args: tuple of API function arguments
364         :param expected_retval: Expected return value (Default value = 0)
365         :returns: reply from the API
366
367         """
368         self.hook.before_api(api_fn.__name__, api_args)
369         reply = api_fn(**api_args)
370         if self._expect_api_retval == self._negative:
371             if hasattr(reply, 'retval') and reply.retval >= 0:
372                 msg = "API call passed unexpectedly: expected negative " \
373                       "return value instead of %d in %s" % \
374                       (reply.retval, moves.reprlib.repr(reply))
375                 self.test_class.logger.info(msg)
376                 raise UnexpectedApiReturnValueError(msg)
377         elif self._expect_api_retval == self._zero:
378             if hasattr(reply, 'retval') and reply.retval != expected_retval:
379                 msg = "API call failed, expected %d return value instead " \
380                       "of %d in %s" % (expected_retval, reply.retval,
381                                        moves.reprlib.repr(reply))
382                 self.test_class.logger.info(msg)
383                 raise UnexpectedApiReturnValueError(msg)
384         else:
385             raise Exception("Internal error, unexpected value for "
386                             "self._expect_api_retval %s" %
387                             self._expect_api_retval)
388         self.hook.after_api(api_fn.__name__, api_args)
389         return reply
390
391     def cli(self, cli):
392         """ Execute a CLI, calling the before/after hooks appropriately.
393
394         :param cli: CLI to execute
395         :returns: CLI output
396
397         """
398         self.hook.before_cli(cli)
399         cli += '\n'
400         r = self.papi.cli_inband(cmd=cli)
401         self.hook.after_cli(cli)
402         if hasattr(r, 'reply'):
403             return r.reply
404
405     def ppcli(self, cli):
406         """ Helper method to print CLI command in case of info logging level.
407
408         :param cli: CLI to execute
409         :returns: CLI output
410         """
411         return cli + "\n" + str(self.cli(cli))
412
413     def set_ip_flow_hash(self,
414                          table_id,
415                          src=1,
416                          dst=1,
417                          sport=1,
418                          dport=1,
419                          proto=1,
420                          reverse=0,
421                          is_ip6=0):
422         return self.api(self.papi.set_ip_flow_hash,
423                         {'vrf_id': table_id,
424                          'src': src,
425                          'dst': dst,
426                          'dport': dport,
427                          'sport': sport,
428                          'proto': proto,
429                          'reverse': reverse,
430                          'is_ipv6': is_ip6})
431
432     def sw_interface_ip6nd_ra_prefix(self,
433                                      sw_if_index,
434                                      address,
435                                      address_length,
436                                      use_default=0,
437                                      no_advertise=0,
438                                      off_link=0,
439                                      no_autoconfig=0,
440                                      no_onlink=0,
441                                      is_no=0,
442                                      val_lifetime=0xffffffff,
443                                      pref_lifetime=0xffffffff):
444         return self.api(self.papi.sw_interface_ip6nd_ra_prefix,
445                         {'sw_if_index': sw_if_index,
446                          'prefix': {
447                              'address': address,
448                              'address_length': address_length,
449                          },
450                          'use_default': use_default,
451                          'no_advertise': no_advertise,
452                          'off_link': off_link,
453                          'no_autoconfig': no_autoconfig,
454                          'no_onlink': no_onlink,
455                          'is_no': is_no,
456                          'val_lifetime': val_lifetime,
457                          'pref_lifetime': pref_lifetime})
458
459     def vxlan_add_del_tunnel(
460             self,
461             src_addr,
462             dst_addr,
463             mcast_sw_if_index=0xFFFFFFFF,
464             is_add=1,
465             is_ipv6=0,
466             encap_vrf_id=0,
467             decap_next_index=0xFFFFFFFF,
468             vni=0,
469             instance=0xFFFFFFFF):
470         """
471
472         :param dst_addr:
473         :param src_addr:
474         :param is_add:  (Default value = 1)
475         :param is_ipv6:  (Default value = 0)
476         :param encap_vrf_id:  (Default value = 0)
477         :param decap_next_index:  (Default value = 0xFFFFFFFF)
478         :param mcast_sw_if_index:  (Default value = 0xFFFFFFFF)
479         :param vni:  (Default value = 0)
480         :param instance:  (Default value = 0xFFFFFFFF)
481
482         """
483         return self.api(self.papi.vxlan_add_del_tunnel,
484                         {'is_add': is_add,
485                          'is_ipv6': is_ipv6,
486                          'src_address': src_addr,
487                          'dst_address': dst_addr,
488                          'mcast_sw_if_index': mcast_sw_if_index,
489                          'encap_vrf_id': encap_vrf_id,
490                          'decap_next_index': decap_next_index,
491                          'vni': vni,
492                          'instance': instance})
493
494     def geneve_add_del_tunnel(
495             self,
496             local_addr,
497             remote_addr,
498             mcast_sw_if_index=0xFFFFFFFF,
499             is_add=1,
500             is_ipv6=0,
501             encap_vrf_id=0,
502             decap_next_index=0xFFFFFFFF,
503             vni=0):
504         """
505
506         :param remote_addr:
507         :param local_addr:
508         :param is_add:  (Default value = 1)
509         :param is_ipv6:  (Default value = 0)
510         :param encap_vrf_id:  (Default value = 0)
511         :param decap_next_index:  (Default value = 0xFFFFFFFF)
512         :param mcast_sw_if_index:  (Default value = 0xFFFFFFFF)
513         :param vni:  (Default value = 0)
514
515         """
516         return self.api(self.papi.geneve_add_del_tunnel,
517                         {'is_add': is_add,
518                          'is_ipv6': is_ipv6,
519                          'local_address': local_addr,
520                          'remote_address': remote_addr,
521                          'mcast_sw_if_index': mcast_sw_if_index,
522                          'encap_vrf_id': encap_vrf_id,
523                          'decap_next_index': decap_next_index,
524                          'vni': vni})
525
526     def bridge_domain_add_del(self, bd_id, flood=1, uu_flood=1, forward=1,
527                               learn=1, arp_term=0, is_add=1):
528         """Create/delete bridge domain.
529
530         :param int bd_id: Bridge domain index.
531         :param int flood: Enable/disable bcast/mcast flooding in the BD.
532             (Default value = 1)
533         :param int uu_flood: Enable/disable unknown unicast flood in the BD.
534             (Default value = 1)
535         :param int forward: Enable/disable forwarding on all interfaces in
536             the BD. (Default value = 1)
537         :param int learn: Enable/disable learning on all interfaces in the BD.
538             (Default value = 1)
539         :param int arp_term: Enable/disable arp termination in the BD.
540             (Default value = 1)
541         :param int is_add: Add or delete flag. (Default value = 1)
542         """
543         return self.api(self.papi.bridge_domain_add_del,
544                         {'bd_id': bd_id,
545                          'flood': flood,
546                          'uu_flood': uu_flood,
547                          'forward': forward,
548                          'learn': learn,
549                          'arp_term': arp_term,
550                          'is_add': is_add})
551
552     def want_ip4_arp_events(self, enable_disable=1, ip="0.0.0.0"):
553         return self.api(self.papi.want_ip4_arp_events,
554                         {'enable_disable': enable_disable,
555                          'ip': ip,
556                          'pid': os.getpid(), })
557
558     def want_ip6_nd_events(self, enable_disable=1, ip="::"):
559         return self.api(self.papi.want_ip6_nd_events,
560                         {'enable_disable': enable_disable,
561                          'ip': ip,
562                          'pid': os.getpid(), })
563
564     def want_ip6_ra_events(self, enable_disable=1):
565         return self.api(self.papi.want_ip6_ra_events,
566                         {'enable_disable': enable_disable,
567                          'pid': os.getpid(), })
568
569     def ip6nd_send_router_solicitation(self, sw_if_index, irt=1, mrt=120,
570                                        mrc=0, mrd=0):
571         return self.api(self.papi.ip6nd_send_router_solicitation,
572                         {'irt': irt,
573                          'mrt': mrt,
574                          'mrc': mrc,
575                          'mrd': mrd,
576                          'sw_if_index': sw_if_index})
577
578     def want_interface_events(self, enable_disable=1):
579         return self.api(self.papi.want_interface_events,
580                         {'enable_disable': enable_disable,
581                          'pid': os.getpid(), })
582
583     def want_l2_macs_events(self, enable_disable=1, scan_delay=0,
584                             max_macs_in_event=0, learn_limit=0):
585         return self.api(self.papi.want_l2_macs_events,
586                         {'enable_disable': enable_disable,
587                          'scan_delay': scan_delay,
588                          'max_macs_in_event': max_macs_in_event,
589                          'learn_limit': learn_limit,
590                          'pid': os.getpid(), })
591
592     def want_dhcp6_reply_events(self, enable_disable=1):
593         return self.api(self.papi.want_dhcp6_reply_events,
594                         {'enable_disable': enable_disable,
595                          'pid': os.getpid()})
596
597     def want_dhcp6_pd_reply_events(self, enable_disable=1):
598         return self.api(self.papi.want_dhcp6_pd_reply_events,
599                         {'enable_disable': enable_disable,
600                          'pid': os.getpid()})
601
602     def dhcp6_send_client_message(self, msg_type, sw_if_index, T1, T2,
603                                   addresses, server_index=0xFFFFFFFF,
604                                   irt=0, mrt=0, mrc=1, mrd=0, stop=0,
605                                   ):
606         return self.api(self.papi.dhcp6_send_client_message,
607                         {'sw_if_index': sw_if_index,
608                          'server_index': server_index,
609                          'irt': irt,
610                          'mrt': mrt,
611                          'mrc': mrc,
612                          'mrd': mrd,
613                          'stop': stop,
614                          'msg_type': msg_type,
615                          'T1': T1,
616                          'T2': T2,
617                          'n_addresses': len(addresses),
618                          'addresses': addresses})
619
620     def dhcp6_pd_send_client_message(self, msg_type, sw_if_index, T1, T2,
621                                      prefixes, server_index=0xFFFFFFFF,
622                                      irt=0, mrt=0, mrc=1, mrd=0, stop=0,
623                                      ):
624         return self.api(self.papi.dhcp6_pd_send_client_message,
625                         {'sw_if_index': sw_if_index,
626                          'server_index': server_index,
627                          'irt': irt,
628                          'mrt': mrt,
629                          'mrc': mrc,
630                          'mrd': mrd,
631                          'stop': stop,
632                          'msg_type': msg_type,
633                          'T1': T1,
634                          'T2': T2,
635                          'n_prefixes': len(prefixes),
636                          'prefixes': prefixes})
637
638     def dhcp6_client_enable_disable(self, sw_if_index, prefix_group='',
639                                     enable=1):
640         return self.api(self.papi.dhcp6_client_enable_disable,
641                         {'sw_if_index': sw_if_index,
642                          'enable': enable})
643
644     def dhcp6_pd_client_enable_disable(self, sw_if_index, prefix_group='',
645                                        enable=1):
646         return self.api(self.papi.dhcp6_pd_client_enable_disable,
647                         {'sw_if_index': sw_if_index,
648                          'prefix_group': prefix_group,
649                          'enable': enable})
650
651     def ip6_add_del_address_using_prefix(self, sw_if_index, address,
652                                          prefix_length, prefix_group,
653                                          is_add=1):
654         return self.api(self.papi.ip6_add_del_address_using_prefix,
655                         {'sw_if_index': sw_if_index,
656                          'prefix_group': prefix_group,
657                          'address': address,
658                          'prefix_length': prefix_length,
659                          'is_add': is_add})
660
661     def sw_interface_set_l2_bridge(self, sw_if_index, bd_id,
662                                    shg=0, port_type=L2_PORT_TYPE.NORMAL,
663                                    enable=1):
664         """Add/remove interface to/from bridge domain.
665
666         :param int sw_if_index: Software interface index of the interface.
667         :param int bd_id: Bridge domain index.
668         :param int shg: Split-horizon group index. (Default value = 0)
669         :param int bvi: Set interface as a bridge group virtual interface.
670             (Default value = 0)
671         :param int enable: Add or remove interface. (Default value = 1)
672         """
673         return self.api(self.papi.sw_interface_set_l2_bridge,
674                         {'rx_sw_if_index': sw_if_index,
675                          'bd_id': bd_id,
676                          'shg': shg,
677                          'port_type': port_type,
678                          'enable': enable})
679
680     def bridge_flags(self, bd_id, is_set, feature_bitmap):
681         """Enable/disable required feature of the bridge domain with defined
682         ID.
683
684         :param int bd_id: Bridge domain ID.
685         :param int is_set: Set to 1 to enable, set to 0 to disable the feature.
686         :param int flags: Bitmap value of the feature to be set:
687             - learn (1 << 0),
688             - forward (1 << 1),
689             - flood (1 << 2),
690             - uu-flood (1 << 3) or
691             - arp-term (1 << 4).
692         """
693         return self.api(self.papi.bridge_flags,
694                         {'bd_id': bd_id,
695                          'is_set': is_set,
696                          'flags': feature_bitmap})
697
698     def l2_interface_vlan_tag_rewrite(
699             self,
700             sw_if_index,
701             vtr_oper,
702             push=0,
703             tag1=0,
704             tag2=0):
705         """L2 interface vlan tag rewrite configure request
706         :param client_index - opaque cookie to identify the sender
707         :param context - sender context, to match reply w/ request
708         :param sw_if_index - interface the operation is applied to
709         :param vtr_op - Choose from l2_vtr_op_t enum values
710         :param push_dot1q - first pushed flag dot1q id set, else dot1ad
711         :param tag1 - Needed for any push or translate vtr op
712         :param tag2 - Needed for any push 2 or translate x-2 vtr ops
713
714         """
715         return self.api(self.papi.l2_interface_vlan_tag_rewrite,
716                         {'sw_if_index': sw_if_index,
717                          'vtr_op': vtr_oper,
718                          'push_dot1q': push,
719                          'tag1': tag1,
720                          'tag2': tag2})
721
722     def sw_interface_set_mac_address(self, sw_if_index, mac):
723         return self.api(self.papi.sw_interface_set_mac_address,
724                         {'sw_if_index': sw_if_index,
725                          'mac_address': mac})
726
727     def create_subif(self, sw_if_index, sub_id, outer_vlan, inner_vlan,
728                      no_tags=0, one_tag=0, two_tags=0, dot1ad=0, exact_match=0,
729                      default_sub=0, outer_vlan_id_any=0, inner_vlan_id_any=0):
730         """Create subinterface
731         from vpe.api: set dot1ad = 0 for dot1q, set dot1ad = 1 for dot1ad
732
733         :param sub_id: param inner_vlan:
734         :param sw_if_index:
735         :param outer_vlan:
736         :param inner_vlan:
737         :param no_tags:  (Default value = 0)
738         :param one_tag:  (Default value = 0)
739         :param two_tags:  (Default value = 0)
740         :param dot1ad:  (Default value = 0)
741         :param exact_match:  (Default value = 0)
742         :param default_sub:  (Default value = 0)
743         :param outer_vlan_id_any:  (Default value = 0)
744         :param inner_vlan_id_any:  (Default value = 0)
745
746         """
747         return self.api(
748             self.papi.create_subif,
749             {'sw_if_index': sw_if_index,
750              'sub_id': sub_id,
751              'no_tags': no_tags,
752              'one_tag': one_tag,
753              'two_tags': two_tags,
754              'dot1ad': dot1ad,
755              'exact_match': exact_match,
756              'default_sub': default_sub,
757              'outer_vlan_id_any': outer_vlan_id_any,
758              'inner_vlan_id_any': inner_vlan_id_any,
759              'outer_vlan_id': outer_vlan,
760              'inner_vlan_id': inner_vlan})
761
762     def p2p_ethernet_add(self, sw_if_index, remote_mac, subif_id):
763         """Create p2p ethernet subinterface
764
765         :param sw_if_index: main (parent) interface
766         :param remote_mac: client (remote) mac address
767
768         """
769         return self.api(
770             self.papi.p2p_ethernet_add,
771             {'parent_if_index': sw_if_index,
772              'remote_mac': remote_mac,
773              'subif_id': subif_id})
774
775     def p2p_ethernet_del(self, sw_if_index, remote_mac):
776         """Delete p2p ethernet subinterface
777
778         :param sw_if_index: main (parent) interface
779         :param remote_mac: client (remote) mac address
780
781         """
782         return self.api(
783             self.papi.p2p_ethernet_del,
784             {'parent_if_index': sw_if_index,
785              'remote_mac': remote_mac})
786
787     def create_vlan_subif(self, sw_if_index, vlan):
788         """
789
790         :param vlan:
791         :param sw_if_index:
792
793         """
794         return self.api(self.papi.create_vlan_subif,
795                         {'sw_if_index': sw_if_index,
796                          'vlan_id': vlan})
797
798     def create_loopback(self, mac=''):
799         """
800
801         :param mac: (Optional)
802         """
803         return self.api(self.papi.create_loopback,
804                         {'mac_address': mac})
805
806     def ip_add_del_route(
807             self,
808             dst_address,
809             dst_address_length,
810             next_hop_address,
811             next_hop_sw_if_index=0xFFFFFFFF,
812             table_id=0,
813             next_hop_table_id=0,
814             next_hop_weight=1,
815             next_hop_n_out_labels=0,
816             next_hop_out_label_stack=[],
817             next_hop_via_label=MPLS_LABEL_INVALID,
818             next_hop_id=0xFFFFFFFF,
819             is_resolve_host=0,
820             is_resolve_attached=0,
821             classify_table_index=0xFFFFFFFF,
822             is_add=1,
823             is_drop=0,
824             is_unreach=0,
825             is_prohibit=0,
826             is_ipv6=0,
827             is_local=0,
828             is_classify=0,
829             is_multipath=0,
830             is_dvr=0,
831             is_udp_encap=0,
832             is_source_lookup=0):
833         """
834
835         :param dst_address_length:
836         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
837         :param dst_address:
838         :param next_hop_address:
839         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
840         :param vrf_id:  (Default value = 0)
841         :param lookup_in_vrf:  (Default value = 0)
842         :param classify_table_index:  (Default value = 0xFFFFFFFF)
843         :param is_add:  (Default value = 1)
844         :param is_drop:  (Default value = 0)
845         :param is_ipv6:  (Default value = 0)
846         :param is_local:  (Default value = 0)
847         :param is_classify:  (Default value = 0)
848         :param is_multipath:  (Default value = 0)
849         :param is_resolve_host:  (Default value = 0)
850         :param is_resolve_attached:  (Default value = 0)
851         :param is_dvr:  (Default value = 0)
852         :param is_source_lookup:  (Default value = 0)
853         :param next_hop_weight:  (Default value = 1)
854
855         """
856
857         return self.api(
858             self.papi.ip_add_del_route,
859             {'next_hop_sw_if_index': next_hop_sw_if_index,
860              'table_id': table_id,
861              'classify_table_index': classify_table_index,
862              'next_hop_table_id': next_hop_table_id,
863              'is_add': is_add,
864              'is_drop': is_drop,
865              'is_unreach': is_unreach,
866              'is_prohibit': is_prohibit,
867              'is_ipv6': is_ipv6,
868              'is_local': is_local,
869              'is_classify': is_classify,
870              'is_multipath': is_multipath,
871              'is_resolve_host': is_resolve_host,
872              'is_resolve_attached': is_resolve_attached,
873              'is_dvr': is_dvr,
874              'is_source_lookup': is_source_lookup,
875              'is_udp_encap': is_udp_encap,
876              'next_hop_weight': next_hop_weight,
877              'dst_address_length': dst_address_length,
878              'dst_address': dst_address,
879              'next_hop_id': next_hop_id,
880              'next_hop_address': next_hop_address,
881              'next_hop_n_out_labels': next_hop_n_out_labels,
882              'next_hop_via_label': next_hop_via_label,
883              'next_hop_out_label_stack': next_hop_out_label_stack})
884
885     def ip_neighbor_add_del(self,
886                             sw_if_index,
887                             mac_address,
888                             ip_address,
889                             is_add=1,
890                             flags=0):
891         """ Add neighbor MAC to IPv4 or IPv6 address.
892
893         :param sw_if_index:
894         :param mac_address:
895         :param dst_address:
896         :param is_add:  (Default value = 1)
897         :param flags:  (Default value = 0/NONE)
898         """
899         return self.api(
900             self.papi.ip_neighbor_add_del,
901             {
902                 'is_add': is_add,
903                 'neighbor': {
904                     'sw_if_index': sw_if_index,
905                     'flags': flags,
906                     'mac_address': mac_address,
907                     'ip_address': ip_address
908                 }
909             }
910         )
911
912     def proxy_arp_add_del(self,
913                           low,
914                           hi,
915                           table_id=0,
916                           is_add=1):
917         """ Config Proxy Arp Range.
918
919         :param low_address: Start address in the rnage to Proxy for
920         :param hi_address: End address in the rnage to Proxy for
921         :param vrf_id: The VRF/table in which to proxy
922         """
923
924         return self.api(
925             self.papi.proxy_arp_add_del,
926             {'proxy':
927                 {
928                     'table_id': table_id,
929                     'low': low,
930                     'hi': hi,
931                 },
932                 'is_add': is_add})
933
934     def proxy_arp_intfc_enable_disable(self,
935                                        sw_if_index,
936                                        is_enable=1):
937         """ Enable/Disable an interface for proxy ARP requests
938
939         :param sw_if_index: Interface
940         :param enable_disable: Enable/Disable
941         """
942
943         return self.api(
944             self.papi.proxy_arp_intfc_enable_disable,
945             {'sw_if_index': sw_if_index,
946              'enable_disable': is_enable
947              }
948         )
949
950     def gre_add_del_tunnel(self,
951                            src_address,
952                            dst_address,
953                            outer_fib_id=0,
954                            tunnel_type=0,
955                            instance=0xFFFFFFFF,
956                            session_id=0,
957                            is_add=1,
958                            is_ip6=0):
959         """ Add a GRE tunnel
960
961         :param src_address:
962         :param dst_address:
963         :param outer_fib_id:  (Default value = 0)
964         :param tunnel_type:  (Default value = 0)
965         :param instance:  (Default value = 0xFFFFFFFF)
966         :param session_id: (Defalt value = 0)
967         :param is_add:  (Default value = 1)
968         :param is_ipv6:  (Default value = 0)
969         """
970
971         return self.api(
972             self.papi.gre_add_del_tunnel,
973             {'is_add': is_add,
974              'is_ipv6': is_ip6,
975              'tunnel_type': tunnel_type,
976              'instance': instance,
977              'src_address': src_address,
978              'dst_address': dst_address,
979              'outer_fib_id': outer_fib_id,
980              'session_id': session_id}
981         )
982
983     def udp_encap_add(self,
984                       src_ip,
985                       dst_ip,
986                       src_port,
987                       dst_port,
988                       table_id=0):
989         """ Add a GRE tunnel
990         :param src_ip:
991         :param dst_ip:
992         :param src_port:
993         :param dst_port:
994         :param outer_fib_id:  (Default value = 0)
995         """
996
997         return self.api(
998             self.papi.udp_encap_add,
999             {
1000                 'udp_encap': {
1001                     'src_ip': src_ip,
1002                     'dst_ip': dst_ip,
1003                     'src_port': src_port,
1004                     'dst_port': dst_port,
1005                     'table_id': table_id
1006                 }
1007             })
1008
1009     def mpls_table_add_del(
1010             self,
1011             table_id,
1012             is_add=1):
1013         """
1014
1015         :param table_id
1016         :param is_add:  (Default value = 1)
1017
1018         """
1019
1020         return self.api(
1021             self.papi.mpls_table_add_del,
1022             {'mt_table_id': table_id,
1023              'mt_is_add': is_add})
1024
1025     def mpls_route_add_del(
1026             self,
1027             label,
1028             eos,
1029             next_hop_proto,
1030             next_hop_address,
1031             next_hop_sw_if_index=0xFFFFFFFF,
1032             table_id=0,
1033             next_hop_table_id=0,
1034             next_hop_weight=1,
1035             next_hop_n_out_labels=0,
1036             next_hop_out_label_stack=[],
1037             next_hop_via_label=MPLS_LABEL_INVALID,
1038             is_resolve_host=0,
1039             is_resolve_attached=0,
1040             is_interface_rx=0,
1041             is_rpf_id=0,
1042             is_multicast=0,
1043             is_add=1,
1044             is_drop=0,
1045             is_multipath=0,
1046             classify_table_index=0xFFFFFFFF,
1047             is_classify=0):
1048         """
1049
1050         :param dst_address_length:
1051         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
1052         :param dst_address:
1053         :param next_hop_address:
1054         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
1055         :param vrf_id:  (Default value = 0)
1056         :param lookup_in_vrf:  (Default value = 0)
1057         :param classify_table_index:  (Default value = 0xFFFFFFFF)
1058         :param is_add:  (Default value = 1)
1059         :param is_drop:  (Default value = 0)
1060         :param is_ipv6:  (Default value = 0)
1061         :param is_local:  (Default value = 0)
1062         :param is_classify:  (Default value = 0)
1063         :param is_multipath:  (Default value = 0)
1064         :param is_multicast:  (Default value = 0)
1065         :param is_resolve_host:  (Default value = 0)
1066         :param is_resolve_attached:  (Default value = 0)
1067         :param next_hop_weight:  (Default value = 1)
1068
1069         """
1070         return self.api(
1071             self.papi.mpls_route_add_del,
1072             {'mr_label': label,
1073              'mr_eos': eos,
1074              'mr_table_id': table_id,
1075              'mr_classify_table_index': classify_table_index,
1076              'mr_is_add': is_add,
1077              'mr_is_classify': is_classify,
1078              'mr_is_multipath': is_multipath,
1079              'mr_is_multicast': is_multicast,
1080              'mr_is_resolve_host': is_resolve_host,
1081              'mr_is_resolve_attached': is_resolve_attached,
1082              'mr_is_interface_rx': is_interface_rx,
1083              'mr_is_rpf_id': is_rpf_id,
1084              'mr_next_hop_proto': next_hop_proto,
1085              'mr_next_hop_weight': next_hop_weight,
1086              'mr_next_hop': next_hop_address,
1087              'mr_next_hop_n_out_labels': next_hop_n_out_labels,
1088              'mr_next_hop_sw_if_index': next_hop_sw_if_index,
1089              'mr_next_hop_table_id': next_hop_table_id,
1090              'mr_next_hop_via_label': next_hop_via_label,
1091              'mr_next_hop_out_label_stack': next_hop_out_label_stack})
1092
1093     def mpls_ip_bind_unbind(
1094             self,
1095             label,
1096             dst_address,
1097             dst_address_length,
1098             table_id=0,
1099             ip_table_id=0,
1100             is_ip4=1,
1101             is_bind=1):
1102         """
1103         """
1104         return self.api(
1105             self.papi.mpls_ip_bind_unbind,
1106             {'mb_mpls_table_id': table_id,
1107              'mb_label': label,
1108              'mb_ip_table_id': ip_table_id,
1109              'mb_is_bind': is_bind,
1110              'mb_is_ip4': is_ip4,
1111              'mb_address_length': dst_address_length,
1112              'mb_address': dst_address})
1113
1114     def mpls_tunnel_add_del(
1115             self,
1116             tun_sw_if_index,
1117             next_hop_proto_is_ip4,
1118             next_hop_address,
1119             next_hop_sw_if_index=0xFFFFFFFF,
1120             next_hop_table_id=0,
1121             next_hop_weight=1,
1122             next_hop_n_out_labels=0,
1123             next_hop_out_label_stack=[],
1124             next_hop_via_label=MPLS_LABEL_INVALID,
1125             is_add=1,
1126             l2_only=0,
1127             is_multicast=0):
1128         """
1129
1130         :param dst_address_length:
1131         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
1132         :param dst_address:
1133         :param next_hop_address:
1134         :param next_hop_sw_if_index:  (Default value = 0xFFFFFFFF)
1135         :param vrf_id:  (Default value = 0)
1136         :param lookup_in_vrf:  (Default value = 0)
1137         :param classify_table_index:  (Default value = 0xFFFFFFFF)
1138         :param is_add:  (Default value = 1)
1139         :param is_drop:  (Default value = 0)
1140         :param is_ipv6:  (Default value = 0)
1141         :param is_local:  (Default value = 0)
1142         :param is_classify:  (Default value = 0)
1143         :param is_multipath:  (Default value = 0)
1144         :param is_resolve_host:  (Default value = 0)
1145         :param is_resolve_attached:  (Default value = 0)
1146         :param next_hop_weight:  (Default value = 1)
1147         :param is_multicast:  (Default value = 0)
1148
1149         """
1150         return self.api(
1151             self.papi.mpls_tunnel_add_del,
1152             {'mt_sw_if_index': tun_sw_if_index,
1153              'mt_is_add': is_add,
1154              'mt_l2_only': l2_only,
1155              'mt_is_multicast': is_multicast,
1156              'mt_next_hop_proto_is_ip4': next_hop_proto_is_ip4,
1157              'mt_next_hop_weight': next_hop_weight,
1158              'mt_next_hop': next_hop_address,
1159              'mt_next_hop_n_out_labels': next_hop_n_out_labels,
1160              'mt_next_hop_sw_if_index': next_hop_sw_if_index,
1161              'mt_next_hop_table_id': next_hop_table_id,
1162              'mt_next_hop_via_label': next_hop_via_label,
1163              'mt_next_hop_out_label_stack': next_hop_out_label_stack})
1164
1165     def nat44_interface_add_del_feature(
1166             self,
1167             sw_if_index,
1168             is_inside=1,
1169             is_add=1):
1170         """Enable/disable NAT44 feature on the interface
1171
1172         :param sw_if_index: Software index of the interface
1173         :param is_inside: 1 if inside, 0 if outside (Default value = 1)
1174         :param is_add: 1 if add, 0 if delete (Default value = 1)
1175         """
1176         return self.api(
1177             self.papi.nat44_interface_add_del_feature,
1178             {'is_add': is_add,
1179              'is_inside': is_inside,
1180              'sw_if_index': sw_if_index})
1181
1182     def nat44_interface_add_del_output_feature(
1183             self,
1184             sw_if_index,
1185             is_inside=1,
1186             is_add=1):
1187         """Enable/disable NAT44 output feature on the interface
1188
1189         :param sw_if_index: Software index of the interface
1190         :param is_inside: 1 if inside, 0 if outside (Default value = 1)
1191         :param is_add: 1 if add, 0 if delete (Default value = 1)
1192         """
1193         return self.api(
1194             self.papi.nat44_interface_add_del_output_feature,
1195             {'is_add': is_add,
1196              'is_inside': is_inside,
1197              'sw_if_index': sw_if_index})
1198
1199     def nat44_add_del_static_mapping(
1200             self,
1201             local_ip,
1202             external_ip=0,
1203             external_sw_if_index=0xFFFFFFFF,
1204             local_port=0,
1205             external_port=0,
1206             addr_only=1,
1207             vrf_id=0,
1208             protocol=0,
1209             twice_nat=0,
1210             self_twice_nat=0,
1211             out2in_only=0,
1212             tag="",
1213             is_add=1):
1214         """Add/delete NAT44 static mapping
1215
1216         :param local_ip: Local IP address
1217         :param external_ip: External IP address
1218         :param external_sw_if_index: External interface instead of IP address
1219         :param local_port: Local port number (Default value = 0)
1220         :param external_port: External port number (Default value = 0)
1221         :param addr_only: 1 if address only mapping, 0 if address and port
1222         :param vrf_id: VRF ID
1223         :param protocol: IP protocol (Default value = 0)
1224         :param twice_nat: 1 if translate external host address and port
1225         :param self_twice_nat: 1 if translate external host address and port
1226                                whenever external host address equals
1227                                local address of internal host
1228         :param out2in_only: if 1 rule is matching only out2in direction
1229         :param tag: Opaque string tag
1230         :param is_add: 1 if add, 0 if delete (Default value = 1)
1231         """
1232         return self.api(
1233             self.papi.nat44_add_del_static_mapping,
1234             {'is_add': is_add,
1235              'addr_only': addr_only,
1236              'local_ip_address': local_ip,
1237              'external_ip_address': external_ip,
1238              'local_port': local_port,
1239              'external_port': external_port,
1240              'external_sw_if_index': external_sw_if_index,
1241              'vrf_id': vrf_id,
1242              'protocol': protocol,
1243              'twice_nat': twice_nat,
1244              'self_twice_nat': self_twice_nat,
1245              'out2in_only': out2in_only,
1246              'tag': tag})
1247
1248     def nat44_add_del_identity_mapping(
1249             self,
1250             ip='0',
1251             sw_if_index=0xFFFFFFFF,
1252             port=0,
1253             addr_only=1,
1254             vrf_id=0,
1255             protocol=0,
1256             tag='',
1257             is_add=1):
1258         """Add/delete NAT44 identity mapping
1259
1260         :param ip: IP address (Default value = 0)
1261         :param sw_if_index: Interface instead of IP address
1262         :param port: Port number (Default value = 0)
1263         :param addr_only: 1 if address only mapping, 0 if address and port
1264         :param vrf_id: VRF ID
1265         :param protocol: IP protocol (Default value = 0)
1266         :param tag: Opaque string tag
1267         :param is_add: 1 if add, 0 if delete (Default value = 1)
1268         """
1269         return self.api(
1270             self.papi.nat44_add_del_identity_mapping,
1271             {'is_add': is_add,
1272              'addr_only': addr_only,
1273              'ip_address': ip,
1274              'port': port,
1275              'sw_if_index': sw_if_index,
1276              'vrf_id': vrf_id,
1277              'tag': tag,
1278              'protocol': protocol})
1279
1280     def nat44_add_del_address_range(
1281             self,
1282             first_ip_address,
1283             last_ip_address,
1284             is_add=1,
1285             vrf_id=0xFFFFFFFF,
1286             twice_nat=0):
1287         """Add/del NAT44 address range
1288
1289         :param first_ip_address: First IP address
1290         :param last_ip_address: Last IP address
1291         :param vrf_id: VRF id for the address range
1292         :param twice_nat: twice NAT address for extenal hosts
1293         :param is_add: 1 if add, 0 if delete (Default value = 1)
1294         """
1295         return self.api(
1296             self.papi.nat44_add_del_address_range,
1297             {'first_ip_address': first_ip_address,
1298              'last_ip_address': last_ip_address,
1299              'vrf_id': vrf_id,
1300              'twice_nat': twice_nat,
1301              'is_add': is_add})
1302
1303     def nat44_add_del_interface_addr(
1304             self,
1305             sw_if_index,
1306             twice_nat=0,
1307             is_add=1):
1308         """Add/del NAT44 address from interface
1309
1310         :param sw_if_index: Software index of the interface
1311         :param twice_nat: twice NAT address for extenal hosts
1312         :param is_add: 1 if add, 0 if delete (Default value = 1)
1313         """
1314         return self.api(
1315             self.papi.nat44_add_del_interface_addr,
1316             {'is_add': is_add,
1317              'sw_if_index': sw_if_index,
1318              'twice_nat': twice_nat})
1319
1320     def nat44_add_del_lb_static_mapping(
1321             self,
1322             external_addr,
1323             external_port,
1324             protocol,
1325             twice_nat=0,
1326             self_twice_nat=0,
1327             out2in_only=0,
1328             tag='',
1329             affinity=0,
1330             local_num=0,
1331             locals=[],
1332             is_add=1):
1333         """Add/delete NAT44 load balancing static mapping
1334
1335         :param twice_nat: 1 if translate external host address and port
1336         :param tag: Opaque string tag
1337         :param affinity: if 0 disabled, otherwise client IP affinity timeout
1338         :param is_add - 1 if add, 0 if delete
1339         """
1340         return self.api(
1341             self.papi.nat44_add_del_lb_static_mapping,
1342             {'is_add': is_add,
1343              'external_addr': external_addr,
1344              'external_port': external_port,
1345              'protocol': protocol,
1346              'twice_nat': twice_nat,
1347              'self_twice_nat': self_twice_nat,
1348              'out2in_only': out2in_only,
1349              'tag': tag,
1350              'affinity': affinity,
1351              'local_num': local_num,
1352              'locals': locals})
1353
1354     def nat44_lb_static_mapping_add_del_local(
1355             self,
1356             external_addr,
1357             external_port,
1358             local_addr,
1359             local_port,
1360             protocol,
1361             probability,
1362             vrf_id=0,
1363             is_add=1):
1364         """Add/delete NAT44 load-balancing static mapping rule backend
1365
1366         :param external_addr: external IPv4 address of the servic
1367         :param external_port: external L4 port number of the service
1368         :param local_addr: IPv4 address of the internal node
1369         :param local_port: L4 port number of the internal node
1370         :param protocol: IP protocol number
1371         :param probability: probability of the internal node
1372         :param vrf_id: VRF id of the internal node
1373         :param is_add: 1 if add, 0 if delete
1374         """
1375         return self.api(
1376             self.papi.nat44_lb_static_mapping_add_del_local,
1377             {'is_add': is_add,
1378              'external_addr': external_addr,
1379              'external_port': external_port,
1380              'local': {
1381                  'addr': local_addr,
1382                  'port': local_port,
1383                  'probability': probability,
1384                  'vrf_id': vrf_id},
1385              'protocol': protocol})
1386
1387     def nat44_del_session(
1388             self,
1389             addr,
1390             port,
1391             protocol,
1392             vrf_id=0,
1393             is_in=1,
1394             ext_host_address=None,
1395             ext_host_port=0):
1396         """Delete NAT44 session
1397
1398         :param addr: IPv4 address
1399         :param por: port number
1400         :param protocol: IP protocol number
1401         :param vrf_id: VRF ID
1402         :param is_in: 1 if inside network addres and port pari, 0 if outside
1403         :param ext_host_address: external host IPv4 address
1404         :param ext_host_port: external host port
1405         """
1406         if ext_host_address is None:
1407             return self.api(
1408                 self.papi.nat44_del_session,
1409                 {'address': addr,
1410                  'port': port,
1411                  'protocol': protocol,
1412                  'vrf_id': vrf_id,
1413                  'is_in': is_in})
1414         else:
1415             return self.api(
1416                 self.papi.nat44_del_session,
1417                 {'address': addr,
1418                  'port': port,
1419                  'protocol': protocol,
1420                  'vrf_id': vrf_id,
1421                  'is_in': is_in,
1422                  'ext_host_valid': 1,
1423                  'ext_host_address': ext_host_address,
1424                  'ext_host_port': ext_host_port})
1425
1426     def nat44_forwarding_enable_disable(
1427             self,
1428             enable):
1429         """Enable/disable forwarding for NAT44
1430
1431         :param enable: 1 for enable, 0 for disable
1432         """
1433         return self.api(
1434             self.papi.nat44_forwarding_enable_disable,
1435             {'enable': enable})
1436
1437     def nat_det_add_del_map(
1438             self,
1439             in_addr,
1440             in_plen,
1441             out_addr,
1442             out_plen,
1443             is_add=1):
1444         """Add/delete deterministic NAT mapping
1445
1446         :param is_add - 1 if add, 0 if delete
1447         :param in_addr - inside IP address
1448         :param in_plen - inside IP address prefix length
1449         :param out_addr - outside IP address
1450         :param out_plen - outside IP address prefix length
1451         """
1452         return self.api(
1453             self.papi.nat_det_add_del_map,
1454             {'is_add': is_add,
1455              'is_nat44': 1,
1456              'in_addr': in_addr,
1457              'in_plen': in_plen,
1458              'out_addr': out_addr,
1459              'out_plen': out_plen})
1460
1461     def nat_det_forward(
1462             self,
1463             in_addr):
1464         """Get outside address and port range from inside address
1465
1466         :param in_addr - inside IP address
1467         """
1468         return self.api(
1469             self.papi.nat_det_forward,
1470             {'in_addr': in_addr,
1471              'is_nat44': 1})
1472
1473     def nat_det_reverse(
1474             self,
1475             out_addr,
1476             out_port):
1477         """Get inside address from outside address and port
1478
1479         :param out_addr - outside IP address
1480         :param out_port - outside port
1481         """
1482         return self.api(
1483             self.papi.nat_det_reverse,
1484             {'out_addr': out_addr,
1485              'out_port': out_port})
1486
1487     def nat_det_map_dump(self):
1488         """Dump deterministic NAT mappings
1489
1490         :return: Dictionary of deterministic NAT mappings
1491         """
1492         return self.api(self.papi.nat_det_map_dump, {})
1493
1494     def nat_set_mss_clamping(self, enable=0, mss_value=1500):
1495         """Set TCP MSS rewriting configuration
1496
1497         :param enable: disable(0)/enable(1) MSS rewriting feature
1498         :param mss_value: MSS value to be used for MSS rewriting
1499         """
1500         return self.api(
1501             self.papi.nat_set_mss_clamping,
1502             {'enable': enable, 'mss_value': mss_value})
1503
1504     def nat_det_close_session_in(
1505             self,
1506             in_addr,
1507             in_port,
1508             ext_addr,
1509             ext_port):
1510         """Close deterministic NAT session using inside address and port
1511
1512         :param in_addr - inside IP address
1513         :param in_port - inside port
1514         :param ext_addr - external host IP address
1515         :param ext_port - external host port
1516         """
1517         return self.api(
1518             self.papi.nat_det_close_session_in,
1519             {'in_addr': in_addr,
1520              'in_port': in_port,
1521              'ext_addr': ext_addr,
1522              'ext_port': ext_port,
1523              'is_nat44': 1})
1524
1525     def nat_det_session_dump(
1526             self,
1527             user_addr):
1528         """Dump deterministic NAT sessions belonging to a user
1529
1530         :param user_addr - inside IP address of the user
1531         :return: Dictionary of deterministic NAT sessions
1532         """
1533         return self.api(
1534             self.papi.nat_det_session_dump,
1535             {'is_nat44': 1,
1536              'user_addr': user_addr})
1537
1538     def nat64_add_del_interface(
1539             self,
1540             sw_if_index,
1541             is_inside=1,
1542             is_add=1):
1543         """Enable/disable NAT64 feature on the interface
1544            :param sw_if_index: Index of the interface
1545            :param is_inside: 1 if inside, 0 if outside (Default value = 1)
1546            :param is_add: 1 if add, 0 if delete (Default value = 1)
1547         """
1548         return self.api(
1549             self.papi.nat64_add_del_interface,
1550             {'sw_if_index': sw_if_index,
1551              'is_inside': is_inside,
1552              'is_add': is_add})
1553
1554     def nat64_add_del_static_bib(
1555             self,
1556             in_ip,
1557             out_ip,
1558             in_port,
1559             out_port,
1560             protocol,
1561             vrf_id=0,
1562             is_add=1):
1563         """Add/delete S-NAT static BIB entry
1564
1565         :param in_ip: Inside IPv6 address
1566         :param out_ip: Outside IPv4 address
1567         :param in_port: Inside port number
1568         :param out_port: Outside port number
1569         :param protocol: IP protocol
1570         :param vrf_id: VRF ID (Default value = 0)
1571         :param is_add: 1 if add, 0 if delete (Default value = 1)
1572         """
1573         return self.api(
1574             self.papi.nat64_add_del_static_bib,
1575             {'i_addr': in_ip,
1576              'o_addr': out_ip,
1577              'i_port': in_port,
1578              'o_port': out_port,
1579              'vrf_id': vrf_id,
1580              'proto': protocol,
1581              'is_add': is_add})
1582
1583     def nat64_bib_dump(self, protocol=255):
1584         """Dump NAT64 BIB
1585
1586         :param protocol: IP protocol (Default value = 255, all BIBs)
1587         :returns: Dictionary of NAT64 BIB entries
1588         """
1589         return self.api(self.papi.nat64_bib_dump, {'proto': protocol})
1590
1591     def nat64_st_dump(self, protocol=255):
1592         """Dump NAT64 session table
1593
1594         :param protocol: IP protocol (Default value = 255, all STs)
1595         :returns: Dictionary of NAT64 sesstion table entries
1596         """
1597         return self.api(self.papi.nat64_st_dump, {'proto': protocol})
1598
1599     def nat64_add_del_prefix(self, prefix, plen, vrf_id=0, is_add=1):
1600         """Add/del NAT64 prefix
1601
1602         :param prefix: NAT64 prefix
1603         :param plen: NAT64 prefix length
1604         :param vrf_id: VRF id of tenant (Default 0)
1605         :param is_add: 1 if add, 0 if delete (Default value = 1)
1606         """
1607         return self.api(
1608             self.papi.nat64_add_del_prefix,
1609             {'prefix': prefix,
1610              'prefix_len': plen,
1611              'vrf_id': vrf_id,
1612              'is_add': is_add})
1613
1614     def nat64_add_del_interface_addr(
1615             self,
1616             sw_if_index,
1617             is_add=1):
1618         """Add/del NAT64 address from interface
1619
1620         :param sw_if_index: Software index of the interface
1621         :param is_add: 1 if add, 0 if delete (Default value = 1)
1622         """
1623         return self.api(self.papi.nat64_add_del_interface_addr,
1624                         {'is_add': is_add, 'sw_if_index': sw_if_index})
1625
1626     def dslite_set_aftr_addr(self, ip6, ip4):
1627         """Set DS-Lite AFTR addresses
1628
1629         :param ip4: IPv4 address
1630         :param ip6: IPv6 address
1631         """
1632         return self.api(
1633             self.papi.dslite_set_aftr_addr,
1634             {'ip4_addr': ip4,
1635              'ip6_addr': ip6})
1636
1637     def dslite_set_b4_addr(self, ip6, ip4):
1638         """Set DS-Lite B4 IPv6 address
1639
1640         :param ip4: IPv4 address
1641         :param ip6: IPv6 address
1642         """
1643         return self.api(
1644             self.papi.dslite_set_b4_addr,
1645             {'ip4_addr': ip4,
1646              'ip6_addr': ip6})
1647
1648     def nat66_add_del_interface(
1649             self,
1650             sw_if_index,
1651             is_inside=1,
1652             is_add=1):
1653         """Enable/disable NAT66 feature on the interface
1654            :param sw_if_index: Index of the interface
1655            :param is_inside: 1 if inside, 0 if outside (Default value = 1)
1656            :param is_add: 1 if add, 0 if delete (Default value = 1)
1657         """
1658         return self.api(
1659             self.papi.nat66_add_del_interface,
1660             {'sw_if_index': sw_if_index,
1661              'is_inside': is_inside,
1662              'is_add': is_add})
1663
1664     def nat66_add_del_static_mapping(
1665             self,
1666             in_ip,
1667             out_ip,
1668             vrf_id=0,
1669             is_add=1):
1670         """Add/delete NAT66 static mapping
1671
1672         :param in_ip: Inside IPv6 address
1673         :param out_ip: Outside IPv6 address
1674         :param vrf_id: VRF ID (Default value = 0)
1675         :param is_add: 1 if add, 0 if delete (Default value = 1)
1676         """
1677         return self.api(
1678             self.papi.nat66_add_del_static_mapping,
1679             {'local_ip_address': in_ip,
1680              'external_ip_address': out_ip,
1681              'vrf_id': vrf_id,
1682              'is_add': is_add})
1683
1684     def nat_ha_set_listener(self, addr, port, path_mtu=512):
1685         """Set HA listener (local settings)
1686
1687         :param addr: local IP4 address
1688         :param port: local UDP port number
1689         :param path_mtu: path MTU (Default value = 512)
1690         """
1691         return self.api(self.papi.nat_ha_set_listener,
1692                         {'ip_address': addr,
1693                          'port': port,
1694                          'path_mtu': path_mtu})
1695
1696     def nat_ha_get_listener(self):
1697         """Get HA listener/local configuration"""
1698         return self.api(self.papi.nat_ha_get_listener, {})
1699
1700     def nat_ha_set_failover(self, addr, port, refresh=10):
1701         """Set HA failover (remote settings)
1702
1703         :param addr: failover IP4 address
1704         :param port: failvoer UDP port number
1705         :param refresh: number of seconds after which to send session refresh
1706         """
1707         return self.api(self.papi.nat_ha_set_failover,
1708                         {'ip_address': addr,
1709                          'port': port,
1710                          'session_refresh_interval': refresh})
1711
1712     def nat_ha_resync(self, want_resync_event=1):
1713         """Resync HA (resend existing sessions to new failover)
1714         :param want_resync_event: if non-zero resync completed event sent
1715         """
1716         return self.api(self.papi.nat_ha_resync,
1717                         {'want_resync_event': want_resync_event,
1718                          'pid': os.getpid()})
1719
1720     def bfd_udp_add(self, sw_if_index, desired_min_tx, required_min_rx,
1721                     detect_mult, local_addr, peer_addr, is_ipv6=0,
1722                     bfd_key_id=None, conf_key_id=None):
1723         if bfd_key_id is None:
1724             return self.api(self.papi.bfd_udp_add,
1725                             {
1726                                 'sw_if_index': sw_if_index,
1727                                 'desired_min_tx': desired_min_tx,
1728                                 'required_min_rx': required_min_rx,
1729                                 'local_addr': local_addr,
1730                                 'peer_addr': peer_addr,
1731                                 'is_ipv6': is_ipv6,
1732                                 'detect_mult': detect_mult,
1733                             })
1734         else:
1735             return self.api(self.papi.bfd_udp_add,
1736                             {
1737                                 'sw_if_index': sw_if_index,
1738                                 'desired_min_tx': desired_min_tx,
1739                                 'required_min_rx': required_min_rx,
1740                                 'local_addr': local_addr,
1741                                 'peer_addr': peer_addr,
1742                                 'is_ipv6': is_ipv6,
1743                                 'detect_mult': detect_mult,
1744                                 'is_authenticated': 1,
1745                                 'bfd_key_id': bfd_key_id,
1746                                 'conf_key_id': conf_key_id,
1747                             })
1748
1749     def bfd_udp_mod(self, sw_if_index, desired_min_tx, required_min_rx,
1750                     detect_mult, local_addr, peer_addr, is_ipv6=0):
1751         return self.api(self.papi.bfd_udp_mod,
1752                         {
1753                             'sw_if_index': sw_if_index,
1754                             'desired_min_tx': desired_min_tx,
1755                             'required_min_rx': required_min_rx,
1756                             'local_addr': local_addr,
1757                             'peer_addr': peer_addr,
1758                             'is_ipv6': is_ipv6,
1759                             'detect_mult': detect_mult,
1760                         })
1761
1762     def bfd_udp_auth_activate(self, sw_if_index, local_addr, peer_addr,
1763                               is_ipv6=0, bfd_key_id=None, conf_key_id=None,
1764                               is_delayed=False):
1765         return self.api(self.papi.bfd_udp_auth_activate,
1766                         {
1767                             'sw_if_index': sw_if_index,
1768                             'local_addr': local_addr,
1769                             'peer_addr': peer_addr,
1770                             'is_ipv6': is_ipv6,
1771                             'is_delayed': 1 if is_delayed else 0,
1772                             'bfd_key_id': bfd_key_id,
1773                             'conf_key_id': conf_key_id,
1774                         })
1775
1776     def bfd_udp_session_set_flags(self, admin_up_down, sw_if_index, local_addr,
1777                                   peer_addr, is_ipv6=0):
1778         return self.api(self.papi.bfd_udp_session_set_flags, {
1779             'admin_up_down': admin_up_down,
1780             'sw_if_index': sw_if_index,
1781             'local_addr': local_addr,
1782             'peer_addr': peer_addr,
1783             'is_ipv6': is_ipv6,
1784         })
1785
1786     def want_bfd_events(self, enable_disable=1):
1787         return self.api(self.papi.want_bfd_events, {
1788             'enable_disable': enable_disable,
1789             'pid': os.getpid(),
1790         })
1791
1792     def bfd_auth_set_key(self, conf_key_id, auth_type, key):
1793         return self.api(self.papi.bfd_auth_set_key, {
1794             'conf_key_id': conf_key_id,
1795             'auth_type': auth_type,
1796             'key': key,
1797             'key_len': len(key),
1798         })
1799
1800     def classify_add_del_table(
1801             self,
1802             is_add,
1803             mask,
1804             match_n_vectors=1,
1805             table_index=0xFFFFFFFF,
1806             nbuckets=2,
1807             memory_size=2097152,
1808             skip_n_vectors=0,
1809             next_table_index=0xFFFFFFFF,
1810             miss_next_index=0xFFFFFFFF,
1811             current_data_flag=0,
1812             current_data_offset=0):
1813         """
1814         :param is_add:
1815         :param mask:
1816         :param match_n_vectors: (Default value = 1)
1817         :param table_index: (Default value = 0xFFFFFFFF)
1818         :param nbuckets:  (Default value = 2)
1819         :param memory_size:  (Default value = 2097152)
1820         :param skip_n_vectors:  (Default value = 0)
1821         :param next_table_index:  (Default value = 0xFFFFFFFF)
1822         :param miss_next_index:  (Default value = 0xFFFFFFFF)
1823         :param current_data_flag:  (Default value = 0)
1824         :param current_data_offset:  (Default value = 0)
1825         """
1826
1827         mask_len = ((len(mask) - 1) / 16 + 1) * 16
1828         mask = mask + '\0' * (mask_len - len(mask))
1829         return self.api(
1830             self.papi.classify_add_del_table,
1831             {'is_add': is_add,
1832              'table_index': table_index,
1833              'nbuckets': nbuckets,
1834              'memory_size': memory_size,
1835              'skip_n_vectors': skip_n_vectors,
1836              'match_n_vectors': match_n_vectors,
1837              'next_table_index': next_table_index,
1838              'miss_next_index': miss_next_index,
1839              'current_data_flag': current_data_flag,
1840              'current_data_offset': current_data_offset,
1841              'mask_len': mask_len,
1842              'mask': mask})
1843
1844     def classify_add_del_session(
1845             self,
1846             is_add,
1847             table_index,
1848             match,
1849             opaque_index=0xFFFFFFFF,
1850             hit_next_index=0xFFFFFFFF,
1851             advance=0,
1852             action=0,
1853             metadata=0):
1854         """
1855         :param is_add:
1856         :param table_index:
1857         :param match:
1858         :param opaque_index:  (Default value = 0xFFFFFFFF)
1859         :param hit_next_index:  (Default value = 0xFFFFFFFF)
1860         :param advance:  (Default value = 0)
1861         :param action:  (Default value = 0)
1862         :param metadata:  (Default value = 0)
1863         """
1864
1865         match_len = ((len(match) - 1) / 16 + 1) * 16
1866         match = match + '\0' * (match_len - len(match))
1867         return self.api(
1868             self.papi.classify_add_del_session,
1869             {'is_add': is_add,
1870              'table_index': table_index,
1871              'hit_next_index': hit_next_index,
1872              'opaque_index': opaque_index,
1873              'advance': advance,
1874              'action': action,
1875              'metadata': metadata,
1876              'match_len': match_len,
1877              'match': match})
1878
1879     def input_acl_set_interface(
1880             self,
1881             is_add,
1882             sw_if_index,
1883             ip4_table_index=0xFFFFFFFF,
1884             ip6_table_index=0xFFFFFFFF,
1885             l2_table_index=0xFFFFFFFF):
1886         """
1887         :param is_add:
1888         :param sw_if_index:
1889         :param ip4_table_index:  (Default value = 0xFFFFFFFF)
1890         :param ip6_table_index:  (Default value = 0xFFFFFFFF)
1891         :param l2_table_index:  (Default value = 0xFFFFFFFF)
1892         """
1893
1894         return self.api(
1895             self.papi.input_acl_set_interface,
1896             {'sw_if_index': sw_if_index,
1897              'ip4_table_index': ip4_table_index,
1898              'ip6_table_index': ip6_table_index,
1899              'l2_table_index': l2_table_index,
1900              'is_add': is_add})
1901
1902     def output_acl_set_interface(
1903             self,
1904             is_add,
1905             sw_if_index,
1906             ip4_table_index=0xFFFFFFFF,
1907             ip6_table_index=0xFFFFFFFF,
1908             l2_table_index=0xFFFFFFFF):
1909         """
1910         :param is_add:
1911         :param sw_if_index:
1912         :param ip4_table_index:  (Default value = 0xFFFFFFFF)
1913         :param ip6_table_index:  (Default value = 0xFFFFFFFF)
1914         :param l2_table_index:  (Default value = 0xFFFFFFFF)
1915         """
1916
1917         return self.api(
1918             self.papi.output_acl_set_interface,
1919             {'sw_if_index': sw_if_index,
1920              'ip4_table_index': ip4_table_index,
1921              'ip6_table_index': ip6_table_index,
1922              'l2_table_index': l2_table_index,
1923              'is_add': is_add})
1924
1925     def set_ipfix_exporter(
1926             self,
1927             collector_address,
1928             src_address,
1929             path_mtu,
1930             template_interval,
1931             vrf_id=0,
1932             collector_port=4739,
1933             udp_checksum=0):
1934         return self.api(
1935             self.papi.set_ipfix_exporter,
1936             {
1937                 'collector_address': collector_address,
1938                 'collector_port': collector_port,
1939                 'src_address': src_address,
1940                 'vrf_id': vrf_id,
1941                 'path_mtu': path_mtu,
1942                 'template_interval': template_interval,
1943                 'udp_checksum': udp_checksum,
1944             })
1945
1946     def dhcp_proxy_config(self,
1947                           dhcp_server,
1948                           dhcp_src_address,
1949                           rx_table_id=0,
1950                           server_table_id=0,
1951                           is_add=1,
1952                           is_ipv6=0):
1953         return self.api(
1954             self.papi.dhcp_proxy_config,
1955             {
1956                 'rx_vrf_id': rx_table_id,
1957                 'server_vrf_id': server_table_id,
1958                 'is_ipv6': is_ipv6,
1959                 'is_add': is_add,
1960                 'dhcp_server': dhcp_server,
1961                 'dhcp_src_address': dhcp_src_address,
1962             })
1963
1964     def dhcp_proxy_set_vss(self,
1965                            table_id,
1966                            vss_type=255,
1967                            vpn_ascii_id="",
1968                            oui=0,
1969                            vpn_index=0,
1970                            is_add=1,
1971                            is_ip6=0):
1972         return self.api(
1973             self.papi.dhcp_proxy_set_vss,
1974             {
1975                 'tbl_id': table_id,
1976                 'vss_type': vss_type,
1977                 'vpn_ascii_id': vpn_ascii_id,
1978                 'oui': oui,
1979                 'vpn_index': vpn_index,
1980                 'is_add': is_add,
1981                 'is_ipv6': is_ip6,
1982             })
1983
1984     def dhcp_client_config(self,
1985                            sw_if_index,
1986                            hostname,
1987                            client_id='',
1988                            is_add=1,
1989                            set_broadcast_flag=1,
1990                            want_dhcp_events=0):
1991         return self.api(
1992             self.papi.dhcp_client_config,
1993             {
1994                 'is_add': is_add,
1995                 'client': {
1996                     'sw_if_index': sw_if_index,
1997                     'hostname': hostname,
1998                     'id': client_id,
1999                     'want_dhcp_event': want_dhcp_events,
2000                     'set_broadcast_flag': set_broadcast_flag,
2001                     'pid': os.getpid()}
2002             })
2003
2004     def ip_mroute_add_del(self,
2005                           src_address,
2006                           grp_address,
2007                           grp_address_length,
2008                           e_flags,
2009                           next_hop_afi,
2010                           next_hop_sw_if_index,
2011                           next_hop_address,
2012                           i_flags,
2013                           bier_imp=0,
2014                           rpf_id=0,
2015                           table_id=0,
2016                           is_add=1,
2017                           is_ipv6=0,
2018                           is_local=0):
2019         """
2020         IP Multicast Route add/del
2021         """
2022         return self.api(
2023             self.papi.ip_mroute_add_del,
2024             {'next_hop_sw_if_index': next_hop_sw_if_index,
2025              'entry_flags': e_flags,
2026              'itf_flags': i_flags,
2027              'table_id': table_id,
2028              'rpf_id': rpf_id,
2029              'is_add': is_add,
2030              'is_ipv6': is_ipv6,
2031              'is_local': is_local,
2032              'bier_imp': bier_imp,
2033              'next_hop_afi': next_hop_afi,
2034              'grp_address_length': grp_address_length,
2035              'grp_address': grp_address,
2036              'src_address': src_address,
2037              'nh_address': next_hop_address})
2038
2039     def lisp_enable_disable(self, is_enabled):
2040         return self.api(
2041             self.papi.lisp_enable_disable,
2042             {
2043                 'is_en': is_enabled,
2044             })
2045
2046     def lisp_add_del_locator_set(self,
2047                                  ls_name,
2048                                  is_add=1):
2049         return self.api(
2050             self.papi.lisp_add_del_locator_set,
2051             {
2052                 'is_add': is_add,
2053                 'locator_set_name': ls_name
2054             })
2055
2056     def lisp_add_del_locator(self,
2057                              ls_name,
2058                              sw_if_index,
2059                              priority=1,
2060                              weight=1,
2061                              is_add=1):
2062         return self.api(
2063             self.papi.lisp_add_del_locator,
2064             {
2065                 'is_add': is_add,
2066                 'locator_set_name': ls_name,
2067                 'sw_if_index': sw_if_index,
2068                 'priority': priority,
2069                 'weight': weight
2070             })
2071
2072     def lisp_locator_dump(self, is_index_set, ls_name=None, ls_index=0):
2073         return self.api(
2074             self.papi.lisp_locator_dump,
2075             {
2076                 'is_index_set': is_index_set,
2077                 'ls_name': ls_name,
2078                 'ls_index': ls_index,
2079             })
2080
2081     def lisp_add_del_local_eid(self,
2082                                ls_name,
2083                                eid_type,
2084                                eid,
2085                                prefix_len,
2086                                vni=0,
2087                                key_id=0,
2088                                key="",
2089                                is_add=1):
2090         return self.api(
2091             self.papi.lisp_add_del_local_eid,
2092             {
2093                 'locator_set_name': ls_name,
2094                 'is_add': is_add,
2095                 'eid_type': eid_type,
2096                 'eid': eid,
2097                 'prefix_len': prefix_len,
2098                 'vni': vni,
2099                 'key_id': key_id,
2100                 'key': key
2101             })
2102
2103     def lisp_eid_table_dump(self,
2104                             eid_set=0,
2105                             prefix_length=0,
2106                             vni=0,
2107                             eid_type=0,
2108                             eid=None,
2109                             filter_opt=0):
2110         return self.api(
2111             self.papi.lisp_eid_table_dump,
2112             {
2113                 'eid_set': eid_set,
2114                 'prefix_length': prefix_length,
2115                 'vni': vni,
2116                 'eid_type': eid_type,
2117                 'eid': eid,
2118                 'filter': filter_opt,
2119             })
2120
2121     def lisp_add_del_remote_mapping(self,
2122                                     eid_type,
2123                                     eid,
2124                                     eid_prefix_len=0,
2125                                     vni=0,
2126                                     rlocs=[],
2127                                     rlocs_num=0,
2128                                     is_src_dst=0,
2129                                     is_add=1):
2130         return self.api(
2131             self.papi.lisp_add_del_remote_mapping,
2132             {
2133                 'is_add': is_add,
2134                 'eid_type': eid_type,
2135                 'eid': eid,
2136                 'eid_len': eid_prefix_len,
2137                 'rloc_num': rlocs_num,
2138                 'rlocs': rlocs,
2139                 'vni': vni,
2140                 'is_src_dst': is_src_dst,
2141             })
2142
2143     def lisp_add_del_adjacency(self,
2144                                leid,
2145                                reid,
2146                                leid_len,
2147                                reid_len,
2148                                eid_type,
2149                                is_add=1,
2150                                vni=0):
2151         return self.api(
2152             self.papi.lisp_add_del_adjacency,
2153             {
2154                 'is_add': is_add,
2155                 'vni': vni,
2156                 'eid_type': eid_type,
2157                 'leid': leid,
2158                 'reid': reid,
2159                 'leid_len': leid_len,
2160                 'reid_len': reid_len,
2161             })
2162
2163     def gtpu_add_del_tunnel(
2164             self,
2165             src_addr,
2166             dst_addr,
2167             is_add=1,
2168             is_ipv6=0,
2169             mcast_sw_if_index=0xFFFFFFFF,
2170             encap_vrf_id=0,
2171             decap_next_index=0xFFFFFFFF,
2172             teid=0):
2173         """
2174
2175         :param is_add:  (Default value = 1)
2176         :param is_ipv6:  (Default value = 0)
2177         :param src_addr:
2178         :param dst_addr:
2179         :param mcast_sw_if_index:  (Default value = 0xFFFFFFFF)
2180         :param encap_vrf_id:  (Default value = 0)
2181         :param decap_next_index:  (Default value = 0xFFFFFFFF)
2182         :param teid:  (Default value = 0)
2183
2184         """
2185         return self.api(self.papi.gtpu_add_del_tunnel,
2186                         {'is_add': is_add,
2187                          'is_ipv6': is_ipv6,
2188                          'src_address': src_addr,
2189                          'dst_address': dst_addr,
2190                          'mcast_sw_if_index': mcast_sw_if_index,
2191                          'encap_vrf_id': encap_vrf_id,
2192                          'decap_next_index': decap_next_index,
2193                          'teid': teid})
2194
2195     def vxlan_gpe_add_del_tunnel(
2196             self,
2197             src_addr,
2198             dst_addr,
2199             mcast_sw_if_index=0xFFFFFFFF,
2200             is_add=1,
2201             is_ipv6=0,
2202             encap_vrf_id=0,
2203             decap_vrf_id=0,
2204             protocol=3,
2205             vni=0):
2206         """
2207
2208         :param local:
2209         :param remote:
2210         :param is_add:  (Default value = 1)
2211         :param is_ipv6:  (Default value = 0)
2212         :param encap_vrf_id:  (Default value = 0)
2213         :param decap_vrf_id:  (Default value = 0)
2214         :param mcast_sw_if_index:  (Default value = 0xFFFFFFFF)
2215         :param protocol:  (Default value = 3)
2216         :param vni:  (Default value = 0)
2217
2218         """
2219         return self.api(self.papi.vxlan_gpe_add_del_tunnel,
2220                         {'is_add': is_add,
2221                          'is_ipv6': is_ipv6,
2222                          'local': src_addr,
2223                          'remote': dst_addr,
2224                          'mcast_sw_if_index': mcast_sw_if_index,
2225                          'encap_vrf_id': encap_vrf_id,
2226                          'decap_vrf_id': decap_vrf_id,
2227                          'protocol': protocol,
2228                          'vni': vni})
2229
2230     def vxlan_gbp_tunnel_add_del(
2231             self,
2232             src,
2233             dst,
2234             mcast_sw_if_index=0xFFFFFFFF,
2235             is_add=1,
2236             is_ipv6=0,
2237             encap_table_id=0,
2238             vni=0,
2239             instance=0xFFFFFFFF):
2240         """
2241
2242         :param dst_addr:
2243         :param src_addr:
2244         :param is_add:  (Default value = 1)
2245         :param is_ipv6:  (Default value = 0)
2246         :param encap_table_id:  (Default value = 0)
2247         :param decap_next_index:  (Default value = 0xFFFFFFFF)
2248         :param mcast_sw_if_index:  (Default value = 0xFFFFFFFF)
2249         :param vni:  (Default value = 0)
2250         :param instance:  (Default value = 0xFFFFFFFF)
2251
2252         """
2253         return self.api(self.papi.vxlan_gbp_tunnel_add_del,
2254                         {'is_add': is_add,
2255                          'tunnel': {
2256                              'src': src,
2257                              'dst': dst,
2258                              'mcast_sw_if_index': mcast_sw_if_index,
2259                              'encap_table_id': encap_table_id,
2260                              'vni': vni,
2261                              'instance': instance}})
2262
2263     def vxlan_gbp_tunnel_dump(self, sw_if_index=0xffffffff):
2264         return self.api(self.papi.vxlan_gbp_tunnel_dump,
2265                         {'sw_if_index': sw_if_index,
2266                          '_no_type_conversion': True})
2267
2268     def pppoe_add_del_session(
2269             self,
2270             client_ip,
2271             client_mac,
2272             session_id=0,
2273             is_add=1,
2274             is_ipv6=0,
2275             decap_vrf_id=0):
2276         """
2277
2278         :param is_add:  (Default value = 1)
2279         :param is_ipv6:  (Default value = 0)
2280         :param client_ip:
2281         :param session_id:  (Default value = 0)
2282         :param client_mac:
2283         :param decap_vrf_id:  (Default value = 0)
2284
2285         """
2286         return self.api(self.papi.pppoe_add_del_session,
2287                         {'is_add': is_add,
2288                          'is_ipv6': is_ipv6,
2289                          'session_id': session_id,
2290                          'client_ip': client_ip,
2291                          'decap_vrf_id': decap_vrf_id,
2292                          'client_mac': client_mac})
2293
2294     def sr_mpls_policy_add(self, bsid, weight, type, segments):
2295         return self.api(self.papi.sr_mpls_policy_add,
2296                         {'bsid': bsid,
2297                          'weight': weight,
2298                          'type': type,
2299                          'n_segments': len(segments),
2300                          'segments': segments})
2301
2302     def sr_mpls_policy_del(self, bsid):
2303         return self.api(self.papi.sr_mpls_policy_del,
2304                         {'bsid': bsid})
2305
2306     def sr_localsid_add_del(self,
2307                             localsid,
2308                             behavior,
2309                             nh_addr4,
2310                             nh_addr6,
2311                             is_del=0,
2312                             end_psp=0,
2313                             sw_if_index=0xFFFFFFFF,
2314                             vlan_index=0,
2315                             fib_table=0,
2316                             ):
2317         """ Add/del IPv6 SR local-SID.
2318
2319         :param localsid:
2320         :param behavior: END=1; END.X=2; END.DX2=4; END.DX6=5;
2321         :param behavior: END.DX4=6; END.DT6=7; END.DT4=8
2322         :param nh_addr4:
2323         :param nh_addr6:
2324         :param is_del:  (Default value = 0)
2325         :param end_psp: (Default value = 0)
2326         :param sw_if_index: (Default value = 0xFFFFFFFF)
2327         :param vlan_index:  (Default value = 0)
2328         :param fib_table:   (Default value = 0)
2329         """
2330         return self.api(
2331             self.papi.sr_localsid_add_del,
2332             {'is_del': is_del,
2333              'localsid': localsid,
2334              'end_psp': end_psp,
2335              'behavior': behavior,
2336              'sw_if_index': sw_if_index,
2337              'vlan_index': vlan_index,
2338              'fib_table': fib_table,
2339              'nh_addr4': nh_addr4,
2340              'nh_addr6': nh_addr6
2341              }
2342         )
2343
2344     def sr_policy_add(
2345             self,
2346             bsid_addr,
2347             weight=1,
2348             is_encap=1,
2349             type=0,
2350             fib_table=0,
2351             n_segments=0,
2352             segments=[]):
2353         """
2354         :param bsid_addr: bindingSID of the SR Policy
2355         :param weight: weight of the sid list. optional. (default: 1)
2356         :param is_encap: (bool) whether SR policy should Encap or SRH insert \
2357             (default: Encap)
2358         :param type: type/behavior of the SR policy. (default or spray) \
2359             (default: default)
2360         :param fib_table: VRF where to install the FIB entry for the BSID \
2361             (default: 0)
2362         :param n_segments: number of segments \
2363             (default: 0)
2364         :param segments: a vector of IPv6 address composing the segment list \
2365             (default: [])
2366         """
2367         return self.api(
2368             self.papi.sr_policy_add,
2369             {'bsid_addr': bsid_addr,
2370              'weight': weight,
2371              'is_encap': is_encap,
2372              'type': type,
2373              'fib_table': fib_table,
2374              'n_segments': n_segments,
2375              'segments': segments
2376              }
2377         )
2378
2379     def sr_policy_del(
2380             self,
2381             bsid_addr,
2382             sr_policy_index=0):
2383         """
2384         :param bsid: bindingSID of the SR Policy
2385         :param sr_policy_index: index of the sr policy (default: 0)
2386         """
2387         return self.api(
2388             self.papi.sr_policy_del,
2389             {'bsid_addr': bsid_addr,
2390              'sr_policy_index': sr_policy_index
2391              })
2392
2393     def sr_steering_add_del(
2394             self,
2395             is_del,
2396             bsid_addr,
2397             sr_policy_index,
2398             table_id,
2399             prefix_addr,
2400             mask_width,
2401             sw_if_index,
2402             traffic_type):
2403         """
2404         Steer traffic L2 and L3 traffic through a given SR policy
2405
2406         :param is_del: delete or add
2407         :param bsid_addr: bindingSID of the SR Policy (alt to sr_policy_index)
2408         :param sr_policy: is the index of the SR Policy (alt to bsid)
2409         :param table_id: is the VRF where to install the FIB entry for the BSID
2410         :param prefix_addr: is the IPv4/v6 address for L3 traffic type
2411         :param mask_width: is the mask for L3 traffic type
2412         :param sw_if_index: is the incoming interface for L2 traffic
2413         :param traffic_type: type of traffic (IPv4: 4, IPv6: 6, L2: 2)
2414         """
2415         return self.api(
2416             self.papi.sr_steering_add_del,
2417             {'is_del': is_del,
2418              'bsid_addr': bsid_addr,
2419              'sr_policy_index': sr_policy_index,
2420              'table_id': table_id,
2421              'prefix_addr': prefix_addr,
2422              'mask_width': mask_width,
2423              'sw_if_index': sw_if_index,
2424              'traffic_type': traffic_type
2425              })
2426
2427     def acl_add_replace(self, acl_index, r, tag='',
2428                         expected_retval=0):
2429         """Add/replace an ACL
2430         :param int acl_index: ACL index to replace, 2^32-1 to create new ACL.
2431         :param acl_rule r: ACL rules array.
2432         :param str tag: symbolic tag (description) for this ACL.
2433         :param int count: number of rules.
2434         """
2435         return self.api(self.papi.acl_add_replace,
2436                         {'acl_index': acl_index,
2437                          'r': r,
2438                          'count': len(r),
2439                          'tag': tag},
2440                         expected_retval=expected_retval)
2441
2442     def acl_del(self, acl_index, expected_retval=0):
2443         """
2444
2445         :param acl_index:
2446         :return:
2447         """
2448         return self.api(self.papi.acl_del,
2449                         {'acl_index': acl_index},
2450                         expected_retval=expected_retval)
2451
2452     def acl_interface_set_acl_list(self, sw_if_index, n_input, acls,
2453                                    expected_retval=0):
2454         return self.api(self.papi.acl_interface_set_acl_list,
2455                         {'sw_if_index': sw_if_index,
2456                          'count': len(acls),
2457                          'n_input': n_input,
2458                          'acls': acls},
2459                         expected_retval=expected_retval)
2460
2461     def acl_interface_set_etype_whitelist(self, sw_if_index,
2462                                           n_input, whitelist,
2463                                           expected_retval=0):
2464         return self.api(self.papi.acl_interface_set_etype_whitelist,
2465                         {'sw_if_index': sw_if_index,
2466                          'count': len(whitelist),
2467                          'n_input': n_input,
2468                          'whitelist': whitelist},
2469                         expected_retval=expected_retval)
2470
2471     def acl_interface_add_del(self,
2472                               sw_if_index,
2473                               acl_index,
2474                               is_add=1):
2475         """ Add/Delete ACL to/from interface
2476
2477         :param sw_if_index:
2478         :param acl_index:
2479         :param is_add:  (Default value = 1)
2480         """
2481
2482         return self.api(self.papi.acl_interface_add_del,
2483                         {'is_add': is_add,
2484                          'is_input': 1,
2485                          'sw_if_index': sw_if_index,
2486                          'acl_index': acl_index})
2487
2488     def acl_dump(self, acl_index, expected_retval=0):
2489         return self.api(self.papi.acl_dump,
2490                         {'acl_index': acl_index},
2491                         expected_retval=expected_retval)
2492
2493     def acl_interface_list_dump(self, sw_if_index=0xFFFFFFFF,
2494                                 expected_retval=0):
2495         return self.api(self.papi.acl_interface_list_dump,
2496                         {'sw_if_index': sw_if_index},
2497                         expected_retval=expected_retval)
2498
2499     def macip_acl_add(self, rules, tag=""):
2500         """ Add MACIP acl
2501
2502         :param rules: list of rules for given acl
2503         :param tag: acl tag
2504         """
2505
2506         return self.api(self.papi.macip_acl_add,
2507                         {'r': rules,
2508                          'count': len(rules),
2509                          'tag': tag})
2510
2511     def macip_acl_add_replace(self, rules, acl_index=0xFFFFFFFF, tag=""):
2512         """ Add MACIP acl
2513
2514         :param rules: list of rules for given acl
2515         :param tag: acl tag
2516         """
2517
2518         return self.api(self.papi.macip_acl_add_replace,
2519                         {'acl_index': acl_index,
2520                          'r': rules,
2521                          'count': len(rules),
2522                          'tag': tag})
2523
2524     def macip_acl_interface_add_del(self,
2525                                     sw_if_index,
2526                                     acl_index,
2527                                     is_add=1):
2528         """ Add MACIP acl to interface
2529
2530         :param sw_if_index:
2531         :param acl_index:
2532         :param is_add:  (Default value = 1)
2533         """
2534
2535         return self.api(self.papi.macip_acl_interface_add_del,
2536                         {'is_add': is_add,
2537                          'sw_if_index': sw_if_index,
2538                          'acl_index': acl_index})
2539
2540     def macip_acl_dump(self, acl_index=4294967295):
2541         """ Return MACIP acl dump
2542         """
2543
2544         return self.api(
2545             self.papi.macip_acl_dump, {'acl_index': acl_index})
2546
2547     def policer_add_del(self,
2548                         name,
2549                         cir,
2550                         eir,
2551                         cb,
2552                         eb,
2553                         is_add=1,
2554                         rate_type=0,
2555                         round_type=0,
2556                         ptype=0,
2557                         color_aware=0,
2558                         conform_action_type=1,
2559                         conform_dscp=0,
2560                         exceed_action_type=0,
2561                         exceed_dscp=0,
2562                         violate_action_type=0,
2563                         violate_dscp=0):
2564         return self.api(self.papi.policer_add_del,
2565                         {'name': name,
2566                          'cir': cir,
2567                          'eir': eir,
2568                          'cb': cb,
2569                          'eb': eb,
2570                          'is_add': is_add,
2571                          'rate_type': rate_type,
2572                          'round_type': round_type,
2573                          'type': ptype,
2574                          'color_aware': color_aware,
2575                          'conform_action_type': conform_action_type,
2576                          'conform_dscp': conform_dscp,
2577                          'exceed_action_type': exceed_action_type,
2578                          'exceed_dscp': exceed_dscp,
2579                          'violate_action_type': violate_action_type,
2580                          'violate_dscp': violate_dscp})
2581
2582     def ip_punt_police(self,
2583                        policer_index,
2584                        is_ip6=0,
2585                        is_add=1):
2586         return self.api(self.papi.ip_punt_police,
2587                         {'policer_index': policer_index,
2588                          'is_add': is_add,
2589                          'is_ip6': is_ip6})
2590
2591     def ip_punt_redirect(self,
2592                          rx_sw_if_index,
2593                          tx_sw_if_index,
2594                          address,
2595                          is_add=1):
2596         return self.api(self.papi.ip_punt_redirect,
2597                         {'punt': {'rx_sw_if_index': rx_sw_if_index,
2598                                   'tx_sw_if_index': tx_sw_if_index,
2599                                   'nh': address},
2600                          'is_add': is_add})
2601
2602     def ip_punt_redirect_dump(self, sw_if_index, is_ipv6=0):
2603         return self.api(self.papi.ip_punt_redirect_dump,
2604                         {'sw_if_index': sw_if_index,
2605                          'is_ipv6': is_ipv6})
2606
2607     def bier_table_add_del(self,
2608                            bti,
2609                            mpls_label,
2610                            is_add=1):
2611         """ BIER Table add/del """
2612         return self.api(
2613             self.papi.bier_table_add_del,
2614             {'bt_tbl_id': {"bt_set": bti.set_id,
2615                            "bt_sub_domain": bti.sub_domain_id,
2616                            "bt_hdr_len_id": bti.hdr_len_id},
2617              'bt_label': mpls_label,
2618              'bt_is_add': is_add})
2619
2620     def bier_table_dump(self):
2621         return self.api(self.papi.bier_table_dump, {})
2622
2623     def bier_route_add_del(self,
2624                            bti,
2625                            bp,
2626                            paths,
2627                            is_add=1,
2628                            is_replace=0):
2629         """ BIER Route add/del """
2630         return self.api(
2631             self.papi.bier_route_add_del,
2632             {'br_tbl_id': {"bt_set": bti.set_id,
2633                            "bt_sub_domain": bti.sub_domain_id,
2634                            "bt_hdr_len_id": bti.hdr_len_id},
2635              'br_bp': bp,
2636              'br_n_paths': len(paths),
2637              'br_paths': paths,
2638              'br_is_add': is_add,
2639              'br_is_replace': is_replace})
2640
2641     def bier_route_dump(self, bti):
2642         return self.api(
2643             self.papi.bier_route_dump,
2644             {'br_tbl_id': {"bt_set": bti.set_id,
2645                            "bt_sub_domain": bti.sub_domain_id,
2646                            "bt_hdr_len_id": bti.hdr_len_id}})
2647
2648     def bier_imp_add(self,
2649                      bti,
2650                      src,
2651                      ibytes,
2652                      is_add=1):
2653         """ BIER Imposition Add """
2654         return self.api(
2655             self.papi.bier_imp_add,
2656             {'bi_tbl_id': {"bt_set": bti.set_id,
2657                            "bt_sub_domain": bti.sub_domain_id,
2658                            "bt_hdr_len_id": bti.hdr_len_id},
2659              'bi_src': src,
2660              'bi_n_bytes': len(ibytes),
2661              'bi_bytes': ibytes})
2662
2663     def bier_imp_del(self, bi_index):
2664         """ BIER Imposition del """
2665         return self.api(
2666             self.papi.bier_imp_del,
2667             {'bi_index': bi_index})
2668
2669     def bier_imp_dump(self):
2670         return self.api(self.papi.bier_imp_dump, {})
2671
2672     def bier_disp_table_add_del(self,
2673                                 bdti,
2674                                 is_add=1):
2675         """ BIER Disposition Table add/del """
2676         return self.api(
2677             self.papi.bier_disp_table_add_del,
2678             {'bdt_tbl_id': bdti,
2679              'bdt_is_add': is_add})
2680
2681     def bier_disp_table_dump(self):
2682         return self.api(self.papi.bier_disp_table_dump, {})
2683
2684     def bier_disp_entry_add_del(self,
2685                                 bdti,
2686                                 bp,
2687                                 payload_proto,
2688                                 next_hop_afi,
2689                                 next_hop,
2690                                 next_hop_tbl_id=0,
2691                                 next_hop_rpf_id=~0,
2692                                 next_hop_is_ip4=1,
2693                                 is_add=1):
2694         """ BIER Route add/del """
2695         lstack = []
2696         while (len(lstack) < 16):
2697             lstack.append({})
2698         return self.api(
2699             self.papi.bier_disp_entry_add_del,
2700             {'bde_tbl_id': bdti,
2701              'bde_bp': bp,
2702              'bde_payload_proto': payload_proto,
2703              'bde_n_paths': 1,
2704              'bde_paths': [{'next_hop': next_hop,
2705                             'table_id': next_hop_tbl_id,
2706                             'afi': next_hop_afi,
2707                             'rpf_id': next_hop_rpf_id,
2708                             'n_labels': 0,
2709                             'label_stack': lstack}],
2710              'bde_is_add': is_add})
2711
2712     def bier_disp_entry_dump(self, bdti):
2713         return self.api(
2714             self.papi.bier_disp_entry_dump,
2715             {'bde_tbl_id': bdti})
2716
2717     def session_enable_disable(self, is_enabled):
2718         return self.api(
2719             self.papi.session_enable_disable,
2720             {'is_enable': is_enabled})
2721
2722     def ipsec_spd_add_del(self, spd_id, is_add=1):
2723         """ SPD add/del - Wrapper to add or del ipsec SPD
2724         Sample CLI : 'ipsec spd add 1'
2725
2726         :param spd_id - SPD ID to be created in the vpp . mandatory
2727         :param is_add - create (1) or delete(0) SPD (Default 1 - add) .
2728               optional
2729         :returns: reply from the API
2730         """
2731         return self.api(
2732             self.papi.ipsec_spd_add_del, {
2733                 'spd_id': spd_id, 'is_add': is_add})
2734
2735     def ipsec_spds_dump(self):
2736         return self.api(self.papi.ipsec_spds_dump, {})
2737
2738     def ipsec_interface_add_del_spd(self, spd_id, sw_if_index, is_add=1):
2739         """ IPSEC interface SPD add/del - \
2740              Wrapper to associate/disassociate SPD to interface in VPP
2741         Sample CLI : 'set interface ipsec spd GigabitEthernet0/6/0 1'
2742
2743         :param spd_id - SPD ID to associate with the interface . mandatory
2744         :param sw_if_index - Interface Index which needs to ipsec \
2745             association mandatory
2746         :param is_add - add(1) or del(0) association with interface \
2747                 (Default 1 - add) . optional
2748         :returns: reply from the API
2749         """
2750         return self.api(
2751             self.papi.ipsec_interface_add_del_spd,
2752             {'spd_id': spd_id, 'sw_if_index': sw_if_index, 'is_add': is_add})
2753
2754     def ipsec_spd_interface_dump(self, spd_index=None):
2755         return self.api(self.papi.ipsec_spd_interface_dump,
2756                         {'spd_index': spd_index if spd_index else 0,
2757                          'spd_index_valid': 1 if spd_index else 0})
2758
2759     def ipsec_sad_entry_add_del(self,
2760                                 sad_id,
2761                                 spi,
2762                                 integrity_algorithm,
2763                                 integrity_key,
2764                                 crypto_algorithm,
2765                                 crypto_key,
2766                                 protocol,
2767                                 tunnel_src_address='',
2768                                 tunnel_dst_address='',
2769                                 flags=0,
2770                                 is_add=1):
2771         """ IPSEC SA add/del
2772         :param sad_id: security association ID
2773         :param spi: security param index of the SA in decimal
2774         :param integrity_algorithm:
2775         :param integrity_key:
2776         :param crypto_algorithm:
2777         :param crypto_key:
2778         :param protocol: AH(0) or ESP(1) protocol
2779         :param tunnel_src_address: tunnel mode outer src address
2780         :param tunnel_dst_address: tunnel mode outer dst address
2781         :param is_add:
2782         :param is_tunnel:
2783         :** reference /vpp/src/vnet/ipsec/ipsec.h file for enum values of
2784              crypto and ipsec algorithms
2785         """
2786         return self.api(
2787             self.papi.ipsec_sad_entry_add_del,
2788             {
2789                 'is_add': is_add,
2790                 'entry':
2791                     {
2792                         'sad_id': sad_id,
2793                         'spi': spi,
2794                         'tunnel_src': tunnel_src_address,
2795                         'tunnel_dst': tunnel_dst_address,
2796                         'protocol': protocol,
2797                         'integrity_algorithm': integrity_algorithm,
2798                         'integrity_key': {
2799                             'length': len(integrity_key),
2800                             'data': integrity_key,
2801                         },
2802                         'crypto_algorithm': crypto_algorithm,
2803                         'crypto_key': {
2804                             'length': len(crypto_key),
2805                             'data': crypto_key,
2806                         },
2807                         'flags': flags,
2808                     }
2809             })
2810
2811     def ipsec_sa_dump(self, sa_id=None):
2812         return self.api(self.papi.ipsec_sa_dump,
2813                         {'sa_id': sa_id if sa_id else 0xffffffff})
2814
2815     def ipsec_spd_entry_add_del(self,
2816                                 spd_id,
2817                                 sa_id,
2818                                 local_address_start,
2819                                 local_address_stop,
2820                                 remote_address_start,
2821                                 remote_address_stop,
2822                                 local_port_start=0,
2823                                 local_port_stop=65535,
2824                                 remote_port_start=0,
2825                                 remote_port_stop=65535,
2826                                 protocol=0,
2827                                 policy=0,
2828                                 priority=100,
2829                                 is_outbound=1,
2830                                 is_add=1,
2831                                 is_ipv6=0,
2832                                 is_ip_any=0):
2833         """ IPSEC policy SPD add/del   -
2834                     Wrapper to configure ipsec SPD policy entries in VPP
2835         :param spd_id: SPD ID for the policy
2836         :param local_address_start: local-ip-range start address
2837         :param local_address_stop : local-ip-range stop address
2838         :param remote_address_start: remote-ip-range start address
2839         :param remote_address_stop : remote-ip-range stop address
2840         :param local_port_start: (Default value = 0)
2841         :param local_port_stop: (Default value = 65535)
2842         :param remote_port_start: (Default value = 0)
2843         :param remote_port_stop: (Default value = 65535)
2844         :param protocol: Any(0), AH(51) & ESP(50) protocol (Default value = 0)
2845         :param sa_id: Security Association ID for mapping it to SPD
2846         :param policy: bypass(0), discard(1), resolve(2) or protect(3) action
2847                (Default value = 0)
2848         :param priority: value for the spd action (Default value = 100)
2849         :param is_outbound: flag for inbound(0) or outbound(1)
2850                (Default value = 1)
2851         :param is_add: (Default value = 1)
2852         """
2853         return self.api(
2854             self.papi.ipsec_spd_entry_add_del,
2855             {
2856                 'is_add': is_add,
2857                 'entry':
2858                     {
2859                         'spd_id': spd_id,
2860                         'sa_id': sa_id,
2861                         'local_address_start': local_address_start,
2862                         'local_address_stop': local_address_stop,
2863                         'remote_address_start': remote_address_start,
2864                         'remote_address_stop': remote_address_stop,
2865                         'local_port_start': local_port_start,
2866                         'local_port_stop': local_port_stop,
2867                         'remote_port_start': remote_port_start,
2868                         'remote_port_stop': remote_port_stop,
2869                         'protocol': protocol,
2870                         'policy': policy,
2871                         'priority': priority,
2872                         'is_outbound': is_outbound,
2873                         'is_ip_any': is_ip_any
2874                     }
2875             })
2876
2877     def ipsec_spd_dump(self, spd_id, sa_id=0xffffffff):
2878         return self.api(self.papi.ipsec_spd_dump,
2879                         {'spd_id': spd_id,
2880                          'sa_id': sa_id})
2881
2882     def ipsec_tunnel_if_add_del(self, local_ip, remote_ip, local_spi,
2883                                 remote_spi, crypto_alg, local_crypto_key,
2884                                 remote_crypto_key, integ_alg, local_integ_key,
2885                                 remote_integ_key, is_add=1, esn=0,
2886                                 anti_replay=1, renumber=0, show_instance=0):
2887         return self.api(
2888             self.papi.ipsec_tunnel_if_add_del,
2889             {'local_ip': local_ip, 'remote_ip': remote_ip,
2890              'local_spi': local_spi, 'remote_spi': remote_spi,
2891              'crypto_alg': crypto_alg,
2892              'local_crypto_key_len': len(local_crypto_key),
2893              'local_crypto_key': local_crypto_key,
2894              'remote_crypto_key_len': len(remote_crypto_key),
2895              'remote_crypto_key': remote_crypto_key, 'integ_alg': integ_alg,
2896              'local_integ_key_len': len(local_integ_key),
2897              'local_integ_key': local_integ_key,
2898              'remote_integ_key_len': len(remote_integ_key),
2899              'remote_integ_key': remote_integ_key, 'is_add': is_add,
2900              'esn': esn, 'anti_replay': anti_replay, 'renumber': renumber,
2901              'show_instance': show_instance
2902              })
2903
2904     def ipsec_select_backend(self, protocol, index):
2905         return self.api(self.papi.ipsec_select_backend,
2906                         {'protocol': protocol, 'index': index})
2907
2908     def ipsec_backend_dump(self):
2909         return self.api(self.papi.ipsec_backend_dump, {})
2910
2911     def app_namespace_add_del(self,
2912                               namespace_id,
2913                               ip4_fib_id=0,
2914                               ip6_fib_id=0,
2915                               sw_if_index=0xFFFFFFFF,
2916                               secret=0):
2917         return self.api(
2918             self.papi.app_namespace_add_del,
2919             {'secret': secret,
2920              'sw_if_index': sw_if_index,
2921              'ip4_fib_id': ip4_fib_id,
2922              'ip6_fib_id': ip6_fib_id,
2923              'namespace_id': namespace_id,
2924              'namespace_id_len': len(namespace_id)})
2925
2926     def punt_socket_register(self, port, pathname, protocol=0x11,
2927                              header_version=1, is_ip4=1):
2928         """ Register punt socket """
2929         return self.api(self.papi.punt_socket_register,
2930                         {'header_version': header_version,
2931                          'punt': {'ipv': is_ip4,
2932                                   'l4_protocol': protocol,
2933                                   'l4_port': port},
2934                          'pathname': pathname})
2935
2936     def punt_socket_deregister(self, port, protocol=0x11, is_ip4=1):
2937         """ Unregister punt socket """
2938         return self.api(self.papi.punt_socket_deregister,
2939                         {'punt': {'ipv': is_ip4,
2940                                   'l4_protocol': protocol,
2941                                   'l4_port': port}})
2942
2943     def punt_socket_dump(self, is_ip6=1):
2944         """ Dump punt socket"""
2945         return self.api(self.papi.punt_socket_dump,
2946                         {'is_ipv6': is_ip6})
2947
2948     def gbp_endpoint_add(self, sw_if_index, ips, mac, sclass, flags,
2949                          tun_src, tun_dst):
2950         """ GBP endpoint Add """
2951         return self.api(self.papi.gbp_endpoint_add,
2952                         {'endpoint': {
2953                             'sw_if_index': sw_if_index,
2954                             'ips': ips,
2955                             'n_ips': len(ips),
2956                             'mac': mac,
2957                             'sclass': sclass,
2958                             'flags': flags,
2959                             'tun': {
2960                                 'src': tun_src,
2961                                 'dst': tun_dst,
2962                             }}})
2963
2964     def gbp_endpoint_del(self, handle):
2965         """ GBP endpoint Del """
2966         return self.api(self.papi.gbp_endpoint_del,
2967                         {'handle': handle})
2968
2969     def gbp_endpoint_dump(self):
2970         """ GBP endpoint Dump """
2971         return self.api(self.papi.gbp_endpoint_dump,
2972                         {'_no_type_conversion': True})
2973
2974     def gbp_endpoint_group_add(self, vnid, sclass, bd,
2975                                rd, uplink_sw_if_index,
2976                                retention):
2977         """ GBP endpoint group Add """
2978         return self.api(self.papi.gbp_endpoint_group_add,
2979                         {'epg':
2980                             {
2981                                 'uplink_sw_if_index': uplink_sw_if_index,
2982                                 'bd_id': bd,
2983                                 'rd_id': rd,
2984                                 'vnid': vnid,
2985                                 'sclass': sclass,
2986                                 'retention': retention
2987                             }})
2988
2989     def gbp_endpoint_group_del(self, sclass):
2990         """ GBP endpoint group Del """
2991         return self.api(self.papi.gbp_endpoint_group_del,
2992                         {'sclass': sclass})
2993
2994     def gbp_bridge_domain_add(self, bd_id, flags,
2995                               bvi_sw_if_index,
2996                               uu_fwd_sw_if_index,
2997                               bm_flood_sw_if_index):
2998         """ GBP bridge-domain Add """
2999         return self.api(self.papi.gbp_bridge_domain_add,
3000                         {'bd':
3001                             {
3002                                 'flags': flags,
3003                                 'bvi_sw_if_index': bvi_sw_if_index,
3004                                 'uu_fwd_sw_if_index': uu_fwd_sw_if_index,
3005                                 'bm_flood_sw_if_index': bm_flood_sw_if_index,
3006                                 'bd_id': bd_id
3007                             }})
3008
3009     def gbp_bridge_domain_del(self, bd_id):
3010         """ GBP bridge-domain Del """
3011         return self.api(self.papi.gbp_bridge_domain_del,
3012                         {'bd_id': bd_id})
3013
3014     def gbp_route_domain_add(self, rd_id,
3015                              ip4_table_id,
3016                              ip6_table_id,
3017                              ip4_uu_sw_if_index,
3018                              ip6_uu_sw_if_index):
3019         """ GBP route-domain Add """
3020         return self.api(self.papi.gbp_route_domain_add,
3021                         {'rd':
3022                             {
3023                                 'ip4_table_id': ip4_table_id,
3024                                 'ip6_table_id': ip6_table_id,
3025                                 'ip4_uu_sw_if_index': ip4_uu_sw_if_index,
3026                                 'ip6_uu_sw_if_index': ip6_uu_sw_if_index,
3027                                 'rd_id': rd_id
3028                             }})
3029
3030     def gbp_route_domain_del(self, rd_id):
3031         """ GBP route-domain Del """
3032         return self.api(self.papi.gbp_route_domain_del,
3033                         {'rd_id': rd_id})
3034
3035     def gbp_recirc_add_del(self, is_add, sw_if_index, sclass, is_ext):
3036         """ GBP recirc Add/Del """
3037         return self.api(self.papi.gbp_recirc_add_del,
3038                         {'is_add': is_add,
3039                          'recirc': {
3040                              'is_ext': is_ext,
3041                              'sw_if_index': sw_if_index,
3042                              'sclass': sclass}})
3043
3044     def gbp_recirc_dump(self):
3045         """ GBP recirc Dump """
3046         return self.api(self.papi.gbp_recirc_dump, {})
3047
3048     def gbp_ext_itf_add_del(self, is_add, sw_if_index, bd_id, rd_id):
3049         """ GBP recirc Add/Del """
3050         return self.api(self.papi.gbp_ext_itf_add_del,
3051                         {'is_add': is_add,
3052                          'ext_itf': {
3053                              'sw_if_index': sw_if_index,
3054                              'bd_id': bd_id,
3055                              'rd_id': rd_id}})
3056
3057     def gbp_ext_itf_dump(self):
3058         """ GBP recirc Dump """
3059         return self.api(self.papi.gbp_ext_itf_dump, {})
3060
3061     def gbp_subnet_add_del(self, is_add, rd_id,
3062                            prefix, type,
3063                            sw_if_index=0xffffffff,
3064                            sclass=0xffff):
3065         """ GBP Subnet Add/Del """
3066         return self.api(self.papi.gbp_subnet_add_del,
3067                         {'is_add': is_add,
3068                          'subnet': {
3069                              'type': type,
3070                              'sw_if_index': sw_if_index,
3071                              'sclass': sclass,
3072                              'prefix': prefix,
3073                              'rd_id': rd_id}})
3074
3075     def gbp_subnet_dump(self):
3076         """ GBP Subnet Dump """
3077         return self.api(self.papi.gbp_subnet_dump,
3078                         {'_no_type_conversion': True})
3079
3080     def gbp_contract_add_del(self, is_add, sclass, dclass, acl_index,
3081                              rules, allowed_ethertypes):
3082         """ GBP contract Add/Del """
3083         return self.api(self.papi.gbp_contract_add_del,
3084                         {'is_add': is_add,
3085                          'contract': {
3086                              'acl_index': acl_index,
3087                              'sclass': sclass,
3088                              'dclass': dclass,
3089                              'n_rules': len(rules),
3090                              'rules': rules,
3091                              'n_ether_types': len(allowed_ethertypes),
3092                              'allowed_ethertypes': allowed_ethertypes}})
3093
3094     def gbp_contract_dump(self):
3095         """ GBP contract Dump """
3096         return self.api(self.papi.gbp_contract_dump, {})
3097
3098     def gbp_vxlan_tunnel_add(self, vni, bd_rd_id, mode, src):
3099         """ GBP VXLAN tunnel add """
3100         return self.api(self.papi.gbp_vxlan_tunnel_add,
3101                         {
3102                             'tunnel': {
3103                                 'vni': vni,
3104                                 'mode': mode,
3105                                 'bd_rd_id': bd_rd_id,
3106                                 'src': src
3107                             }
3108                         })
3109
3110     def gbp_vxlan_tunnel_del(self, vni):
3111         """ GBP VXLAN tunnel del """
3112         return self.api(self.papi.gbp_vxlan_tunnel_del,
3113                         {
3114                             'vni': vni,
3115                         })
3116
3117     def gbp_vxlan_tunnel_dump(self):
3118         """ GBP VXLAN tunnel add/del """
3119         return self.api(self.papi.gbp_vxlan_tunnel_dump, {})
3120
3121     def qos_egress_map_update(self, id, outputs):
3122         """ QOS egress map update """
3123         return self.api(self.papi.qos_egress_map_update,
3124                         {'map_id': id,
3125                          'rows': outputs})
3126
3127     def qos_egress_map_delete(self, id):
3128         """ QOS egress map delete """
3129         return self.api(self.papi.qos_egress_map_delete,
3130                         {'map_id': id})
3131
3132     def qos_mark_enable_disable(self, sw_if_index,
3133                                 output_source,
3134                                 map_id,
3135                                 enable):
3136         """ QOS Mark Enable/Disable """
3137         return self.api(self.papi.qos_mark_enable_disable,
3138                         {'map_id': map_id,
3139                          'sw_if_index': sw_if_index,
3140                          'output_source': output_source,
3141                          'enable': enable})
3142
3143     def igmp_enable_disable(self, sw_if_index, enable, host):
3144         """ Enable/disable IGMP on a given interface """
3145         return self.api(self.papi.igmp_enable_disable,
3146                         {'enable': enable,
3147                          'mode': host,
3148                          'sw_if_index': sw_if_index})
3149
3150     def igmp_proxy_device_add_del(self, vrf_id, sw_if_index, add):
3151         """ Add/del IGMP proxy device """
3152         return self.api(self.papi.igmp_proxy_device_add_del,
3153                         {'vrf_id': vrf_id, 'sw_if_index': sw_if_index,
3154                          'add': add})
3155
3156     def igmp_proxy_device_add_del_interface(self, vrf_id, sw_if_index, add):
3157         """ Add/del interface to/from IGMP proxy device """
3158         return self.api(self.papi.igmp_proxy_device_add_del_interface,
3159                         {'vrf_id': vrf_id, 'sw_if_index': sw_if_index,
3160                          'add': add})
3161
3162     def igmp_listen(self, filter, sw_if_index, saddrs, gaddr):
3163         """ Listen for new (S,G) on specified interface
3164
3165         :param enable: add/del
3166         :param sw_if_index: interface sw index
3167         :param saddr: source ip4 addr
3168         :param gaddr: group ip4 addr
3169         """
3170         return self.api(self.papi.igmp_listen,
3171                         {
3172                             'group':
3173                                 {
3174                                     'filter': filter,
3175                                     'sw_if_index': sw_if_index,
3176                                     'n_srcs': len(saddrs),
3177                                     'saddrs': saddrs,
3178                                     'gaddr': gaddr
3179                                 }
3180                         })
3181
3182     def igmp_clear_interface(self, sw_if_index):
3183         """ Remove all (S,G)s from specified interface
3184             doesn't send IGMP report!
3185         """
3186         return self.api(
3187             self.papi.igmp_clear_interface, {
3188                 'sw_if_index': sw_if_index})
3189
3190     def want_igmp_events(self, enable=1):
3191         return self.api(self.papi.want_igmp_events, {'enable': enable,
3192                                                      'pid': os.getpid()})
3193
3194     def bond_create(
3195             self,
3196             mode,
3197             lb,
3198             use_custom_mac,
3199             mac_address='',
3200             interface_id=0xFFFFFFFF):
3201         """
3202         :param mode: mode
3203         :param lb: load balance
3204         :param use_custom_mac: use custom mac
3205         :param mac_address: mac address
3206         :param interface_id: custom interface ID
3207         """
3208         return self.api(
3209             self.papi.bond_create,
3210             {'mode': mode,
3211              'lb': lb,
3212              'use_custom_mac': use_custom_mac,
3213              'mac_address': mac_address,
3214              'id': interface_id
3215              })
3216
3217     def pipe_delete(self, parent_sw_if_index):
3218         return self.api(self.papi.pipe_delete,
3219                         {'parent_sw_if_index': parent_sw_if_index})
3220
3221     def memif_create(
3222             self,
3223             role,
3224             mode,
3225             rx_queues=None,
3226             tx_queues=None,
3227             _id=None,
3228             socket_id=None,
3229             secret=None,
3230             ring_size=None,
3231             buffer_size=None,
3232             hw_addr=None):
3233         return self.api(self.papi.memif_create,
3234                         {'role': role,
3235                          'mode': mode,
3236                          'rx_queues': rx_queues,
3237                          'tx_queues': tx_queues,
3238                          'id': _id,
3239                          'socket_id': socket_id,
3240                          'secret': secret,
3241                          'ring_size': ring_size,
3242                          'buffer_size': buffer_size,
3243                          'hw_addr': hw_addr})
3244
3245     def svs_table_add_del(self, af, table_id, is_add=1):
3246         return self.api(self.papi.svs_table_add_del,
3247                         {
3248                             'table_id': table_id,
3249                             'is_add': is_add,
3250                             'af': af,
3251                         })
3252
3253     def svs_route_add_del(self, table_id, prefix, src_table_id, is_add=1):
3254         return self.api(self.papi.svs_route_add_del,
3255                         {
3256                             'table_id': table_id,
3257                             'source_table_id': src_table_id,
3258                             'prefix': prefix,
3259                             'is_add': is_add,
3260                         })
3261
3262     def svs_enable_disable(self, af, table_id, sw_if_index, is_enable=1):
3263         return self.api(self.papi.svs_enable_disable,
3264                         {
3265                             'af': af,
3266                             'table_id': table_id,
3267                             'sw_if_index': sw_if_index,
3268                             'is_enable': is_enable,
3269                         })