FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
device.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2018 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 
18 #include <stdio.h>
19 #include <net/if.h>
20 #include <linux/if_link.h>
21 #include <bpf/libbpf.h>
22 #include <vlib/vlib.h>
23 #include <vlib/unix/unix.h>
24 #include <vlib/pci/pci.h>
25 #include <vppinfra/linux/sysfs.h>
26 #include <vppinfra/unix.h>
27 #include <vnet/ethernet/ethernet.h>
29 #include "af_xdp.h"
30 
32 
33 typedef struct
34 {
38 
40 gdb_af_xdp_get_prod (const struct xsk_ring_prod *prod)
41 {
42  gdb_af_xdp_pair_t pair = { *prod->producer, *prod->consumer };
43  return pair;
44 }
45 
47 gdb_af_xdp_get_cons (const struct xsk_ring_cons * cons)
48 {
49  gdb_af_xdp_pair_t pair = { *cons->producer, *cons->consumer };
50  return pair;
51 }
52 
53 static clib_error_t *
54 af_xdp_mac_change (vnet_hw_interface_t * hw, const u8 * old, const u8 * new)
55 {
57  af_xdp_device_t *ad = vec_elt_at_index (am->devices, hw->dev_instance);
58  errno_t err = memcpy_s (ad->hwaddr, sizeof (ad->hwaddr), new, 6);
59  if (err)
61  "mac change failed");
62  return 0;
63 }
64 
65 static u32
67 {
69  af_xdp_device_t *ad = vec_elt_at_index (am->devices, hw->dev_instance);
70 
71  switch (flags)
72  {
73  case 0:
74  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "set unicast not supported yet");
75  return ~0;
77  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad,
78  "set promiscuous not supported yet");
79  return ~0;
81  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "set mtu not supported yet");
82  return ~0;
83  }
84 
85  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "unknown flag %x requested", flags);
86  return ~0;
87 }
88 
89 void
91 {
92  vnet_main_t *vnm = vnet_get_main ();
93  af_xdp_main_t *axm = &af_xdp_main;
94  struct xsk_socket **xsk;
95  struct xsk_umem **umem;
96  int i;
97 
98  if (ad->hw_if_index)
99  {
102  }
103 
104  for (i = 0; i < ad->rxq_num; i++)
105  clib_file_del_by_index (&file_main, vec_elt (ad->rxqs, i).file_index);
106 
107  for (i = 0; i < ad->txq_num; i++)
108  clib_spinlock_free (&vec_elt (ad->txqs, i).lock);
109 
110  vec_foreach (xsk, ad->xsk)
111  xsk_socket__delete (*xsk);
112 
113  vec_foreach (umem, ad->umem)
114  xsk_umem__delete (*umem);
115 
116  if (ad->bpf_obj)
117  {
118  bpf_set_link_xdp_fd (ad->linux_ifindex, -1, 0);
119  bpf_object__unload (ad->bpf_obj);
120  }
121 
122  vec_free (ad->xsk);
123  vec_free (ad->umem);
125  vec_free (ad->rxqs);
126  vec_free (ad->txqs);
127  clib_error_free (ad->error);
128  pool_put (axm->devices, ad);
129 }
130 
131 static int
133 {
134  int fd;
135 
137  if (!ad->linux_ifindex)
138  {
139  args->rv = VNET_API_ERROR_INVALID_VALUE;
140  args->error =
141  clib_error_return_unix (0, "if_nametoindex(%s) failed",
142  ad->linux_ifname);
143  goto err0;
144  }
145 
146  if (bpf_prog_load (args->prog, BPF_PROG_TYPE_XDP, &ad->bpf_obj, &fd))
147  {
148  args->rv = VNET_API_ERROR_SYSCALL_ERROR_5;
149  args->error =
150  clib_error_return_unix (0, "bpf_prog_load(%s) failed", args->prog);
151  goto err0;
152  }
153 
154 #ifndef XDP_FLAGS_REPLACE
155 #define XDP_FLAGS_REPLACE 0
156 #endif
157  if (bpf_set_link_xdp_fd (ad->linux_ifindex, fd, XDP_FLAGS_REPLACE))
158  {
159  args->rv = VNET_API_ERROR_SYSCALL_ERROR_6;
160  args->error =
161  clib_error_return_unix (0, "bpf_set_link_xdp_fd(%s) failed",
162  ad->linux_ifname);
163  goto err1;
164  }
165 
166  return 0;
167 
168 err1:
169  bpf_object__unload (ad->bpf_obj);
170  ad->bpf_obj = 0;
171 err0:
172  ad->linux_ifindex = ~0;
173  return -1;
174 }
175 
176 static int
178  af_xdp_device_t *ad, int qid)
179 {
180  struct xsk_umem **umem;
181  struct xsk_socket **xsk;
182  af_xdp_rxq_t *rxq;
183  af_xdp_txq_t *txq;
184  struct xsk_umem_config umem_config;
185  struct xsk_socket_config sock_config;
186  struct xdp_options opt;
187  socklen_t optlen;
188  const int is_rx = qid < ad->rxq_num;
189  const int is_tx = qid < ad->txq_num;
190 
192  umem = vec_elt_at_index (ad->umem, qid);
193 
195  xsk = vec_elt_at_index (ad->xsk, qid);
196 
198  rxq = vec_elt_at_index (ad->rxqs, qid);
199 
201  txq = vec_elt_at_index (ad->txqs, qid);
202 
203  /*
204  * fq and cq must always be allocated even if unused
205  * whereas rx and tx indicates whether we want rxq, txq, or both
206  */
207  struct xsk_ring_cons *rx = is_rx ? &rxq->rx : 0;
208  struct xsk_ring_prod *fq = &rxq->fq;
209  struct xsk_ring_prod *tx = is_tx ? &txq->tx : 0;
210  struct xsk_ring_cons *cq = &txq->cq;
211  int fd;
212 
213  memset (&umem_config, 0, sizeof (umem_config));
214  umem_config.fill_size = args->rxq_size;
215  umem_config.comp_size = args->txq_size;
216  umem_config.frame_size =
218  umem_config.frame_headroom = sizeof (vlib_buffer_t);
219  umem_config.flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG;
220  if (xsk_umem__create
221  (umem, uword_to_pointer (vm->buffer_main->buffer_mem_start, void *),
222  vm->buffer_main->buffer_mem_size, fq, cq, &umem_config))
223  {
224  args->rv = VNET_API_ERROR_SYSCALL_ERROR_1;
225  args->error = clib_error_return_unix (0, "xsk_umem__create() failed");
226  goto err0;
227  }
228 
229  memset (&sock_config, 0, sizeof (sock_config));
230  sock_config.rx_size = args->rxq_size;
231  sock_config.tx_size = args->txq_size;
232  sock_config.bind_flags = XDP_USE_NEED_WAKEUP;
233  switch (args->mode)
234  {
235  case AF_XDP_MODE_AUTO:
236  break;
237  case AF_XDP_MODE_COPY:
238  sock_config.bind_flags |= XDP_COPY;
239  break;
241  sock_config.bind_flags |= XDP_ZEROCOPY;
242  break;
243  }
244  if (xsk_socket__create
245  (xsk, ad->linux_ifname, qid, *umem, rx, tx, &sock_config))
246  {
247  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
248  args->error =
250  "xsk_socket__create() failed (is linux netdev %s up?)",
251  ad->linux_ifname);
252  goto err1;
253  }
254 
255  fd = xsk_socket__fd (*xsk);
256  optlen = sizeof (opt);
257  if (getsockopt (fd, SOL_XDP, XDP_OPTIONS, &opt, &optlen))
258  {
259  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
260  args->error =
261  clib_error_return_unix (0, "getsockopt(XDP_OPTIONS) failed");
262  goto err2;
263  }
264  if (opt.flags & XDP_OPTIONS_ZEROCOPY)
265  ad->flags |= AF_XDP_DEVICE_F_ZEROCOPY;
266 
267  rxq->xsk_fd = is_rx ? fd : -1;
268 
269  if (is_tx)
270  {
271  txq->xsk_fd = fd;
272  if (is_rx && (ad->flags & AF_XDP_DEVICE_F_SYSCALL_LOCK))
273  {
274  /* This is a shared rx+tx queue and we need to lock before syscalls.
275  * Prior to Linux 5.6 there is a race condition preventing to call
276  * poll() and sendto() concurrently on AF_XDP sockets. This was
277  * fixed with commit 11cc2d21499cabe7e7964389634ed1de3ee91d33
278  * to workaround this issue, we protect the syscalls with a
279  * spinlock. Note that it also prevents to use interrupt mode in
280  * multi workers setup, because in this case the poll() is done in
281  * the framework w/o any possibility to protect it.
282  * See
283  * https://lore.kernel.org/bpf/BYAPR11MB365382C5DB1E5FCC53242609C1549@BYAPR11MB3653.namprd11.prod.outlook.com/
284  */
286  txq->syscall_lock = rxq->syscall_lock;
287  }
288  }
289  else
290  {
291  txq->xsk_fd = -1;
292  }
293 
294  return 0;
295 
296 err2:
297  xsk_socket__delete (*xsk);
298 err1:
299  xsk_umem__delete (*umem);
300 err0:
301  *umem = 0;
302  *xsk = 0;
303  return -1;
304 }
305 
306 static int
307 af_xdp_get_numa (const char *ifname)
308 {
309  char *path;
310  clib_error_t *err;
311  int numa;
312 
313  path =
314  (char *) format (0, "/sys/class/net/%s/device/numa_node%c", ifname, 0);
315  err = clib_sysfs_read (path, "%d", &numa);
316  if (err || numa < 0)
317  numa = 0;
318 
319  clib_error_free (err);
320  vec_free (path);
321  return numa;
322 }
323 
324 static clib_error_t *
326 {
328  return 0;
329 }
330 
331 static clib_error_t *
333  const af_xdp_rxq_mode_t mode)
334 {
337  clib_file_t *f;
338 
339  if (rxq->mode == mode)
340  return 0;
341 
342  switch (mode)
343  {
345  update = UNIX_FILE_UPDATE_DELETE;
346  break;
348  if (ad->flags & AF_XDP_DEVICE_F_SYSCALL_LOCK)
349  return clib_error_create (
350  "kernel workaround incompatible with interrupt mode");
351  update = UNIX_FILE_UPDATE_ADD;
352  break;
353  default:
354  ASSERT (0);
355  return clib_error_create ("unknown rxq mode %i", mode);
356  }
357 
358  f = clib_file_get (fm, rxq->file_index);
359  fm->file_update (f, update);
360  rxq->mode = mode;
361  return 0;
362 }
363 
364 void
366 {
367  vnet_main_t *vnm = vnet_get_main ();
370  af_xdp_device_t *ad;
373  int rxq_num, txq_num, q_num;
374  int i;
375 
376  args->rxq_size = args->rxq_size ? args->rxq_size : 2 * VLIB_FRAME_SIZE;
377  args->txq_size = args->txq_size ? args->txq_size : 2 * VLIB_FRAME_SIZE;
378  rxq_num = args->rxq_num ? args->rxq_num : 1;
379  txq_num = tm->n_vlib_mains;
380 
381  if (!args->linux_ifname)
382  {
383  args->rv = VNET_API_ERROR_INVALID_VALUE;
384  args->error = clib_error_return (0, "missing host interface");
385  goto err0;
386  }
387 
388  if (args->rxq_size < VLIB_FRAME_SIZE || args->txq_size < VLIB_FRAME_SIZE ||
389  args->rxq_size > 65535 || args->txq_size > 65535 ||
390  !is_pow2 (args->rxq_size) || !is_pow2 (args->txq_size))
391  {
392  args->rv = VNET_API_ERROR_INVALID_VALUE;
393  args->error =
395  "queue size must be a power of two between %i and 65535",
397  goto err0;
398  }
399 
400  pool_get_zero (am->devices, ad);
401 
402  if (tm->n_vlib_mains > 1 &&
404  ad->flags |= AF_XDP_DEVICE_F_SYSCALL_LOCK;
405 
406  ad->linux_ifname = (char *) format (0, "%s", args->linux_ifname);
407  vec_validate (ad->linux_ifname, IFNAMSIZ - 1); /* libbpf expects ifname to be at least IFNAMSIZ */
408 
409  if (args->prog && af_xdp_load_program (args, ad))
410  goto err1;
411 
412  q_num = clib_max (rxq_num, txq_num);
413  ad->rxq_num = rxq_num;
414  ad->txq_num = txq_num;
415  for (i = 0; i < q_num; i++)
416  {
417  if (af_xdp_create_queue (vm, args, ad, i))
418  {
419  /*
420  * queue creation failed
421  * it is only a fatal error if we could not create the number of rx
422  * queues requested explicitely by the user and the user did not
423  * requested 'max'
424  * we might create less tx queues than workers but this is ok
425  */
426 
427  /* fixup vectors length */
428  vec_set_len (ad->umem, i);
429  vec_set_len (ad->xsk, i);
430  vec_set_len (ad->rxqs, i);
431  vec_set_len (ad->txqs, i);
432 
433  ad->rxq_num = clib_min (i, rxq_num);
434  ad->txq_num = clib_min (i, txq_num);
435 
436  if (i < rxq_num && AF_XDP_NUM_RX_QUEUES_ALL != rxq_num)
437  {
438  ad->rxq_num = ad->txq_num = 0;
439  goto err1; /* failed creating requested rxq: fatal error, bailing
440  out */
441  }
442 
443  if (i < txq_num)
444  {
445  /* we created less txq than threads not an error but initialize lock for shared txq */
446  for (i = 0; i < ad->txq_num; i++)
447  clib_spinlock_init (&vec_elt (ad->txqs, i).lock);
448  }
449 
450  args->rv = 0;
451  clib_error_free (args->error);
452  break;
453  }
454  }
455 
456  ad->dev_instance = ad - am->devices;
458  ad->pool =
461  (ad->linux_ifname));
462  if (!args->name)
463  ad->name =
464  (char *) format (0, "%s/%d", ad->linux_ifname, ad->dev_instance);
465  else
466  ad->name = (char *) format (0, "%s", args->name);
467 
469 
470  /* create interface */
472  ad->dev_instance, ad->hwaddr,
474  {
475  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
476  args->error =
477  clib_error_return (0, "ethernet_register_interface() failed");
478  goto err1;
479  }
480 
481  sw = vnet_get_hw_sw_interface (vnm, ad->hw_if_index);
482  hw = vnet_get_hw_interface (vnm, ad->hw_if_index);
483  args->sw_if_index = ad->sw_if_index = sw->sw_if_index;
485 
487 
488  for (i = 0; i < ad->rxq_num; i++)
489  {
490  af_xdp_rxq_t *rxq = vec_elt_at_index (ad->rxqs, i);
493  u8 *desc = format (0, "%U rxq %d", format_af_xdp_device_name,
494  ad->dev_instance, i);
495  clib_file_t f = {
496  .file_descriptor = rxq->xsk_fd,
497  .private_data = rxq->queue_index,
498  .read_function = af_xdp_device_rxq_read_ready,
499  .description = desc,
500  };
501  rxq->file_index = clib_file_add (&file_main, &f);
503  rxq->file_index);
505  goto err1;
506  }
507 
509 
510  /* buffer template */
512  ad->buffer_template->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
513  ad->buffer_template->ref_count = 1;
514  vnet_buffer (ad->buffer_template)->sw_if_index[VLIB_RX] = ad->sw_if_index;
515  vnet_buffer (ad->buffer_template)->sw_if_index[VLIB_TX] = (u32) ~ 0;
517 
518  return;
519 
520 err1:
521  af_xdp_delete_if (vm, ad);
522 err0:
523  vlib_log_err (am->log_class, "%U", format_clib_error, args->error);
524 }
525 
526 static clib_error_t *
528 {
529  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
531  af_xdp_device_t *ad = vec_elt_at_index (am->devices, hi->dev_instance);
533 
534  if (ad->flags & AF_XDP_DEVICE_F_ERROR)
535  return clib_error_return (0, "device is in error state");
536 
537  if (is_up)
538  {
541  ad->flags |= AF_XDP_DEVICE_F_ADMIN_UP;
543  }
544  else
545  {
547  ad->flags &= ~AF_XDP_DEVICE_F_ADMIN_UP;
548  }
549  return 0;
550 }
551 
552 static clib_error_t *
555 {
557  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
558  af_xdp_device_t *ad = pool_elt_at_index (am->devices, hw->dev_instance);
559  af_xdp_rxq_t *rxq = vec_elt_at_index (ad->rxqs, qid);
560 
561  switch (mode)
562  {
563  default: /* fallthrough */
564  case VNET_HW_IF_RX_MODE_UNKNOWN: /* fallthrough */
566  return clib_error_create ("uknown rx mode - doing nothing");
567  case VNET_HW_IF_RX_MODE_DEFAULT: /* fallthrough */
570  case VNET_HW_IF_RX_MODE_INTERRUPT: /* fallthrough */
573  }
574 
575  ASSERT (0 && "unreachable");
576  return clib_error_create ("unreachable");
577 }
578 
579 static void
581  u32 node_index)
582 {
584  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
585  af_xdp_device_t *ad = pool_elt_at_index (am->devices, hw->dev_instance);
586 
587  /* Shut off redirection */
588  if (node_index == ~0)
589  {
591  return;
592  }
593 
596  node_index);
597 }
598 
600 #define _(n,s) s,
602 #undef _
603 };
604 
605 static void
606 af_xdp_clear (u32 dev_instance)
607 {
609  af_xdp_device_t *ad = pool_elt_at_index (am->devices, dev_instance);
610  clib_error_free (ad->error);
611 }
612 
613 /* *INDENT-OFF* */
615  .name = "AF_XDP interface",
616  .format_device = format_af_xdp_device,
617  .format_device_name = format_af_xdp_device_name,
618  .admin_up_down_function = af_xdp_interface_admin_up_down,
619  .rx_mode_change_function = af_xdp_interface_rx_mode_change,
620  .rx_redirect_to_node = af_xdp_set_interface_next_node,
621  .tx_function_n_errors = AF_XDP_TX_N_ERROR,
622  .tx_function_error_strings = af_xdp_tx_func_error_strings,
623  .mac_addr_change_function = af_xdp_mac_change,
624  .clear_counters = af_xdp_clear,
625 };
626 /* *INDENT-ON* */
627 
628 clib_error_t *
630 {
632 
633  am->log_class = vlib_log_register_class ("af_xdp", 0);
634 
635  return 0;
636 }
637 
639 
640 /*
641  * fd.io coding-style-patch-verification: ON
642  *
643  * Local Variables:
644  * eval: (c-set-style "gnu")
645  * End:
646  */
af_xdp_log
#define af_xdp_log(lvl, dev, f,...)
Definition: af_xdp.h:27
vlib.h
af_xdp_create_queue
static int af_xdp_create_queue(vlib_main_t *vm, af_xdp_create_if_args_t *args, af_xdp_device_t *ad, int qid)
Definition: device.c:177
clib_spinlock_init
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
VNET_HW_IF_RXQ_THREAD_ANY
#define VNET_HW_IF_RXQ_THREAD_ANY
Definition: interface.h:598
vlib_buffer_t::buffer_pool_index
u8 buffer_pool_index
index of buffer pool this buffer belongs.
Definition: buffer.h:142
file_main
clib_file_main_t file_main
Definition: main.c:63
af_xdp_create_if_args_t::flags
af_xdp_create_flag_t flags
Definition: af_xdp.h:153
af_xdp_device_t::xsk
struct xsk_socket ** xsk
Definition: af_xdp.h:117
af_xdp_interface_rx_mode_change
static clib_error_t * af_xdp_interface_rx_mode_change(vnet_main_t *vnm, u32 hw_if_index, u32 qid, vnet_hw_if_rx_mode mode)
Definition: device.c:553
VNET_HW_IF_RX_MODE_ADAPTIVE
@ VNET_HW_IF_RX_MODE_ADAPTIVE
Definition: interface.h:58
vnet_sw_interface_t
Definition: interface.h:868
vnet_hw_interface_t::caps
vnet_hw_interface_capabilities_t caps
Definition: interface.h:645
af_xdp_create_if_args_t::prog
char * prog
Definition: af_xdp.h:151
af_xdp_main_t
Definition: af_xdp.h:126
af_xdp.h
af_xdp_create_if_args_t::mode
af_xdp_mode_t mode
Definition: af_xdp.h:152
vlib_node_add_next
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1177
AF_XDP_TX_N_ERROR
@ AF_XDP_TX_N_ERROR
Definition: af_xdp.h:196
af_xdp_device_t::rxqs
af_xdp_rxq_t * rxqs
Definition: af_xdp.h:97
clib_max
#define clib_max(x, y)
Definition: clib.h:335
f
vlib_frame_t * f
Definition: interface_output.c:1080
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
af_xdp_device_t::umem
struct xsk_umem ** umem
Definition: af_xdp.h:116
af_xdp_device_t::pool
u8 pool
Definition: af_xdp.h:104
af_xdp_create_if_args_t::rxq_size
u32 rxq_size
Definition: af_xdp.h:154
memcpy_s
__clib_export errno_t memcpy_s(void *__restrict__ dest, rsize_t dmax, const void *__restrict__ src, rsize_t n)
copy src to dest, at most n bytes, up to dmax
Definition: string.c:120
vlib_log_register_class
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
VLIB_FRAME_SIZE
#define VLIB_FRAME_SIZE
Definition: node.h:368
path
vl_api_fib_path_t path
Definition: mfib_types.api:44
AF_XDP_MODE_AUTO
@ AF_XDP_MODE_AUTO
Definition: af_xdp.h:137
format_af_xdp_device_name
format_function_t format_af_xdp_device_name
Definition: af_xdp.h:174
af_xdp_rxq_t::xsk_fd
int xsk_fd
Definition: af_xdp.h:69
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
VNET_DEVICE_CLASS
VNET_DEVICE_CLASS(af_xdp_device_class)
af_xdp_main_t::devices
af_xdp_device_t * devices
Definition: af_xdp.h:128
if_nametoindex
unsigned int if_nametoindex(const char *ifname)
mode
vl_api_tunnel_mode_t mode
Definition: gre.api:48
am
app_main_t * am
Definition: application.c:489
VNET_SW_INTERFACE_FLAG_ADMIN_UP
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:843
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
VNET_HW_IF_RX_MODE_POLLING
@ VNET_HW_IF_RX_MODE_POLLING
Definition: interface.h:56
vlib_main_t::buffer_main
vlib_buffer_main_t * buffer_main
Definition: main.h:165
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
fm
vnet_feature_main_t * fm
Definition: nat44_ei_hairpinning.c:589
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
node_index
node node_index
Definition: interface_output.c:420
VNET_HW_INTERFACE_FLAG_LINK_UP
@ VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:509
af_xdp_device_class
vnet_device_class_t af_xdp_device_class
af_xdp_rxq_t::mode
af_xdp_rxq_mode_t mode
Definition: af_xdp.h:75
gdb_af_xdp_pair_t::cons
u32 cons
Definition: device.c:36
VNET_HW_IF_NUM_RX_MODES
@ VNET_HW_IF_NUM_RX_MODES
Definition: interface.h:60
af_xdp_tx_func_error_strings
static char * af_xdp_tx_func_error_strings[]
Definition: device.c:599
hi
vl_api_ip4_address_t hi
Definition: arp.api:37
af_xdp_get_numa
static int af_xdp_get_numa(const char *ifname)
Definition: device.c:307
clib_file_main_t
Definition: file.h:85
af_xdp_txq_t::tx
struct xsk_ring_prod tx
Definition: af_xdp.h:86
vnet_hw_interface_t::dev_instance
u32 dev_instance
Definition: interface.h:660
VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT
@ VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT
Definition: devices.h:28
UNIX_FILE_UPDATE_ADD
@ UNIX_FILE_UPDATE_ADD
Definition: file.h:80
af_xdp_txq_t::syscall_lock
clib_spinlock_t syscall_lock
Definition: af_xdp.h:85
ethernet.h
af_xdp_device_t::txqs
af_xdp_txq_t * txqs
Definition: af_xdp.h:98
sysfs.h
vlib_log_err
#define vlib_log_err(...)
Definition: log.h:133
XDP_FLAGS_REPLACE
#define XDP_FLAGS_REPLACE
format_clib_error
__clib_export u8 * format_clib_error(u8 *s, va_list *va)
Definition: error.c:191
af_xdp_create_if
void af_xdp_create_if(vlib_main_t *vm, af_xdp_create_if_args_t *args)
Definition: device.c:365
af_xdp_device_t::buffer_template
vlib_buffer_t * buffer_template
Definition: af_xdp.h:99
vec_elt
#define vec_elt(v, i)
Get vector value at index i.
Definition: vec_bootstrap.h:210
af_xdp_rxq_t::rx
struct xsk_ring_cons rx
Definition: af_xdp.h:67
clib_sysfs_read
__clib_export clib_error_t * clib_sysfs_read(char *file_name, char *fmt,...)
Definition: sysfs.c:51
vnet_sw_interface_t::sw_if_index
u32 sw_if_index
Definition: interface.h:875
vlib_thread_main_t::n_vlib_mains
u32 n_vlib_mains
Definition: threads.h:283
clib_error_return_code
#define clib_error_return_code(e, code, flags, args...)
Definition: error.h:93
clib_error_create
#define clib_error_create(args...)
Definition: error.h:96
af_xdp_init
clib_error_t * af_xdp_init(vlib_main_t *vm)
Definition: device.c:629
AF_XDP_MODE_COPY
@ AF_XDP_MODE_COPY
Definition: af_xdp.h:138
gdb_af_xdp_get_cons
gdb_af_xdp_pair_t gdb_af_xdp_get_cons(const struct xsk_ring_cons *cons)
Definition: device.c:47
af_xdp_main
af_xdp_main_t af_xdp_main
Definition: device.c:31
af_xdp_txq_t::xsk_fd
int xsk_fd
Definition: af_xdp.h:88
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
vec_elt_at_index
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
Definition: vec_bootstrap.h:203
vnet_get_hw_interface
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:44
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
clib_file
Definition: file.h:51
af_xdp_mac_change
static clib_error_t * af_xdp_mac_change(vnet_hw_interface_t *hw, const u8 *old, const u8 *new)
Definition: device.c:54
af_xdp_rxq_t::syscall_lock
clib_spinlock_t syscall_lock
Definition: af_xdp.h:66
rx_queue_funcs.h
vec_validate_aligned
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:534
vnet_hw_if_rx_mode
vnet_hw_if_rx_mode
Definition: interface.h:53
af_xdp_create_if_args_t::linux_ifname
char * linux_ifname
Definition: af_xdp.h:149
uword
u64 uword
Definition: types.h:112
af_xdp_device_t
Definition: af_xdp.h:91
af_xdp_device_t::hwaddr
u8 hwaddr[6]
Definition: af_xdp.h:112
vnet_hw_if_update_runtime_data
void vnet_hw_if_update_runtime_data(vnet_main_t *vnm, u32 hw_if_index)
Definition: runtime.c:58
CLIB_ERROR_ERRNO_VALID
@ CLIB_ERROR_ERRNO_VALID
Definition: error_bootstrap.h:51
VNET_HW_IF_RX_MODE_INTERRUPT
@ VNET_HW_IF_RX_MODE_INTERRUPT
Definition: interface.h:57
af_xdp_txq_t::cq
struct xsk_ring_cons cq
Definition: af_xdp.h:87
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
clib_spinlock_free
static void clib_spinlock_free(clib_spinlock_t *p)
Definition: lock.h:72
ETHERNET_INTERFACE_FLAG_MTU
#define ETHERNET_INTERFACE_FLAG_MTU
Definition: ethernet.h:166
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
vnet_hw_if_rx_queue_set_int_pending
static_always_inline void vnet_hw_if_rx_queue_set_int_pending(vnet_main_t *vnm, u32 queue_index)
Definition: rx_queue_funcs.h:51
vlib_buffer_t::ref_count
volatile u8 ref_count
Reference count for this buffer.
Definition: buffer.h:139
VNET_HW_IF_RX_MODE_DEFAULT
@ VNET_HW_IF_RX_MODE_DEFAULT
Definition: interface.h:59
errno_t
int errno_t
Definition: string.h:130
clib_min
#define clib_min(x, y)
Definition: clib.h:342
vlib_buffer_main_t::buffer_mem_size
uword buffer_mem_size
Definition: buffer.h:481
af_xdp_device_t::bpf_obj
struct bpf_object * bpf_obj
Definition: af_xdp.h:119
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
af_xdp_load_program
static int af_xdp_load_program(af_xdp_create_if_args_t *args, af_xdp_device_t *ad)
Definition: device.c:132
af_xdp_create_if_args_t::rxq_num
u32 rxq_num
Definition: af_xdp.h:156
af_xdp_create_if_args_t::name
char * name
Definition: af_xdp.h:150
vlib_buffer_main_t::buffer_mem_start
uword buffer_mem_start
Definition: buffer.h:480
af_xdp_device_t::flags
u32 flags
Definition: af_xdp.h:103
vnet_hw_if_set_rx_queue_file_index
void vnet_hw_if_set_rx_queue_file_index(vnet_main_t *vnm, u32 queue_index, u32 file_index)
Definition: rx_queue.c:144
UNIX_FILE_UPDATE_DELETE
@ UNIX_FILE_UPDATE_DELETE
Definition: file.h:82
clib_file_get
static clib_file_t * clib_file_get(clib_file_main_t *fm, u32 file_index)
Definition: file.h:152
af_xdp_create_if_args_t::rv
int rv
Definition: af_xdp.h:159
af_xdp_create_if_args_t::txq_size
u32 txq_size
Definition: af_xdp.h:155
gdb_af_xdp_get_prod
gdb_af_xdp_pair_t gdb_af_xdp_get_prod(const struct xsk_ring_prod *prod)
Definition: device.c:40
af_xdp_rxq_t::file_index
uword file_index
Definition: af_xdp.h:73
AF_XDP_RXQ_MODE_INTERRUPT
@ AF_XDP_RXQ_MODE_INTERRUPT
Definition: af_xdp.h:57
gdb_af_xdp_pair_t
Definition: device.c:33
vec_set_len
#define vec_set_len(v, l)
Set vector length to a user-defined value.
Definition: vec_bootstrap.h:179
af_xdp_clear
static void af_xdp_clear(u32 dev_instance)
Definition: device.c:606
vnet_hw_interface_t
Definition: interface.h:638
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
af_xdp_create_if_args_t::error
clib_error_t * error
Definition: af_xdp.h:161
ethernet_mac_address_generate
static void ethernet_mac_address_generate(u8 *mac)
Definition: mac_address.h:74
af_xdp_device_t::linux_ifname
char * linux_ifname
Definition: af_xdp.h:110
af_xdp_device_input_refill
void af_xdp_device_input_refill(af_xdp_device_t *ad)
Definition: input.c:347
af_xdp_device_rxq_read_ready
static clib_error_t * af_xdp_device_rxq_read_ready(clib_file_t *f)
Definition: device.c:325
af_xdp_interface_admin_up_down
static clib_error_t * af_xdp_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: device.c:527
af_xdp_create_if_args_t
Definition: af_xdp.h:147
format
description fragment has unexpected format
Definition: map.api:433
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
vnet_get_hw_sw_interface
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:72
vlib_buffer_get_default_data_size
static_always_inline u32 vlib_buffer_get_default_data_size(vlib_main_t *vm)
Definition: buffer_funcs.h:122
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
ethernet_delete_interface
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:393
vlib_thread_main_t
Definition: threads.h:264
af_xdp_device_t::hw_if_index
u32 hw_if_index
Definition: af_xdp.h:102
af_xdp_rxq_t::fq
struct xsk_ring_prod fq
Definition: af_xdp.h:68
format_af_xdp_device
format_function_t format_af_xdp_device
Definition: af_xdp.h:173
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
AF_XDP_MODE_ZERO_COPY
@ AF_XDP_MODE_ZERO_COPY
Definition: af_xdp.h:139
pci.h
clib_error_return_unix
#define clib_error_return_unix(e, args...)
Definition: error.h:102
clib_file_add
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Definition: file.h:96
AF_XDP_NUM_RX_QUEUES_ALL
#define AF_XDP_NUM_RX_QUEUES_ALL
Definition: af_xdp.h:25
af_xdp_rxq_t::queue_index
u32 queue_index
Definition: af_xdp.h:74
vlib_buffer_pool_get_default_for_numa
static u8 vlib_buffer_pool_get_default_for_numa(vlib_main_t *vm, u32 numa_node)
Definition: buffer_funcs.h:189
vlib_main_t
Definition: main.h:102
vnet_hw_if_register_rx_queue
u32 vnet_hw_if_register_rx_queue(vnet_main_t *vnm, u32 hw_if_index, u32 queue_id, u32 thread_index)
Definition: rx_queue.c:64
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
pool_get_zero
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:258
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vnet_hw_interface_set_flags
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
Definition: interface.c:513
unix.h
clib_file_update_type_t
clib_file_update_type_t
Definition: file.h:78
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
ETHERNET_INTERFACE_FLAG_ACCEPT_ALL
#define ETHERNET_INTERFACE_FLAG_ACCEPT_ALL
Definition: ethernet.h:163
af_xdp_device_t::txq_num
u8 txq_num
Definition: af_xdp.h:105
uword_to_pointer
#define uword_to_pointer(u, type)
Definition: types.h:136
af_xdp_rxq_t
Definition: af_xdp.h:60
af_xdp_delete_if
void af_xdp_delete_if(vlib_main_t *vm, af_xdp_device_t *ad)
Definition: device.c:90
af_xdp_input_node
vlib_node_registration_t af_xdp_input_node
(constructor) VLIB_REGISTER_NODE (af_xdp_input_node)
Definition: input.c:357
af_xdp_device_t::sw_if_index
u32 sw_if_index
Definition: af_xdp.h:101
clib_file_del_by_index
static void clib_file_del_by_index(clib_file_main_t *um, uword index)
Definition: file.h:119
VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE
@ VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE
Definition: interface.h:550
clib_error_free
#define clib_error_free(e)
Definition: error.h:86
af_xdp_device_t::rxq_num
u8 rxq_num
Definition: af_xdp.h:114
af_xdp_device_set_rxq_mode
static clib_error_t * af_xdp_device_set_rxq_mode(const af_xdp_device_t *ad, af_xdp_rxq_t *rxq, const af_xdp_rxq_mode_t mode)
Definition: device.c:332
gdb_af_xdp_pair_t::prod
u32 prod
Definition: device.c:35
af_xdp_set_interface_next_node
static void af_xdp_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: device.c:580
af_xdp_device_t::per_interface_next_index
u32 per_interface_next_index
Definition: af_xdp.h:100
vlib_get_thread_main
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
is_pow2
static uword is_pow2(uword x)
Definition: clib.h:267
unix.h
af_xdp_txq_t
Definition: af_xdp.h:78
foreach_af_xdp_tx_func_error
#define foreach_af_xdp_tx_func_error
Definition: af_xdp.h:186
VLIB_TX
@ VLIB_TX
Definition: defs.h:47
AF_XDP_RXQ_MODE_POLLING
@ AF_XDP_RXQ_MODE_POLLING
Definition: af_xdp.h:56
AF_XDP_CREATE_FLAGS_NO_SYSCALL_LOCK
@ AF_XDP_CREATE_FLAGS_NO_SYSCALL_LOCK
Definition: af_xdp.h:144
af_xdp_create_if_args_t::sw_if_index
u32 sw_if_index
Definition: af_xdp.h:160
af_xdp_flag_change
static u32 af_xdp_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hw, u32 flags)
Definition: device.c:66
ethernet_register_interface
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, const u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
Definition: interface.c:348
af_xdp_device_t::dev_instance
u32 dev_instance
Definition: af_xdp.h:111
vnet_hw_if_set_input_node
void vnet_hw_if_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: rx_queue.c:157
af_xdp_device_t::name
char * name
Definition: af_xdp.h:109
vlib_buffer_t::flags
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
Definition: buffer.h:133
VNET_HW_IF_RX_MODE_UNKNOWN
@ VNET_HW_IF_RX_MODE_UNKNOWN
Definition: interface.h:55
af_xdp_device_t::linux_ifindex
unsigned linux_ifindex
Definition: af_xdp.h:120
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
af_xdp_device_t::error
clib_error_t * error
Definition: af_xdp.h:123
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105