FD.io VPP  v18.01-8-g0eacf49
Vector Packet Processing
sample.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /**
16  * @file
17  * @brief Sample Plugin, plugin API / trace / CLI handling.
18  */
19 
20 #include <vnet/vnet.h>
21 #include <vnet/plugin/plugin.h>
22 #include <sample/sample.h>
23 
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 
27 /* define message IDs */
28 #include <sample/sample_msg_enum.h>
29 
30 /* define message structures */
31 #define vl_typedefs
32 #include <sample/sample_all_api_h.h>
33 #undef vl_typedefs
34 
35 /* define generated endian-swappers */
36 #define vl_endianfun
37 #include <sample/sample_all_api_h.h>
38 #undef vl_endianfun
39 
40 /* instantiate all the print functions we know about */
41 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
42 #define vl_printfun
43 #include <sample/sample_all_api_h.h>
44 #undef vl_printfun
45 
46 /* Get the API version number */
47 #define vl_api_version(n,v) static u32 api_version=(v);
49 #undef vl_api_version
50 
51 #define REPLY_MSG_ID_BASE sm->msg_id_base
53 
54 /* List of message types that this plugin understands */
55 
56 #define foreach_sample_plugin_api_msg \
57 _(SAMPLE_MACSWAP_ENABLE_DISABLE, sample_macswap_enable_disable)
58 
59 /* *INDENT-OFF* */
61  .version = SAMPLE_PLUGIN_BUILD_VER,
62  .description = "Sample of VPP Plugin",
63 };
64 /* *INDENT-ON* */
65 
66 /**
67  * @brief Enable/disable the macswap plugin.
68  *
69  * Action function shared between message handler and debug CLI.
70  */
71 
73  int enable_disable)
74 {
76  int rv = 0;
77 
78  /* Utterly wrong? */
80  sw_if_index))
81  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
82 
83  /* Not a physical port? */
84  sw = vnet_get_sw_interface (sm->vnet_main, sw_if_index);
86  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
87 
88  vnet_feature_enable_disable ("device-input", "sample",
89  sw_if_index, enable_disable, 0, 0);
90 
91  return rv;
92 }
93 
94 static clib_error_t *
96  unformat_input_t * input,
97  vlib_cli_command_t * cmd)
98 {
99  sample_main_t * sm = &sample_main;
100  u32 sw_if_index = ~0;
101  int enable_disable = 1;
102 
103  int rv;
104 
105  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
106  if (unformat (input, "disable"))
107  enable_disable = 0;
108  else if (unformat (input, "%U", unformat_vnet_sw_interface,
109  sm->vnet_main, &sw_if_index))
110  ;
111  else
112  break;
113  }
114 
115  if (sw_if_index == ~0)
116  return clib_error_return (0, "Please specify an interface...");
117 
118  rv = sample_macswap_enable_disable (sm, sw_if_index, enable_disable);
119 
120  switch(rv) {
121  case 0:
122  break;
123 
124  case VNET_API_ERROR_INVALID_SW_IF_INDEX:
125  return clib_error_return
126  (0, "Invalid interface, only works on physical ports");
127  break;
128 
129  case VNET_API_ERROR_UNIMPLEMENTED:
130  return clib_error_return (0, "Device driver doesn't support redirection");
131  break;
132 
133  default:
134  return clib_error_return (0, "sample_macswap_enable_disable returned %d",
135  rv);
136  }
137  return 0;
138 }
139 
140 /**
141  * @brief CLI command to enable/disable the sample macswap plugin.
142  */
143 VLIB_CLI_COMMAND (sr_content_command, static) = {
144  .path = "sample macswap",
145  .short_help =
146  "sample macswap <interface-name> [disable]",
148 };
149 
150 /**
151  * @brief Plugin API message handler.
152  */
155 {
156  vl_api_sample_macswap_enable_disable_reply_t * rmp;
157  sample_main_t * sm = &sample_main;
158  int rv;
159 
160  rv = sample_macswap_enable_disable (sm, ntohl(mp->sw_if_index),
161  (int) (mp->enable_disable));
162 
163  REPLY_MACRO(VL_API_SAMPLE_MACSWAP_ENABLE_DISABLE_REPLY);
164 }
165 
166 /**
167  * @brief Set up the API message handling tables.
168  */
169 static clib_error_t *
171 {
172  sample_main_t * sm = &sample_main;
173 #define _(N,n) \
174  vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
175  #n, \
176  vl_api_##n##_t_handler, \
177  vl_noop_handler, \
178  vl_api_##n##_t_endian, \
179  vl_api_##n##_t_print, \
180  sizeof(vl_api_##n##_t), 1);
182 #undef _
183 
184  return 0;
185 }
186 
187 #define vl_msg_name_crc_list
188 #include <sample/sample_all_api_h.h>
189 #undef vl_msg_name_crc_list
190 
191 static void
193 {
194 #define _(id,n,crc) \
195  vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base);
196  foreach_vl_msg_name_crc_sample;
197 #undef _
198 }
199 
200 /**
201  * @brief Initialize the sample plugin.
202  */
204 {
205  sample_main_t * sm = &sample_main;
206  clib_error_t * error = 0;
207  u8 * name;
208 
209  sm->vnet_main = vnet_get_main ();
210 
211  name = format (0, "sample_%08x%c", api_version, 0);
212 
213  /* Ask for a correctly-sized block of API message decode slots */
215  ((char *) name, VL_MSG_FIRST_AVAILABLE);
216 
217  error = sample_plugin_api_hookup (vm);
218 
219  /* Add our API messages to the global name_crc hash table */
221 
222  vec_free(name);
223 
224  return error;
225 }
226 
228 
229 /**
230  * @brief Hook the sample plugin into the VPP graph hierarchy.
231  */
232 VNET_FEATURE_INIT (sample, static) =
233 {
234  .arc_name = "device-input",
235  .node_name = "sample",
236  .runs_before = VNET_FEATURES ("ethernet-input"),
237 };
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:872
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
vnet_interface_main_t interface_main
Definition: vnet.h:56
static void vl_api_sample_macswap_enable_disable_t_handler(vl_api_sample_macswap_enable_disable_t *mp)
Plugin API message handler.
Definition: sample.c:154
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
unformat_function_t unformat_vnet_sw_interface
#define SAMPLE_PLUGIN_BUILD_VER
Definition: sample.h:38
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
#define clib_error_return(e, args...)
Definition: error.h:99
VLIB_PLUGIN_REGISTER()
sample_main_t sample_main
struct _unformat_input_t unformat_input_t
#define REPLY_MACRO(t)
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:198
api_main_t api_main
Definition: api_shared.c:35
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
vlib_main_t * vm
Definition: buffer.c:283
int sample_macswap_enable_disable(sample_main_t *sm, u32 sw_if_index, int enable_disable)
Enable/disable the macswap plugin.
Definition: sample.c:72
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:268
vnet_main_t * vnet_main
Definition: sample.h:31
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
static void setup_message_id_table(sample_main_t *sm, api_main_t *am)
Definition: sample.c:192
unsigned int u32
Definition: types.h:88
static clib_error_t * sample_init(vlib_main_t *vm)
Initialize the sample plugin.
Definition: sample.c:203
#define VNET_FEATURES(...)
Definition: feature.h:368
static clib_error_t * sample_plugin_api_hookup(vlib_main_t *vm)
Set up the API message handling tables.
Definition: sample.c:170
unsigned char u8
Definition: types.h:56
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:663
VNET_FEATURE_INIT(sample, static)
Hook the sample plugin into the VPP graph hierarchy.
vnet_sw_interface_type_t type
Definition: interface.h:571
static clib_error_t * macswap_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: sample.c:95
u16 msg_id_base
Definition: sample.h:28
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:229
#define foreach_sample_plugin_api_msg
Definition: sample.c:56
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169