FD.io VPP  v21.06-1-gbb7418cf9
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 {
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 {
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);
532  uword is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
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);
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);
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  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:524
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:133
clib_spinlock_t syscall_lock
Definition: af_xdp.h:85
#define clib_min(x, y)
Definition: clib.h:342
#define vec_set_len(v, l)
Set vector length to a user-defined value.
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
af_xdp_main_t af_xdp_main
Definition: device.c:31
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:393
vnet_device_class_t af_xdp_device_class
struct xsk_ring_cons rx
Definition: af_xdp.h:67
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:258
u32 per_interface_next_index
Definition: af_xdp.h:100
format_function_t format_af_xdp_device_name
Definition: af_xdp.h:174
vnet_hw_interface_capabilities_t caps
Definition: interface.h:645
u64 private_data
Definition: file.h:64
clib_error_t * error
Definition: af_xdp.h:123
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
struct xsk_ring_prod fq
Definition: af_xdp.h:68
vlib_buffer_main_t * buffer_main
Definition: main.h:165
#define XDP_FLAGS_REPLACE
static_always_inline void vnet_hw_if_rx_queue_set_int_pending(vnet_main_t *vnm, u32 queue_index)
void af_xdp_create_if(vlib_main_t *vm, af_xdp_create_if_args_t *args)
Definition: device.c:365
vl_api_fib_path_t path
Definition: mfib_types.api:44
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:535
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
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1177
unsigned char u8
Definition: types.h:56
af_xdp_device_t * devices
Definition: af_xdp.h:128
u8 buffer_pool_index
index of buffer pool this buffer belongs.
Definition: buffer.h:142
af_xdp_rxq_t * rxqs
Definition: af_xdp.h:97
static int af_xdp_load_program(af_xdp_create_if_args_t *args, af_xdp_device_t *ad)
Definition: device.c:132
static void clib_spinlock_free(clib_spinlock_t *p)
Definition: lock.h:72
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
unsigned int u32
Definition: types.h:88
struct xsk_umem ** umem
Definition: af_xdp.h:116
vlib_frame_t * f
vlib_log_class_t log_class
Definition: af_xdp.h:129
struct xsk_socket ** xsk
Definition: af_xdp.h:117
vlib_buffer_t * buffer_template
Definition: af_xdp.h:99
vnet_feature_main_t * fm
gdb_af_xdp_pair_t gdb_af_xdp_get_prod(const struct xsk_ring_prod *prod)
Definition: device.c:40
VNET_DEVICE_CLASS(af_xdp_device_class)
static clib_file_t * clib_file_get(clib_file_main_t *fm, u32 file_index)
Definition: file.h:152
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
clib_file_update_type_t
Definition: file.h:78
description fragment has unexpected format
Definition: map.api:433
uword buffer_mem_size
Definition: buffer.h:481
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
uword file_index
Definition: af_xdp.h:73
#define clib_error_return(e, args...)
Definition: error.h:99
vnet_main_t * vnet_get_main(void)
clib_file_main_t file_main
Definition: main.c:63
#define clib_error_create(args...)
Definition: error.h:96
char * name
Definition: af_xdp.h:109
#define VLIB_FRAME_SIZE
Definition: node.h:369
unsigned linux_ifindex
Definition: af_xdp.h:120
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
af_xdp_rxq_mode_t mode
Definition: af_xdp.h:75
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
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
int xsk_fd
Definition: af_xdp.h:69
#define clib_error_return_unix(e, args...)
Definition: error.h:102
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
void vnet_hw_if_update_runtime_data(vnet_main_t *vnm, u32 hw_if_index)
Definition: runtime.c:58
void(* file_update)(clib_file_t *file, clib_file_update_type_t update_type)
Definition: file.h:90
#define vlib_log_err(...)
Definition: log.h:133
gdb_af_xdp_pair_t gdb_af_xdp_get_cons(const struct xsk_ring_cons *cons)
Definition: device.c:47
static void af_xdp_clear(u32 dev_instance)
Definition: device.c:606
vl_api_tunnel_mode_t mode
Definition: gre.api:48
static clib_error_t * af_xdp_mac_change(vnet_hw_interface_t *hw, const u8 *old, const u8 *new)
Definition: device.c:54
static_always_inline u32 vlib_buffer_get_default_data_size(vlib_main_t *vm)
Definition: buffer_funcs.h:122
u32 dev_instance
Definition: af_xdp.h:111
static char * af_xdp_tx_func_error_strings[]
Definition: device.c:599
static void af_xdp_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: device.c:580
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:395
struct xsk_ring_prod tx
Definition: af_xdp.h:86
#define ETHERNET_INTERFACE_FLAG_MTU
Definition: ethernet.h:166
char * linux_ifname
Definition: af_xdp.h:110
#define ETHERNET_INTERFACE_FLAG_ACCEPT_ALL
Definition: ethernet.h:163
static u32 af_xdp_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hw, u32 flags)
Definition: device.c:66
format_function_t format_af_xdp_device
Definition: af_xdp.h:173
#define uword_to_pointer(u, type)
Definition: types.h:136
#define ASSERT(truth)
clib_error_t * af_xdp_init(vlib_main_t *vm)
Definition: device.c:629
u8 hwaddr[6]
Definition: af_xdp.h:112
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
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Definition: file.h:96
__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
static void clib_file_del_by_index(clib_file_main_t *um, uword index)
Definition: file.h:119
void af_xdp_device_input_refill(af_xdp_device_t *ad)
Definition: input.c:347
#define AF_XDP_NUM_RX_QUEUES_ALL
Definition: af_xdp.h:25
unsigned int if_nametoindex(const char *ifname)
u32 hw_if_index
Definition: af_xdp.h:102
#define clib_max(x, y)
Definition: clib.h:335
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
vl_api_ip4_address_t hi
Definition: arp.api:37
static uword is_pow2(uword x)
Definition: clib.h:267
int xsk_fd
Definition: af_xdp.h:88
#define vec_elt(v, i)
Get vector value at index i.
#define foreach_af_xdp_tx_func_error
Definition: af_xdp.h:186
void vnet_hw_if_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: rx_queue.c:157
Definition: defs.h:47
static clib_error_t * af_xdp_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: device.c:527
static void ethernet_mac_address_generate(u8 *mac)
Definition: mac_address.h:74
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
VLIB buffer representation.
Definition: buffer.h:111
u64 uword
Definition: types.h:112
clib_error_t * error
Definition: af_xdp.h:161
u32 sw_if_index
Definition: af_xdp.h:101
uword buffer_mem_start
Definition: buffer.h:480
node node_index
#define clib_error_free(e)
Definition: error.h:86
#define vnet_buffer(b)
Definition: buffer.h:437
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
#define clib_error_return_code(e, code, flags, args...)
Definition: error.h:93
vlib_node_registration_t af_xdp_input_node
(constructor) VLIB_REGISTER_NODE (af_xdp_input_node)
Definition: input.c:357
vnet_hw_if_rx_mode
Definition: interface.h:53
#define vec_foreach(var, vec)
Vector iterator.
__clib_export clib_error_t * clib_sysfs_read(char *file_name, char *fmt,...)
Definition: sysfs.c:51
af_xdp_txq_t * txqs
Definition: af_xdp.h:98
Definition: file.h:51
af_xdp_mode_t mode
Definition: af_xdp.h:152
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
u32 queue_index
Definition: af_xdp.h:74
static int af_xdp_get_numa(const char *ifname)
Definition: device.c:307
static u8 vlib_buffer_pool_get_default_for_numa(vlib_main_t *vm, u32 numa_node)
Definition: buffer_funcs.h:189
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
app_main_t * am
Definition: application.c:489
#define af_xdp_log(lvl, dev, f,...)
Definition: af_xdp.h:27
#define VNET_HW_IF_RXQ_THREAD_ANY
Definition: interface.h:598
void af_xdp_delete_if(vlib_main_t *vm, af_xdp_device_t *ad)
Definition: device.c:90
volatile u8 ref_count
Reference count for this buffer.
Definition: buffer.h:139
__clib_export u8 * format_clib_error(u8 *s, va_list *va)
Definition: error.c:191
struct xsk_ring_cons cq
Definition: af_xdp.h:87
struct bpf_object * bpf_obj
Definition: af_xdp.h:119
void vnet_hw_if_set_rx_queue_file_index(vnet_main_t *vnm, u32 queue_index, u32 file_index)
Definition: rx_queue.c:144
clib_spinlock_t syscall_lock
Definition: af_xdp.h:66
static clib_error_t * af_xdp_device_rxq_read_ready(clib_file_t *f)
Definition: device.c:325
Definition: defs.h:46
af_xdp_create_flag_t flags
Definition: af_xdp.h:153
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
int errno_t
Definition: string.h:130