FD.io VPP  v21.01.1
Vector Packet Processing
af_packet.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * af_packet.c - linux kernel packet interface
4  *
5  * Copyright (c) 2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <linux/if_ether.h>
21 #include <linux/if_packet.h>
22 #include <sys/ioctl.h>
23 #include <net/if.h>
24 #include <dirent.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <fcntl.h>
28 
29 #include <vppinfra/linux/sysfs.h>
30 #include <vlib/vlib.h>
31 #include <vlib/unix/unix.h>
32 #include <vnet/ip/ip.h>
33 #include <vnet/ethernet/ethernet.h>
34 
36 
38 
39 #define AF_PACKET_TX_FRAMES_PER_BLOCK 1024
40 #define AF_PACKET_TX_FRAME_SIZE (2048 * 5)
41 #define AF_PACKET_TX_BLOCK_NR 1
42 #define AF_PACKET_TX_FRAME_NR (AF_PACKET_TX_BLOCK_NR * \
43  AF_PACKET_TX_FRAMES_PER_BLOCK)
44 #define AF_PACKET_TX_BLOCK_SIZE (AF_PACKET_TX_FRAME_SIZE * \
45  AF_PACKET_TX_FRAMES_PER_BLOCK)
46 
47 #define AF_PACKET_RX_FRAMES_PER_BLOCK 1024
48 #define AF_PACKET_RX_FRAME_SIZE (2048 * 5)
49 #define AF_PACKET_RX_BLOCK_NR 1
50 #define AF_PACKET_RX_FRAME_NR (AF_PACKET_RX_BLOCK_NR * \
51  AF_PACKET_RX_FRAMES_PER_BLOCK)
52 #define AF_PACKET_RX_BLOCK_SIZE (AF_PACKET_RX_FRAME_SIZE * \
53  AF_PACKET_RX_FRAMES_PER_BLOCK)
54 
55 /*defined in net/if.h but clashes with dpdk headers */
56 unsigned int if_nametoindex (const char *ifname);
57 
58 typedef struct tpacket_req tpacket_req_t;
59 
60 static u32
62  u32 flags)
63 {
65  u8 *s;
67  af_packet_if_t *apif =
69 
70  if (flags == ETHERNET_INTERFACE_FLAG_MTU)
71  {
72  s = format (0, "/sys/class/net/%s/mtu%c", apif->host_if_name, 0);
73 
74  error = clib_sysfs_write ((char *) s, "%d", hi->max_packet_bytes);
75  vec_free (s);
76 
77  if (error)
78  {
79  vlib_log_err (apm->log_class,
80  "sysfs write failed to change MTU: %U",
81  format_clib_error, error);
82  clib_error_free (error);
83  return VNET_API_ERROR_SYSCALL_ERROR_1;
84  }
85  }
86 
87  return 0;
88 }
89 
90 static clib_error_t *
92 {
94  vnet_main_t *vnm = vnet_get_main ();
95  u32 idx = uf->private_data;
96  af_packet_if_t *apif = pool_elt_at_index (apm->interfaces, idx);
97 
100 
101  /* Schedule the rx node */
103 
104  return 0;
105 }
106 
107 static int
108 is_bridge (const u8 * host_if_name)
109 {
110  u8 *s;
111  DIR *dir = NULL;
112 
113  s = format (0, "/sys/class/net/%s/bridge%c", host_if_name, 0);
114  dir = opendir ((char *) s);
115  vec_free (s);
116 
117  if (dir)
118  {
119  closedir (dir);
120  return 0;
121  }
122 
123  return -1;
124 }
125 
126 static int
127 create_packet_v2_sock (int host_if_index, tpacket_req_t * rx_req,
128  tpacket_req_t * tx_req, int *fd, u8 ** ring)
129 {
131  int ret;
132  struct sockaddr_ll sll;
133  int ver = TPACKET_V2;
134  socklen_t req_sz = sizeof (struct tpacket_req);
135  u32 ring_sz = rx_req->tp_block_size * rx_req->tp_block_nr +
136  tx_req->tp_block_size * tx_req->tp_block_nr;
137 
138  if ((*fd = socket (AF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
139  {
141  "Failed to create AF_PACKET socket: %s (errno %d)",
142  strerror (errno), errno);
143  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
144  goto error;
145  }
146 
147  /* bind before rx ring is cfged so we don't receive packets from other interfaces */
148  clib_memset (&sll, 0, sizeof (sll));
149  sll.sll_family = PF_PACKET;
150  sll.sll_protocol = htons (ETH_P_ALL);
151  sll.sll_ifindex = host_if_index;
152  if (bind (*fd, (struct sockaddr *) &sll, sizeof (sll)) < 0)
153  {
155  "Failed to bind rx packet socket: %s (errno %d)",
156  strerror (errno), errno);
157  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
158  goto error;
159  }
160 
161  if (setsockopt (*fd, SOL_PACKET, PACKET_VERSION, &ver, sizeof (ver)) < 0)
162  {
164  "Failed to set rx packet interface version: %s (errno %d)",
165  strerror (errno), errno);
166  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
167  goto error;
168  }
169 
170  int opt = 1;
171  if (setsockopt (*fd, SOL_PACKET, PACKET_LOSS, &opt, sizeof (opt)) < 0)
172  {
174  "Failed to set packet tx ring error handling option: %s (errno %d)",
175  strerror (errno), errno);
176  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
177  goto error;
178  }
179 
180  if (setsockopt (*fd, SOL_PACKET, PACKET_RX_RING, rx_req, req_sz) < 0)
181  {
183  "Failed to set packet rx ring options: %s (errno %d)",
184  strerror (errno), errno);
185  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
186  goto error;
187  }
188 
189  if (setsockopt (*fd, SOL_PACKET, PACKET_TX_RING, tx_req, req_sz) < 0)
190  {
192  "Failed to set packet tx ring options: %s (errno %d)",
193  strerror (errno), errno);
194  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
195  goto error;
196  }
197 
198  *ring =
199  mmap (NULL, ring_sz, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, *fd,
200  0);
201  if (*ring == MAP_FAILED)
202  {
203  vlib_log_debug (apm->log_class, "mmap failure: %s (errno %d)",
204  strerror (errno), errno);
205  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
206  goto error;
207  }
208 
209  return 0;
210 error:
211  if (*fd >= 0)
212  {
213  close (*fd);
214  *fd = -1;
215  }
216  return ret;
217 }
218 
219 int
220 af_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set,
221  u32 * sw_if_index)
222 {
224  int ret, fd = -1, fd2 = -1;
225  struct tpacket_req *rx_req = 0;
226  struct tpacket_req *tx_req = 0;
227  struct ifreq ifr;
228  u8 *ring = 0;
229  af_packet_if_t *apif = 0;
230  u8 hw_addr[6];
235  vnet_main_t *vnm = vnet_get_main ();
236  uword *p;
237  uword if_index;
238  u8 *host_if_name_dup = 0;
239  int host_if_index = -1;
240 
241  p = mhash_get (&apm->if_index_by_host_if_name, host_if_name);
242  if (p)
243  {
244  apif = vec_elt_at_index (apm->interfaces, p[0]);
245  *sw_if_index = apif->sw_if_index;
246  return VNET_API_ERROR_IF_ALREADY_EXISTS;
247  }
248 
249  host_if_name_dup = vec_dup (host_if_name);
250 
251  vec_validate (rx_req, 0);
252  rx_req->tp_block_size = AF_PACKET_RX_BLOCK_SIZE;
253  rx_req->tp_frame_size = AF_PACKET_RX_FRAME_SIZE;
254  rx_req->tp_block_nr = AF_PACKET_RX_BLOCK_NR;
255  rx_req->tp_frame_nr = AF_PACKET_RX_FRAME_NR;
256 
257  vec_validate (tx_req, 0);
258  tx_req->tp_block_size = AF_PACKET_TX_BLOCK_SIZE;
259  tx_req->tp_frame_size = AF_PACKET_TX_FRAME_SIZE;
260  tx_req->tp_block_nr = AF_PACKET_TX_BLOCK_NR;
261  tx_req->tp_frame_nr = AF_PACKET_TX_FRAME_NR;
262 
263  /*
264  * make sure host side of interface is 'UP' before binding AF_PACKET
265  * socket on it.
266  */
267  if ((fd2 = socket (AF_UNIX, SOCK_DGRAM, 0)) < 0)
268  {
270  "Failed to create AF_UNIX socket: %s (errno %d)",
271  strerror (errno), errno);
272  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
273  goto error;
274  }
275 
276  clib_memcpy (ifr.ifr_name, (const char *) host_if_name,
277  vec_len (host_if_name));
278  if (ioctl (fd2, SIOCGIFINDEX, &ifr) < 0)
279  {
281  "Failed to retrieve the interface (%s) index: %s (errno %d)",
282  host_if_name, strerror (errno), errno);
283  ret = VNET_API_ERROR_INVALID_INTERFACE;
284  goto error;
285  }
286 
287  host_if_index = ifr.ifr_ifindex;
288  if (ioctl (fd2, SIOCGIFFLAGS, &ifr) < 0)
289  {
291  "Failed to get the active flag: %s (errno %d)",
292  strerror (errno), errno);
293  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
294  goto error;
295  }
296 
297  if (!(ifr.ifr_flags & IFF_UP))
298  {
299  ifr.ifr_flags |= IFF_UP;
300  if (ioctl (fd2, SIOCSIFFLAGS, &ifr) < 0)
301  {
303  "Failed to set the active flag: %s (errno %d)",
304  strerror (errno), errno);
305  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
306  goto error;
307  }
308  }
309 
310  if (fd2 > -1)
311  {
312  close (fd2);
313  fd2 = -1;
314  }
315 
316  ret = create_packet_v2_sock (host_if_index, rx_req, tx_req, &fd, &ring);
317 
318  if (ret != 0)
319  goto error;
320 
321  ret = is_bridge (host_if_name);
322 
323  if (ret == 0) /* is a bridge, ignore state */
324  host_if_index = -1;
325 
326  /* So far everything looks good, let's create interface */
327  pool_get (apm->interfaces, apif);
328  if_index = apif - apm->interfaces;
329 
330  apif->host_if_index = host_if_index;
331  apif->fd = fd;
332  apif->rx_ring = ring;
333  apif->tx_ring = ring + rx_req->tp_block_size * rx_req->tp_block_nr;
334  apif->rx_req = rx_req;
335  apif->tx_req = tx_req;
336  apif->host_if_name = host_if_name_dup;
337  apif->per_interface_next_index = ~0;
338  apif->next_tx_frame = 0;
339  apif->next_rx_frame = 0;
340 
341  if (tm->n_vlib_mains > 1)
342  clib_spinlock_init (&apif->lockp);
343 
344  {
345  clib_file_t template = { 0 };
347  template.file_descriptor = fd;
348  template.private_data = if_index;
350  template.description = format (0, "%U", format_af_packet_device_name,
351  if_index);
352  apif->clib_file_index = clib_file_add (&file_main, &template);
353  }
354 
355  /*use configured or generate random MAC address */
356  if (hw_addr_set)
357  clib_memcpy (hw_addr, hw_addr_set, 6);
358  else
359  {
360  f64 now = vlib_time_now (vm);
361  u32 rnd;
362  rnd = (u32) (now * 1e6);
363  rnd = random_u32 (&rnd);
364 
365  clib_memcpy (hw_addr + 2, &rnd, sizeof (rnd));
366  hw_addr[0] = 2;
367  hw_addr[1] = 0xfe;
368  }
369 
371  if_index, hw_addr, &apif->hw_if_index,
373 
374  if (error)
375  {
376  clib_memset (apif, 0, sizeof (*apif));
377  pool_put (apm->interfaces, apif);
378  vlib_log_err (apm->log_class, "Unable to register interface: %U",
379  format_clib_error, error);
380  clib_error_free (error);
381  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
382  goto error;
383  }
384 
385  sw = vnet_get_hw_sw_interface (vnm, apif->hw_if_index);
386  hw = vnet_get_hw_interface (vnm, apif->hw_if_index);
387  apif->sw_if_index = sw->sw_if_index;
389  af_packet_input_node.index);
390 
391  vnet_hw_interface_assign_rx_thread (vnm, apif->hw_if_index, 0, /* queue */
392  ~0 /* any cpu */ );
393 
397 
400 
401  mhash_set_mem (&apm->if_index_by_host_if_name, host_if_name_dup, &if_index,
402  0);
403  if (sw_if_index)
404  *sw_if_index = apif->sw_if_index;
405 
406  return 0;
407 
408 error:
409  if (fd2 > -1)
410  {
411  close (fd2);
412  fd2 = -1;
413  }
414  vec_free (host_if_name_dup);
415  vec_free (rx_req);
416  vec_free (tx_req);
417  return ret;
418 }
419 
420 int
422 {
423  vnet_main_t *vnm = vnet_get_main ();
425  af_packet_if_t *apif;
426  uword *p;
427  uword if_index;
428  u32 ring_sz;
429 
430  p = mhash_get (&apm->if_index_by_host_if_name, host_if_name);
431  if (p == NULL)
432  {
433  vlib_log_warn (apm->log_class, "Host interface %s does not exist",
434  host_if_name);
435  return VNET_API_ERROR_SYSCALL_ERROR_1;
436  }
437  apif = pool_elt_at_index (apm->interfaces, p[0]);
438  if_index = apif - apm->interfaces;
439 
440  /* bring down the interface */
443 
444  /* clean up */
445  if (apif->clib_file_index != ~0)
446  {
448  apif->clib_file_index = ~0;
449  }
450  else
451  close (apif->fd);
452 
453  ring_sz = apif->rx_req->tp_block_size * apif->rx_req->tp_block_nr +
454  apif->tx_req->tp_block_size * apif->tx_req->tp_block_nr;
455  if (munmap (apif->rx_ring, ring_sz))
456  vlib_log_warn (apm->log_class,
457  "Host interface %s could not free rx/tx ring",
458  host_if_name);
459  apif->rx_ring = NULL;
460  apif->tx_ring = NULL;
461  apif->fd = -1;
462 
463  vec_free (apif->rx_req);
464  apif->rx_req = NULL;
465  vec_free (apif->tx_req);
466  apif->tx_req = NULL;
467 
468  vec_free (apif->host_if_name);
469  apif->host_if_name = NULL;
470  apif->host_if_index = -1;
471 
472  mhash_unset (&apm->if_index_by_host_if_name, host_if_name, &if_index);
473 
475 
476  pool_put (apm->interfaces, apif);
477 
478  return 0;
479 }
480 
481 int
483 {
484  vnet_main_t *vnm = vnet_get_main ();
486 
487  hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
488 
489  if (hw->dev_class_index != af_packet_device_class.index)
490  return VNET_API_ERROR_INVALID_INTERFACE;
491 
492  if (set)
494  else
496 
497  return 0;
498 }
499 
500 int
502 {
504  af_packet_if_t *apif;
505  af_packet_if_detail_t *r_af_packet_ifs = NULL;
506  af_packet_if_detail_t *af_packet_if = NULL;
507 
508  /* *INDENT-OFF* */
509  pool_foreach (apif, apm->interfaces)
510  {
511  vec_add2 (r_af_packet_ifs, af_packet_if, 1);
512  af_packet_if->sw_if_index = apif->sw_if_index;
513  if (apif->host_if_name)
514  {
515  clib_memcpy (af_packet_if->host_if_name, apif->host_if_name,
516  MIN (ARRAY_LEN (af_packet_if->host_if_name) - 1,
517  strlen ((const char *) apif->host_if_name)));
518  }
519  }
520  /* *INDENT-ON* */
521 
522  *out_af_packet_ifs = r_af_packet_ifs;
523 
524  return 0;
525 }
526 
527 static clib_error_t *
529 {
532 
533  clib_memset (apm, 0, sizeof (af_packet_main_t));
534 
536 
539 
540  apm->log_class = vlib_log_register_class ("af_packet", 0);
541  vlib_log_debug (apm->log_class, "initialized");
542 
543  return 0;
544 }
545 
547 
548 /*
549  * fd.io coding-style-patch-verification: ON
550  *
551  * Local Variables:
552  * eval: (c-set-style "gnu")
553  * End:
554  */
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:338
u32 ** rx_buffers
Definition: af_packet.h:61
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
#define UNIX_FILE_EVENT_EDGE_TRIGGERED
Definition: file.h:58
static void clib_file_del(clib_file_main_t *um, clib_file_t *f)
Definition: file.h:109
#define vlib_log_warn(...)
Definition: log.h:133
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105
uword * pending_input_bitmap
Definition: af_packet.h:58
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:393
int af_packet_set_l4_cksum_offload(vlib_main_t *vm, u32 sw_if_index, u8 set)
Definition: af_packet.c:482
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
#define AF_PACKET_TX_BLOCK_NR
Definition: af_packet.c:41
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:334
u64 private_data
Definition: file.h:64
struct tpacket_req * tx_req
Definition: af_packet.h:38
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
int af_packet_dump_ifs(af_packet_if_detail_t **out_af_packet_ifs)
Definition: af_packet.c:501
#define AF_PACKET_RX_FRAME_NR
Definition: af_packet.c:50
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
Definition: vec.h:630
static void mhash_init_vec_string(mhash_t *h, uword n_value_bytes)
Definition: mhash.h:84
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
vlib_main_t * vm
Definition: in2out_ed.c:1580
struct tpacket_req * rx_req
Definition: af_packet.h:37
#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
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:251
unsigned char u8
Definition: types.h:56
clib_file_function_t * read_function
Definition: file.h:67
double f64
Definition: types.h:142
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define clib_memcpy(d, s, n)
Definition: string.h:180
u8 * host_if_name
Definition: af_packet.h:34
clib_file_t * file_pool
Definition: file.h:88
af_packet_if_t * interfaces
Definition: af_packet.h:55
__clib_export clib_error_t * clib_sysfs_write(char *file_name, char *fmt,...)
Definition: sysfs.c:26
uword flags
Definition: clib_error.h:29
#define AF_PACKET_TX_BLOCK_SIZE
Definition: af_packet.c:44
clib_spinlock_t lockp
Definition: af_packet.h:33
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u32 next_rx_frame
Definition: af_packet.h:45
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
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
clib_file_main_t file_main
Definition: main.c:63
unsigned int u32
Definition: types.h:88
#define vlib_log_debug(...)
Definition: log.h:136
#define MIN(x, y)
Definition: node.h:31
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:65
Definition: cJSON.c:84
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
format_function_t format_af_packet_device_name
Definition: af_packet.h:81
int vnet_hw_interface_set_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_if_rx_mode mode)
Definition: devices.c:253
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:301
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:429
#define AF_PACKET_RX_BLOCK_NR
Definition: af_packet.c:49
vlib_log_class_t log_class
log class
Definition: af_packet.h:67
struct tpacket_req tpacket_req_t
Definition: af_packet.c:58
u32 next_tx_frame
Definition: af_packet.h:46
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
#define AF_PACKET_RX_BLOCK_SIZE
Definition: af_packet.c:52
#define ETHERNET_INTERFACE_FLAG_MTU
Definition: ethernet.h:166
u32 per_interface_next_index
Definition: af_packet.h:48
#define ARRAY_LEN(x)
Definition: clib.h:67
vlib_node_registration_t af_packet_input_node
(constructor) VLIB_REGISTER_NODE (af_packet_input_node)
Definition: node.c:370
int host_if_index
Definition: af_packet.h:35
u32 clib_file_index
Definition: af_packet.h:43
af_packet_main_t af_packet_main
Definition: af_packet.c:37
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
static uword * mhash_get(mhash_t *h, const void *key)
Definition: mhash.h:110
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Definition: file.h:96
mhash_t if_index_by_host_if_name
Definition: af_packet.h:64
unsigned int if_nametoindex(const char *ifname)
vl_api_ip4_address_t hi
Definition: arp.api:37
vnet_device_class_t af_packet_device_class
static clib_error_t * af_packet_fd_read_ready(clib_file_t *uf)
Definition: af_packet.c:91
__clib_export uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:346
#define AF_PACKET_TX_FRAME_SIZE
Definition: af_packet.c:40
static int create_packet_v2_sock(int host_if_index, tpacket_req_t *rx_req, tpacket_req_t *tx_req, int *fd, u8 **ring)
Definition: af_packet.c:127
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
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
u64 uword
Definition: types.h:112
#define AF_PACKET_RX_FRAME_SIZE
Definition: af_packet.c:48
#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
static u32 random_u32(u32 *seed)
32-bit random number generator
Definition: random.h:69
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
static clib_error_t * af_packet_init(vlib_main_t *vm)
Definition: af_packet.c:528
#define vlib_log_err(...)
Definition: log.h:132
static int is_bridge(const u8 *host_if_name)
Definition: af_packet.c:108
Definition: file.h:51
static u32 af_packet_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
Definition: af_packet.c:61
int af_packet_create_if(vlib_main_t *vm, u8 *host_if_name, u8 *hw_addr_set, u32 *sw_if_index)
Definition: af_packet.c:220
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
__clib_export u8 * format_clib_error(u8 *s, va_list *va)
Definition: error.c:191
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: devices.h:79
__clib_export uword mhash_set_mem(mhash_t *h, void *key, uword *new_value, uword *old_value)
Definition: mhash.c:264
#define AF_PACKET_TX_FRAME_NR
Definition: af_packet.c:42
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
int af_packet_delete_if(vlib_main_t *vm, u8 *host_if_name)
Definition: af_packet.c:421