7 If you are writing a Control plane in GO that interfaces with VPP, `GoVPP <https://github.com/FDio/govpp>`__ is the library that will allow you to connect to VPP, and program it through its binary API socket.
12 The API client connecting to VPP consists of several elements :
14 * First, everything stems from the api definition living in the VPP repository. The message definitions live in ``*.api`` files that you will find instances of in most VPP plugins.
15 * The repository contains an api generator ``make json-api-files`` that converts those ``.api`` files into ``.json`` files to be consumed by language specific bindings.
16 * The program ingesting these ``.json`` files is called ``binapi-generator`` and lives inside `GoVPP <https://github.com/FDio/govpp>`__. It contains the logic converting them to ``.ba.go`` files with the appropriate struct definitions matching all the api messages defined in the ``.api`` files.
17 * `GoVPP <https://github.com/FDio/govpp>`__'s repo also contains the logic for attaching to VPP's binary API socket, and wrappers for sending and receiving messages over it.
22 Generating the API bindings from the VPP source
23 -----------------------------------------------
25 * First create your project directory (watch out for path as it is important for go modules) :
29 mkdir -p $HOME/myproject
31 * Run the bindings generation at the root of the repo :
36 make ARGS="--output-dir=$HOME/myproject/vppbinapi --import-prefix=mygit.com/myproject/vppbinapi" go-api-files
40 The two options are similar but specify two different things. The output-dir option sets the directory where the generated bindings will be stored. The import prefix sets the go package name to be used in the generated bindings, this will be the string to be used in your ``import ( "" )`` in go. Both can or can not match depending on your ``go.mod``.
43 This should prompt you with the name of the directory were the generated go api bindings live. (e.g. ``Go API bindings were generated to myproject/vppbinapi``)
45 Generating the API bindings from the VPP package
46 ------------------------------------------------
48 * You should find its corresponding ``api.json`` files present on your system, typically in ``/usr/share/vpp/api/``
52 # First install the binary API generator
53 # It will be installed to $GOPATH/bin/binapi-generator
54 # or $HOME/go/bin/binapi-generator
55 go install git.fd.io/govpp.git/cmd/binapi-generator@latest
57 # Run the binapi-generator
58 $GOPATH/bin/binapi-generator \
59 --input-dir=/usr/share/vpp/api/ \
60 --output-dir=$HOME/myproject/vppbinapi \
61 --import-prefix=mygit.com/myproject/vppbinapi
63 This should output the go bindings to ``$HOME/myproject/vppbinapi``
71 cat << EOF > /tmp/startup.conf
72 unix {nodaemon cli-listen /tmp/vpp/api.sock}
74 path /vpp/build-root/install-vpp_debug-native/vpp/lib/x86_64-linux-gnu/vpp_plugins
75 plugin dpdk_plugin.so { disable }
79 # If VPP was built from source:
80 <vpp_repo_dir>/build-root/install-vpp_debug-native/vpp/bin/vpp -c /tmp/startup.conf
82 # If VPP was installed from package:
83 vpp -c /tmp/startup.conf
89 Once you have your go bindings in ``$HOME/myproject/vppbinapi``, you can start building an agent leveraging them. A typical agent would look like this
91 * Back to your project directory, add govpp as a dependency
96 go mod init mygit.com/myproject
97 go get git.fd.io/govpp.git@latest
99 * Create ``main.go`` in ``$HOME/myproject`` like below :
109 "git.fd.io/govpp.git"
110 "git.fd.io/govpp.git/api"
112 "mygit.com/myproject/vppbinapi/af_packet"
113 interfaces "mygit.com/myproject/vppbinapi/interface"
114 "mygit.com/myproject/vppbinapi/interface_types"
117 func CreateHostInterface (ch api.Channel, ifName string) (uint32, error) {
118 response := &af_packet.AfPacketCreateReply{}
119 request := &af_packet.AfPacketCreate{HostIfName: ifName}
120 err := ch.SendRequest(request).ReceiveReply(response)
123 } else if response.Retval != 0 {
124 return 0, fmt.Errorf("AfPacketCreate failed: req %+v reply %+v", request, response)
126 return uint32(response.SwIfIndex), nil
129 func InterfaceAdminUp(ch api.Channel, swIfIndex uint32) error {
130 request := &interfaces.SwInterfaceSetFlags{
131 SwIfIndex: interface_types.InterfaceIndex(swIfIndex),
132 Flags: interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
134 response := &interfaces.SwInterfaceSetFlagsReply{}
135 err := ch.SendRequest(request).ReceiveReply(response)
144 conn, err := govpp.Connect("/tmp/vpp/api.sock")
145 defer conn.Disconnect()
147 fmt.Printf("Could not connect: %s\n", err)
152 ch, err := conn.NewAPIChannel()
155 fmt.Printf("Could not open API channel: %s\n", err)
159 swIfIndex, err := CreateHostInterface(ch, "eth0")
161 fmt.Printf("Could not create host interface: %s\n", err)
164 err = InterfaceAdminUp(ch, swIfIndex)
166 fmt.Printf("Could not set interface up: %s\n", err)
170 fmt.Printf("Created host interface & set it up, id=%d\n", swIfIndex)
173 * Finally build and launch application. This will connect to VPP on its API socket ``/tmp/vpp/api.sock``, create an AF_PACKET interface on ``eth0`` and set it up