andrew | 7403026 | 2018-08-05 21:18:45 -0400 | [diff] [blame] | 1 | .. _sample_plugin: |
| 2 | |
John DeNisco | ce96dda | 2018-08-14 16:04:09 -0400 | [diff] [blame] | 3 | Integrating a plugin |
| 4 | ===================== |
andrew | 7403026 | 2018-08-05 21:18:45 -0400 | [diff] [blame] | 5 | |
John DeNisco | ce96dda | 2018-08-14 16:04:09 -0400 | [diff] [blame] | 6 | .. toctree:: |
andrew | 7403026 | 2018-08-05 21:18:45 -0400 | [diff] [blame] | 7 | |
| 8 | Overview |
| 9 | ________ |
| 10 | |
| 11 | This section shows how a VPP plugin developer can modify VPP scripts to add and load their plugin as a node in VPP. |
| 12 | |
| 13 | As an example we will integrate the **Sample Plugin** found in *vpp/src/examples/sample-plugin/sample* The VPP Sample Plugin is a small plugin that demonstrates simple implementation of a macswap algorithim. Since it is a VPP plugin, it has runtime integration with the VPP graph hierachy, API, and CLI. |
| 14 | |
| 15 | This section will not go into the details of the plugin itself. For a deeper dive into the sample plugin see the annotations in `sample.c <https://docs.fd.io/vpp/18.11/da/d30/sample_8c.html>`_, or go to the next page for general VPP C API usage. |
| 16 | |
| 17 | Setup |
| 18 | _____ |
| 19 | |
| 20 | Each plugin has their own automake file (\*.am) used by *configure.ac*, as well as a separate directory containing C files for the plugin. The directory containing these for each plugin is *vpp/src/plugins* |
| 21 | |
| 22 | To get a basic idea for how a VPP automake plugin file specifies its C files, here is part of the Sample Plugin automake file, *sample.am* |
| 23 | |
| 24 | .. code-block:: console |
| 25 | |
| 26 | sample_plugin_la_SOURCES = \ |
| 27 | sample/sample.c \ |
| 28 | sample/node.c \ |
| 29 | sample/sample_plugin.api.h |
| 30 | |
| 31 | API_FILES += sample/sample.api |
| 32 | |
| 33 | nobase_apiinclude_HEADERS += \ |
| 34 | sample/sample_all_api_h.h \ |
| 35 | sample/sample_msg_enum.h \ |
| 36 | sample/sample.api.h |
| 37 | |
| 38 | |
| 39 | The Sample Plugin is located in *vpp/src/examples/sample-plugin/sample*, so as mentioned above we will need to copy its contents into *vpp/src/plugins* |
| 40 | |
| 41 | In your */vpp* directory, or the directory above */src*, run: |
| 42 | |
| 43 | .. code-block:: console |
| 44 | |
| 45 | $ cp -r src/examples/sample-plugin/sample src/plugins |
| 46 | $ cp src/examples/sample-plugin/sample.am src/plugins |
| 47 | |
| 48 | Modifying configure.ac and Makefile.am |
| 49 | ______________________________________ |
| 50 | |
| 51 | We now need to modify the plugin sections of the VPP automake and configuration scripts so that VPP builds correctly with your new plugin. |
| 52 | |
| 53 | Using a text editor such as *vi*, add the following entry to the plugins section in *vpp/src/configure.ac* |
| 54 | |
| 55 | .. code-block:: console |
| 56 | |
| 57 | PLUGIN_ENABLED(sample) |
| 58 | |
| 59 | For reference, the plugins section of that file looks like this: |
| 60 | |
| 61 | .. code-block:: console |
| 62 | |
| 63 | ############################################################################### |
| 64 | # Plugins |
| 65 | ############################################################################### |
| 66 | |
| 67 | # Please keep alphabetical order |
| 68 | PLUGIN_ENABLED(abf) |
| 69 | PLUGIN_ENABLED(acl) |
| 70 | PLUGIN_ENABLED(avf) |
| 71 | PLUGIN_ENABLED(cdp) |
| 72 | PLUGIN_ENABLED(dpdk) |
| 73 | PLUGIN_ENABLED(flowprobe) |
| 74 | |
| 75 | |
| 76 | Using a text editor such as *vi*, now add the following entry to the plugins section in *vpp/src/plugins/Makefile.am* |
| 77 | |
| 78 | .. code-block:: console |
| 79 | |
| 80 | if ENABLE_SAMPLE_PLUGIN |
| 81 | include sample.am |
| 82 | endif |
| 83 | |
| 84 | For reference, the plugins section of that file looks something like this: |
| 85 | |
| 86 | .. code-block:: console |
| 87 | |
| 88 | vppapitestpluginsdir = ${libdir}/vpp_api_test_plugins |
| 89 | vpppluginsdir = ${libdir}/vpp_plugins |
| 90 | |
| 91 | if ENABLE_ABF_PLUGIN |
| 92 | include abf.am |
| 93 | endif |
| 94 | |
| 95 | if ENABLE_ACL_PLUGIN |
| 96 | include acl.am |
| 97 | endif |
| 98 | |
| 99 | if ENABLE_AVF_PLUGIN |
| 100 | include avf.am |
| 101 | endif |
| 102 | |
| 103 | Building and Running |
| 104 | ____________________ |
| 105 | |
| 106 | |
| 107 | Build VPP by using the main Makefile found in */vpp/Makefile* |
| 108 | |
| 109 | .. code-block:: console |
| 110 | |
| 111 | $ make build |
| 112 | |
| 113 | .. note:: |
| 114 | |
| 115 | If you want to have a fresh debug build and compile every VPP file from scratch, you can wipe all compiled files and build VPP with: |
| 116 | |
| 117 | .. code-block:: console |
| 118 | |
| 119 | $ make rebuild |
| 120 | |
| 121 | However this will take much longer than just running *make build* |
| 122 | |
| 123 | Run VPP and make sure the plugin is loaded. Below is the command for running the VPP debug binary, accompanied with sample output. |
| 124 | |
| 125 | .. code-block:: console |
| 126 | |
| 127 | $ make run |
| 128 | vlib_plugin_early_init:361: plugin path /vpp/build-root/install-vpp_debug-native/vpp/lib/vpp_plugins:/vpp/build-root/install-vpp_debug-native/vpp/lib64/vpp_plugins |
| 129 | load_one_plugin:189: Loaded plugin: abf_plugin.so (ACL based Forwarding) |
| 130 | load_one_plugin:189: Loaded plugin: acl_plugin.so (Access Control Lists) |
| 131 | load_one_plugin:189: Loaded plugin: avf_plugin.so (Intel Adaptive Virtual Function (AVF) Device Plugin) |
| 132 | load_one_plugin:191: Loaded plugin: cdp_plugin.so |
| 133 | ... |
| 134 | load_one_plugin:189: Loaded plugin: sample_plugin.so (Sample of VPP Plugin) |
| 135 | ... |
| 136 | load_one_vat_plugin:67: Loaded plugin: avf_test_plugin.so |
| 137 | load_one_vat_plugin:67: Loaded plugin: mactime_test_plugin.so |
| 138 | load_one_vat_plugin:67: Loaded plugin: sample_test_plugin.so |
| 139 | ... |
| 140 | _______ _ _ _____ ___ |
| 141 | __/ __/ _ \ (_)__ | | / / _ \/ _ \ |
| 142 | _/ _// // / / / _ \ | |/ / ___/ ___/ |
| 143 | /_/ /____(_)_/\___/ |___/_/ /_/ |
| 144 | |
| 145 | DBGvpp# |
| 146 | |
| 147 | .. note:: |
| 148 | |
| 149 | Notice when running the debug build that (\*_test_plugin.so) is also loaded, which is meant for testing your plugin. |
| 150 | |
| 151 | To enable the sample plugin, use this command: |
| 152 | |
| 153 | .. code-block:: console |
| 154 | |
| 155 | DBGvpp# sample macswap <interface name> |
| 156 | |
| 157 | To disable the sample plugin, use this command: |
| 158 | |
| 159 | .. code-block:: console |
| 160 | |
| 161 | DBGvpp# sample macswap <interface name> disable |
| 162 | |
| 163 | |
| 164 | Great! Now you've successfully added your plugin as a VPP node. |
| 165 | |
| 166 | |
| 167 | Additional remarks |
| 168 | __________________ |
| 169 | |
| 170 | How the build process works for plugins is that the (\*.api) plugin file is automatically translated to a JSON file (\*.api.json) in *vpp/build-root/install-vpp_debug-native/vpp/share/vpp/api/plugins*, which the code generator then parses and generates a C header file (\*.api.h) in *vpp/build-root/install-vpp_debug-native/vpp/include/vpp_plugins/\**. |
| 171 | |
| 172 | After the build process is completed you finally end up with two plugin files (\*_plugin.so and \*_test_plugin.so) found in *vpp/build-root/install-vpp_debug-native/vpp/lib64/vpp_plugins* and *vpp/build-root/install-vpp_debug-native/vpp/lib64/vpp_api_test_plugins* respectively, that are loaded at runtime during a debug binary run of VPP (*make run*). |
| 173 | |