FD.io VPP  v21.10.1-2-g0a485f517
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 <sys/ioctl.h>
21 #include <linux/ethtool.h>
22 #include <linux/if_link.h>
23 #include <linux/sockios.h>
24 #include <bpf/libbpf.h>
25 #include <vlib/vlib.h>
26 #include <vlib/unix/unix.h>
27 #include <vlib/pci/pci.h>
28 #include <vppinfra/linux/sysfs.h>
29 #include <vppinfra/unix.h>
30 #include <vnet/ethernet/ethernet.h>
32 #include "af_xdp.h"
33 
35 
36 typedef struct
37 {
41 
43 gdb_af_xdp_get_prod (const struct xsk_ring_prod *prod)
44 {
45  gdb_af_xdp_pair_t pair = { *prod->producer, *prod->consumer };
46  return pair;
47 }
48 
50 gdb_af_xdp_get_cons (const struct xsk_ring_cons * cons)
51 {
52  gdb_af_xdp_pair_t pair = { *cons->producer, *cons->consumer };
53  return pair;
54 }
55 
56 static clib_error_t *
57 af_xdp_mac_change (vnet_hw_interface_t * hw, const u8 * old, const u8 * new)
58 {
60  af_xdp_device_t *ad = vec_elt_at_index (am->devices, hw->dev_instance);
61  errno_t err = memcpy_s (ad->hwaddr, sizeof (ad->hwaddr), new, 6);
62  if (err)
64  "mac change failed");
65  return 0;
66 }
67 
68 static u32
70 {
72  af_xdp_device_t *ad = vec_elt_at_index (am->devices, hw->dev_instance);
73 
74  switch (flags)
75  {
76  case 0:
77  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "set unicast not supported yet");
78  return ~0;
80  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad,
81  "set promiscuous not supported yet");
82  return ~0;
84  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "set mtu not supported yet");
85  return ~0;
86  }
87 
88  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "unknown flag %x requested", flags);
89  return ~0;
90 }
91 
92 void
94 {
95  vnet_main_t *vnm = vnet_get_main ();
96  af_xdp_main_t *axm = &af_xdp_main;
97  struct xsk_socket **xsk;
98  struct xsk_umem **umem;
99  int i;
100 
101  if (ad->hw_if_index)
102  {
105  }
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  for (i = 0; i < ad->rxq_num; i++)
117  clib_file_del_by_index (&file_main, vec_elt (ad->rxqs, i).file_index);
118 
119  if (ad->bpf_obj)
120  {
121  bpf_set_link_xdp_fd (ad->linux_ifindex, -1, 0);
122  bpf_object__unload (ad->bpf_obj);
123  }
124 
125  vec_free (ad->xsk);
126  vec_free (ad->umem);
128  vec_free (ad->rxqs);
129  vec_free (ad->txqs);
130  clib_error_free (ad->error);
131  pool_put (axm->devices, ad);
132 }
133 
134 static int
136 {
137  int fd;
138 
140  if (!ad->linux_ifindex)
141  {
142  args->rv = VNET_API_ERROR_INVALID_VALUE;
143  args->error =
144  clib_error_return_unix (0, "if_nametoindex(%s) failed",
145  ad->linux_ifname);
146  goto err0;
147  }
148 
149  if (bpf_prog_load (args->prog, BPF_PROG_TYPE_XDP, &ad->bpf_obj, &fd))
150  {
151  args->rv = VNET_API_ERROR_SYSCALL_ERROR_5;
152  args->error =
153  clib_error_return_unix (0, "bpf_prog_load(%s) failed", args->prog);
154  goto err0;
155  }
156 
157 #ifndef XDP_FLAGS_REPLACE
158 #define XDP_FLAGS_REPLACE 0
159 #endif
160  if (bpf_set_link_xdp_fd (ad->linux_ifindex, fd, XDP_FLAGS_REPLACE))
161  {
162  args->rv = VNET_API_ERROR_SYSCALL_ERROR_6;
163  args->error =
164  clib_error_return_unix (0, "bpf_set_link_xdp_fd(%s) failed",
165  ad->linux_ifname);
166  goto err1;
167  }
168 
169  return 0;
170 
171 err1:
172  bpf_object__unload (ad->bpf_obj);
173  ad->bpf_obj = 0;
174 err0:
175  ad->linux_ifindex = ~0;
176  return -1;
177 }
178 
179 static int
181  af_xdp_device_t *ad, int qid)
182 {
183  struct xsk_umem **umem;
184  struct xsk_socket **xsk;
185  af_xdp_rxq_t *rxq;
186  af_xdp_txq_t *txq;
187  struct xsk_umem_config umem_config;
188  struct xsk_socket_config sock_config;
189  struct xdp_options opt;
190  socklen_t optlen;
191  const int is_rx = qid < ad->rxq_num;
192  const int is_tx = qid < ad->txq_num;
193 
194  umem = vec_elt_at_index (ad->umem, qid);
195  xsk = vec_elt_at_index (ad->xsk, qid);
196  rxq = vec_elt_at_index (ad->rxqs, qid);
197  txq = vec_elt_at_index (ad->txqs, qid);
198 
199  /*
200  * fq and cq must always be allocated even if unused
201  * whereas rx and tx indicates whether we want rxq, txq, or both
202  */
203  struct xsk_ring_cons *rx = is_rx ? &rxq->rx : 0;
204  struct xsk_ring_prod *fq = &rxq->fq;
205  struct xsk_ring_prod *tx = is_tx ? &txq->tx : 0;
206  struct xsk_ring_cons *cq = &txq->cq;
207  int fd;
208 
209  memset (&umem_config, 0, sizeof (umem_config));
210  umem_config.fill_size = args->rxq_size;
211  umem_config.comp_size = args->txq_size;
212  umem_config.frame_size =
214  umem_config.frame_headroom = sizeof (vlib_buffer_t);
215  umem_config.flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG;
216  if (xsk_umem__create
217  (umem, uword_to_pointer (vm->buffer_main->buffer_mem_start, void *),
218  vm->buffer_main->buffer_mem_size, fq, cq, &umem_config))
219  {
220  args->rv = VNET_API_ERROR_SYSCALL_ERROR_1;
221  args->error = clib_error_return_unix (0, "xsk_umem__create() failed");
222  goto err0;
223  }
224 
225  memset (&sock_config, 0, sizeof (sock_config));
226  sock_config.rx_size = args->rxq_size;
227  sock_config.tx_size = args->txq_size;
228  sock_config.bind_flags = XDP_USE_NEED_WAKEUP;
229  switch (args->mode)
230  {
231  case AF_XDP_MODE_AUTO:
232  break;
233  case AF_XDP_MODE_COPY:
234  sock_config.bind_flags |= XDP_COPY;
235  break;
237  sock_config.bind_flags |= XDP_ZEROCOPY;
238  break;
239  }
240  if (xsk_socket__create
241  (xsk, ad->linux_ifname, qid, *umem, rx, tx, &sock_config))
242  {
243  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
244  args->error =
246  "xsk_socket__create() failed (is linux netdev %s up?)",
247  ad->linux_ifname);
248  goto err1;
249  }
250 
251  fd = xsk_socket__fd (*xsk);
252  optlen = sizeof (opt);
253  if (getsockopt (fd, SOL_XDP, XDP_OPTIONS, &opt, &optlen))
254  {
255  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
256  args->error =
257  clib_error_return_unix (0, "getsockopt(XDP_OPTIONS) failed");
258  goto err2;
259  }
260  if (opt.flags & XDP_OPTIONS_ZEROCOPY)
261  ad->flags |= AF_XDP_DEVICE_F_ZEROCOPY;
262 
263  rxq->xsk_fd = is_rx ? fd : -1;
264 
265  if (is_tx)
266  {
267  txq->xsk_fd = fd;
268  if (is_rx && (ad->flags & AF_XDP_DEVICE_F_SYSCALL_LOCK))
269  {
270  /* This is a shared rx+tx queue and we need to lock before syscalls.
271  * Prior to Linux 5.6 there is a race condition preventing to call
272  * poll() and sendto() concurrently on AF_XDP sockets. This was
273  * fixed with commit 11cc2d21499cabe7e7964389634ed1de3ee91d33
274  * to workaround this issue, we protect the syscalls with a
275  * spinlock. Note that it also prevents to use interrupt mode in
276  * multi workers setup, because in this case the poll() is done in
277  * the framework w/o any possibility to protect it.
278  * See
279  * https://lore.kernel.org/bpf/BYAPR11MB365382C5DB1E5FCC53242609C1549@BYAPR11MB3653.namprd11.prod.outlook.com/
280  */
282  txq->syscall_lock = rxq->syscall_lock;
283  }
284  }
285  else
286  {
287  txq->xsk_fd = -1;
288  }
289 
290  return 0;
291 
292 err2:
293  xsk_socket__delete (*xsk);
294 err1:
295  xsk_umem__delete (*umem);
296 err0:
297  *umem = 0;
298  *xsk = 0;
299  return -1;
300 }
301 
302 static int
303 af_xdp_get_numa (const char *ifname)
304 {
305  char *path;
306  clib_error_t *err;
307  int numa;
308 
309  path =
310  (char *) format (0, "/sys/class/net/%s/device/numa_node%c", ifname, 0);
311  err = clib_sysfs_read (path, "%d", &numa);
312  if (err || numa < 0)
313  numa = 0;
314 
315  clib_error_free (err);
316  vec_free (path);
317  return numa;
318 }
319 
320 static void
321 af_xdp_get_q_count (const char *ifname, int *rxq_num, int *txq_num)
322 {
323  struct ethtool_channels ec = { .cmd = ETHTOOL_GCHANNELS };
324  struct ifreq ifr = { .ifr_data = (void *) &ec };
325  int fd, err;
326 
327  *rxq_num = *txq_num = 1;
328 
329  fd = socket (AF_INET, SOCK_DGRAM, 0);
330  if (fd < 0)
331  return;
332 
333  snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", ifname);
334  err = ioctl (fd, SIOCETHTOOL, &ifr);
335 
336  close (fd);
337 
338  if (err)
339  return;
340 
341  *rxq_num = clib_max (ec.combined_count, ec.rx_count);
342  *txq_num = clib_max (ec.combined_count, ec.tx_count);
343 }
344 
345 static clib_error_t *
347 {
349  return 0;
350 }
351 
352 static clib_error_t *
354  const af_xdp_rxq_mode_t mode)
355 {
358  clib_file_t *f;
359 
360  if (rxq->mode == mode)
361  return 0;
362 
363  switch (mode)
364  {
366  update = UNIX_FILE_UPDATE_DELETE;
367  break;
369  if (ad->flags & AF_XDP_DEVICE_F_SYSCALL_LOCK)
370  return clib_error_create (
371  "kernel workaround incompatible with interrupt mode");
372  update = UNIX_FILE_UPDATE_ADD;
373  break;
374  default:
375  ASSERT (0);
376  return clib_error_create ("unknown rxq mode %i", mode);
377  }
378 
379  f = clib_file_get (fm, rxq->file_index);
380  fm->file_update (f, update);
381  rxq->mode = mode;
382  return 0;
383 }
384 
385 void
387 {
388  vnet_main_t *vnm = vnet_get_main ();
391  af_xdp_device_t *ad;
394  int rxq_num, txq_num, q_num;
395  int i;
396 
397  args->rxq_size = args->rxq_size ? args->rxq_size : 2 * VLIB_FRAME_SIZE;
398  args->txq_size = args->txq_size ? args->txq_size : 2 * VLIB_FRAME_SIZE;
399  args->rxq_num = args->rxq_num ? args->rxq_num : 1;
400 
401  if (!args->linux_ifname)
402  {
403  args->rv = VNET_API_ERROR_INVALID_VALUE;
404  args->error = clib_error_return (0, "missing host interface");
405  goto err0;
406  }
407 
408  if (args->rxq_size < VLIB_FRAME_SIZE || args->txq_size < VLIB_FRAME_SIZE ||
409  args->rxq_size > 65535 || args->txq_size > 65535 ||
410  !is_pow2 (args->rxq_size) || !is_pow2 (args->txq_size))
411  {
412  args->rv = VNET_API_ERROR_INVALID_VALUE;
413  args->error =
415  "queue size must be a power of two between %i and 65535",
417  goto err0;
418  }
419 
420  af_xdp_get_q_count (args->linux_ifname, &rxq_num, &txq_num);
421  if (args->rxq_num > rxq_num && AF_XDP_NUM_RX_QUEUES_ALL != args->rxq_num)
422  {
423  args->rv = VNET_API_ERROR_INVALID_VALUE;
424  args->error = clib_error_create ("too many rxq requested (%d > %d)",
425  args->rxq_num, rxq_num);
426  goto err0;
427  }
428  rxq_num = clib_min (rxq_num, args->rxq_num);
429  txq_num = clib_min (txq_num, tm->n_vlib_mains);
430 
431  pool_get_zero (am->devices, ad);
432 
433  if (tm->n_vlib_mains > 1 &&
435  ad->flags |= AF_XDP_DEVICE_F_SYSCALL_LOCK;
436 
437  ad->linux_ifname = (char *) format (0, "%s", args->linux_ifname);
438  vec_validate (ad->linux_ifname, IFNAMSIZ - 1); /* libbpf expects ifname to be at least IFNAMSIZ */
439 
440  if (args->prog && af_xdp_load_program (args, ad))
441  goto err1;
442 
443  q_num = clib_max (rxq_num, txq_num);
444  ad->rxq_num = rxq_num;
445  ad->txq_num = txq_num;
446 
451 
452  for (i = 0; i < q_num; i++)
453  {
454  if (af_xdp_create_queue (vm, args, ad, i))
455  {
456  /*
457  * queue creation failed
458  * it is only a fatal error if we could not create the number of rx
459  * queues requested explicitely by the user and the user did not
460  * requested 'max'
461  * we might create less tx queues than workers but this is ok
462  */
463 
464  /* fixup vectors length */
465  vec_set_len (ad->umem, i);
466  vec_set_len (ad->xsk, i);
467  vec_set_len (ad->rxqs, i);
468  vec_set_len (ad->txqs, i);
469 
470  ad->rxq_num = clib_min (i, rxq_num);
471  ad->txq_num = clib_min (i, txq_num);
472 
473  if (i < rxq_num && AF_XDP_NUM_RX_QUEUES_ALL != args->rxq_num)
474  {
475  ad->rxq_num = ad->txq_num = 0;
476  goto err1; /* failed creating requested rxq: fatal error, bailing
477  out */
478  }
479 
480  if (i < txq_num)
481  {
482  /* we created less txq than threads not an error but initialize lock for shared txq */
483  for (i = 0; i < ad->txq_num; i++)
484  clib_spinlock_init (&vec_elt (ad->txqs, i).lock);
485  }
486 
487  args->rv = 0;
488  clib_error_free (args->error);
489  break;
490  }
491  }
492 
493  ad->dev_instance = ad - am->devices;
495  ad->pool =
498  (ad->linux_ifname));
499  if (!args->name)
500  ad->name =
501  (char *) format (0, "%s/%d", ad->linux_ifname, ad->dev_instance);
502  else
503  ad->name = (char *) format (0, "%s", args->name);
504 
506 
507  /* create interface */
509  ad->dev_instance, ad->hwaddr,
511  {
512  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
513  args->error =
514  clib_error_return (0, "ethernet_register_interface() failed");
515  goto err1;
516  }
517 
518  sw = vnet_get_hw_sw_interface (vnm, ad->hw_if_index);
519  hw = vnet_get_hw_interface (vnm, ad->hw_if_index);
520  args->sw_if_index = ad->sw_if_index = sw->sw_if_index;
522 
524 
525  for (i = 0; i < ad->rxq_num; i++)
526  {
527  af_xdp_rxq_t *rxq = vec_elt_at_index (ad->rxqs, i);
530  u8 *desc = format (0, "%U rxq %d", format_af_xdp_device_name,
531  ad->dev_instance, i);
532  clib_file_t f = {
533  .file_descriptor = rxq->xsk_fd,
534  .private_data = rxq->queue_index,
535  .read_function = af_xdp_device_rxq_read_ready,
536  .description = desc,
537  };
538  rxq->file_index = clib_file_add (&file_main, &f);
540  rxq->file_index);
542  goto err1;
543  }
544 
546 
547  /* buffer template */
549  ad->buffer_template->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
550  ad->buffer_template->ref_count = 1;
551  vnet_buffer (ad->buffer_template)->sw_if_index[VLIB_RX] = ad->sw_if_index;
552  vnet_buffer (ad->buffer_template)->sw_if_index[VLIB_TX] = (u32) ~ 0;
554 
555  return;
556 
557 err1:
558  af_xdp_delete_if (vm, ad);
559 err0:
560  vlib_log_err (am->log_class, "%U", format_clib_error, args->error);
561 }
562 
563 static clib_error_t *
565 {
566  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
568  af_xdp_device_t *ad = vec_elt_at_index (am->devices, hi->dev_instance);
570 
571  if (ad->flags & AF_XDP_DEVICE_F_ERROR)
572  return clib_error_return (0, "device is in error state");
573 
574  if (is_up)
575  {
578  ad->flags |= AF_XDP_DEVICE_F_ADMIN_UP;
580  }
581  else
582  {
584  ad->flags &= ~AF_XDP_DEVICE_F_ADMIN_UP;
585  }
586  return 0;
587 }
588 
589 static clib_error_t *
592 {
594  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
595  af_xdp_device_t *ad = pool_elt_at_index (am->devices, hw->dev_instance);
596  af_xdp_rxq_t *rxq = vec_elt_at_index (ad->rxqs, qid);
597 
598  switch (mode)
599  {
600  default: /* fallthrough */
601  case VNET_HW_IF_RX_MODE_UNKNOWN: /* fallthrough */
603  return clib_error_create ("uknown rx mode - doing nothing");
604  case VNET_HW_IF_RX_MODE_DEFAULT: /* fallthrough */
607  case VNET_HW_IF_RX_MODE_INTERRUPT: /* fallthrough */
610  }
611 
612  ASSERT (0 && "unreachable");
613  return clib_error_create ("unreachable");
614 }
615 
616 static void
618  u32 node_index)
619 {
621  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
622  af_xdp_device_t *ad = pool_elt_at_index (am->devices, hw->dev_instance);
623 
624  /* Shut off redirection */
625  if (node_index == ~0)
626  {
628  return;
629  }
630 
633  node_index);
634 }
635 
637 #define _(n,s) s,
639 #undef _
640 };
641 
642 static void
643 af_xdp_clear (u32 dev_instance)
644 {
646  af_xdp_device_t *ad = pool_elt_at_index (am->devices, dev_instance);
647  clib_error_free (ad->error);
648 }
649 
650 /* *INDENT-OFF* */
652  .name = "AF_XDP interface",
653  .format_device = format_af_xdp_device,
654  .format_device_name = format_af_xdp_device_name,
655  .admin_up_down_function = af_xdp_interface_admin_up_down,
656  .rx_mode_change_function = af_xdp_interface_rx_mode_change,
657  .rx_redirect_to_node = af_xdp_set_interface_next_node,
658  .tx_function_n_errors = AF_XDP_TX_N_ERROR,
659  .tx_function_error_strings = af_xdp_tx_func_error_strings,
660  .mac_addr_change_function = af_xdp_mac_change,
661  .clear_counters = af_xdp_clear,
662 };
663 /* *INDENT-ON* */
664 
665 clib_error_t *
667 {
669 
670  am->log_class = vlib_log_register_class ("af_xdp", 0);
671 
672  return 0;
673 }
674 
676 
677 /*
678  * fd.io coding-style-patch-verification: ON
679  *
680  * Local Variables:
681  * eval: (c-set-style "gnu")
682  * End:
683  */
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:180
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:590
VNET_HW_IF_RX_MODE_ADAPTIVE
@ VNET_HW_IF_RX_MODE_ADAPTIVE
Definition: interface.h:58
vnet_sw_interface_t
Definition: interface.h:869
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:1098
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
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:844
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:167
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:592
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
node_index
node node_index
Definition: interface_output.c:440
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:39
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:636
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:303
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:386
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:876
vlib_thread_main_t::n_vlib_mains
u32 n_vlib_mains
Definition: threads.h:262
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:666
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:50
af_xdp_main
af_xdp_main_t af_xdp_main
Definition: device.c:34
af_xdp_txq_t::xsk_fd
int xsk_fd
Definition: af_xdp.h:88
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
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:57
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
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
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:165
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:52
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
CLIB_ERROR_ERRNO_VALID
@ CLIB_ERROR_ERRNO_VALID
Definition: error_bootstrap.h:51
vlib_buffer_main_t::buffer_mem_size
uword buffer_mem_size
Definition: buffer.h:485
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:58
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:135
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:484
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:43
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:36
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:643
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:346
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:564
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:243
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:162
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:93
i
int i
Definition: flowhash_template.h:376
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:353
gdb_af_xdp_pair_t::prod
u32 prod
Definition: device.c:38
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:617
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_get_q_count
static void af_xdp_get_q_count(const char *ifname, int *rxq_num, int *txq_num)
Definition: device.c:321
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:69
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