FD.io VPP  v17.07-30-g839fa73
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 #include <vlibsocket/api.h>
27 
28 /* define message IDs */
29 #include <sample/sample_msg_enum.h>
30 
31 /* define message structures */
32 #define vl_typedefs
33 #include <sample/sample_all_api_h.h>
34 #undef vl_typedefs
35 
36 /* define generated endian-swappers */
37 #define vl_endianfun
38 #include <sample/sample_all_api_h.h>
39 #undef vl_endianfun
40 
41 /* instantiate all the print functions we know about */
42 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
43 #define vl_printfun
44 #include <sample/sample_all_api_h.h>
45 #undef vl_printfun
46 
47 /* Get the API version number */
48 #define vl_api_version(n,v) static u32 api_version=(v);
50 #undef vl_api_version
51 
52 #define REPLY_MSG_ID_BASE sm->msg_id_base
54 
55 /* List of message types that this plugin understands */
56 
57 #define foreach_sample_plugin_api_msg \
58 _(SAMPLE_MACSWAP_ENABLE_DISABLE, sample_macswap_enable_disable)
59 
60 /* *INDENT-OFF* */
62  .version = SAMPLE_PLUGIN_BUILD_VER,
63  .description = "Sample of VPP Plugin",
64 };
65 /* *INDENT-ON* */
66 
67 /**
68  * @brief Enable/disable the macswap plugin.
69  *
70  * Action function shared between message handler and debug CLI.
71  */
72 
74  int enable_disable)
75 {
77  int rv = 0;
78 
79  /* Utterly wrong? */
81  sw_if_index))
82  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
83 
84  /* Not a physical port? */
85  sw = vnet_get_sw_interface (sm->vnet_main, sw_if_index);
87  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
88 
89  vnet_feature_enable_disable ("device-input", "sample",
90  sw_if_index, enable_disable, 0, 0);
91 
92  return rv;
93 }
94 
95 static clib_error_t *
97  unformat_input_t * input,
98  vlib_cli_command_t * cmd)
99 {
100  sample_main_t * sm = &sample_main;
101  u32 sw_if_index = ~0;
102  int enable_disable = 1;
103 
104  int rv;
105 
106  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
107  if (unformat (input, "disable"))
108  enable_disable = 0;
109  else if (unformat (input, "%U", unformat_vnet_sw_interface,
110  sm->vnet_main, &sw_if_index))
111  ;
112  else
113  break;
114  }
115 
116  if (sw_if_index == ~0)
117  return clib_error_return (0, "Please specify an interface...");
118 
119  rv = sample_macswap_enable_disable (sm, sw_if_index, enable_disable);
120 
121  switch(rv) {
122  case 0:
123  break;
124 
125  case VNET_API_ERROR_INVALID_SW_IF_INDEX:
126  return clib_error_return
127  (0, "Invalid interface, only works on physical ports");
128  break;
129 
130  case VNET_API_ERROR_UNIMPLEMENTED:
131  return clib_error_return (0, "Device driver doesn't support redirection");
132  break;
133 
134  default:
135  return clib_error_return (0, "sample_macswap_enable_disable returned %d",
136  rv);
137  }
138  return 0;
139 }
140 
141 /**
142  * @brief CLI command to enable/disable the sample macswap plugin.
143  */
144 VLIB_CLI_COMMAND (sr_content_command, static) = {
145  .path = "sample macswap",
146  .short_help =
147  "sample macswap <interface-name> [disable]",
149 };
150 
151 /**
152  * @brief Plugin API message handler.
153  */
156 {
157  vl_api_sample_macswap_enable_disable_reply_t * rmp;
158  sample_main_t * sm = &sample_main;
159  int rv;
160 
161  rv = sample_macswap_enable_disable (sm, ntohl(mp->sw_if_index),
162  (int) (mp->enable_disable));
163 
164  REPLY_MACRO(VL_API_SAMPLE_MACSWAP_ENABLE_DISABLE_REPLY);
165 }
166 
167 /**
168  * @brief Set up the API message handling tables.
169  */
170 static clib_error_t *
172 {
173  sample_main_t * sm = &sample_main;
174 #define _(N,n) \
175  vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
176  #n, \
177  vl_api_##n##_t_handler, \
178  vl_noop_handler, \
179  vl_api_##n##_t_endian, \
180  vl_api_##n##_t_print, \
181  sizeof(vl_api_##n##_t), 1);
183 #undef _
184 
185  return 0;
186 }
187 
188 #define vl_msg_name_crc_list
189 #include <sample/sample_all_api_h.h>
190 #undef vl_msg_name_crc_list
191 
192 static void
194 {
195 #define _(id,n,crc) \
196  vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base);
197  foreach_vl_msg_name_crc_sample;
198 #undef _
199 }
200 
201 /**
202  * @brief Initialize the sample plugin.
203  */
205 {
206  sample_main_t * sm = &sample_main;
207  clib_error_t * error = 0;
208  u8 * name;
209 
210  sm->vnet_main = vnet_get_main ();
211 
212  name = format (0, "sample_%08x%c", api_version, 0);
213 
214  /* Ask for a correctly-sized block of API message decode slots */
216  ((char *) name, VL_MSG_FIRST_AVAILABLE);
217 
218  error = sample_plugin_api_hookup (vm);
219 
220  /* Add our API messages to the global name_crc hash table */
222 
223  vec_free(name);
224 
225  return error;
226 }
227 
229 
230 /**
231  * @brief Hook the sample plugin into the VPP graph hierarchy.
232  */
233 VNET_FEATURE_INIT (sample, static) =
234 {
235  .arc_name = "device-input",
236  .node_name = "sample",
237  .runs_before = VNET_FEATURES ("ethernet-input"),
238 };
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:837
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
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:155
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
Definition: sample.h:34
struct _unformat_input_t unformat_input_t
#define REPLY_MACRO(t)
api_main_t api_main
Definition: api_shared.c:35
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
int sample_macswap_enable_disable(sample_main_t *sm, u32 sw_if_index, int enable_disable)
Enable/disable the macswap plugin.
Definition: sample.c:73
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:238
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:193
unsigned int u32
Definition: types.h:88
static clib_error_t * sample_init(vlib_main_t *vm)
Initialize the sample plugin.
Definition: sample.c:204
#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:171
unsigned char u8
Definition: types.h:56
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:644
VNET_FEATURE_INIT(sample, static)
Hook the sample plugin into the VPP graph hierarchy.
vnet_sw_interface_type_t type
Definition: interface.h:555
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:96
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:225
#define foreach_sample_plugin_api_msg
Definition: sample.c:57
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169