FD.io VPP  v18.01.1-37-g7ea3975
Vector Packet Processing
cli.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2016 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 #include <stdint.h>
18 #include <net/if.h>
19 #include <sys/ioctl.h>
20 #include <inttypes.h>
21 
22 #include <vlib/vlib.h>
23 #include <vlib/unix/unix.h>
24 #include <vnet/ethernet/ethernet.h>
25 
26 #include <memif/memif.h>
27 #include <memif/private.h>
28 
29 static clib_error_t *
31  vlib_cli_command_t * cmd)
32 {
33  unformat_input_t _line_input, *line_input = &_line_input;
34  int r;
35  u32 ring_size = MEMIF_DEFAULT_RING_SIZE;
36  memif_create_if_args_t args = { 0 };
38  u32 rx_queues = MEMIF_DEFAULT_RX_QUEUES;
39  u32 tx_queues = MEMIF_DEFAULT_TX_QUEUES;
40 
41  /* Get a line of input. */
42  if (!unformat_user (input, unformat_line_input, line_input))
43  return 0;
44 
45  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
46  {
47  if (unformat (line_input, "id %u", &args.id))
48  ;
49  else if (unformat (line_input, "socket %s", &args.socket_filename))
50  ;
51  else if (unformat (line_input, "secret %s", &args.secret))
52  ;
53  else if (unformat (line_input, "ring-size %u", &ring_size))
54  ;
55  else if (unformat (line_input, "rx-queues %u", &rx_queues))
56  ;
57  else if (unformat (line_input, "tx-queues %u", &tx_queues))
58  ;
59  else if (unformat (line_input, "buffer-size %u", &args.buffer_size))
60  ;
61  else if (unformat (line_input, "master"))
62  args.is_master = 1;
63  else if (unformat (line_input, "slave"))
64  args.is_master = 0;
65  else if (unformat (line_input, "mode ip"))
67  else if (unformat (line_input, "hw-addr %U",
69  args.hw_addr_set = 1;
70  else
71  return clib_error_return (0, "unknown input `%U'",
72  format_unformat_error, input);
73  }
74  unformat_free (line_input);
75 
76  if (!is_pow2 (ring_size))
77  return clib_error_return (0, "ring size must be power of 2");
78 
79  if (ring_size > 32768)
80  return clib_error_return (0, "maximum ring size is 32768");
81 
82  args.log2_ring_size = min_log2 (ring_size);
83 
84  if (rx_queues > 255 || rx_queues < 1)
85  return clib_error_return (0, "rx queue must be between 1 - 255");
86  if (tx_queues > 255 || tx_queues < 1)
87  return clib_error_return (0, "tx queue must be between 1 - 255");
88 
89  args.rx_queues = rx_queues;
90  args.tx_queues = tx_queues;
91 
92  r = memif_create_if (vm, &args);
93 
95  vec_free (args.secret);
96 
97  if (r <= VNET_API_ERROR_SYSCALL_ERROR_1
98  && r >= VNET_API_ERROR_SYSCALL_ERROR_10)
99  return clib_error_return (0, "%s (errno %d)", strerror (errno), errno);
100 
101  if (r == VNET_API_ERROR_INVALID_INTERFACE)
102  return clib_error_return (0, "Invalid interface name");
103 
104  if (r == VNET_API_ERROR_SUBIF_ALREADY_EXISTS)
105  return clib_error_return (0, "Interface with same id already exists");
106 
107  return 0;
108 }
109 
110 /* *INDENT-OFF* */
111 VLIB_CLI_COMMAND (memif_create_command, static) = {
112  .path = "create memif",
113  .short_help = "create memif [id <id>] [socket <path>] "
114  "[ring-size <size>] [buffer-size <size>] [hw-addr <mac-address>] "
115  "<master|slave> [rx-queues <number>] [tx-queues <number>] "
116  "[mode ip] [secret <string>]",
117  .function = memif_create_command_fn,
118 };
119 /* *INDENT-ON* */
120 
121 static clib_error_t *
123  vlib_cli_command_t * cmd)
124 {
125  unformat_input_t _line_input, *line_input = &_line_input;
126  u32 sw_if_index = ~0;
128  memif_main_t *mm = &memif_main;
129  memif_if_t *mif;
130  vnet_main_t *vnm = vnet_get_main ();
131 
132  /* Get a line of input. */
133  if (!unformat_user (input, unformat_line_input, line_input))
134  return 0;
135 
136  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
137  {
138  if (unformat (line_input, "sw_if_index %d", &sw_if_index))
139  ;
140  else if (unformat (line_input, "%U", unformat_vnet_sw_interface,
141  vnm, &sw_if_index))
142  ;
143  else
144  return clib_error_return (0, "unknown input `%U'",
145  format_unformat_error, input);
146  }
147  unformat_free (line_input);
148 
149  if (sw_if_index == ~0)
150  return clib_error_return (0,
151  "please specify interface name or sw_if_index");
152 
153  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
154  if (hw == NULL || memif_device_class.index != hw->dev_class_index)
155  return clib_error_return (0, "not a memif interface");
156 
157  mif = pool_elt_at_index (mm->interfaces, hw->dev_instance);
158  memif_delete_if (vm, mif);
159 
160  return 0;
161 }
162 
163 /* *INDENT-OFF* */
164 VLIB_CLI_COMMAND (memif_delete_command, static) = {
165  .path = "delete memif",
166  .short_help = "delete memif {<interface> | sw_if_index <sw_idx>}",
167  .function = memif_delete_command_fn,
168 };
169 /* *INDENT-ON* */
170 
171 static u8 *
172 format_memif_if_flags (u8 * s, va_list * args)
173 {
174  u32 flags = va_arg (*args, u32);
175 #define _(a,b,c) if ( flags & (1 << a)) s = format (s, " %s", c);
177 #undef _
178  return s;
179 }
180 
181 static u8 *
182 format_memif_if_mode (u8 * s, va_list * args)
183 {
184  memif_if_t *mif = va_arg (*args, memif_if_t *);
186  return format (s, "ethernet");
187  if (mif->mode == MEMIF_INTERFACE_MODE_IP)
188  return format (s, "ip");
190  return format (s, "punt-inject");
191  return format (s, "unknown mode (%u)", mif->mode);;
192 }
193 
194 static u8 *
195 format_memif_queue (u8 * s, va_list * args)
196 {
197  memif_queue_t *mq = va_arg (*args, memif_queue_t *);
198  uword i = va_arg (*args, uword);
199  u32 indent = format_get_indent (s);
200 
201  s = format (s, "%U%s ring %u:\n",
202  format_white_space, indent,
203  (mq->type == MEMIF_RING_S2M) ?
204  "slave-to-master" : "master-to-slave", i);
205  s = format (s, "%Uregion %u offset %u ring-size %u int-fd %d\n",
206  format_white_space, indent + 4,
207  mq->region, mq->offset, (1 << mq->log2_ring_size), mq->int_fd);
208 
209  if (mq->ring)
210  s = format (s, "%Uhead %u tail %u flags 0x%04x interrupts %u\n",
211  format_white_space, indent + 4,
212  mq->ring->head, mq->ring->tail, mq->ring->flags,
213  mq->int_count);
214 
215  return s;
216 }
217 
218 static u8 *
219 format_memif_descriptor (u8 * s, va_list * args)
220 {
221  memif_if_t *mif = va_arg (*args, memif_if_t *);
222  memif_queue_t *mq = va_arg (*args, memif_queue_t *);
223  u32 indent = format_get_indent (s);
224  memif_ring_t *ring;
225  u16 ring_size;
226  u16 slot;
227 
228  ring_size = 1 << mq->log2_ring_size;
229  ring = mq->ring;
230  if (ring)
231  {
232  s = format (s, "%Udescriptor table:\n", format_white_space, indent);
233  s =
234  format (s,
235  "%Uid flags buf len desc len address offset user address\n",
236  format_white_space, indent);
237  s =
238  format (s,
239  "%U===== ===== ======= ======== ================== ====== ==================\n",
240  format_white_space, indent);
241  for (slot = 0; slot < ring_size; slot++)
242  {
243  s = format (s, "%U%-5d %-5d %-7d %-7d 0x%016lx %-6d 0x%016lx\n",
244  format_white_space, indent, slot,
245  ring->desc[slot].flags, ring->desc[slot].buffer_length,
246  ring->desc[slot].length,
247  mif->regions[ring->desc[slot].region].shm,
248  ring->desc[slot].offset, memif_get_buffer (mif, ring,
249  slot));
250  }
251  s = format (s, "\n");
252  }
253 
254  return s;
255 }
256 
257 static clib_error_t *
259  vlib_cli_command_t * cmd)
260 {
261  memif_main_t *mm = &memif_main;
262  memif_if_t *mif;
263  vnet_main_t *vnm = vnet_get_main ();
264  memif_queue_t *mq;
265  uword i;
266  int show_descr = 0;
267  clib_error_t *error = 0;
268  u32 hw_if_index, *hw_if_indices = 0;
269 
271  {
272  if (unformat
273  (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
274  vec_add1 (hw_if_indices, hw_if_index);
275  else if (unformat (input, "descriptors"))
276  show_descr = 1;
277  else
278  {
279  error = clib_error_return (0, "unknown input `%U'",
280  format_unformat_error, input);
281  goto done;
282  }
283  }
284 
285  if (vec_len (hw_if_indices) == 0)
286  {
287  /* *INDENT-OFF* */
288  pool_foreach (mif, mm->interfaces,
289  vec_add1 (hw_if_indices, mif->hw_if_index);
290  );
291  /* *INDENT-ON* */
292  }
293 
294  for (hw_if_index = 0; hw_if_index < vec_len (hw_if_indices); hw_if_index++)
295  {
297  vnet_get_hw_interface (vnm, hw_if_indices[hw_if_index]);
298  mif = pool_elt_at_index (mm->interfaces, hi->dev_instance);
300  mif->socket_file_index);
301  vlib_cli_output (vm, "interface %U", format_vnet_sw_if_index_name,
302  vnm, mif->sw_if_index);
303  if (mif->remote_name)
304  vlib_cli_output (vm, " remote-name \"%s\"", mif->remote_name);
305  if (mif->remote_if_name)
306  vlib_cli_output (vm, " remote-interface \"%s\"",
307  mif->remote_if_name);
308  vlib_cli_output (vm, " id %d mode %U file %s", mif->id,
309  format_memif_if_mode, mif, msf->filename);
310  vlib_cli_output (vm, " flags%U", format_memif_if_flags, mif->flags);
311  vlib_cli_output (vm, " listener-fd %d conn-fd %d",
312  msf->sock ? msf->sock->fd : 0,
313  mif->sock ? mif->sock->fd : 0);
314  vlib_cli_output (vm,
315  " num-s2m-rings %u num-m2s-rings %u buffer-size %u",
316  mif->run.num_s2m_rings, mif->run.num_m2s_rings,
317  mif->run.buffer_size);
318 
319  if (mif->local_disc_string)
320  vlib_cli_output (vm, " local-disc-reason \"%s\"",
321  mif->local_disc_string);
322  if (mif->remote_disc_string)
323  vlib_cli_output (vm, " remote-disc-reason \"%s\"",
324  mif->remote_disc_string);
325 
326  vec_foreach_index (i, mif->tx_queues)
327  {
328  mq = vec_elt_at_index (mif->tx_queues, i);
329  vlib_cli_output (vm, " %U", format_memif_queue, mq, i);
330  if (show_descr)
331  vlib_cli_output (vm, " %U", format_memif_descriptor, mif, mq);
332  }
333  vec_foreach_index (i, mif->rx_queues)
334  {
335  mq = vec_elt_at_index (mif->rx_queues, i);
336  vlib_cli_output (vm, " %U", format_memif_queue, mq, i);
337  if (show_descr)
338  vlib_cli_output (vm, " %U", format_memif_descriptor, mif, mq);
339  }
340  }
341 done:
342  vec_free (hw_if_indices);
343  return error;
344 }
345 
346 /* *INDENT-OFF* */
347 VLIB_CLI_COMMAND (memif_show_command, static) = {
348  .path = "show memif",
349  .short_help = "show memif {<interface>] [descriptors]",
350  .function = memif_show_command_fn,
351 };
352 /* *INDENT-ON* */
353 
354 clib_error_t *
356 {
357  return 0;
358 }
359 
361 
362 /*
363  * fd.io coding-style-patch-verification: ON
364  *
365  * Local Variables:
366  * eval: (c-set-style "gnu")
367  * End:
368  */
memif_if_t * interfaces
Definition: private.h:184
unformat_function_t unformat_vnet_hw_interface
vmrglw vmrglh hi
#define vec_foreach_index(var, v)
Iterate over vector indices.
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
memif_socket_file_t * socket_files
Definition: private.h:187
#define NULL
Definition: clib.h:55
struct memif_if_t::@366 run
static clib_error_t * memif_create_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:30
static u8 * format_memif_if_flags(u8 *s, va_list *args)
Definition: cli.c:172
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:518
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
static u32 format_get_indent(u8 *s)
Definition: format.h:72
memif_interface_mode_t mode
Definition: private.h:211
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
unformat_function_t unformat_vnet_sw_interface
u8 num_m2s_rings
Definition: private.h:159
format_function_t format_vnet_sw_if_index_name
static uword min_log2(uword x)
Definition: clib.h:197
uint32_t length
Definition: memif.h:152
uint32_t buffer_length
Definition: memif.h:151
u8 * remote_name
Definition: private.h:152
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:438
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
uword socket_file_index
Definition: private.h:142
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
u16 buffer_size
Definition: private.h:160
memif_log2_ring_size_t log2_ring_size
Definition: private.h:212
uint16_t flags
Definition: memif.h:148
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
vnet_device_class_t memif_device_class
#define clib_error_return(e, args...)
Definition: error.h:99
memif_region_offset_t offset
Definition: private.h:99
unformat_function_t unformat_line_input
Definition: format.h:281
memif_region_index_t region
Definition: memif.h:150
static clib_error_t * memif_delete_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:122
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:459
memif_desc_t desc[0]
Definition: memif.h:174
static clib_error_t * memif_show_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: cli.c:258
int memif_delete_if(vlib_main_t *vm, memif_if_t *mif)
Definition: memif.c:468
struct _unformat_input_t unformat_input_t
memif_interface_id_t id
Definition: private.h:207
int memif_create_if(vlib_main_t *vm, memif_create_if_args_t *args)
Definition: memif.c:548
#define MEMIF_DEFAULT_TX_QUEUES
Definition: private.h:23
memif_queue_t * tx_queues
Definition: private.h:149
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
vlib_main_t * vm
Definition: buffer.c:283
u8 * local_disc_string
Definition: private.h:172
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
static u8 * format_memif_if_mode(u8 *s, va_list *args)
Definition: cli.c:182
#define MEMIF_DEFAULT_BUFFER_SIZE
Definition: private.h:24
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
memif_ring_type_t type
Definition: private.h:110
memif_region_t * regions
Definition: private.h:146
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
Definition: format.c:227
unsigned int u32
Definition: types.h:88
static_always_inline void * memif_get_buffer(memif_if_t *mif, memif_ring_t *ring, u16 slot)
Definition: private.h:228
u32 flags
Definition: private.h:131
memif_ring_t * ring
Definition: private.h:96
#define MEMIF_DEFAULT_RX_QUEUES
Definition: private.h:22
u32 hw_if_index
Definition: private.h:133
u64 int_count
Definition: private.h:107
static uword is_pow2(uword x)
Definition: clib.h:280
u64 uword
Definition: types.h:112
memif_region_offset_t offset
Definition: memif.h:154
u8 num_s2m_rings
Definition: private.h:158
unsigned short u16
Definition: types.h:57
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
clib_error_t * memif_cli_init(vlib_main_t *vm)
Definition: cli.c:355
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
void * shm
Definition: private.h:82
u8 * remote_if_name
Definition: private.h:153
memif_interface_id_t id
Definition: private.h:132
memif_log2_ring_size_t log2_ring_size
Definition: private.h:97
static u8 * format_memif_descriptor(u8 *s, va_list *args)
Definition: cli.c:219
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
#define MEMIF_DEFAULT_RING_SIZE
Definition: private.h:21
uint16_t flags
Definition: memif.h:168
u8 * remote_disc_string
Definition: private.h:173
volatile uint16_t head
Definition: memif.h:170
clib_socket_t * sock
Definition: private.h:141
memif_queue_t * rx_queues
Definition: private.h:148
static u8 * format_memif_queue(u8 *s, va_list *args)
Definition: cli.c:195
u32 flags
Definition: vhost-user.h:77
memif_main_t memif_main
Definition: memif.c:43
memif_region_index_t region
Definition: private.h:98
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
clib_socket_t * sock
Definition: private.h:68
u32 sw_if_index
Definition: private.h:134
volatile uint16_t tail
Definition: memif.h:172
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
memif_interface_mode_t mode
Definition: private.h:136
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169