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