Learning VPP: Python API

logo_fdio-300x184

Overview

VPP preferred interface is a binary API that is used by Northbound control plane applications like Honeycomb. Furthermore, VPP provides an autogenerated Python wrapper for your convenience.

While Python API channel is significantly slower than native binary API (1500 messages/second versus 450000), it is still a great option.

There are three classes of VPP API methods:

  1. Synchronous request/reply.
  2. Dump functions.
  3. Events.

Install

1. Build VPP.

2. Check JSON API definitions under

vpp/build-root/install-vpp_debug-native/vpp/share/vpp/api/core

3. Set LD_LIBRARY_PATH to point to the location of libvppapiclient.so

4. Install Python package.

cd vpp
cd src/vpp-api/python
sudo python setup.py install

Code

The code below is doing the following.

  1. Connect to VPP.
  2. Print version.
  3. Print all interfaces.
  4. Subscribe on interface statistics updates.
  5. Disconnect from VPP.
#!/bin/env python

from __future__ import print_function
import os
import fnmatch
import time
from vpp_papi import VPP

def papi_event_handler(msgname, result):
    print(msgname)
    print(result)
 
vpp_json_dir = '/usr/share/vpp/api/'
 
jsonfiles = []
for root, dirnames, filenames in os.walk(vpp_json_dir):
    for filename in fnmatch.filter(filenames, '*.api.json'):
        jsonfiles.append(os.path.join(vpp_json_dir, filename))
 
if not jsonfiles:
    print('Error: no json api files found')
    exit(-1)
 
vpp = VPP(jsonfiles)
r = vpp.connect('papi-example')

rv = vpp.api.show_version()
print('VPP version =', rv.version.decode().rstrip('\0x00'))

for intf in vpp.api.sw_interface_dump():
    print(intf.interface_name.decode())

async=True                                                                                                                                                                                                
r=vpp.register_event_callback(papi_event_handler)
pid=os.getpid()
sw_ifs = [2]
r = vpp.api.want_per_interface_simple_stats(enable_disable=True, sw_ifs=sw_ifs, num=len(sw_ifs), pid=pid)
print(r)
                                                                                                                                                                                
time.sleep(60)
r = vpp.api.want_per_interface_simple_stats(enable_disable=False)
 
r = vpp.disconnect()
exit(r)

Output

sudo python vpp.py
VPP version = 19.01.00.01.01-rc0~11-gc069ff9
local0
GigabitEthernet0/3/0
GigabitEthernet0/8/0
want_per_interface_simple_stats_reply(_0=862, context=3, retval=0)
vnet_per_interface_simple_counters
vnet_per_interface_simple_counters(_0=887, count=1, timestamp=785, data=[vl_api_vnet_simple_counter_t(sw_if_index=2, drop=44, punt=0, rx_ip4=62, rx_ip6=0, rx_no_buffer=0, rx_miss=0, rx_error=0, tx_error=44, rx_mpls=0)])
vnet_per_interface_simple_counters
vnet_per_interface_simple_counters(_0=887, count=1, timestamp=795, data=[vl_api_vnet_simple_counter_t(sw_if_index=2, drop=44, punt=0, rx_ip4=72, rx_ip6=0, rx_no_buffer=0, rx_miss=0, rx_error=0, tx_error=44, rx_mpls=0)])
vnet_per_interface_simple_counters

References