blob: 2148e94b2a8c5b0104945bdf14f61c4453864dda [file] [log] [blame]
Klement Sekera277b89c2016-10-28 13:20:27 +02001import os
Klement Sekeraf62ae122016-10-11 11:47:09 +02002from logging import error
3from hook import Hook
4
Klement Sekera277b89c2016-10-28 13:20:27 +02005do_import = True
6try:
7 no_vpp_papi = os.getenv("NO_VPP_PAPI")
8 if no_vpp_papi == "1":
9 do_import = False
10except:
11 pass
12
13if do_import:
14 import vpp_papi
15
16
Klement Sekeraf62ae122016-10-11 11:47:09 +020017# from vnet/vnet/mpls/mpls_types.h
18MPLS_IETF_MAX_LABEL = 0xfffff
19MPLS_LABEL_INVALID = MPLS_IETF_MAX_LABEL + 1
20
21
22class VppPapiProvider(object):
23 """VPP-api provider using vpp-papi
24
25 @property hook: hook object providing before and after api/cli hooks
26
27
28 """
29
30 def __init__(self, name, shm_prefix):
Klement Sekera277b89c2016-10-28 13:20:27 +020031 self.hook = Hook("vpp-papi-provider")
Klement Sekeraf62ae122016-10-11 11:47:09 +020032 self.name = name
33 self.shm_prefix = shm_prefix
34
35 def register_hook(self, hook):
36 """Replace hook registration with new hook
37
38 :param hook:
39
40 """
41 self.hook = hook
42
43 def connect(self):
44 """Connect the API to VPP"""
45 vpp_papi.connect(self.name, self.shm_prefix)
46
47 def disconnect(self):
48 """Disconnect the API from VPP"""
49 vpp_papi.disconnect()
50
51 def api(self, api_fn, api_args, expected_retval=0):
52 """Call API function and check it's return value
53 Call the appropriate hooks before and after the API call
54
55 :param api_fn: API function to call
56 :param api_args: tuple of API function arguments
57 :param expected_retval: Expected return value (Default value = 0)
58 :returns: reply from the API
59
60 """
61 self.hook.before_api(api_fn.__name__, api_args)
62 reply = api_fn(*api_args)
63 if hasattr(reply, 'retval') and reply.retval != expected_retval:
64 msg = "API call failed, expected retval == %d, got %s" % (
65 expected_retval, repr(reply))
66 error(msg)
67 raise Exception(msg)
68 self.hook.after_api(api_fn.__name__, api_args)
69 return reply
70
71 def cli(self, cli):
Jan49c0fca2016-10-26 15:44:27 +020072 """
73 Execute a CLI, calling the before/after hooks appropriately.
Klement Sekeraf62ae122016-10-11 11:47:09 +020074
75 :param cli: CLI to execute
76 :returns: CLI output
77
78 """
79 self.hook.before_cli(cli)
80 cli += '\n'
81 r = vpp_papi.cli_inband(len(cli), cli)
82 self.hook.after_cli(cli)
Jan49c0fca2016-10-26 15:44:27 +020083 if hasattr(r, 'reply'):
Klement Sekeraf62ae122016-10-11 11:47:09 +020084 return r.reply[0].decode().rstrip('\x00')
85
Jan49c0fca2016-10-26 15:44:27 +020086 def ppcli(self, cli):
87 """
88 Helping method to print CLI command in case of info logging level.
89
90 :param cli: CLI to execute
91 :returns: CLI output
92 """
93 return cli + "\n" + self.cli(cli)
94
Klement Sekeraf62ae122016-10-11 11:47:09 +020095 def show_version(self):
96 """ """
97 return vpp_papi.show_version()
98
99 def pg_create_interface(self, pg_index):
100 """
101
102 :param pg_index:
103
104 """
105 return self.api(vpp_papi.pg_create_interface, (pg_index, ))
106
107 def sw_interface_dump(self, filter=None):
108 """
109
110 :param filter: (Default value = None)
111
112 """
113 if filter is not None:
114 args = (1, filter)
115 else:
116 args = (0, b'')
117 return self.api(vpp_papi.sw_interface_dump, args)
118
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000119 def sw_interface_set_table(self, sw_if_index, is_ipv6, table_id):
120 """
121 Set the IPvX Table-id for the Interface
122
123 :param sw_if_index:
124 :param is_ipv6:
125 :param table_id:
126
127 """
128 return self.api(vpp_papi.sw_interface_set_table,
129 (sw_if_index, is_ipv6, table_id))
130
Klement Sekeraf62ae122016-10-11 11:47:09 +0200131 def sw_interface_add_del_address(self, sw_if_index, addr, addr_len,
132 is_ipv6=0, is_add=1, del_all=0):
133 """
134
135 :param addr: param is_ipv6: (Default value = 0)
136 :param sw_if_index:
137 :param addr_len:
138 :param is_ipv6: (Default value = 0)
139 :param is_add: (Default value = 1)
140 :param del_all: (Default value = 0)
141
142 """
143 return self.api(vpp_papi.sw_interface_add_del_address,
144 (sw_if_index, is_add, is_ipv6, del_all, addr_len, addr))
145
Neale Ranns8fe8cc22016-11-01 10:05:08 +0000146 def sw_interface_enable_disable_mpls(self, sw_if_index,
147 is_enable=1):
148 """
149 Enable/Disable MPLS on the interface
150 :param sw_if_index:
151 :param is_enable: (Default value = 1)
152
153 """
154 return self.api(vpp_papi.sw_interface_set_mpls_enable,
155 (sw_if_index, is_enable))
156
Klement Sekeraf62ae122016-10-11 11:47:09 +0200157 def sw_interface_ra_suppress(self, sw_if_index):
158 suppress = 1
159 managed = 0
160 other = 0
161 ll_option = 0
162 send_unicast = 0
163 cease = 0
164 is_no = 0
165 default_router = 0
166 max_interval = 0
167 min_interval = 0
168 lifetime = 0
169 initial_count = 0
170 initial_interval = 0
171 async = False
172 return self.api(vpp_papi.sw_interface_ip6nd_ra_config,
173 (sw_if_index, suppress, managed, other,
174 ll_option, send_unicast, cease, is_no,
175 default_router, max_interval, min_interval,
176 lifetime, initial_count, initial_interval, async))
177
Klement Sekeraf62ae122016-10-11 11:47:09 +0200178 def vxlan_add_del_tunnel(
179 self,
180 src_addr,
181 dst_addr,
182 is_add=1,
183 is_ipv6=0,
184 encap_vrf_id=0,
185 decap_next_index=0xFFFFFFFF,
186 vni=0):
187 """
188
189 :param dst_addr:
190 :param src_addr:
191 :param is_add: (Default value = 1)
192 :param is_ipv6: (Default value = 0)
193 :param encap_vrf_id: (Default value = 0)
194 :param decap_next_index: (Default value = 0xFFFFFFFF)
195 :param vni: (Default value = 0)
196
197 """
198 return self.api(vpp_papi.vxlan_add_del_tunnel,
199 (is_add, is_ipv6, src_addr, dst_addr, encap_vrf_id,
200 decap_next_index, vni))
201
202 def sw_interface_set_l2_bridge(self, sw_if_index, bd_id,
203 shg=0, bvi=0, enable=1):
204 """
205
206 :param bd_id:
207 :param sw_if_index:
208 :param shg: (Default value = 0)
209 :param bvi: (Default value = 0)
210 :param enable: (Default value = 1)
211
212 """
213 return self.api(vpp_papi.sw_interface_set_l2_bridge,
214 (sw_if_index, bd_id, shg, bvi, enable))
215
216 def sw_interface_set_l2_xconnect(self, rx_sw_if_index, tx_sw_if_index,
217 enable):
218 """Create or delete unidirectional cross-connect from Tx interface to
219 Rx interface.
220
221 :param rx_sw_if_index: Software interface index of Rx interface.
222 :param tx_sw_if_index: Software interface index of Tx interface.
223 :param enable: Create cross-connect if equal to 1, delete cross-connect
Klement Sekera277b89c2016-10-28 13:20:27 +0200224 if equal to 0.
Klement Sekeraf62ae122016-10-11 11:47:09 +0200225 :type rx_sw_if_index: str or int
226 :type rx_sw_if_index: str or int
227 :type enable: int
228
229 """
230 return self.api(vpp_papi.sw_interface_set_l2_xconnect,
231 (rx_sw_if_index, tx_sw_if_index, enable))
232
233 def sw_interface_set_flags(self, sw_if_index, admin_up_down,
234 link_up_down=0, deleted=0):
235 """
236
237 :param admin_up_down:
238 :param sw_if_index:
239 :param link_up_down: (Default value = 0)
240 :param deleted: (Default value = 0)
241
242 """
243 return self.api(vpp_papi.sw_interface_set_flags,
244 (sw_if_index, admin_up_down, link_up_down, deleted))
245
246 def create_subif(self, sw_if_index, sub_id, outer_vlan, inner_vlan,
247 no_tags=0, one_tag=0, two_tags=0, dot1ad=0, exact_match=0,
248 default_sub=0, outer_vlan_id_any=0, inner_vlan_id_any=0):
249 """Create subinterface
250 from vpe.api: set dot1ad = 0 for dot1q, set dot1ad = 1 for dot1ad
251
252 :param sub_id: param inner_vlan:
253 :param sw_if_index:
254 :param outer_vlan:
255 :param inner_vlan:
256 :param no_tags: (Default value = 0)
257 :param one_tag: (Default value = 0)
258 :param two_tags: (Default value = 0)
259 :param dot1ad: (Default value = 0)
260 :param exact_match: (Default value = 0)
261 :param default_sub: (Default value = 0)
262 :param outer_vlan_id_any: (Default value = 0)
263 :param inner_vlan_id_any: (Default value = 0)
264
265 """
266 return self.api(
267 vpp_papi.create_subif,
268 (sw_if_index,
269 sub_id,
270 no_tags,
271 one_tag,
272 two_tags,
273 dot1ad,
274 exact_match,
275 default_sub,
276 outer_vlan_id_any,
277 inner_vlan_id_any,
278 outer_vlan,
279 inner_vlan))
280
281 def create_vlan_subif(self, sw_if_index, vlan):
282 """
283
284 :param vlan:
285 :param sw_if_index:
286
287 """
288 return self.api(vpp_papi.create_vlan_subif, (sw_if_index, vlan))
289
Matej Klotton0178d522016-11-04 11:11:44 +0100290 def create_loopback(self, mac=''):
291 """
292
293 :param mac: (Optional)
294 """
295 return self.api(vpp_papi.create_loopback, (mac,))
296
Klement Sekeraf62ae122016-10-11 11:47:09 +0200297 def ip_add_del_route(
298 self,
299 dst_address,
300 dst_address_length,
301 next_hop_address,
302 next_hop_sw_if_index=0xFFFFFFFF,
303 table_id=0,
304 resolve_attempts=0,
305 classify_table_index=0xFFFFFFFF,
306 next_hop_out_label=MPLS_LABEL_INVALID,
307 next_hop_table_id=0,
308 create_vrf_if_needed=0,
309 resolve_if_needed=0,
310 is_add=1,
311 is_drop=0,
Juraj Sloboda86a2c572016-10-27 10:44:25 +0200312 is_unreach=0,
313 is_prohibit=0,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200314 is_ipv6=0,
315 is_local=0,
316 is_classify=0,
317 is_multipath=0,
318 is_resolve_host=0,
319 is_resolve_attached=0,
320 not_last=0,
321 next_hop_weight=1):
322 """
323
324 :param dst_address_length:
325 :param next_hop_sw_if_index: (Default value = 0xFFFFFFFF)
326 :param dst_address:
327 :param next_hop_address:
328 :param next_hop_sw_if_index: (Default value = 0xFFFFFFFF)
329 :param vrf_id: (Default value = 0)
330 :param lookup_in_vrf: (Default value = 0)
331 :param resolve_attempts: (Default value = 0)
332 :param classify_table_index: (Default value = 0xFFFFFFFF)
333 :param create_vrf_if_needed: (Default value = 0)
334 :param resolve_if_needed: (Default value = 0)
335 :param is_add: (Default value = 1)
336 :param is_drop: (Default value = 0)
337 :param is_ipv6: (Default value = 0)
338 :param is_local: (Default value = 0)
339 :param is_classify: (Default value = 0)
340 :param is_multipath: (Default value = 0)
341 :param is_resolve_host: (Default value = 0)
342 :param is_resolve_attached: (Default value = 0)
343 :param not_last: (Default value = 0)
344 :param next_hop_weight: (Default value = 1)
345
346 """
347 return self.api(
348 vpp_papi.ip_add_del_route,
349 (next_hop_sw_if_index,
350 table_id,
351 resolve_attempts,
352 classify_table_index,
353 next_hop_out_label,
354 next_hop_table_id,
355 create_vrf_if_needed,
356 resolve_if_needed,
357 is_add,
358 is_drop,
Juraj Sloboda86a2c572016-10-27 10:44:25 +0200359 is_unreach,
360 is_prohibit,
Klement Sekeraf62ae122016-10-11 11:47:09 +0200361 is_ipv6,
362 is_local,
363 is_classify,
364 is_multipath,
365 is_resolve_host,
366 is_resolve_attached,
367 not_last,
368 next_hop_weight,
369 dst_address_length,
370 dst_address,
371 next_hop_address))
Matej Klotton0178d522016-11-04 11:11:44 +0100372
373 def ip_neighbor_add_del(self,
374 sw_if_index,
375 mac_address,
376 dst_address,
377 vrf_id=0,
378 is_add=1,
379 is_ipv6=0,
380 is_static=0,
381 ):
382 """ Add neighbor MAC to IPv4 or IPv6 address.
383
384 :param sw_if_index:
385 :param mac_address:
386 :param dst_address:
387 :param vrf_id: (Default value = 0)
388 :param is_add: (Default value = 1)
389 :param is_ipv6: (Default value = 0)
390 :param is_static: (Default value = 0)
391 """
392
393 return self.api(
394 vpp_papi.ip_neighbor_add_del,
395 (vrf_id,
396 sw_if_index,
397 is_add,
398 is_ipv6,
399 is_static,
400 mac_address,
401 dst_address
402 )
403 )
Pavel Kotucekf6e3dc42016-11-04 09:58:01 +0100404
405 def sw_interface_span_enable_disable(self, sw_if_index_from, sw_if_index_to, enable=1):
406 """
407
408 :param sw_if_index_from:
409 :param sw_if_index_to:
410 :param enable
411
412 """
413 return self.api(vpp_papi.sw_interface_span_enable_disable, (sw_if_index_from, sw_if_index_to, enable ))