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