FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
device.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2016 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 <stdint.h>
19 #include <net/if.h>
20 #include <sys/ioctl.h>
21 
22 #include <vlib/vlib.h>
23 #include <vlib/unix/unix.h>
24 #include <vnet/ethernet/ethernet.h>
25 
26 #include <vnet/devices/netmap/net_netmap.h>
27 #include <vnet/devices/netmap/netmap.h>
28 
29 #define foreach_netmap_tx_func_error \
30 _(NO_FREE_SLOTS, "no free tx slots") \
31 _(PENDING_MSGS, "pending msgs in tx ring")
32 
33 typedef enum
34 {
35 #define _(f,s) NETMAP_TX_ERROR_##f,
37 #undef _
40 
41 static char *netmap_tx_func_error_strings[] = {
42 #define _(n,s) s,
44 #undef _
45 };
46 
47 
48 static u8 *
49 format_netmap_device_name (u8 * s, va_list * args)
50 {
51  u32 i = va_arg (*args, u32);
52  netmap_main_t *apm = &netmap_main;
54 
55  s = format (s, "netmap-%s", nif->host_if_name);
56  return s;
57 }
58 
59 static u8 *
60 format_netmap_device (u8 * s, va_list * args)
61 {
62  u32 dev_instance = va_arg (*args, u32);
63  int verbose = va_arg (*args, int);
65  netmap_if_t *nif = vec_elt_at_index (nm->interfaces, dev_instance);
66  u32 indent = format_get_indent (s);
67 
68  s = format (s, "NETMAP interface");
69  if (verbose)
70  {
71  s = format (s, "\n%U version %d flags 0x%x"
72  "\n%U region %u memsize 0x%x offset 0x%x"
73  "\n%U tx_slots %u rx_slots %u tx_rings %u rx_rings %u",
74  format_white_space, indent + 2,
75  nif->req->nr_version,
76  nif->req->nr_flags,
77  format_white_space, indent + 2,
78  nif->mem_region,
79  nif->req->nr_memsize,
80  nif->req->nr_offset,
81  format_white_space, indent + 2,
82  nif->req->nr_tx_slots,
83  nif->req->nr_rx_slots,
84  nif->req->nr_tx_rings, nif->req->nr_rx_rings);
85  }
86  return s;
87 }
88 
89 static u8 *
90 format_netmap_tx_trace (u8 * s, va_list * args)
91 {
92  s = format (s, "Unimplemented...");
93  return s;
94 }
95 
99 {
101  u32 *buffers = vlib_frame_vector_args (frame);
102  u32 n_left = frame->n_vectors;
103  f64 const time_constant = 1e3;
104  vnet_interface_output_runtime_t *rd = (void *) node->runtime_data;
106  int cur_ring;
107 
108  clib_spinlock_lock_if_init (&nif->lockp);
109 
110  cur_ring = nif->first_tx_ring;
111 
112  while (n_left && cur_ring <= nif->last_tx_ring)
113  {
114  struct netmap_ring *ring = NETMAP_TXRING (nif->nifp, cur_ring);
115  int n_free_slots = nm_ring_space (ring);
116  uint cur = ring->cur;
117 
118  if (nm_tx_pending (ring))
119  {
120  if (ioctl (nif->fd, NIOCTXSYNC, NULL) < 0)
121  clib_unix_warning ("NIOCTXSYNC");
122  clib_cpu_time_wait (time_constant);
123 
124  if (nm_tx_pending (ring) && !n_free_slots)
125  {
126  cur_ring++;
127  continue;
128  }
129  }
130 
131  while (n_left && n_free_slots)
132  {
133  vlib_buffer_t *b0 = 0;
134  u32 bi = buffers[0];
135  u32 len;
136  u32 offset = 0;
137  buffers++;
138 
139  struct netmap_slot *slot = &ring->slot[cur];
140 
141  do
142  {
143  b0 = vlib_get_buffer (vm, bi);
144  len = b0->current_length;
145  /* memcpy */
146  clib_memcpy_fast ((u8 *) NETMAP_BUF (ring, slot->buf_idx) +
148  offset += len;
149  }
150  while ((bi = b0->next_buffer));
151 
152  slot->len = offset;
153  cur = (cur + 1) % ring->num_slots;
154  n_free_slots--;
155  n_left--;
156  }
158  ring->head = ring->cur = cur;
159  }
160 
161  if (n_left < frame->n_vectors)
162  ioctl (nif->fd, NIOCTXSYNC, NULL);
163 
164  clib_spinlock_unlock_if_init (&nif->lockp);
165 
166  if (n_left)
167  vlib_error_count (vm, node->node_index,
168  (n_left ==
169  frame->n_vectors ? NETMAP_TX_ERROR_PENDING_MSGS :
170  NETMAP_TX_ERROR_NO_FREE_SLOTS), n_left);
171 
173  return frame->n_vectors;
174 }
175 
176 static void
178  u32 node_index)
179 {
180  netmap_main_t *apm = &netmap_main;
181  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
183 
184  /* Shut off redirection */
185  if (node_index == ~0)
186  {
188  return;
189  }
190 
193  node_index);
194 }
195 
196 static void
198 {
199  /* Nothing for now */
200 }
201 
202 static clib_error_t *
204 {
205  netmap_main_t *apm = &netmap_main;
206  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
208  u32 hw_flags;
209 
211 
212  if (nif->is_admin_up)
214  else
215  hw_flags = 0;
216 
217  vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
218 
219  return 0;
220 }
221 
222 static clib_error_t *
224  u32 hw_if_index,
225  struct vnet_sw_interface_t *st, int is_add)
226 {
227  /* Nothing for now */
228  return 0;
229 }
230 
231 /* *INDENT-OFF* */
233  .name = "netmap",
234  .format_device_name = format_netmap_device_name,
235  .format_device = format_netmap_device,
236  .format_tx_trace = format_netmap_tx_trace,
237  .tx_function_n_errors = NETMAP_TX_N_ERROR,
238  .tx_function_error_strings = netmap_tx_func_error_strings,
239  .rx_redirect_to_node = netmap_set_interface_next_node,
240  .clear_counters = netmap_clear_hw_interface_counters,
241  .admin_up_down_function = netmap_interface_admin_up_down,
242  .subif_add_del_function = netmap_subif_add_del_function,
243 };
244 /* *INDENT-ON* */
245 
246 /*
247  * fd.io coding-style-patch-verification: ON
248  *
249  * Local Variables:
250  * eval: (c-set-style "gnu")
251  * End:
252  */
vlib.h
vlib_buffer_t::next_buffer
u32 next_buffer
Next buffer for this linked-list of buffers.
Definition: buffer.h:149
nmreq::nr_tx_slots
uint32_t nr_tx_slots
Definition: net_netmap.h:479
netmap_ring
Definition: net_netmap.h:259
vlib_buffer_free
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: buffer_funcs.h:982
format_netmap_device
static u8 * format_netmap_device(u8 *s, va_list *args)
Definition: device.c:60
netmap_main
netmap_main_t netmap_main
Definition: netmap.c:30
vnet_sw_interface_t
Definition: interface.h:868
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
vlib_node_add_next
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1177
format_netmap_tx_trace
static u8 * format_netmap_tx_trace(u8 *s, va_list *args)
Definition: device.c:90
clib_spinlock_lock_if_init
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:106
netmap_if_t::req
struct nmreq * req
Definition: netmap.h:59
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
foreach_netmap_tx_func_error
#define foreach_netmap_tx_func_error
Definition: device.c:29
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
nat44_ei_main_s::interfaces
nat44_ei_interface_t * interfaces
Definition: nat44_ei.h:339
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
VNET_DEVICE_CLASS
VNET_DEVICE_CLASS(af_xdp_device_class)
VNET_SW_INTERFACE_FLAG_ADMIN_UP
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:843
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
node_index
node node_index
Definition: interface_output.c:420
VNET_HW_INTERFACE_FLAG_LINK_UP
@ VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:509
vnet_hw_interface_t::dev_instance
u32 dev_instance
Definition: interface.h:660
vlib_error_count
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
Definition: error_funcs.h:57
vlib_frame_t
Definition: node.h:372
clib_memcpy_fast
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
Definition: string.h:92
ethernet.h
VNET_DEVICE_CLASS_TX_FN
#define VNET_DEVICE_CLASS_TX_FN(devclass)
Definition: interface.h:317
clib_unix_warning
#define clib_unix_warning(format, args...)
Definition: error.h:68
netmap_tx_func_error_t
netmap_tx_func_error_t
Definition: device.c:33
nmreq::nr_version
uint32_t nr_version
Definition: net_netmap.h:476
netmap_ring::head
uint32_t head
Definition: net_netmap.h:271
netmap_tx_func_error_strings
static char * netmap_tx_func_error_strings[]
Definition: device.c:41
netmap_interface_admin_up_down
static clib_error_t * netmap_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: device.c:203
netmap_clear_hw_interface_counters
static void netmap_clear_hw_interface_counters(u32 instance)
Definition: device.c:197
clib_cpu_time_wait
static void clib_cpu_time_wait(u64 dt)
Definition: time.h:236
len
u8 len
Definition: ip_types.api:103
nmreq::nr_flags
uint32_t nr_flags
Definition: net_netmap.h:513
slot
u8 slot
Definition: pci_types.api:22
vnet_interface_output_runtime_t::dev_instance
u32 dev_instance
Definition: interface_funcs.h:476
netmap_device_class
VNET_DEVICE_CLASS_TX_FN() netmap_device_class(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: device.c:96
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
netmap_slot
Definition: net_netmap.h:145
offset
struct clib_bihash_value offset
template key/value backing page structure
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
NETMAP_TX_N_ERROR
@ NETMAP_TX_N_ERROR
Definition: device.c:38
netmap_subif_add_del_function
static clib_error_t * netmap_subif_add_del_function(vnet_main_t *vnm, u32 hw_if_index, struct vnet_sw_interface_t *st, int is_add)
Definition: device.c:223
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
f64
double f64
Definition: types.h:142
netmap_if_t::mem_region
u16 mem_region
Definition: netmap.h:60
nmreq::nr_offset
uint32_t nr_offset
Definition: net_netmap.h:477
CLIB_MEMORY_BARRIER
#define CLIB_MEMORY_BARRIER()
Definition: clib.h:137
netmap_main_t
Definition: netmap.h:77
vlib_buffer_t::current_length
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:122
netmap_if_t::is_admin_up
u8 is_admin_up
Definition: netmap.h:56
format_netmap_device_name
static u8 * format_netmap_device_name(u8 *s, va_list *args)
Definition: device.c:49
netmap_main_t::interfaces
netmap_if_t * interfaces
Definition: netmap.h:80
vnet_hw_interface_t
Definition: interface.h:638
vnet_main_t
Definition: vnet.h:76
nmreq::nr_memsize
uint32_t nr_memsize
Definition: net_netmap.h:478
clib_bihash_value
template key/value backing page structure
Definition: bihash_doc.h:44
nmreq::nr_rx_rings
uint16_t nr_rx_rings
Definition: net_netmap.h:482
netmap_if_t::host_if_name
u8 * host_if_name
Definition: netmap.h:49
format
description fragment has unexpected format
Definition: map.api:433
format_get_indent
static u32 format_get_indent(u8 *s)
Definition: format.h:72
netmap_if_t::per_interface_next_index
u32 per_interface_next_index
Definition: netmap.h:55
u32
unsigned int u32
Definition: types.h:88
nmreq::nr_tx_rings
uint16_t nr_tx_rings
Definition: net_netmap.h:481
n_left
u32 n_left
Definition: interface_output.c:1078
instance
u32 instance
Definition: gre.api:51
n_vectors
return frame n_vectors
Definition: nat44_ei_hairpinning.c:485
netmap_ring::num_slots
const uint32_t num_slots
Definition: net_netmap.h:266
nm
nat44_ei_main_t * nm
Definition: nat44_ei_hairpinning.c:413
netmap_if_t
Definition: netmap.h:45
vlib_main_t
Definition: main.h:102
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
netmap_ring::cur
uint32_t cur
Definition: net_netmap.h:272
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
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
netmap_ring::slot
struct netmap_slot slot[0]
Definition: net_netmap.h:287
nmreq::nr_rx_slots
uint32_t nr_rx_slots
Definition: net_netmap.h:480
netmap_set_interface_next_node
static void netmap_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
Definition: device.c:177
vlib_node_runtime_t
Definition: node.h:454
clib_spinlock_unlock_if_init
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:129
netmap_input_node
vlib_node_registration_t netmap_input_node
(constructor) VLIB_REGISTER_NODE (netmap_input_node)
Definition: node.c:277
NIOCTXSYNC
#define NIOCTXSYNC
Definition: net_netmap.h:596
format_white_space
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:129
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
vnet_interface_output_runtime_t
Definition: interface_funcs.h:472
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105