blob: d29f90c1789bf8ca16a4821a77f365cfbc69aaba [file] [log] [blame]
Klement Sekera277b89c2016-10-28 13:20:27 +02001import os
Neale Rannsad422ed2016-11-02 14:20:04 +00002import array
Klement Sekeraf62ae122016-10-11 11:47:09 +02003from logging import error
4from hook import Hook
5
Klement Sekera277b89c2016-10-28 13:20:27 +02006do_import = True
7try:
8 no_vpp_papi = os.getenv("NO_VPP_PAPI")
9 if no_vpp_papi == "1":
10 do_import = False
11except:
12 pass
13
14if do_import:
15 import vpp_papi
16
17
Klement Sekeraf62ae122016-10-11 11:47:09 +020018# from vnet/vnet/mpls/mpls_types.h
19MPLS_IETF_MAX_LABEL = 0xfffff
20MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
21
Neale Ranns177bbdc2016-11-15 09:46:51 +000022class L2_VTR_OP:
23 L2_POP_1 = 3
24
Neale Rannsad422ed2016-11-02 14:20:04 +000025need_swap = True if os.sys.byteorder == 'little' else False
Klement Sekeraf62ae122016-10-11 11:47:09 +020026
27class VppPapiProvider(object):
28 """VPP-api provider using vpp-papi
29
30 @property hook: hook object providing before and after api/cli hooks
31
32
33 """
34
35 def __init__(self, name, shm_prefix):
Klement Sekera277b89c2016-10-28 13:20:27 +020036 self.hook = Hook("vpp-papi-provider")
Klement Sekeraf62ae122016-10-11 11:47:09 +020037 self.name = name
38 self.shm_prefix = shm_prefix
39
40 def register_hook(self, hook):
41 """Replace hook registration with new hook
42
43 :param hook:
44
45 """
46 self.hook = hook
47
48 def connect(self):
49 """Connect the API to VPP"""
50 vpp_papi.connect(self.name, self.shm_prefix)
51
52 def disconnect(self):
53 """Disconnect the API from VPP"""
54 vpp_papi.disconnect()
55
56 def api(self, api_fn, api_args, expected_retval=0):
57 """Call API function and check it's return value
58 Call the appropriate hooks before and after the API call
59
60 :param api_fn: API function to call
61 :param api_args: tuple of API function arguments
62 :param expected_retval: Expected return value (Default value = 0)
63 :returns: reply from the API
64
65 """
66 self.hook.before_api(api_fn.__name__, api_args)
67 reply = api_fn(*api_args)
68 if hasattr(reply, 'retval') and reply.retval != expected_retval:
69 msg = "API call failed, expected retval == %d, got %s" % (
70 expected_retval, repr(reply))
71 error(msg)
72 raise Exception(msg)
73 self.hook.after_api(api_fn.__name__, api_args)
74 return reply
75
76 def cli(self, cli):
Jan49c0fca2016-10-26 15:44:27 +020077 """
78 Execute a CLI, calling the before/after hooks appropriately.
Klement Sekeraf62ae122016-10-11 11:47:09 +020079
80 :param cli: CLI to execute
81 :returns: CLI output
82
83 """
84 self.hook.before_cli(cli)
85 cli += '\n'
86 r = vpp_papi.cli_inband(len(cli), cli)
87 self.hook.after_cli(cli)
Jan49c0fca2016-10-26 15:44:27 +020088 if hasattr(r, 'reply'):
Klement Sekeraf62ae122016-10-11 11:47:09 +020089 return r.reply[0].decode().rstrip('\x00')
90
Jan49c0fca2016-10-26 15:44:27 +020091 def ppcli(self, cli):
92 """
93 Helping method to print CLI command in case of info logging level.
94
95 :param cli: CLI to execute
96 :returns: CLI output
97 """
Ed Warnickeb8ff5d62016-11-28 13:59:22 -060098 return cli + "\n" + str(self.cli(cli))
Jan49c0fca2016-10-26 15:44:27 +020099
Jan4af521d2016-11-15 17:05:00 +0100100 def _convert_mac(self, mac):
101 return int(mac.replace(":", ""), 16) << 16
102
Klement Sekeraf62ae122016-10-11 11:47:09 +0200103 def show_version(self):
104 """ """
105 return vpp_papi.show_version()
106
107 def pg_create_interface(self, pg_index):
108 """
109
110 :param pg_index:
111
112 """
113 return self.api(vpp_papi.pg_create_interface, (pg_index, ))
114
115 def sw_interface_dump(self, filter=None):
116 """
117
118 :param filter: (Default value = None)
119
120 """
121 if filter is not None:
122 args = (1, filter)
123 else:
124 args = (0, b'')
125 return self.api(vpp_papi.sw_interface_dump, args)
126
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000127 def sw_interface_set_table(self, sw_if_index, is_ipv6, table_id):
128 """
129 Set the IPvX Table-id for the Interface
130
131 :param sw_if_index:
132 :param is_ipv6:
133 :param table_id:
134
135 """
136 return self.api(vpp_papi.sw_interface_set_table,
137 (sw_if_index, is_ipv6, table_id))
138
Klement Sekeraf62ae122016-10-11 11:47:09 +0200139 def sw_interface_add_del_address(self, sw_if_index, addr, addr_len,
140 is_ipv6=0, is_add=1, del_all=0):
141 """
142
143 :param addr: param is_ipv6: (Default value = 0)
144 :param sw_if_index:
145 :param addr_len:
146 :param is_ipv6: (Default value = 0)
147 :param is_add: (Default value = 1)
148 :param del_all: (Default value = 0)
149
150 """
151 return self.api(vpp_papi.sw_interface_add_del_address,
152 (sw_if_index, is_add, is_ipv6, del_all, addr_len, addr))
153
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000154 def sw_interface_enable_disable_mpls(self, sw_if_index,
155 is_enable=1):
156 """
157 Enable/Disable MPLS on the interface
158 :param sw_if_index:
159 :param is_enable: (Default value = 1)
160
161 """
162 return self.api(vpp_papi.sw_interface_set_mpls_enable,
163 (sw_if_index, is_enable))
164
Klement Sekeraf62ae122016-10-11 11:47:09 +0200165 def sw_interface_ra_suppress(self, sw_if_index):
166 suppress = 1
167 managed = 0
168 other = 0
169 ll_option = 0
170 send_unicast = 0
171 cease = 0
172 is_no = 0
173 default_router = 0
174 max_interval = 0
175 min_interval = 0
176 lifetime = 0
177 initial_count = 0
178 initial_interval = 0
179 async = False
180 return self.api(vpp_papi.sw_interface_ip6nd_ra_config,
181 (sw_if_index, suppress, managed, other,
182 ll_option, send_unicast, cease, is_no,
183 default_router, max_interval, min_interval,
184 lifetime, initial_count, initial_interval, async))
185
Klement Sekeraf62ae122016-10-11 11:47:09 +0200186 def vxlan_add_del_tunnel(
187 self,
188 src_addr,
189 dst_addr,
Eyal Baric5b13602016-11-24 19:42:43 +0200190 mcast_sw_if_index=0xFFFFFFFF,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200191 is_add=1,
192 is_ipv6=0,
193 encap_vrf_id=0,
194 decap_next_index=0xFFFFFFFF,
195 vni=0):
196 """
197
198 :param dst_addr:
199 :param src_addr:
200 :param is_add: (Default value = 1)
201 :param is_ipv6: (Default value = 0)
202 :param encap_vrf_id: (Default value = 0)
203 :param decap_next_index: (Default value = 0xFFFFFFFF)
Eyal Baric5b13602016-11-24 19:42:43 +0200204 :param mcast_sw_if_index: (Default value = 0xFFFFFFFF)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200205 :param vni: (Default value = 0)
206
207 """
208 return self.api(vpp_papi.vxlan_add_del_tunnel,
Eyal Baric5b13602016-11-24 19:42:43 +0200209 (is_add, is_ipv6, src_addr, dst_addr, mcast_sw_if_index,
210 encap_vrf_id, decap_next_index, vni))
Klement Sekeraf62ae122016-10-11 11:47:09 +0200211
Jan4af521d2016-11-15 17:05:00 +0100212 def bridge_domain_add_del(self, bd_id, flood=1, uu_flood=1, forward=1,
213 learn=1, arp_term=0, is_add=1):
214 """Create/delete bridge domain.
215
216 :param int bd_id: Bridge domain index.
217 :param int flood: Enable/disable bcast/mcast flooding in the BD.
218 (Default value = 1)
219 :param int uu_flood: Enable/disable unknown unicast flood in the BD.
220 (Default value = 1)
221 :param int forward: Enable/disable forwarding on all interfaces in
222 the BD. (Default value = 1)
223 :param int learn: Enable/disable learning on all interfaces in the BD.
224 (Default value = 1)
225 :param int arp_term: Enable/disable arp termination in the BD.
226 (Default value = 1)
227 :param int is_add: Add or delete flag. (Default value = 1)
228 """
229 return self.api(vpp_papi.bridge_domain_add_del,
230 (bd_id, flood, uu_flood, forward, learn, arp_term,
231 is_add))
232
233 def l2fib_add_del(self, mac, bd_id, sw_if_index, is_add=1, static_mac=0,
234 filter_mac=0, bvi_mac=0):
235 """Create/delete L2 FIB entry.
236
237 :param str mac: MAC address to create FIB entry for.
238 :param int bd_id: Bridge domain index.
239 :param int sw_if_index: Software interface index of the interface.
240 :param int is_add: Add or delete flag. (Default value = 1)
241 :param int static_mac: Set to 1 to create static MAC entry.
242 (Default value = 0)
243 :param int filter_mac: Set to 1 to drop packet that's source or
244 destination MAC address contains defined MAC address.
245 (Default value = 0)
246 :param int bvi_mac: Set to 1 to create entry that points to BVI
247 interface. (Default value = 0)
248 """
249 return self.api(vpp_papi.l2fib_add_del,
250 (self._convert_mac(mac), bd_id, sw_if_index, is_add,
251 static_mac, filter_mac, bvi_mac))
252
Klement Sekeraf62ae122016-10-11 11:47:09 +0200253 def sw_interface_set_l2_bridge(self, sw_if_index, bd_id,
254 shg=0, bvi=0, enable=1):
Jan4af521d2016-11-15 17:05:00 +0100255 """Add/remove interface to/from bridge domain.
Klement Sekeraf62ae122016-10-11 11:47:09 +0200256
Jan4af521d2016-11-15 17:05:00 +0100257 :param int sw_if_index: Software interface index of the interface.
258 :param int bd_id: Bridge domain index.
259 :param int shg: Split-horizon group index. (Default value = 0)
260 :param int bvi: Set interface as a bridge group virtual interface.
261 (Default value = 0)
262 :param int enable: Add or remove interface. (Default value = 1)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200263 """
264 return self.api(vpp_papi.sw_interface_set_l2_bridge,
265 (sw_if_index, bd_id, shg, bvi, enable))
266
267 def sw_interface_set_l2_xconnect(self, rx_sw_if_index, tx_sw_if_index,
268 enable):
269 """Create or delete unidirectional cross-connect from Tx interface to
270 Rx interface.
271
Jan4af521d2016-11-15 17:05:00 +0100272 :param int rx_sw_if_index: Software interface index of Rx interface.
273 :param int tx_sw_if_index: Software interface index of Tx interface.
274 :param int enable: Create cross-connect if equal to 1, delete
275 cross-connect if equal to 0.
Klement Sekeraf62ae122016-10-11 11:47:09 +0200276
277 """
278 return self.api(vpp_papi.sw_interface_set_l2_xconnect,
279 (rx_sw_if_index, tx_sw_if_index, enable))
280
Neale Ranns177bbdc2016-11-15 09:46:51 +0000281 def sw_interface_set_l2_tag_rewrite(self, sw_if_index, vtr_oper, push=0, tag1=0, tag2=0):
282 """L2 interface vlan tag rewrite configure request
283 :param client_index - opaque cookie to identify the sender
284 :param context - sender context, to match reply w/ request
285 :param sw_if_index - interface the operation is applied to
286 :param vtr_op - Choose from l2_vtr_op_t enum values
287 :param push_dot1q - first pushed flag dot1q id set, else dot1ad
288 :param tag1 - Needed for any push or translate vtr op
289 :param tag2 - Needed for any push 2 or translate x-2 vtr ops
290
291 """
292 return self.api(vpp_papi.l2_interface_vlan_tag_rewrite,
293 (sw_if_index, vtr_oper, push, tag1, tag2))
294
Klement Sekeraf62ae122016-10-11 11:47:09 +0200295 def sw_interface_set_flags(self, sw_if_index, admin_up_down,
296 link_up_down=0, deleted=0):
297 """
298
299 :param admin_up_down:
300 :param sw_if_index:
301 :param link_up_down: (Default value = 0)
302 :param deleted: (Default value = 0)
303
304 """
305 return self.api(vpp_papi.sw_interface_set_flags,
306 (sw_if_index, admin_up_down, link_up_down, deleted))
307
308 def create_subif(self, sw_if_index, sub_id, outer_vlan, inner_vlan,
309 no_tags=0, one_tag=0, two_tags=0, dot1ad=0, exact_match=0,
310 default_sub=0, outer_vlan_id_any=0, inner_vlan_id_any=0):
311 """Create subinterface
312 from vpe.api: set dot1ad = 0 for dot1q, set dot1ad = 1 for dot1ad
313
314 :param sub_id: param inner_vlan:
315 :param sw_if_index:
316 :param outer_vlan:
317 :param inner_vlan:
318 :param no_tags: (Default value = 0)
319 :param one_tag: (Default value = 0)
320 :param two_tags: (Default value = 0)
321 :param dot1ad: (Default value = 0)
322 :param exact_match: (Default value = 0)
323 :param default_sub: (Default value = 0)
324 :param outer_vlan_id_any: (Default value = 0)
325 :param inner_vlan_id_any: (Default value = 0)
326
327 """
328 return self.api(
329 vpp_papi.create_subif,
330 (sw_if_index,
331 sub_id,
332 no_tags,
333 one_tag,
334 two_tags,
335 dot1ad,
336 exact_match,
337 default_sub,
338 outer_vlan_id_any,
339 inner_vlan_id_any,
340 outer_vlan,
341 inner_vlan))
342
Neale Ranns177bbdc2016-11-15 09:46:51 +0000343 def delete_subif(self, sw_if_index):
344 """Delete subinterface
345
346 :param sw_if_index:
347 """
348 return self.api(vpp_papi.delete_subif, ([sw_if_index]))
349
Klement Sekeraf62ae122016-10-11 11:47:09 +0200350 def create_vlan_subif(self, sw_if_index, vlan):
351 """
352
353 :param vlan:
354 :param sw_if_index:
355
356 """
357 return self.api(vpp_papi.create_vlan_subif, (sw_if_index, vlan))
358
Matej Klotton0178d522016-11-04 11:11:44 +0100359 def create_loopback(self, mac=''):
360 """
361
362 :param mac: (Optional)
363 """
364 return self.api(vpp_papi.create_loopback, (mac,))
365
Klement Sekeraf62ae122016-10-11 11:47:09 +0200366 def ip_add_del_route(
367 self,
368 dst_address,
369 dst_address_length,
370 next_hop_address,
371 next_hop_sw_if_index=0xFFFFFFFF,
372 table_id=0,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200373 next_hop_table_id=0,
Neale Rannsad422ed2016-11-02 14:20:04 +0000374 next_hop_weight=1,
375 next_hop_n_out_labels = 0,
376 next_hop_out_label_stack = [],
377 next_hop_via_label = MPLS_LABEL_INVALID,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200378 create_vrf_if_needed=0,
Neale Rannsad422ed2016-11-02 14:20:04 +0000379 is_resolve_host=0,
380 is_resolve_attached=0,
381 classify_table_index=0xFFFFFFFF,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200382 is_add=1,
383 is_drop=0,
Juraj Sloboda86a2c572016-10-27 10:44:25 +0200384 is_unreach=0,
385 is_prohibit=0,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200386 is_ipv6=0,
387 is_local=0,
388 is_classify=0,
389 is_multipath=0,
Neale Rannsad422ed2016-11-02 14:20:04 +0000390 not_last=0):
Klement Sekeraf62ae122016-10-11 11:47:09 +0200391 """
392
393 :param dst_address_length:
394 :param next_hop_sw_if_index: (Default value = 0xFFFFFFFF)
395 :param dst_address:
396 :param next_hop_address:
397 :param next_hop_sw_if_index: (Default value = 0xFFFFFFFF)
398 :param vrf_id: (Default value = 0)
399 :param lookup_in_vrf: (Default value = 0)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200400 :param classify_table_index: (Default value = 0xFFFFFFFF)
401 :param create_vrf_if_needed: (Default value = 0)
Klement Sekeraf62ae122016-10-11 11:47:09 +0200402 :param is_add: (Default value = 1)
403 :param is_drop: (Default value = 0)
404 :param is_ipv6: (Default value = 0)
405 :param is_local: (Default value = 0)
406 :param is_classify: (Default value = 0)
407 :param is_multipath: (Default value = 0)
408 :param is_resolve_host: (Default value = 0)
409 :param is_resolve_attached: (Default value = 0)
410 :param not_last: (Default value = 0)
411 :param next_hop_weight: (Default value = 1)
412
413 """
Neale Rannsad422ed2016-11-02 14:20:04 +0000414 stack = array.array('I', next_hop_out_label_stack)
415 if need_swap:
416 stack.byteswap()
417 stack = stack.tostring()
418
Klement Sekeraf62ae122016-10-11 11:47:09 +0200419 return self.api(
420 vpp_papi.ip_add_del_route,
421 (next_hop_sw_if_index,
422 table_id,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200423 classify_table_index,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200424 next_hop_table_id,
425 create_vrf_if_needed,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200426 is_add,
427 is_drop,
Juraj Sloboda86a2c572016-10-27 10:44:25 +0200428 is_unreach,
429 is_prohibit,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200430 is_ipv6,
431 is_local,
432 is_classify,
433 is_multipath,
434 is_resolve_host,
435 is_resolve_attached,
436 not_last,
437 next_hop_weight,
438 dst_address_length,
439 dst_address,
Neale Rannsad422ed2016-11-02 14:20:04 +0000440 next_hop_address,
441 next_hop_n_out_labels,
442 next_hop_via_label,
443 stack))
Matej Klotton0178d522016-11-04 11:11:44 +0100444
445 def ip_neighbor_add_del(self,
446 sw_if_index,
447 mac_address,
448 dst_address,
449 vrf_id=0,
450 is_add=1,
451 is_ipv6=0,
452 is_static=0,
453 ):
454 """ Add neighbor MAC to IPv4 or IPv6 address.
455
456 :param sw_if_index:
457 :param mac_address:
458 :param dst_address:
459 :param vrf_id: (Default value = 0)
460 :param is_add: (Default value = 1)
461 :param is_ipv6: (Default value = 0)
462 :param is_static: (Default value = 0)
463 """
464
465 return self.api(
466 vpp_papi.ip_neighbor_add_del,
467 (vrf_id,
468 sw_if_index,
469 is_add,
470 is_ipv6,
471 is_static,
472 mac_address,
473 dst_address
474 )
475 )
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100476
477 def sw_interface_span_enable_disable(self, sw_if_index_from, sw_if_index_to, enable=1):
478 """
479
480 :param sw_if_index_from:
481 :param sw_if_index_to:
482 :param enable
483
484 """
485 return self.api(vpp_papi.sw_interface_span_enable_disable, (sw_if_index_from, sw_if_index_to, enable ))
Neale Ranns177bbdc2016-11-15 09:46:51 +0000486
487 def gre_tunnel_add_del(self,
488 src_address,
489 dst_address,
490 outer_fib_id=0,
491 is_teb=0,
492 is_add=1,
493 is_ip6=0):
494 """ Add a GRE tunnel
495
496 :param src_address:
497 :param dst_address:
498 :param outer_fib_id: (Default value = 0)
499 :param is_add: (Default value = 1)
500 :param is_ipv6: (Default value = 0)
501 :param is_teb: (Default value = 0)
502 """
503
504 return self.api(
505 vpp_papi.gre_add_del_tunnel,
506 (is_add,
507 is_ip6,
508 is_teb,
509 src_address,
510 dst_address,
511 outer_fib_id)
512 )
Neale Rannsad422ed2016-11-02 14:20:04 +0000513
514 def mpls_route_add_del(
515 self,
516 label,
517 eos,
518 next_hop_proto_is_ip4,
519 next_hop_address,
520 next_hop_sw_if_index=0xFFFFFFFF,
521 table_id=0,
522 next_hop_table_id=0,
523 next_hop_weight=1,
524 next_hop_n_out_labels = 0,
525 next_hop_out_label_stack = [],
526 next_hop_via_label = MPLS_LABEL_INVALID,
527 create_vrf_if_needed=0,
528 is_resolve_host=0,
529 is_resolve_attached=0,
530 is_add=1,
531 is_drop=0,
532 is_multipath=0,
533 classify_table_index=0xFFFFFFFF,
534 is_classify=0,
535 not_last=0):
536 """
537
538 :param dst_address_length:
539 :param next_hop_sw_if_index: (Default value = 0xFFFFFFFF)
540 :param dst_address:
541 :param next_hop_address:
542 :param next_hop_sw_if_index: (Default value = 0xFFFFFFFF)
543 :param vrf_id: (Default value = 0)
544 :param lookup_in_vrf: (Default value = 0)
545 :param classify_table_index: (Default value = 0xFFFFFFFF)
546 :param create_vrf_if_needed: (Default value = 0)
547 :param is_add: (Default value = 1)
548 :param is_drop: (Default value = 0)
549 :param is_ipv6: (Default value = 0)
550 :param is_local: (Default value = 0)
551 :param is_classify: (Default value = 0)
552 :param is_multipath: (Default value = 0)
553 :param is_resolve_host: (Default value = 0)
554 :param is_resolve_attached: (Default value = 0)
555 :param not_last: (Default value = 0)
556 :param next_hop_weight: (Default value = 1)
557
558 """
559 stack = array.array('I', next_hop_out_label_stack)
560 if need_swap:
561 stack.byteswap()
562 stack = stack.tostring()
563
564 return self.api(
565 vpp_papi.mpls_route_add_del,
566 (label,
567 eos,
568 table_id,
569 classify_table_index,
570 create_vrf_if_needed,
571 is_add,
572 is_classify,
573 is_multipath,
574 is_resolve_host,
575 is_resolve_attached,
576 next_hop_proto_is_ip4,
577 next_hop_weight,
578 next_hop_address,
579 next_hop_n_out_labels,
580 next_hop_sw_if_index,
581 next_hop_table_id,
582 next_hop_via_label,
583 stack))
584
585 def mpls_ip_bind_unbind(
586 self,
587 label,
588 dst_address,
589 dst_address_length,
590 table_id=0,
591 ip_table_id=0,
592 is_ip4=1,
593 create_vrf_if_needed=0,
594 is_bind=1):
595 """
596 """
597 return self.api(
598 vpp_papi.mpls_ip_bind_unbind,
599 (table_id,
600 label,
601 ip_table_id,
602 create_vrf_if_needed,
603 is_bind,
604 is_ip4,
605 dst_address_length,
606 dst_address))
607
608 def mpls_tunnel_add_del(
609 self,
610 tun_sw_if_index,
611 next_hop_proto_is_ip4,
612 next_hop_address,
613 next_hop_sw_if_index=0xFFFFFFFF,
614 next_hop_table_id=0,
615 next_hop_weight=1,
616 next_hop_n_out_labels = 0,
617 next_hop_out_label_stack = [],
618 next_hop_via_label = MPLS_LABEL_INVALID,
619 create_vrf_if_needed=0,
620 is_add=1,
621 l2_only=0):
622 """
623
624 :param dst_address_length:
625 :param next_hop_sw_if_index: (Default value = 0xFFFFFFFF)
626 :param dst_address:
627 :param next_hop_address:
628 :param next_hop_sw_if_index: (Default value = 0xFFFFFFFF)
629 :param vrf_id: (Default value = 0)
630 :param lookup_in_vrf: (Default value = 0)
631 :param classify_table_index: (Default value = 0xFFFFFFFF)
632 :param create_vrf_if_needed: (Default value = 0)
633 :param is_add: (Default value = 1)
634 :param is_drop: (Default value = 0)
635 :param is_ipv6: (Default value = 0)
636 :param is_local: (Default value = 0)
637 :param is_classify: (Default value = 0)
638 :param is_multipath: (Default value = 0)
639 :param is_resolve_host: (Default value = 0)
640 :param is_resolve_attached: (Default value = 0)
641 :param not_last: (Default value = 0)
642 :param next_hop_weight: (Default value = 1)
643
644 """
645 stack = array.array('I', next_hop_out_label_stack)
646 if need_swap:
647 stack.byteswap()
648 stack = stack.tostring()
649
650 return self.api(
651 vpp_papi.mpls_tunnel_add_del,
652 (tun_sw_if_index,
653 is_add,
654 l2_only,
655 next_hop_proto_is_ip4,
656 next_hop_weight,
657 next_hop_address,
658 next_hop_n_out_labels,
659 next_hop_sw_if_index,
660 next_hop_table_id,
661 stack))
662