FD.io VPP  v21.01.1
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>
28 #include "af_xdp.h"
29 
31 
32 typedef struct
33 {
37 
39 gdb_af_xdp_get_prod (const struct xsk_ring_prod *prod)
40 {
41  gdb_af_xdp_pair_t pair = { *prod->producer, *prod->consumer };
42  return pair;
43 }
44 
46 gdb_af_xdp_get_cons (const struct xsk_ring_cons * cons)
47 {
48  gdb_af_xdp_pair_t pair = { *cons->producer, *cons->consumer };
49  return pair;
50 }
51 
52 static clib_error_t *
53 af_xdp_mac_change (vnet_hw_interface_t * hw, const u8 * old, const u8 * new)
54 {
57  errno_t err = memcpy_s (ad->hwaddr, sizeof (ad->hwaddr), new, 6);
58  if (err)
60  "mac change failed");
61  return 0;
62 }
63 
64 static u32
66 {
69 
70  switch (flags)
71  {
72  case 0:
73  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "set unicast not supported yet");
74  return ~0;
76  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad,
77  "set promiscuous not supported yet");
78  return ~0;
80  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "set mtu not supported yet");
81  return ~0;
82  }
83 
84  af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "unknown flag %x requested", flags);
85  return ~0;
86 }
87 
88 void
90 {
91  vnet_main_t *vnm = vnet_get_main ();
92  af_xdp_main_t *axm = &af_xdp_main;
93  struct xsk_socket **xsk;
94  struct xsk_umem **umem;
95  af_xdp_rxq_t *rxq;
96  af_xdp_txq_t *txq;
97 
98  if (ad->hw_if_index)
99  {
103  }
104 
106  rxq->file_index);
107  vec_foreach (txq, ad->txqs) clib_spinlock_free (&txq->lock);
108  vec_foreach (xsk, ad->xsk) xsk_socket__delete (*xsk);
109  vec_foreach (umem, ad->umem) xsk_umem__delete (*umem);
110 
111  if (ad->bpf_obj)
112  {
113  bpf_set_link_xdp_fd (ad->linux_ifindex, -1, 0);
114  bpf_object__unload (ad->bpf_obj);
115  }
116 
117  vec_free (ad->xsk);
118  vec_free (ad->umem);
120  vec_free (ad->rxqs);
121  vec_free (ad->txqs);
122  clib_error_free (ad->error);
123  pool_put (axm->devices, ad);
124 }
125 
126 static int
128 {
129  int fd;
130 
132  if (!ad->linux_ifindex)
133  {
134  args->rv = VNET_API_ERROR_INVALID_VALUE;
135  args->error =
136  clib_error_return_unix (0, "if_nametoindex(%s) failed",
137  ad->linux_ifname);
138  goto err0;
139  }
140 
141  if (bpf_prog_load (args->prog, BPF_PROG_TYPE_XDP, &ad->bpf_obj, &fd))
142  {
143  args->rv = VNET_API_ERROR_SYSCALL_ERROR_5;
144  args->error =
145  clib_error_return_unix (0, "bpf_prog_load(%s) failed", args->prog);
146  goto err0;
147  }
148 
149 #ifndef XDP_FLAGS_REPLACE
150 #define XDP_FLAGS_REPLACE 0
151 #endif
152  if (bpf_set_link_xdp_fd (ad->linux_ifindex, fd, XDP_FLAGS_REPLACE))
153  {
154  args->rv = VNET_API_ERROR_SYSCALL_ERROR_6;
155  args->error =
156  clib_error_return_unix (0, "bpf_set_link_xdp_fd(%s) failed",
157  ad->linux_ifname);
158  goto err1;
159  }
160 
161  return 0;
162 
163 err1:
164  bpf_object__unload (ad->bpf_obj);
165  ad->bpf_obj = 0;
166 err0:
167  ad->linux_ifindex = ~0;
168  return -1;
169 }
170 
171 static int
173  af_xdp_device_t * ad, int qid, int rxq_num, int txq_num)
174 {
175  struct xsk_umem **umem;
176  struct xsk_socket **xsk;
177  af_xdp_rxq_t *rxq;
178  af_xdp_txq_t *txq;
179  struct xsk_umem_config umem_config;
180  struct xsk_socket_config sock_config;
181  struct xdp_options opt;
182  socklen_t optlen;
183 
185  umem = vec_elt_at_index (ad->umem, qid);
186 
188  xsk = vec_elt_at_index (ad->xsk, qid);
189 
191  rxq = vec_elt_at_index (ad->rxqs, qid);
192 
194  txq = vec_elt_at_index (ad->txqs, qid);
195 
196  /*
197  * fq and cq must always be allocated even if unused
198  * whereas rx and tx indicates whether we want rxq, txq, or both
199  */
200  struct xsk_ring_cons *rx = qid < rxq_num ? &rxq->rx : 0;
201  struct xsk_ring_prod *fq = &rxq->fq;
202  struct xsk_ring_prod *tx = qid < txq_num ? &txq->tx : 0;
203  struct xsk_ring_cons *cq = &txq->cq;
204  int fd;
205 
206  memset (&umem_config, 0, sizeof (umem_config));
207  umem_config.fill_size = args->rxq_size;
208  umem_config.comp_size = args->txq_size;
209  umem_config.frame_size =
211  umem_config.flags = XDP_UMEM_UNALIGNED_CHUNK_FLAG;
212  if (xsk_umem__create
213  (umem, uword_to_pointer (vm->buffer_main->buffer_mem_start, void *),
214  vm->buffer_main->buffer_mem_size, fq, cq, &umem_config))
215  {
216  args->rv = VNET_API_ERROR_SYSCALL_ERROR_1;
217  args->error = clib_error_return_unix (0, "xsk_umem__create() failed");
218  goto err0;
219  }
220 
221  memset (&sock_config, 0, sizeof (sock_config));
222  sock_config.rx_size = args->rxq_size;
223  sock_config.tx_size = args->txq_size;
224  sock_config.bind_flags = XDP_USE_NEED_WAKEUP;
225  switch (args->mode)
226  {
227  case AF_XDP_MODE_AUTO:
228  break;
229  case AF_XDP_MODE_COPY:
230  sock_config.bind_flags |= XDP_COPY;
231  break;
233  sock_config.bind_flags |= XDP_ZEROCOPY;
234  break;
235  }
236  if (xsk_socket__create
237  (xsk, ad->linux_ifname, qid, *umem, rx, tx, &sock_config))
238  {
239  args->rv = VNET_API_ERROR_SYSCALL_ERROR_2;
240  args->error =
242  "xsk_socket__create() failed (is linux netdev %s up?)",
243  ad->linux_ifname);
244  goto err1;
245  }
246 
247  fd = xsk_socket__fd (*xsk);
248  optlen = sizeof (opt);
249  if (getsockopt (fd, SOL_XDP, XDP_OPTIONS, &opt, &optlen))
250  {
251  args->rv = VNET_API_ERROR_SYSCALL_ERROR_3;
252  args->error =
253  clib_error_return_unix (0, "getsockopt(XDP_OPTIONS) failed");
254  goto err2;
255  }
256  if (opt.flags & XDP_OPTIONS_ZEROCOPY)
257  ad->flags |= AF_XDP_DEVICE_F_ZEROCOPY;
258 
259  rxq->xsk_fd = qid < rxq_num ? fd : -1;
260  txq->xsk_fd = qid < txq_num ? fd : -1;
261 
262  return 0;
263 
264 err2:
265  xsk_socket__delete (*xsk);
266 err1:
267  xsk_umem__delete (*umem);
268 err0:
269  *umem = 0;
270  *xsk = 0;
271  return -1;
272 }
273 
274 static int
275 af_xdp_get_numa (const char *ifname)
276 {
277  char *path;
278  clib_error_t *err;
279  int numa;
280 
281  path =
282  (char *) format (0, "/sys/class/net/%s/device/numa_node%c", ifname, 0);
283  err = clib_sysfs_read (path, "%d", &numa);
284  if (err || numa < 0)
285  numa = 0;
286 
287  clib_error_free (err);
288  vec_free (path);
289  return numa;
290 }
291 
292 static clib_error_t *
294 {
295  vnet_main_t *vnm = vnet_get_main ();
296  const af_xdp_main_t *am = &af_xdp_main;
297  const u32 dev_instance = f->private_data >> 16;
298  const u16 qid = f->private_data & 0xffff;
299  const af_xdp_device_t *ad = vec_elt_at_index (am->devices, dev_instance);
301  return 0;
302 }
303 
304 void
306 {
307  vnet_main_t *vnm = vnet_get_main ();
309  af_xdp_main_t *am = &af_xdp_main;
310  af_xdp_device_t *ad;
313  int rxq_num, txq_num, q_num;
314  int i;
315 
316  args->rxq_size = args->rxq_size ? args->rxq_size : 2 * VLIB_FRAME_SIZE;
317  args->txq_size = args->txq_size ? args->txq_size : 2 * VLIB_FRAME_SIZE;
318  rxq_num = args->rxq_num ? args->rxq_num : 1;
319  txq_num = tm->n_vlib_mains;
320 
321  if (!args->linux_ifname)
322  {
323  args->rv = VNET_API_ERROR_INVALID_VALUE;
324  args->error = clib_error_return (0, "missing host interface");
325  goto err0;
326  }
327 
328  if (args->rxq_size < VLIB_FRAME_SIZE || args->txq_size < VLIB_FRAME_SIZE ||
329  args->rxq_size > 65535 || args->txq_size > 65535 ||
330  !is_pow2 (args->rxq_size) || !is_pow2 (args->txq_size))
331  {
332  args->rv = VNET_API_ERROR_INVALID_VALUE;
333  args->error =
335  "queue size must be a power of two between %i and 65535",
337  goto err0;
338  }
339 
340  pool_get_zero (am->devices, ad);
341 
342  ad->linux_ifname = (char *) format (0, "%s", args->linux_ifname);
343  vec_validate (ad->linux_ifname, IFNAMSIZ - 1); /* libbpf expects ifname to be at least IFNAMSIZ */
344 
345  if (args->prog && af_xdp_load_program (args, ad))
346  goto err1;
347 
348  q_num = clib_max (rxq_num, txq_num);
349  ad->txq_num = txq_num;
350  for (i = 0; i < q_num; i++)
351  {
352  if (af_xdp_create_queue (vm, args, ad, i, rxq_num, txq_num))
353  {
354  /*
355  * queue creation failed
356  * it is only a fatal error if we could not create the number of rx
357  * queues requested explicitely by the user and the user did not
358  * requested 'max'
359  * we might create less tx queues than workers but this is ok
360  */
361 
362  /* fixup vectors length */
363  vec_set_len (ad->umem, i);
364  vec_set_len (ad->xsk, i);
365  vec_set_len (ad->rxqs, i);
366  vec_set_len (ad->txqs, i);
367 
368  if (i < rxq_num && AF_XDP_NUM_RX_QUEUES_ALL != rxq_num)
369  goto err1; /* failed creating requested rxq: fatal error, bailing out */
370 
371  if (i < txq_num)
372  {
373  /* we created less txq than threads not an error but initialize lock for shared txq */
374  af_xdp_txq_t *txq;
375  ad->txq_num = i;
376  vec_foreach (txq, ad->txqs) clib_spinlock_init (&txq->lock);
377  }
378 
379  args->rv = 0;
380  clib_error_free (args->error);
381  break;
382  }
383  }
384 
385  ad->dev_instance = ad - am->devices;
387  ad->pool =
390  (ad->linux_ifname));
391  if (!args->name)
392  ad->name =
393  (char *) format (0, "%s/%d", ad->linux_ifname, ad->dev_instance);
394  else
395  ad->name = (char *) format (0, "%s", args->name);
396 
398 
399  /* create interface */
401  ad->dev_instance, ad->hwaddr,
403  {
404  args->rv = VNET_API_ERROR_INVALID_INTERFACE;
405  args->error =
406  clib_error_return (0, "ethernet_register_interface() failed");
407  goto err1;
408  }
409 
410  sw = vnet_get_hw_sw_interface (vnm, ad->hw_if_index);
411  hw = vnet_get_hw_interface (vnm, ad->hw_if_index);
412  args->sw_if_index = ad->sw_if_index = sw->sw_if_index;
414 
416  af_xdp_input_node.index);
417 
418  for (i = 0; i < vec_len (ad->rxqs); i++)
419  {
420  af_xdp_rxq_t *rxq = vec_elt_at_index (ad->rxqs, i);
421  clib_file_t f = {
422  .file_descriptor = rxq->xsk_fd,
424  .private_data = (uword) ad->dev_instance << 16 | (uword) i,
425  .read_function = af_xdp_device_rxq_read_ready,
426  .description =
427  format (0, "%U rxq %d", format_af_xdp_device_name, ad->dev_instance,
428  i),
429  };
430  rxq->file_index = clib_file_add (&file_main, &f);
432  }
433 
434  /* buffer template */
436  ad->buffer_template->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
437  ad->buffer_template->ref_count = 1;
438  vnet_buffer (ad->buffer_template)->sw_if_index[VLIB_RX] = ad->sw_if_index;
439  vnet_buffer (ad->buffer_template)->sw_if_index[VLIB_TX] = (u32) ~ 0;
441 
442  return;
443 
444 err1:
445  af_xdp_delete_if (vm, ad);
446 err0:
447  vlib_log_err (am->log_class, "%U", format_clib_error, args->error);
448 }
449 
450 static clib_error_t *
452 {
453  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
454  af_xdp_main_t *am = &af_xdp_main;
456  uword is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
457 
458  if (ad->flags & AF_XDP_DEVICE_F_ERROR)
459  return clib_error_return (0, "device is in error state");
460 
461  if (is_up)
462  {
465  ad->flags |= AF_XDP_DEVICE_F_ADMIN_UP;
466  }
467  else
468  {
470  ad->flags &= ~AF_XDP_DEVICE_F_ADMIN_UP;
471  }
472  return 0;
473 }
474 
475 static void
477  u32 node_index)
478 {
479  af_xdp_main_t *am = &af_xdp_main;
480  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
482 
483  /* Shut off redirection */
484  if (node_index == ~0)
485  {
486  ad->per_interface_next_index = node_index;
487  return;
488  }
489 
492  node_index);
493 }
494 
496 #define _(n,s) s,
498 #undef _
499 };
500 
501 static void
502 af_xdp_clear (u32 dev_instance)
503 {
504  af_xdp_main_t *am = &af_xdp_main;
505  af_xdp_device_t *ad = pool_elt_at_index (am->devices, dev_instance);
506  clib_error_free (ad->error);
507 }
508 
509 /* *INDENT-OFF* */
511 {
512  .name = "AF_XDP interface",
513  .format_device = format_af_xdp_device,
514  .format_device_name = format_af_xdp_device_name,
515  .admin_up_down_function = af_xdp_interface_admin_up_down,
516  .rx_redirect_to_node = af_xdp_set_interface_next_node,
517  .tx_function_n_errors = AF_XDP_TX_N_ERROR,
518  .tx_function_error_strings = af_xdp_tx_func_error_strings,
519  .mac_addr_change_function = af_xdp_mac_change,
520  .clear_counters = af_xdp_clear,
521 };
522 /* *INDENT-ON* */
523 
524 clib_error_t *
526 {
527  af_xdp_main_t *am = &af_xdp_main;
528 
529  am->log_class = vlib_log_register_class ("af_xdp", 0);
530 
531  return 0;
532 }
533 
535 
536 /*
537  * fd.io coding-style-patch-verification: ON
538  *
539  * Local Variables:
540  * eval: (c-set-style "gnu")
541  * End:
542  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:338
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
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:124
#define UNIX_FILE_EVENT_EDGE_TRIGGERED
Definition: file.h:58
#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:30
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:58
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:254
u32 per_interface_next_index
Definition: af_xdp.h:88
format_function_t format_af_xdp_device_name
Definition: af_xdp.h:152
u64 private_data
Definition: file.h:64
clib_error_t * error
Definition: af_xdp.h:109
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
u32 file_descriptor
Definition: file.h:54
struct xsk_ring_prod fq
Definition: af_xdp.h:59
vlib_buffer_main_t * buffer_main
Definition: main.h:182
#define XDP_FLAGS_REPLACE
vlib_main_t * vm
Definition: in2out_ed.c:1580
void af_xdp_create_if(vlib_main_t *vm, af_xdp_create_if_args_t *args)
Definition: device.c:305
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:520
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:509
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1173
unsigned char u8
Definition: types.h:56
af_xdp_device_t * devices
Definition: af_xdp.h:114
u8 buffer_pool_index
index of buffer pool this buffer belongs.
Definition: buffer.h:133
af_xdp_rxq_t * rxqs
Definition: af_xdp.h:85
static int af_xdp_load_program(af_xdp_create_if_args_t *args, af_xdp_device_t *ad)
Definition: device.c:127
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)
struct xsk_umem ** umem
Definition: af_xdp.h:102
vlib_log_class_t log_class
Definition: af_xdp.h:115
struct xsk_socket ** xsk
Definition: af_xdp.h:103
vlib_buffer_t * buffer_template
Definition: af_xdp.h:87
gdb_af_xdp_pair_t gdb_af_xdp_get_prod(const struct xsk_ring_prod *prod)
Definition: device.c:39
VNET_DEVICE_CLASS(af_xdp_device_class)
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:127
description fragment has unexpected format
Definition: map.api:433
vnet_hw_interface_flags_t flags
Definition: interface.h:538
uword buffer_mem_size
Definition: buffer.h:457
#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:64
#define clib_error_return(e, args...)
Definition: error.h:99
clib_file_main_t file_main
Definition: main.c:63
unsigned int u32
Definition: types.h:88
char * name
Definition: af_xdp.h:97
#define VLIB_FRAME_SIZE
Definition: node.h:378
unsigned linux_ifindex
Definition: af_xdp.h:106
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
int xsk_fd
Definition: af_xdp.h:60
unsigned short u16
Definition: types.h:57
#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:301
gdb_af_xdp_pair_t gdb_af_xdp_get_cons(const struct xsk_ring_cons *cons)
Definition: device.c:46
static void af_xdp_clear(u32 dev_instance)
Definition: device.c:502
static clib_error_t * af_xdp_mac_change(vnet_hw_interface_t *hw, const u8 *old, const u8 *new)
Definition: device.c:53
static_always_inline u32 vlib_buffer_get_default_data_size(vlib_main_t *vm)
Definition: buffer_funcs.h:96
u32 dev_instance
Definition: af_xdp.h:99
static char * af_xdp_tx_func_error_strings[]
Definition: device.c:495
static void af_xdp_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: device.c:476
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
struct xsk_ring_prod tx
Definition: af_xdp.h:74
#define ETHERNET_INTERFACE_FLAG_MTU
Definition: ethernet.h:166
char * linux_ifname
Definition: af_xdp.h:98
#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:65
format_function_t format_af_xdp_device
Definition: af_xdp.h:151
#define uword_to_pointer(u, type)
Definition: types.h:136
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
Definition: devices.c:139
clib_error_t * af_xdp_init(vlib_main_t *vm)
Definition: device.c:525
u8 hwaddr[6]
Definition: af_xdp.h:100
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
clib_spinlock_t lock
Definition: af_xdp.h:73
#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:90
#define clib_max(x, y)
Definition: clib.h:321
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
vl_api_ip4_address_t hi
Definition: arp.api:37
static uword is_pow2(uword x)
Definition: clib.h:253
int xsk_fd
Definition: af_xdp.h:76
#define foreach_af_xdp_tx_func_error
Definition: af_xdp.h:164
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:451
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
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:102
u64 uword
Definition: types.h:112
clib_error_t * error
Definition: af_xdp.h:141
u32 sw_if_index
Definition: af_xdp.h:89
uword buffer_mem_start
Definition: buffer.h:456
#define clib_error_free(e)
Definition: error.h:86
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.c:188
#define vnet_buffer(b)
Definition: buffer.h:417
static int af_xdp_create_queue(vlib_main_t *vm, af_xdp_create_if_args_t *args, af_xdp_device_t *ad, int qid, int rxq_num, int txq_num)
Definition: device.c:172
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
#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:349
#define vec_foreach(var, vec)
Vector iterator.
__clib_export clib_error_t * clib_sysfs_read(char *file_name, char *fmt,...)
Definition: sysfs.c:50
#define vlib_log_err(...)
Definition: log.h:132
af_xdp_txq_t * txqs
Definition: af_xdp.h:86
Definition: file.h:51
af_xdp_mode_t mode
Definition: af_xdp.h:133
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
static int af_xdp_get_numa(const char *ifname)
Definition: device.c:275
static u8 vlib_buffer_pool_get_default_for_numa(vlib_main_t *vm, u32 numa_node)
Definition: buffer_funcs.h:199
#define af_xdp_log(lvl, dev, f,...)
Definition: af_xdp.h:27
void af_xdp_delete_if(vlib_main_t *vm, af_xdp_device_t *ad)
Definition: device.c:89
volatile u8 ref_count
Reference count for this buffer.
Definition: buffer.h:130
__clib_export u8 * format_clib_error(u8 *s, va_list *va)
Definition: error.c:191
struct xsk_ring_cons cq
Definition: af_xdp.h:75
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: devices.h:79
struct bpf_object * bpf_obj
Definition: af_xdp.h:105
static clib_error_t * af_xdp_device_rxq_read_ready(clib_file_t *f)
Definition: device.c:293
Definition: defs.h:46
int errno_t
Definition: string.h:113