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