-
Notifications
You must be signed in to change notification settings - Fork 708
VPP Python_API
- 1 Python binding for the VPP API
- 2 Installation
- 3 Step by Step
- 4 Implementation
- 5 Architecture
- 6 Examples
- 7 API generation
- 8 Future Improvements / TODOs
The vpp-papi module in vpp-api/python/ provides a Python binding to the VPP API. The Python bindings to the API is auto-generated from JSON API definitions. These JSON definitions must be passed to the VPP class init method. Both individual components and plugins provide API definitions. The JSON files are also generated, from .api files. In a binary installation the JSON API definitions are installed under /usr/share/vpp/api/
Currently there are three classes of VPP API methods:
- Simple request / reply. For example the show_version() call the SHOW_VERSION message is the request and the SHOW_VERSION_REPLY is the answer back. By convention replies are named ending with _REPLY.
- Dump functions. For example sw_interface_dump() send the SW_INTERFACE_DUMP message and receive a set of messages back. In this example SW_INTERFACE_DETAILS and SW_INTERFACE_SET_FLAGS are (typically) received. The CONTROL_PING/CONTROL_PING_REPLY is used as a method to signal to the client that the last message has been received. By convention the request message have names ending with _DUMP and the replies have names ending in _DETAILS.
- Register for events. For example want_stats() sends a WANT_STATS message, get a WANT_STATS_REPLY message back, and the client will then asynchronously receive VNET_INTERFACE_COUNTERS messages.
The API is by default blocking although there is possible to get asynchronous behaviour by setting the function argument async=True.
Each call uses the arguments as specified in the API definitions file (e.g. vpe.api). The "client_index" and "context" fields are handled by the module itself. A call returns a named tuple or a list of named tuples.
The main VPP build will build the C library (libvppapiclient.so). If VPP is installed via the Linux package system that library will be available on the system. To run within a build directory, set LD_LIBRARY_PATH to point to the location of libvppapiclient.so.
To build the VPP_PAPI Python package (and shared library): This step maybe unnecessary if you have already done it (generally one time)
make build
The Python package can either be installed in the Python system directory or in a Virtualenv environment. To install the Python component:
cd src/vpp-api/python
sudo python setup.py install
To test:
alagalah@thing1:vpp (master)*$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import vpp_papi
>>>
If you run from the development directory in a virtualenv environment, you might have to set LD_LIBRARY_PATH to e.g. build-root/install-vpp_debug-native/vpp-api/lib64/
The Python package can also be installed from the vpp-python-api RPM/DEB. It is then installed in the system default Python library directory.
-
# install preresquisites -
sudo apt-get install python-virtualenv -
-
export VPP=~vpp/ -
cd $VPP -
-
# build vpp -
make bootstrap build -
-
# create virtualenv -
virtualenv virtualenv -
-
# (optional) install python packages -
# ipaddress is used by some scripts -
virtualenv/bin/pip install ipaddress -
# nice to have to get the tab completion and other CLI niceties -
virtualenv/bin/pip install scapy -
-
# install vpp python api -
pushd $VPP/src/vpp-api/python/ -
$VPP/virtualenv/bin/python setup.py install -
popd -
-
# Now set the LD_LIBRARY_PATH such that it points to the directory containing libvppapiclient.so -
export LD_LIBRARY_PATH=`find $VPP -name "libvppapiclient.so" -exec dirname {} \; | grep install-vpp | head -n 1` -
-
# You will now need two windows : -
# one for vpp, and the other for python -
-
# VPP -
cd $VPP -
make run -
-
# python -
# (as root, as vpp.connect() requires root privileges) -
# Note that sudo cannot not preserve LD_LIBRARY_PATH -
cd $VPP -
-
# you can run a script -
sudo -E LD_LIBRARY_PATH=$LD_LIBRARY_PATH $VPP/virtualenv/bin/python vpp-api/python/tests/vpp_hello_world.py.py -
-
# or get a python prompt -
sudo -E LD_LIBRARY_PATH=$LD_LIBRARY_PATH $VPP/virtualenv/bin/python
VPP python's hello world
-
#!/bin/env python -
-
from __future__ import print_function -
from vpp_papi import VPPApiClient -
import fnmatch -
import os -
-
# this is 25.02-rc0~196-g098d0c594 version test -
vpp_json_dir = '/opt/vpp/build-root/install-vpp_debug-native/vpp/share/vpp/api/core' -
-
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) -
-
-
# use all those files to create vpp. -
# Note that there will be no vpp method available before vpp.connect() -
vpp = VPPApiClient(apidir=vpp_json_dir, apifiles=jsonfiles) -
r = vpp.connect('papi-example') -
print(r) -
# None -
-
# You're all set. -
# You can check the list of available methods by calling dir(vpp) -
-
# show vpp version -
rv = vpp.api.show_version() -
if isinstance(rv.version, bytes): -
version_str = rv.version.decode().rstrip('\x00') -
else: -
version_str = rv.version.rstrip('\x00') -
-
print('VPP version =', version_str) -
-
# disconnect from vpp -
r = vpp.disconnect() -
print(r) -
-
exit(r)
Note: This is out of date and needs updating; pneum has been replaced by libvppapiclient; the semantics are otherwise mostly the same.
The vpp/api/vpe.api file specifies a set of messages that can be exchanged between VPP and the API client. The semantics of those messages are somewhat up to interpretation and convention.
The language binding is implemented simply by exposing four C calls to Python. Those are:
int pneum_connect(char *name);
int pneum_disconnect(void);
int pneum_read(char **data, int *l);
int pneum_write(char *data, int len);
In addition there is a Python message handler callback called by the C RX pthread. All message handling and parsing is done in Python.
Packaging:
-
#!/usr/bin/env python -
-
from __future__ import print_function -
-
import os -
import fnmatch -
-
from vpp_papi import VPPApiClient -
-
-
vpp_json_dir = '/usr/share/vpp/api/core/' -
-
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 = VPPApiClient(apifiles=jsonfiles) -
-
r = vpp.connect("test_papi") -
print(r) -
-
for intf in vpp.api.sw_interface_dump(): -
if isinstance(intf.interface_name, bytes): -
print(intf.interface_name.decode()) -
else: -
print(intf.interface_name) -
-
exit(vpp.disconnect())
-
#!/usr/bin/env python -
-
from vpp_papi import VPPApiClient -
import os -
import sys -
import fnmatch -
import time -
def papi_event_handler(msgname, result): -
print(msgname) -
print(result) -
-
vpp_json_dir = os.environ['VPP'] + '/build-root/install-vpp_debug-native/vpp/share/vpp/api/core' -
-
# construct a list of all the json api files -
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) -
# use all those files to create vpp. -
vpp = VPPApiClient(apifiles=jsonfiles) -
r = vpp.connect("test_papi") -
print(r) -
-
async=True -
r=vpp.register_event_callback(papi_event_handler) -
r = vpp.api.want_interface_events(enable_disable=1, pid=os.getpid()) -
print(r) -
# Wait for some stats -
time.sleep(60) -
r = vpp.api.want_interface_events(enable_disable=False) -
r = vpp.disconnect()
The Python binding is automatically generated from the API definitions. See figure below.
-
A common context field is used as a transaction id, for the client to be able to match replies with requests. Not all messages have context and the API handles that, as long as the CONTROL_PING is used to embed them.
-
The API generates code that will send a CONTROL_PING for _DUMP/_DETAIL message exchanges. It will not do so for CALL/CALL_REPLY style calls, so it is important that those conventions are followed.
-
Some messages, e.g. VNET_INTERFACE_COUNTERS are variable sized, with an unspecified u8 data[0] field and a something like a u32 count or u32 nitems field telling the message specific handler the size of the message. There is no way to automatically generate code to handle this, so the Python API returns these to the caller as a byte string. These can then be handled by message specific code like:
if result.vl_msg_id == vpp_papi.VL_API_VNET_INTERFACE_COUNTERS:
format = '>' + str(int(len(result.data) / 8)) + 'Q'
counters = struct.unpack(format, result.data)
Performance: Python essentially runs single threaded. The RX thread will hold the Global Interpreter Lock during callback. Current performance is about 1500 messages/second. An implementation in C gets about 450000 messages/second in comparison.
API: Use Python Async I/O?
Exception / error handling
Handle messages like GET_NODE_GRAPH where the reply is a reference to shared memory.
- VPP 2022 Make Test Use Case Poll
- VPP-AArch64
- VPP-ABF
- VPP Alternative Builds
- VPP API Concepts
- VPP API Versioning
- VPP-ApiChangeProcess
- VPP-ArtifactVersioning
- VPP-BIER
- VPP-Bihash
- VPP-BugReports
- VPP Build System Deep Dive
- VPP Build, Install, And Test Images
- VPP-BuildArtifactRetentionPolicy
- VPP-c2cpel
- VPP Code Walkthrough VoD
- VPP Code Walkthrough VoD Topic Index
- VPP Code Walkthrough VoDs
- VPP-CodeStyleConventions
- VPP-CodingTips
- VPP Command Line Arguments
- VPP Command Line Interface CLI Guide
- VPP-CommitMessages
- VPP-Committers-SMEs
- VPP-CommitterTasks-ApiFreeze
- VPP CommitterTasks Compare API Changes
- VPP-CommitterTasks-CutPointRelease
- VPP-CommitterTasks-CutRelease
- VPP-CommitterTasks-FinalReleaseCandidate
- VPP-CommitterTasks-PullThrottleBranch
- VPP-CommitterTasks-ReleasePlan
- VPP Configuration Tool
- VPP Configure An LW46 MAP E Terminator
- VPP Configure VPP As A Router Between Namespaces
- VPP Configure VPP TAP Interfaces For Container Routing
- VPP-CoreFileMismatch
- VPP-cpel
- VPP-cpeldump
- VPP-CurrentData
- VPP-DHCPKit
- VPP-DHCPv6
- VPP-DistributedOwnership
- VPP-Documentation
- VPP DPOs And Feature Arcs
- VPP EC2 Instance With SRIOV
- VPP-elog
- VPP-FAQ
- VPP Feature Arcs
- VPP-Features
- VPP-Features-IPv6
- VPP-FIB
- VPP-g2
- VPP Getting VPP 16.06
- VPP Getting VPP Release Binaries
- VPP-HA
- VPP-HostStack
- VPP-HostStack-BuiltinEchoClientServer
- VPP-HostStack-EchoClientServer
- VPP-HostStack-ExternalEchoClientServer
- VPP HostStack Hs Test
- VPP-HostStack-LDP-iperf
- VPP-HostStack-LDP-nginx
- VPP-HostStack-LDP-sshd
- VPP-HostStack-nginx
- VPP-HostStack-SessionLayerArchitecture
- VPP-HostStack-TestHttpServer
- VPP-HostStack-TestProxy
- VPP-HostStack-TLS
- VPP-HostStack-VCL
- VPP-HostStack-VclEchoClientServer
- VPP-Hotplug
- VPP How To Add A Tunnel Encapsulation
- VPP How To Build The Sample Plugin
- VPP How To Connect A PCI Interface To VPP
- VPP How To Create A VPP Binary Control Plane API
- VPP How To Deploy VPP In EC2 Instance And Use It To Connect Two Different VPCs
- VPP How To Optimize Performance %28System Tuning%29
- VPP How To Use The API Trace Tools
- VPP How To Use The C API
- VPP How To Use The Packet Generator And Packet Tracer
- VPP-Howtos
- VPP-index
- VPP Installing VPP Binaries From Packages
- VPP Interconnecting vRouters With VPP
- VPP Introduction To IP Adjacency
- VPP Introduction To N Tuple Classifiers
- VPP IP Adjacency Introduction
- VPP-IPFIX
- VPP-IPSec
- VPP IPSec And IKEv2
- VPP IPv6 SR VIRL Topology File
- VPP Java API
- VPP Java API Plugin Support
- VPP Jira Workflow
- VPP-Macswapplugin
- VPP-MakeTestFramework
- VPP-Meeting
- VPP-MFIB
- VPP Missing Prefetches
- VPP Modifying The Packet Processing Directed Graph
- VPP MPLS FIB
- VPP-NAT
- VPP Nataas Test
- VPP-OVN
- VPP Per Feature Notes
- VPP Performance Analysis Tools
- VPP-perftop
- VPP Progressive VPP Tutorial
- VPP Project Meeting Minutes
- VPP Pulling, Building, Running, Hacking And Pushing VPP Code
- VPP Pure L3 Between Namespaces With 32s
- VPP Pure L3 Container Networking
- VPP Pushing And Testing A Tag
- VPP Python API
- VPP-PythonVersionPolicy
- VPP-QuickTrexSetup
- VPP Random Hints And Kinks For KVM Usage
- VPP Release Plans Release Plan 16.09
- VPP Release Plans Release Plan 17.01
- VPP Release Plans Release Plan 17.04
- VPP Release Plans Release Plan 17.07
- VPP Release Plans Release Plan 17.10
- VPP Release Plans Release Plan 18.01
- VPP Release Plans Release Plan 18.04
- VPP Release Plans Release Plan 18.07
- VPP Release Plans Release Plan 18.10
- VPP Release Plans Release Plan 19.01
- VPP Release Plans Release Plan 19.04
- VPP Release Plans Release Plan 19.08
- VPP Release Plans Release Plan 20.01
- VPP Release Plans Release Plan 20.05
- VPP Release Plans Release Plan 20.09
- VPP Release Plans Release Plan 21.01
- VPP Release Plans Release Plan 21.06
- VPP Release Plans Release Plan 21.10
- VPP Release Plans Release Plan 22.02
- VPP Release Plans Release Plan 22.06
- VPP Release Plans Release Plan 22.10
- VPP Release Plans Release Plan 23.02
- VPP Release Plans Release Plan 23.06
- VPP Release Plans Release Plan 23.10
- VPP Release Plans Release Plan 24.02
- VPP Release Plans Release Plan 24.06
- VPP Release Plans Release Plan 24.10
- VPP Release Plans Release Plan 25.02
- VPP Release Plans Release Plan 25.06
- VPP Release Plans Release Plan 25.10
- VPP Release Plans Release Plan 26.02
- VPP Release Plans Release Plan 26.06
- VPP-RM
- VPP-SecurityGroups
- VPP Segment Routing For IPv6
- VPP Segment Routing For MPLS
- VPP Setting Up Your Dev Environment
- VPP-SNAT
- VPP Software Architecture
- VPP STN Testing
- VPP The VPP API
- VPP Training Events
- VPP-Troubleshooting
- VPP-Troubleshooting-BuildIssues
- VPP-Troubleshooting-Vagrant
- VPP Tutorial DPDK And MacSwap
- VPP Tutorial Routing And Switching
- VPP-Tutorials
- VPP Use VPP To Chain VMs Using Vhost User Interface
- VPP Use VPP To Connect VMs Using Vhost User Interface
- VPP Using mTCP User Mode TCP Stack With VPP
- VPP Using VPP As A VXLAN Tunnel Terminator
- VPP Using VPP In A Multi Thread Model
- VPP-VOM
- VPP VPP BFD Nexus
- VPP VPP Home Gateway
- VPP VPP WIKI DEPRECATED CONTENT
- VPP-VPPCommunicationsLibrary
- VPP-VPPConfig
- VPP What Is ODP4VPP
- VPP What Is VPP
- VPP Working Environments
- VPP Working With The 16.06 Throttle Branch


