FD.io VPP  v18.07.1-19-g511ce25
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 
67 
68 /**
69  * @brief Enable/disable the macswap plugin.
70  *
71  * Action function shared between message handler and debug CLI.
72  */
73 
75  int enable_disable)
76 {
78  int rv = 0;
79 
80  /* Utterly wrong? */
82  sw_if_index))
83  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
84 
85  /* Not a physical port? */
86  sw = vnet_get_sw_interface (sm->vnet_main, sw_if_index);
88  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
89 
90  vnet_feature_enable_disable ("device-input", "sample",
91  sw_if_index, enable_disable, 0, 0);
92 
93  return rv;
94 }
95 
96 static clib_error_t *
98  unformat_input_t * input,
99  vlib_cli_command_t * cmd)
100 {
101  sample_main_t * sm = &sample_main;
102  u32 sw_if_index = ~0;
103  int enable_disable = 1;
104 
105  int rv;
106 
107  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
108  if (unformat (input, "disable"))
109  enable_disable = 0;
110  else if (unformat (input, "%U", unformat_vnet_sw_interface,
111  sm->vnet_main, &sw_if_index))
112  ;
113  else
114  break;
115  }
116 
117  if (sw_if_index == ~0)
118  return clib_error_return (0, "Please specify an interface...");
119 
120  rv = sample_macswap_enable_disable (sm, sw_if_index, enable_disable);
121 
122  switch(rv) {
123  case 0:
124  break;
125 
126  case VNET_API_ERROR_INVALID_SW_IF_INDEX:
127  return clib_error_return
128  (0, "Invalid interface, only works on physical ports");
129  break;
130 
131  case VNET_API_ERROR_UNIMPLEMENTED:
132  return clib_error_return (0, "Device driver doesn't support redirection");
133  break;
134 
135  default:
136  return clib_error_return (0, "sample_macswap_enable_disable returned %d",
137  rv);
138  }
139  return 0;
140 }
141 
142 /**
143  * @brief CLI command to enable/disable the sample macswap plugin.
144  */
145 VLIB_CLI_COMMAND (sr_content_command, static) = {
146  .path = "sample macswap",
147  .short_help =
148  "sample macswap <interface-name> [disable]",
150 };
151 
152 /**
153  * @brief Plugin API message handler.
154  */
157 {
158  vl_api_sample_macswap_enable_disable_reply_t * rmp;
159  sample_main_t * sm = &sample_main;
160  int rv;
161 
162  rv = sample_macswap_enable_disable (sm, ntohl(mp->sw_if_index),
163  (int) (mp->enable_disable));
164 
165  REPLY_MACRO(VL_API_SAMPLE_MACSWAP_ENABLE_DISABLE_REPLY);
166 }
167 
168 /**
169  * @brief Set up the API message handling tables.
170  */
171 static clib_error_t *
173 {
174  sample_main_t * sm = &sample_main;
175 #define _(N,n) \
176  vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
177  #n, \
178  vl_api_##n##_t_handler, \
179  vl_noop_handler, \
180  vl_api_##n##_t_endian, \
181  vl_api_##n##_t_print, \
182  sizeof(vl_api_##n##_t), 1);
184 #undef _
185 
186  return 0;
187 }
188 
189 #define vl_msg_name_crc_list
190 #include <sample/sample_all_api_h.h>
191 #undef vl_msg_name_crc_list
192 
193 static void
195 {
196 #define _(id,n,crc) \
197  vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base);
198  foreach_vl_msg_name_crc_sample;
199 #undef _
200 }
201 
202 /**
203  * @brief Initialize the sample plugin.
204  */
206 {
207  sample_main_t * sm = &sample_main;
208  clib_error_t * error = 0;
209  u8 * name;
210 
211  sm->vnet_main = vnet_get_main ();
212 
213  name = format (0, "sample_%08x%c", api_version, 0);
214 
215  /* Ask for a correctly-sized block of API message decode slots */
217  ((char *) name, VL_MSG_FIRST_AVAILABLE);
218 
219  error = sample_plugin_api_hookup (vm);
220 
221  /* Add our API messages to the global name_crc hash table */
223 
224  vec_free(name);
225 
226  return error;
227 }
228 
230 
231 /**
232  * @brief Hook the sample plugin into the VPP graph hierarchy.
233  */
234 VNET_FEATURE_INIT (sample, static) =
235 {
236  .arc_name = "device-input",
237  .node_name = "sample",
238  .runs_before = VNET_FEATURES ("ethernet-input"),
239 };
sample_main_t sample_main
Definition: sample.c:66
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:156
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
unsigned char u8
Definition: types.h:56
#define SAMPLE_PLUGIN_BUILD_VER
Definition: sample.h:38
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:156
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
VLIB_PLUGIN_REGISTER()
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:201
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
vlib_main_t * vm
Definition: buffer.c:294
int sample_macswap_enable_disable(sample_main_t *sm, u32 sw_if_index, int enable_disable)
Enable/disable the macswap plugin.
Definition: sample.c:74
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:271
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:194
static clib_error_t * sample_init(vlib_main_t *vm)
Initialize the sample plugin.
Definition: sample.c:205
#define VNET_FEATURES(...)
Definition: feature.h:391
static clib_error_t * sample_plugin_api_hookup(vlib_main_t *vm)
Set up the API message handling tables.
Definition: sample.c:172
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:802
VNET_FEATURE_INIT(sample, static)
Hook the sample plugin into the VPP graph hierarchy.
vnet_sw_interface_type_t type
Definition: interface.h:656
api_main_t api_main
Definition: api_shared.c:35
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:97
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:233
#define foreach_sample_plugin_api_msg
Definition: sample.c:56
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:872