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