tests: update test_lb.py to use api call lb_conf.
[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: (Defalt 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 extenal 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 extenal 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 servic
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 addres and port pari, 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 sesstion 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: failvoer 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             instance=0xFFFFFFFF):
1841         """
1842
1843         :param dst_addr:
1844         :param src_addr:
1845         :param is_add:  (Default value = 1)
1846         :param is_ipv6:  (Default value = 0)
1847         :param encap_table_id:  (Default value = 0)
1848         :param decap_next_index:  (Default value = 0xFFFFFFFF)
1849         :param mcast_sw_if_index:  (Default value = 0xFFFFFFFF)
1850         :param vni:  (Default value = 0)
1851         :param instance:  (Default value = 0xFFFFFFFF)
1852
1853         """
1854         return self.api(self.papi.vxlan_gbp_tunnel_add_del,
1855                         {'is_add': is_add,
1856                          'tunnel': {
1857                              'src': src,
1858                              'dst': dst,
1859                              'mcast_sw_if_index': mcast_sw_if_index,
1860                              'encap_table_id': encap_table_id,
1861                              'vni': vni,
1862                              'instance': instance}})
1863
1864     def vxlan_gbp_tunnel_dump(self, sw_if_index=0xffffffff):
1865         return self.api(self.papi.vxlan_gbp_tunnel_dump,
1866                         {'sw_if_index': sw_if_index,
1867                          '_no_type_conversion': True})
1868
1869     def pppoe_add_del_session(
1870             self,
1871             client_ip,
1872             client_mac,
1873             session_id=0,
1874             is_add=1,
1875             is_ipv6=0,
1876             decap_vrf_id=0):
1877         """
1878
1879         :param is_add:  (Default value = 1)
1880         :param is_ipv6:  (Default value = 0)
1881         :param client_ip:
1882         :param session_id:  (Default value = 0)
1883         :param client_mac:
1884         :param decap_vrf_id:  (Default value = 0)
1885
1886         """
1887         return self.api(self.papi.pppoe_add_del_session,
1888                         {'is_add': is_add,
1889                          'is_ipv6': is_ipv6,
1890                          'session_id': session_id,
1891                          'client_ip': client_ip,
1892                          'decap_vrf_id': decap_vrf_id,
1893                          'client_mac': client_mac})
1894
1895     def sr_mpls_policy_add(self, bsid, weight, type, segments):
1896         return self.api(self.papi.sr_mpls_policy_add,
1897                         {'bsid': bsid,
1898                          'weight': weight,
1899                          'type': type,
1900                          'n_segments': len(segments),
1901                          'segments': segments})
1902
1903     def sr_mpls_policy_del(self, bsid):
1904         return self.api(self.papi.sr_mpls_policy_del,
1905                         {'bsid': bsid})
1906
1907     def sr_localsid_add_del(self,
1908                             localsid,
1909                             behavior,
1910                             nh_addr4,
1911                             nh_addr6,
1912                             is_del=0,
1913                             end_psp=0,
1914                             sw_if_index=0xFFFFFFFF,
1915                             vlan_index=0,
1916                             fib_table=0,
1917                             ):
1918         """ Add/del IPv6 SR local-SID.
1919
1920         :param localsid:
1921         :param behavior: END=1; END.X=2; END.DX2=4; END.DX6=5;
1922         :param behavior: END.DX4=6; END.DT6=7; END.DT4=8
1923         :param nh_addr4:
1924         :param nh_addr6:
1925         :param is_del:  (Default value = 0)
1926         :param end_psp: (Default value = 0)
1927         :param sw_if_index: (Default value = 0xFFFFFFFF)
1928         :param vlan_index:  (Default value = 0)
1929         :param fib_table:   (Default value = 0)
1930         """
1931         return self.api(
1932             self.papi.sr_localsid_add_del,
1933             {'is_del': is_del,
1934              'localsid': localsid,
1935              'end_psp': end_psp,
1936              'behavior': behavior,
1937              'sw_if_index': sw_if_index,
1938              'vlan_index': vlan_index,
1939              'fib_table': fib_table,
1940              'nh_addr4': nh_addr4,
1941              'nh_addr6': nh_addr6
1942              }
1943         )
1944
1945     def sr_policy_add(
1946             self,
1947             bsid_addr,
1948             weight=1,
1949             is_encap=1,
1950             type=0,
1951             fib_table=0,
1952             n_segments=0,
1953             segments=[]):
1954         """
1955         :param bsid_addr: bindingSID of the SR Policy
1956         :param weight: weight of the sid list. optional. (default: 1)
1957         :param is_encap: (bool) whether SR policy should Encap or SRH insert \
1958             (default: Encap)
1959         :param type: type/behavior of the SR policy. (default or spray) \
1960             (default: default)
1961         :param fib_table: VRF where to install the FIB entry for the BSID \
1962             (default: 0)
1963         :param n_segments: number of segments \
1964             (default: 0)
1965         :param segments: a vector of IPv6 address composing the segment list \
1966             (default: [])
1967         """
1968         return self.api(
1969             self.papi.sr_policy_add,
1970             {'bsid_addr': bsid_addr,
1971              'weight': weight,
1972              'is_encap': is_encap,
1973              'type': type,
1974              'fib_table': fib_table,
1975              'n_segments': n_segments,
1976              'segments': segments
1977              }
1978         )
1979
1980     def sr_policy_del(
1981             self,
1982             bsid_addr,
1983             sr_policy_index=0):
1984         """
1985         :param bsid: bindingSID of the SR Policy
1986         :param sr_policy_index: index of the sr policy (default: 0)
1987         """
1988         return self.api(
1989             self.papi.sr_policy_del,
1990             {'bsid_addr': bsid_addr,
1991              'sr_policy_index': sr_policy_index
1992              })
1993
1994     def sr_steering_add_del(
1995             self,
1996             is_del,
1997             bsid_addr,
1998             sr_policy_index,
1999             table_id,
2000             prefix_addr,
2001             mask_width,
2002             sw_if_index,
2003             traffic_type):
2004         """
2005         Steer traffic L2 and L3 traffic through a given SR policy
2006
2007         :param is_del: delete or add
2008         :param bsid_addr: bindingSID of the SR Policy (alt to sr_policy_index)
2009         :param sr_policy: is the index of the SR Policy (alt to bsid)
2010         :param table_id: is the VRF where to install the FIB entry for the BSID
2011         :param prefix_addr: is the IPv4/v6 address for L3 traffic type
2012         :param mask_width: is the mask for L3 traffic type
2013         :param sw_if_index: is the incoming interface for L2 traffic
2014         :param traffic_type: type of traffic (IPv4: 4, IPv6: 6, L2: 2)
2015         """
2016         return self.api(
2017             self.papi.sr_steering_add_del,
2018             {'is_del': is_del,
2019              'bsid_addr': bsid_addr,
2020              'sr_policy_index': sr_policy_index,
2021              'table_id': table_id,
2022              'prefix_addr': prefix_addr,
2023              'mask_width': mask_width,
2024              'sw_if_index': sw_if_index,
2025              'traffic_type': traffic_type
2026              })
2027
2028     def acl_add_replace(self, acl_index, r, tag='',
2029                         expected_retval=0):
2030         """Add/replace an ACL
2031         :param int acl_index: ACL index to replace, 2^32-1 to create new ACL.
2032         :param acl_rule r: ACL rules array.
2033         :param str tag: symbolic tag (description) for this ACL.
2034         :param int count: number of rules.
2035         """
2036         return self.api(self.papi.acl_add_replace,
2037                         {'acl_index': acl_index,
2038                          'r': r,
2039                          'count': len(r),
2040                          'tag': tag},
2041                         expected_retval=expected_retval)
2042
2043     def acl_del(self, acl_index, expected_retval=0):
2044         """
2045
2046         :param acl_index:
2047         :return:
2048         """
2049         return self.api(self.papi.acl_del,
2050                         {'acl_index': acl_index},
2051                         expected_retval=expected_retval)
2052
2053     def acl_interface_set_acl_list(self, sw_if_index, n_input, acls,
2054                                    expected_retval=0):
2055         return self.api(self.papi.acl_interface_set_acl_list,
2056                         {'sw_if_index': sw_if_index,
2057                          'count': len(acls),
2058                          'n_input': n_input,
2059                          'acls': acls},
2060                         expected_retval=expected_retval)
2061
2062     def acl_interface_set_etype_whitelist(self, sw_if_index,
2063                                           n_input, whitelist,
2064                                           expected_retval=0):
2065         return self.api(self.papi.acl_interface_set_etype_whitelist,
2066                         {'sw_if_index': sw_if_index,
2067                          'count': len(whitelist),
2068                          'n_input': n_input,
2069                          'whitelist': whitelist},
2070                         expected_retval=expected_retval)
2071
2072     def acl_interface_add_del(self,
2073                               sw_if_index,
2074                               acl_index,
2075                               is_add=1):
2076         """ Add/Delete ACL to/from interface
2077
2078         :param sw_if_index:
2079         :param acl_index:
2080         :param is_add:  (Default value = 1)
2081         """
2082
2083         return self.api(self.papi.acl_interface_add_del,
2084                         {'is_add': is_add,
2085                          'is_input': 1,
2086                          'sw_if_index': sw_if_index,
2087                          'acl_index': acl_index})
2088
2089     def acl_dump(self, acl_index, expected_retval=0):
2090         return self.api(self.papi.acl_dump,
2091                         {'acl_index': acl_index},
2092                         expected_retval=expected_retval)
2093
2094     def acl_interface_list_dump(self, sw_if_index=0xFFFFFFFF,
2095                                 expected_retval=0):
2096         return self.api(self.papi.acl_interface_list_dump,
2097                         {'sw_if_index': sw_if_index},
2098                         expected_retval=expected_retval)
2099
2100     def macip_acl_add(self, rules, tag=""):
2101         """ Add MACIP acl
2102
2103         :param rules: list of rules for given acl
2104         :param tag: acl tag
2105         """
2106
2107         return self.api(self.papi.macip_acl_add,
2108                         {'r': rules,
2109                          'count': len(rules),
2110                          'tag': tag})
2111
2112     def macip_acl_add_replace(self, rules, acl_index=0xFFFFFFFF, tag=""):
2113         """ Add MACIP acl
2114
2115         :param rules: list of rules for given acl
2116         :param tag: acl tag
2117         """
2118
2119         return self.api(self.papi.macip_acl_add_replace,
2120                         {'acl_index': acl_index,
2121                          'r': rules,
2122                          'count': len(rules),
2123                          'tag': tag})
2124
2125     def macip_acl_interface_add_del(self,
2126                                     sw_if_index,
2127                                     acl_index,
2128                                     is_add=1):
2129         """ Add MACIP acl to interface
2130
2131         :param sw_if_index:
2132         :param acl_index:
2133         :param is_add:  (Default value = 1)
2134         """
2135
2136         return self.api(self.papi.macip_acl_interface_add_del,
2137                         {'is_add': is_add,
2138                          'sw_if_index': sw_if_index,
2139                          'acl_index': acl_index})
2140
2141     def macip_acl_dump(self, acl_index=4294967295):
2142         """ Return MACIP acl dump
2143         """
2144
2145         return self.api(
2146             self.papi.macip_acl_dump, {'acl_index': acl_index})
2147
2148     def policer_add_del(self,
2149                         name,
2150                         cir,
2151                         eir,
2152                         cb,
2153                         eb,
2154                         is_add=1,
2155                         rate_type=0,
2156                         round_type=0,
2157                         ptype=0,
2158                         color_aware=0,
2159                         conform_action_type=1,
2160                         conform_dscp=0,
2161                         exceed_action_type=0,
2162                         exceed_dscp=0,
2163                         violate_action_type=0,
2164                         violate_dscp=0):
2165         return self.api(self.papi.policer_add_del,
2166                         {'name': name,
2167                          'cir': cir,
2168                          'eir': eir,
2169                          'cb': cb,
2170                          'eb': eb,
2171                          'is_add': is_add,
2172                          'rate_type': rate_type,
2173                          'round_type': round_type,
2174                          'type': ptype,
2175                          'color_aware': color_aware,
2176                          'conform_action_type': conform_action_type,
2177                          'conform_dscp': conform_dscp,
2178                          'exceed_action_type': exceed_action_type,
2179                          'exceed_dscp': exceed_dscp,
2180                          'violate_action_type': violate_action_type,
2181                          'violate_dscp': violate_dscp})
2182
2183     def ip_punt_police(self,
2184                        policer_index,
2185                        is_ip6=0,
2186                        is_add=1):
2187         return self.api(self.papi.ip_punt_police,
2188                         {'policer_index': policer_index,
2189                          'is_add': is_add,
2190                          'is_ip6': is_ip6})
2191
2192     def ip_punt_redirect(self,
2193                          rx_sw_if_index,
2194                          tx_sw_if_index,
2195                          address,
2196                          is_add=1):
2197         return self.api(self.papi.ip_punt_redirect,
2198                         {'punt': {'rx_sw_if_index': rx_sw_if_index,
2199                                   'tx_sw_if_index': tx_sw_if_index,
2200                                   'nh': address},
2201                          'is_add': is_add})
2202
2203     def ip_punt_redirect_dump(self, sw_if_index, is_ipv6=0):
2204         return self.api(self.papi.ip_punt_redirect_dump,
2205                         {'sw_if_index': sw_if_index,
2206                          'is_ipv6': is_ipv6})
2207
2208     def bier_table_add_del(self,
2209                            bti,
2210                            mpls_label,
2211                            is_add=1):
2212         """ BIER Table add/del """
2213         return self.api(
2214             self.papi.bier_table_add_del,
2215             {'bt_tbl_id': {"bt_set": bti.set_id,
2216                            "bt_sub_domain": bti.sub_domain_id,
2217                            "bt_hdr_len_id": bti.hdr_len_id},
2218              'bt_label': mpls_label,
2219              'bt_is_add': is_add})
2220
2221     def bier_table_dump(self):
2222         return self.api(self.papi.bier_table_dump, {})
2223
2224     def bier_route_add_del(self,
2225                            bti,
2226                            bp,
2227                            paths,
2228                            is_add=1,
2229                            is_replace=0):
2230         """ BIER Route add/del """
2231         return self.api(
2232             self.papi.bier_route_add_del,
2233             {'br_tbl_id': {"bt_set": bti.set_id,
2234                            "bt_sub_domain": bti.sub_domain_id,
2235                            "bt_hdr_len_id": bti.hdr_len_id},
2236              'br_bp': bp,
2237              'br_n_paths': len(paths),
2238              'br_paths': paths,
2239              'br_is_add': is_add,
2240              'br_is_replace': is_replace})
2241
2242     def bier_route_dump(self, bti):
2243         return self.api(
2244             self.papi.bier_route_dump,
2245             {'br_tbl_id': {"bt_set": bti.set_id,
2246                            "bt_sub_domain": bti.sub_domain_id,
2247                            "bt_hdr_len_id": bti.hdr_len_id}})
2248
2249     def bier_imp_add(self,
2250                      bti,
2251                      src,
2252                      ibytes,
2253                      is_add=1):
2254         """ BIER Imposition Add """
2255         return self.api(
2256             self.papi.bier_imp_add,
2257             {'bi_tbl_id': {"bt_set": bti.set_id,
2258                            "bt_sub_domain": bti.sub_domain_id,
2259                            "bt_hdr_len_id": bti.hdr_len_id},
2260              'bi_src': src,
2261              'bi_n_bytes': len(ibytes),
2262              'bi_bytes': ibytes})
2263
2264     def bier_imp_del(self, bi_index):
2265         """ BIER Imposition del """
2266         return self.api(
2267             self.papi.bier_imp_del,
2268             {'bi_index': bi_index})
2269
2270     def bier_imp_dump(self):
2271         return self.api(self.papi.bier_imp_dump, {})
2272
2273     def bier_disp_table_add_del(self,
2274                                 bdti,
2275                                 is_add=1):
2276         """ BIER Disposition Table add/del """
2277         return self.api(
2278             self.papi.bier_disp_table_add_del,
2279             {'bdt_tbl_id': bdti,
2280              'bdt_is_add': is_add})
2281
2282     def bier_disp_table_dump(self):
2283         return self.api(self.papi.bier_disp_table_dump, {})
2284
2285     def bier_disp_entry_add_del(self,
2286                                 bdti,
2287                                 bp,
2288                                 payload_proto,
2289                                 next_hop_afi,
2290                                 next_hop,
2291                                 next_hop_tbl_id=0,
2292                                 next_hop_rpf_id=~0,
2293                                 next_hop_is_ip4=1,
2294                                 is_add=1):
2295         """ BIER Route add/del """
2296         lstack = []
2297         while (len(lstack) < 16):
2298             lstack.append({})
2299         return self.api(
2300             self.papi.bier_disp_entry_add_del,
2301             {'bde_tbl_id': bdti,
2302              'bde_bp': bp,
2303              'bde_payload_proto': payload_proto,
2304              'bde_n_paths': 1,
2305              'bde_paths': [{'next_hop': next_hop,
2306                             'table_id': next_hop_tbl_id,
2307                             'afi': next_hop_afi,
2308                             'rpf_id': next_hop_rpf_id,
2309                             'n_labels': 0,
2310                             'label_stack': lstack}],
2311              'bde_is_add': is_add})
2312
2313     def bier_disp_entry_dump(self, bdti):
2314         return self.api(
2315             self.papi.bier_disp_entry_dump,
2316             {'bde_tbl_id': bdti})
2317
2318     def session_enable_disable(self, is_enabled):
2319         return self.api(
2320             self.papi.session_enable_disable,
2321             {'is_enable': is_enabled})
2322
2323     def ipsec_spd_add_del(self, spd_id, is_add=1):
2324         """ SPD add/del - Wrapper to add or del ipsec SPD
2325         Sample CLI : 'ipsec spd add 1'
2326
2327         :param spd_id - SPD ID to be created in the vpp . mandatory
2328         :param is_add - create (1) or delete(0) SPD (Default 1 - add) .
2329               optional
2330         :returns: reply from the API
2331         """
2332         return self.api(
2333             self.papi.ipsec_spd_add_del, {
2334                 'spd_id': spd_id, 'is_add': is_add})
2335
2336     def ipsec_spds_dump(self):
2337         return self.api(self.papi.ipsec_spds_dump, {})
2338
2339     def ipsec_interface_add_del_spd(self, spd_id, sw_if_index, is_add=1):
2340         """ IPSEC interface SPD add/del - \
2341              Wrapper to associate/disassociate SPD to interface in VPP
2342         Sample CLI : 'set interface ipsec spd GigabitEthernet0/6/0 1'
2343
2344         :param spd_id - SPD ID to associate with the interface . mandatory
2345         :param sw_if_index - Interface Index which needs to ipsec \
2346             association mandatory
2347         :param is_add - add(1) or del(0) association with interface \
2348                 (Default 1 - add) . optional
2349         :returns: reply from the API
2350         """
2351         return self.api(
2352             self.papi.ipsec_interface_add_del_spd,
2353             {'spd_id': spd_id, 'sw_if_index': sw_if_index, 'is_add': is_add})
2354
2355     def ipsec_spd_interface_dump(self, spd_index=None):
2356         return self.api(self.papi.ipsec_spd_interface_dump,
2357                         {'spd_index': spd_index if spd_index else 0,
2358                          'spd_index_valid': 1 if spd_index else 0})
2359
2360     def ipsec_sad_entry_add_del(self,
2361                                 sad_id,
2362                                 spi,
2363                                 integrity_algorithm,
2364                                 integrity_key,
2365                                 crypto_algorithm,
2366                                 crypto_key,
2367                                 protocol,
2368                                 tunnel_src_address='',
2369                                 tunnel_dst_address='',
2370                                 flags=0,
2371                                 is_add=1):
2372         """ IPSEC SA add/del
2373         :param sad_id: security association ID
2374         :param spi: security param index of the SA in decimal
2375         :param integrity_algorithm:
2376         :param integrity_key:
2377         :param crypto_algorithm:
2378         :param crypto_key:
2379         :param protocol: AH(0) or ESP(1) protocol
2380         :param tunnel_src_address: tunnel mode outer src address
2381         :param tunnel_dst_address: tunnel mode outer dst address
2382         :param is_add:
2383         :param is_tunnel:
2384         :** reference /vpp/src/vnet/ipsec/ipsec.h file for enum values of
2385              crypto and ipsec algorithms
2386         """
2387         return self.api(
2388             self.papi.ipsec_sad_entry_add_del,
2389             {
2390                 'is_add': is_add,
2391                 'entry':
2392                     {
2393                         'sad_id': sad_id,
2394                         'spi': spi,
2395                         'tunnel_src': tunnel_src_address,
2396                         'tunnel_dst': tunnel_dst_address,
2397                         'protocol': protocol,
2398                         'integrity_algorithm': integrity_algorithm,
2399                         'integrity_key': {
2400                             'length': len(integrity_key),
2401                             'data': integrity_key,
2402                         },
2403                         'crypto_algorithm': crypto_algorithm,
2404                         'crypto_key': {
2405                             'length': len(crypto_key),
2406                             'data': crypto_key,
2407                         },
2408                         'flags': flags,
2409                     }
2410             })
2411
2412     def ipsec_sa_dump(self, sa_id=None):
2413         return self.api(self.papi.ipsec_sa_dump,
2414                         {'sa_id': sa_id if sa_id else 0xffffffff})
2415
2416     def ipsec_spd_entry_add_del(self,
2417                                 spd_id,
2418                                 sa_id,
2419                                 local_address_start,
2420                                 local_address_stop,
2421                                 remote_address_start,
2422                                 remote_address_stop,
2423                                 local_port_start=0,
2424                                 local_port_stop=65535,
2425                                 remote_port_start=0,
2426                                 remote_port_stop=65535,
2427                                 protocol=0,
2428                                 policy=0,
2429                                 priority=100,
2430                                 is_outbound=1,
2431                                 is_add=1,
2432                                 is_ipv6=0,
2433                                 is_ip_any=0):
2434         """ IPSEC policy SPD add/del   -
2435                     Wrapper to configure ipsec SPD policy entries in VPP
2436         :param spd_id: SPD ID for the policy
2437         :param local_address_start: local-ip-range start address
2438         :param local_address_stop : local-ip-range stop address
2439         :param remote_address_start: remote-ip-range start address
2440         :param remote_address_stop : remote-ip-range stop address
2441         :param local_port_start: (Default value = 0)
2442         :param local_port_stop: (Default value = 65535)
2443         :param remote_port_start: (Default value = 0)
2444         :param remote_port_stop: (Default value = 65535)
2445         :param protocol: Any(0), AH(51) & ESP(50) protocol (Default value = 0)
2446         :param sa_id: Security Association ID for mapping it to SPD
2447         :param policy: bypass(0), discard(1), resolve(2) or protect(3) action
2448                (Default value = 0)
2449         :param priority: value for the spd action (Default value = 100)
2450         :param is_outbound: flag for inbound(0) or outbound(1)
2451                (Default value = 1)
2452         :param is_add: (Default value = 1)
2453         """
2454         return self.api(
2455             self.papi.ipsec_spd_entry_add_del,
2456             {
2457                 'is_add': is_add,
2458                 'entry':
2459                     {
2460                         'spd_id': spd_id,
2461                         'sa_id': sa_id,
2462                         'local_address_start': local_address_start,
2463                         'local_address_stop': local_address_stop,
2464                         'remote_address_start': remote_address_start,
2465                         'remote_address_stop': remote_address_stop,
2466                         'local_port_start': local_port_start,
2467                         'local_port_stop': local_port_stop,
2468                         'remote_port_start': remote_port_start,
2469                         'remote_port_stop': remote_port_stop,
2470                         'protocol': protocol,
2471                         'policy': policy,
2472                         'priority': priority,
2473                         'is_outbound': is_outbound,
2474                         'is_ip_any': is_ip_any
2475                     }
2476             })
2477
2478     def ipsec_spd_dump(self, spd_id, sa_id=0xffffffff):
2479         return self.api(self.papi.ipsec_spd_dump,
2480                         {'spd_id': spd_id,
2481                          'sa_id': sa_id})
2482
2483     def ipsec_tunnel_if_add_del(self, local_ip, remote_ip, local_spi,
2484                                 remote_spi, crypto_alg, local_crypto_key,
2485                                 remote_crypto_key, integ_alg, local_integ_key,
2486                                 remote_integ_key, is_add=1, esn=0,
2487                                 anti_replay=1, renumber=0, show_instance=0):
2488         return self.api(
2489             self.papi.ipsec_tunnel_if_add_del,
2490             {
2491                 'local_ip': local_ip,
2492                 'remote_ip': remote_ip,
2493                 'local_spi': local_spi,
2494                 'remote_spi': remote_spi,
2495                 'crypto_alg': crypto_alg,
2496                 'local_crypto_key_len': len(local_crypto_key),
2497                 'local_crypto_key': local_crypto_key,
2498                 'remote_crypto_key_len': len(remote_crypto_key),
2499                 'remote_crypto_key': remote_crypto_key,
2500                 'integ_alg': integ_alg,
2501                 'local_integ_key_len': len(local_integ_key),
2502                 'local_integ_key': local_integ_key,
2503                 'remote_integ_key_len': len(remote_integ_key),
2504                 'remote_integ_key': remote_integ_key,
2505                 'is_add': is_add,
2506                 'esn': esn,
2507                 'anti_replay': anti_replay,
2508                 'renumber': renumber,
2509                 'show_instance': show_instance
2510             })
2511
2512     def ipsec_select_backend(self, protocol, index):
2513         return self.api(self.papi.ipsec_select_backend,
2514                         {'protocol': protocol, 'index': index})
2515
2516     def ipsec_backend_dump(self):
2517         return self.api(self.papi.ipsec_backend_dump, {})
2518
2519     def app_namespace_add_del(self,
2520                               namespace_id,
2521                               ip4_fib_id=0,
2522                               ip6_fib_id=0,
2523                               sw_if_index=0xFFFFFFFF,
2524                               secret=0):
2525         return self.api(
2526             self.papi.app_namespace_add_del,
2527             {'secret': secret,
2528              'sw_if_index': sw_if_index,
2529              'ip4_fib_id': ip4_fib_id,
2530              'ip6_fib_id': ip6_fib_id,
2531              'namespace_id': namespace_id,
2532              'namespace_id_len': len(namespace_id)})
2533
2534     def punt_socket_register(self, port, pathname, protocol=0x11,
2535                              header_version=1, is_ip4=1):
2536         """ Register punt socket """
2537         return self.api(self.papi.punt_socket_register,
2538                         {'header_version': header_version,
2539                          'punt': {'ipv': is_ip4,
2540                                   'l4_protocol': protocol,
2541                                   'l4_port': port},
2542                          'pathname': pathname})
2543
2544     def punt_socket_deregister(self, port, protocol=0x11, is_ip4=1):
2545         """ Unregister punt socket """
2546         return self.api(self.papi.punt_socket_deregister,
2547                         {'punt': {'ipv': is_ip4,
2548                                   'l4_protocol': protocol,
2549                                   'l4_port': port}})
2550
2551     def punt_socket_dump(self, is_ip6=1):
2552         """ Dump punt socket"""
2553         return self.api(self.papi.punt_socket_dump,
2554                         {'is_ipv6': is_ip6})
2555
2556     def gbp_endpoint_add(self, sw_if_index, ips, mac, sclass, flags,
2557                          tun_src, tun_dst):
2558         """ GBP endpoint Add """
2559         return self.api(self.papi.gbp_endpoint_add,
2560                         {'endpoint': {
2561                             'sw_if_index': sw_if_index,
2562                             'ips': ips,
2563                             'n_ips': len(ips),
2564                             'mac': mac,
2565                             'sclass': sclass,
2566                             'flags': flags,
2567                             'tun': {
2568                                 'src': tun_src,
2569                                 'dst': tun_dst,
2570                             }}})
2571
2572     def gbp_endpoint_del(self, handle):
2573         """ GBP endpoint Del """
2574         return self.api(self.papi.gbp_endpoint_del,
2575                         {'handle': handle})
2576
2577     def gbp_endpoint_dump(self):
2578         """ GBP endpoint Dump """
2579         return self.api(self.papi.gbp_endpoint_dump,
2580                         {'_no_type_conversion': True})
2581
2582     def gbp_endpoint_group_add(self, vnid, sclass, bd,
2583                                rd, uplink_sw_if_index,
2584                                retention):
2585         """ GBP endpoint group Add """
2586         return self.api(self.papi.gbp_endpoint_group_add,
2587                         {'epg':
2588                             {
2589                                 'uplink_sw_if_index': uplink_sw_if_index,
2590                                 'bd_id': bd,
2591                                 'rd_id': rd,
2592                                 'vnid': vnid,
2593                                 'sclass': sclass,
2594                                 'retention': retention
2595                             }})
2596
2597     def gbp_endpoint_group_del(self, sclass):
2598         """ GBP endpoint group Del """
2599         return self.api(self.papi.gbp_endpoint_group_del,
2600                         {'sclass': sclass})
2601
2602     def gbp_bridge_domain_add(self, bd_id, flags,
2603                               bvi_sw_if_index,
2604                               uu_fwd_sw_if_index,
2605                               bm_flood_sw_if_index):
2606         """ GBP bridge-domain Add """
2607         return self.api(self.papi.gbp_bridge_domain_add,
2608                         {'bd':
2609                             {
2610                                 'flags': flags,
2611                                 'bvi_sw_if_index': bvi_sw_if_index,
2612                                 'uu_fwd_sw_if_index': uu_fwd_sw_if_index,
2613                                 'bm_flood_sw_if_index': bm_flood_sw_if_index,
2614                                 'bd_id': bd_id
2615                             }})
2616
2617     def gbp_bridge_domain_del(self, bd_id):
2618         """ GBP bridge-domain Del """
2619         return self.api(self.papi.gbp_bridge_domain_del,
2620                         {'bd_id': bd_id})
2621
2622     def gbp_route_domain_add(self, rd_id,
2623                              ip4_table_id,
2624                              ip6_table_id,
2625                              ip4_uu_sw_if_index,
2626                              ip6_uu_sw_if_index):
2627         """ GBP route-domain Add """
2628         return self.api(self.papi.gbp_route_domain_add,
2629                         {'rd':
2630                             {
2631                                 'ip4_table_id': ip4_table_id,
2632                                 'ip6_table_id': ip6_table_id,
2633                                 'ip4_uu_sw_if_index': ip4_uu_sw_if_index,
2634                                 'ip6_uu_sw_if_index': ip6_uu_sw_if_index,
2635                                 'rd_id': rd_id
2636                             }})
2637
2638     def gbp_route_domain_del(self, rd_id):
2639         """ GBP route-domain Del """
2640         return self.api(self.papi.gbp_route_domain_del,
2641                         {'rd_id': rd_id})
2642
2643     def gbp_recirc_add_del(self, is_add, sw_if_index, sclass, is_ext):
2644         """ GBP recirc Add/Del """
2645         return self.api(self.papi.gbp_recirc_add_del,
2646                         {'is_add': is_add,
2647                          'recirc': {
2648                              'is_ext': is_ext,
2649                              'sw_if_index': sw_if_index,
2650                              'sclass': sclass}})
2651
2652     def gbp_recirc_dump(self):
2653         """ GBP recirc Dump """
2654         return self.api(self.papi.gbp_recirc_dump, {})
2655
2656     def gbp_ext_itf_add_del(self, is_add, sw_if_index, bd_id, rd_id):
2657         """ GBP recirc Add/Del """
2658         return self.api(self.papi.gbp_ext_itf_add_del,
2659                         {'is_add': is_add,
2660                          'ext_itf': {
2661                              'sw_if_index': sw_if_index,
2662                              'bd_id': bd_id,
2663                              'rd_id': rd_id}})
2664
2665     def gbp_ext_itf_dump(self):
2666         """ GBP recirc Dump """
2667         return self.api(self.papi.gbp_ext_itf_dump, {})
2668
2669     def gbp_subnet_add_del(self, is_add, rd_id,
2670                            prefix, type,
2671                            sw_if_index=0xffffffff,
2672                            sclass=0xffff):
2673         """ GBP Subnet Add/Del """
2674         return self.api(self.papi.gbp_subnet_add_del,
2675                         {'is_add': is_add,
2676                          'subnet': {
2677                              'type': type,
2678                              'sw_if_index': sw_if_index,
2679                              'sclass': sclass,
2680                              'prefix': prefix,
2681                              'rd_id': rd_id}})
2682
2683     def gbp_subnet_dump(self):
2684         """ GBP Subnet Dump """
2685         return self.api(self.papi.gbp_subnet_dump,
2686                         {'_no_type_conversion': True})
2687
2688     def gbp_contract_add_del(self, is_add, sclass, dclass, acl_index,
2689                              rules, allowed_ethertypes):
2690         """ GBP contract Add/Del """
2691         return self.api(self.papi.gbp_contract_add_del,
2692                         {'is_add': is_add,
2693                          'contract': {
2694                              'acl_index': acl_index,
2695                              'sclass': sclass,
2696                              'dclass': dclass,
2697                              'n_rules': len(rules),
2698                              'rules': rules,
2699                              'n_ether_types': len(allowed_ethertypes),
2700                              'allowed_ethertypes': allowed_ethertypes}})
2701
2702     def gbp_contract_dump(self):
2703         """ GBP contract Dump """
2704         return self.api(self.papi.gbp_contract_dump, {})
2705
2706     def gbp_vxlan_tunnel_add(self, vni, bd_rd_id, mode, src):
2707         """ GBP VXLAN tunnel add """
2708         return self.api(self.papi.gbp_vxlan_tunnel_add,
2709                         {
2710                             'tunnel': {
2711                                 'vni': vni,
2712                                 'mode': mode,
2713                                 'bd_rd_id': bd_rd_id,
2714                                 'src': src
2715                             }
2716                         })
2717
2718     def gbp_vxlan_tunnel_del(self, vni):
2719         """ GBP VXLAN tunnel del """
2720         return self.api(self.papi.gbp_vxlan_tunnel_del,
2721                         {
2722                             'vni': vni,
2723                         })
2724
2725     def gbp_vxlan_tunnel_dump(self):
2726         """ GBP VXLAN tunnel add/del """
2727         return self.api(self.papi.gbp_vxlan_tunnel_dump, {})
2728
2729     def qos_egress_map_update(self, id, outputs):
2730         """ QOS egress map update """
2731         return self.api(self.papi.qos_egress_map_update,
2732                         {'map_id': id,
2733                          'rows': outputs})
2734
2735     def qos_egress_map_delete(self, id):
2736         """ QOS egress map delete """
2737         return self.api(self.papi.qos_egress_map_delete,
2738                         {'map_id': id})
2739
2740     def qos_mark_enable_disable(self, sw_if_index,
2741                                 output_source,
2742                                 map_id,
2743                                 enable):
2744         """ QOS Mark Enable/Disable """
2745         return self.api(self.papi.qos_mark_enable_disable,
2746                         {'map_id': map_id,
2747                          'sw_if_index': sw_if_index,
2748                          'output_source': output_source,
2749                          'enable': enable})
2750
2751     def igmp_enable_disable(self, sw_if_index, enable, host):
2752         """ Enable/disable IGMP on a given interface """
2753         return self.api(self.papi.igmp_enable_disable,
2754                         {'enable': enable,
2755                          'mode': host,
2756                          'sw_if_index': sw_if_index})
2757
2758     def igmp_proxy_device_add_del(self, vrf_id, sw_if_index, add):
2759         """ Add/del IGMP proxy device """
2760         return self.api(self.papi.igmp_proxy_device_add_del,
2761                         {'vrf_id': vrf_id, 'sw_if_index': sw_if_index,
2762                          'add': add})
2763
2764     def igmp_proxy_device_add_del_interface(self, vrf_id, sw_if_index, add):
2765         """ Add/del interface to/from IGMP proxy device """
2766         return self.api(self.papi.igmp_proxy_device_add_del_interface,
2767                         {'vrf_id': vrf_id, 'sw_if_index': sw_if_index,
2768                          'add': add})
2769
2770     def igmp_listen(self, filter, sw_if_index, saddrs, gaddr):
2771         """ Listen for new (S,G) on specified interface
2772
2773         :param enable: add/del
2774         :param sw_if_index: interface sw index
2775         :param saddr: source ip4 addr
2776         :param gaddr: group ip4 addr
2777         """
2778         return self.api(self.papi.igmp_listen,
2779                         {
2780                             'group':
2781                                 {
2782                                     'filter': filter,
2783                                     'sw_if_index': sw_if_index,
2784                                     'n_srcs': len(saddrs),
2785                                     'saddrs': saddrs,
2786                                     'gaddr': gaddr
2787                                 }
2788                         })
2789
2790     def igmp_clear_interface(self, sw_if_index):
2791         """ Remove all (S,G)s from specified interface
2792             doesn't send IGMP report!
2793         """
2794         return self.api(
2795             self.papi.igmp_clear_interface, {
2796                 'sw_if_index': sw_if_index})
2797
2798     def want_igmp_events(self, enable=1):
2799         return self.api(self.papi.want_igmp_events, {'enable': enable,
2800                                                      'pid': os.getpid()})
2801
2802     def bond_create(
2803             self,
2804             mode,
2805             lb,
2806             use_custom_mac,
2807             mac_address='',
2808             interface_id=0xFFFFFFFF):
2809         """
2810         :param mode: mode
2811         :param lb: load balance
2812         :param use_custom_mac: use custom mac
2813         :param mac_address: mac address
2814         :param interface_id: custom interface ID
2815         """
2816         return self.api(
2817             self.papi.bond_create,
2818             {'mode': mode,
2819              'lb': lb,
2820              'use_custom_mac': use_custom_mac,
2821              'mac_address': mac_address,
2822              'id': interface_id
2823              })
2824
2825     def pipe_delete(self, parent_sw_if_index):
2826         return self.api(self.papi.pipe_delete,
2827                         {'parent_sw_if_index': parent_sw_if_index})
2828
2829     def memif_create(
2830             self,
2831             role,
2832             mode,
2833             rx_queues=None,
2834             tx_queues=None,
2835             _id=None,
2836             socket_id=None,
2837             secret=None,
2838             ring_size=None,
2839             buffer_size=None,
2840             hw_addr=None):
2841         return self.api(self.papi.memif_create,
2842                         {'role': role,
2843                          'mode': mode,
2844                          'rx_queues': rx_queues,
2845                          'tx_queues': tx_queues,
2846                          'id': _id,
2847                          'socket_id': socket_id,
2848                          'secret': secret,
2849                          'ring_size': ring_size,
2850                          'buffer_size': buffer_size,
2851                          'hw_addr': hw_addr})
2852
2853     def svs_table_add_del(self, af, table_id, is_add=1):
2854         return self.api(self.papi.svs_table_add_del,
2855                         {
2856                             'table_id': table_id,
2857                             'is_add': is_add,
2858                             'af': af,
2859                         })
2860
2861     def svs_route_add_del(self, table_id, prefix, src_table_id, is_add=1):
2862         return self.api(self.papi.svs_route_add_del,
2863                         {
2864                             'table_id': table_id,
2865                             'source_table_id': src_table_id,
2866                             'prefix': prefix,
2867                             'is_add': is_add,
2868                         })
2869
2870     def svs_enable_disable(self, af, table_id, sw_if_index, is_enable=1):
2871         return self.api(self.papi.svs_enable_disable,
2872                         {
2873                             'af': af,
2874                             'table_id': table_id,
2875                             'sw_if_index': sw_if_index,
2876                             'is_enable': is_enable,
2877                         })