FD.io VPP  v17.04-9-g99c0734
Vector Packet Processing
netmap.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 #include <sys/types.h>
22 #include <fcntl.h>
24 
25 #include <vlib/vlib.h>
26 #include <vlib/unix/unix.h>
27 #include <vnet/ethernet/ethernet.h>
29 
30 static u32
32  u32 flags)
33 {
34  /* nothing for now */
35  return 0;
36 }
37 
38 static clib_error_t *
40 {
43  u32 idx = uf->private_data;
44 
47 
48  /* Schedule the rx node */
50 
51  return 0;
52 }
53 
54 static void
56 {
57  if (nif->unix_file_index != ~0)
58  {
60  nif->unix_file_index = ~0;
61  }
62  else if (nif->fd > -1)
63  close (nif->fd);
64 
65  if (nif->mem_region)
66  {
67  netmap_mem_region_t *reg = &nm->mem_regions[nif->mem_region];
68  if (--reg->refcnt == 0)
69  {
70  munmap (reg->mem, reg->region_size);
71  reg->region_size = 0;
72  }
73  }
74 
75 
77  &nif->if_index);
78  vec_free (nif->host_if_name);
79  vec_free (nif->req);
80 
81  memset (nif, 0, sizeof (*nif));
82  pool_put (nm->interfaces, nif);
83 }
84 
85 int
87 {
88  /* if worker threads are enabled, switch to polling mode */
90  {
91  vlib_node_set_state (this_vlib_main,
92  netmap_input_node.index,
93  VLIB_NODE_STATE_POLLING);
94  }));
95 
96  return 0;
97 }
98 
99 int
101 {
103  {
104  vlib_node_set_state (this_vlib_main,
105  netmap_input_node.index,
106  VLIB_NODE_STATE_INTERRUPT);
107  }));
108 
109  return 0;
110 }
111 
112 int
113 netmap_create_if (vlib_main_t * vm, u8 * if_name, u8 * hw_addr_set,
114  u8 is_pipe, u8 is_master, u32 * sw_if_index)
115 {
116  netmap_main_t *nm = &netmap_main;
117  int ret = 0;
118  netmap_if_t *nif = 0;
119  u8 hw_addr[6];
120  clib_error_t *error = 0;
122  vnet_main_t *vnm = vnet_get_main ();
123  uword *p;
124  struct nmreq *req = 0;
125  netmap_mem_region_t *reg;
127  int fd;
128 
129  p = mhash_get (&nm->if_index_by_host_if_name, if_name);
130  if (p)
131  return VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
132 
133  fd = open ("/dev/netmap", O_RDWR);
134  if (fd < 0)
135  return VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
136 
137  pool_get (nm->interfaces, nif);
138  nif->if_index = nif - nm->interfaces;
139  nif->fd = fd;
140  nif->unix_file_index = ~0;
141 
142  vec_validate (req, 0);
143  nif->req = req;
144  req->nr_version = NETMAP_API;
145  req->nr_flags = NR_REG_ALL_NIC;
146 
147  if (is_pipe)
148  req->nr_flags = is_master ? NR_REG_PIPE_MASTER : NR_REG_PIPE_SLAVE;
149  else
150  req->nr_flags = NR_REG_ALL_NIC;
151 
153  snprintf (req->nr_name, IFNAMSIZ, "%s", if_name);
154  req->nr_name[IFNAMSIZ - 1] = 0;
155 
156  if (ioctl (nif->fd, NIOCREGIF, req))
157  {
158  ret = VNET_API_ERROR_NOT_CONNECTED;
159  goto error;
160  }
161 
162  nif->mem_region = req->nr_arg2;
163  vec_validate (nm->mem_regions, nif->mem_region);
164  reg = &nm->mem_regions[nif->mem_region];
165  if (reg->region_size == 0)
166  {
167  reg->mem = mmap (NULL, req->nr_memsize, PROT_READ | PROT_WRITE,
168  MAP_SHARED, fd, 0);
169  clib_warning ("mem %p", reg->mem);
170  if (reg->mem == MAP_FAILED)
171  {
172  ret = VNET_API_ERROR_NOT_CONNECTED;
173  goto error;
174  }
175  reg->region_size = req->nr_memsize;
176  }
177  reg->refcnt++;
178 
179  nif->nifp = NETMAP_IF (reg->mem, req->nr_offset);
180  nif->first_rx_ring = 0;
181  nif->last_rx_ring = 0;
182  nif->first_tx_ring = 0;
183  nif->last_tx_ring = 0;
184  nif->host_if_name = if_name;
185  nif->per_interface_next_index = ~0;
186 
187  if (tm->n_vlib_mains > 1)
188  {
191  memset ((void *) nif->lockp, 0, CLIB_CACHE_LINE_BYTES);
192  }
193 
194  {
195  unix_file_t template = { 0 };
197  template.file_descriptor = nif->fd;
198  template.private_data = nif->if_index;
199  nif->unix_file_index = unix_file_add (&unix_main, &template);
200  }
201 
202  /*use configured or generate random MAC address */
203  if (hw_addr_set)
204  memcpy (hw_addr, hw_addr_set, 6);
205  else
206  {
207  f64 now = vlib_time_now (vm);
208  u32 rnd;
209  rnd = (u32) (now * 1e6);
210  rnd = random_u32 (&rnd);
211 
212  memcpy (hw_addr + 2, &rnd, sizeof (rnd));
213  hw_addr[0] = 2;
214  hw_addr[1] = 0xfe;
215  }
216 
218  nif->if_index, hw_addr,
219  &nif->hw_if_index,
221 
222  if (error)
223  {
224  clib_error_report (error);
225  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
226  goto error;
227  }
228 
229  sw = vnet_get_hw_sw_interface (vnm, nif->hw_if_index);
230  nif->sw_if_index = sw->sw_if_index;
231 
232  mhash_set_mem (&nm->if_index_by_host_if_name, if_name, &nif->if_index, 0);
233 
234  if (sw_if_index)
235  *sw_if_index = nif->sw_if_index;
236 
237  if (tm->n_vlib_mains > 1 && pool_elts (nm->interfaces) == 1)
239 
240  return 0;
241 
242 error:
243  close_netmap_if (nm, nif);
244  return ret;
245 }
246 
247 int
248 netmap_delete_if (vlib_main_t * vm, u8 * host_if_name)
249 {
250  vnet_main_t *vnm = vnet_get_main ();
251  netmap_main_t *nm = &netmap_main;
252  netmap_if_t *nif;
253  uword *p;
255 
256  p = mhash_get (&nm->if_index_by_host_if_name, host_if_name);
257  if (p == NULL)
258  {
259  clib_warning ("Host interface %s does not exist", host_if_name);
260  return VNET_API_ERROR_SYSCALL_ERROR_1;
261  }
262  nif = pool_elt_at_index (nm->interfaces, p[0]);
263 
264  /* bring down the interface */
266 
268 
269  close_netmap_if (nm, nif);
270 
271  if (tm->n_vlib_mains > 1 && pool_elts (nm->interfaces) == 0)
273 
274  return 0;
275 }
276 
277 static clib_error_t *
279 {
280  netmap_main_t *nm = &netmap_main;
283  uword *p;
284 
285  memset (nm, 0, sizeof (netmap_main_t));
286 
287  nm->input_cpu_first_index = 0;
288  nm->input_cpu_count = 1;
289 
290  /* find out which cpus will be used for input */
291  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
292  tr = p ? (vlib_thread_registration_t *) p[0] : 0;
293 
294  if (tr && tr->count > 0)
295  {
297  nm->input_cpu_count = tr->count;
298  }
299 
301 
304 
305  return 0;
306 }
307 
309 
310 /*
311  * fd.io coding-style-patch-verification: ON
312  *
313  * Local Variables:
314  * eval: (c-set-style "gnu")
315  * End:
316  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
unix_file_t * file_pool
Definition: unix.h:89
vmrglw vmrglh hi
uint32_t nr_offset
Definition: net_netmap.h:477
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:530
unix_file_function_t * read_function
Definition: unix.h:62
netmap_if_t * interfaces
Definition: netmap.h:78
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:295
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
int netmap_worker_thread_enable()
Definition: netmap.c:86
volatile u32 * lockp
Definition: netmap.h:46
static void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:181
unix_main_t unix_main
Definition: main.c:59
#define NULL
Definition: clib.h:55
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:353
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:185
uint32_t nr_memsize
Definition: net_netmap.h:478
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
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:447
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
u32 sw_if_index
Definition: netmap.h:50
#define NIOCREGIF
Definition: net_netmap.h:595
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
u32 per_interface_next_index
Definition: netmap.h:53
char nr_name[IFNAMSIZ]
Definition: net_netmap.h:475
u32 input_cpu_count
Definition: netmap.h:96
struct netmap_if * nifp
Definition: netmap.h:60
#define NETMAP_API
Definition: net_netmap.h:42
struct nmreq * req
Definition: netmap.h:57
static uword unix_file_add(unix_main_t *um, unix_file_t *template)
Definition: unix.h:136
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
uword private_data
Definition: unix.h:59
netmap_mem_region_t * mem_regions
Definition: netmap.h:90
uword mhash_set_mem(mhash_t *h, void *key, uword *new_value, uword *old_value)
Definition: mhash.c:271
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
uint32_t nr_version
Definition: net_netmap.h:476
static u32 netmap_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
Definition: netmap.c:31
#define foreach_vlib_main(body)
Definition: threads.h:225
u16 first_rx_ring
Definition: netmap.h:63
mhash_t if_index_by_host_if_name
Definition: netmap.h:87
vlib_main_t * vm
Definition: buffer.c:276
int fd
Definition: netmap.h:59
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
u16 first_tx_ring
Definition: netmap.h:61
#define NR_ACCEPT_VNET_HDR
Definition: net_netmap.h:543
#define clib_warning(format, args...)
Definition: error.h:59
u32 hw_if_index
Definition: netmap.h:49
int netmap_create_if(vlib_main_t *vm, u8 *if_name, u8 *hw_addr_set, u8 is_pipe, u8 is_master, u32 *sw_if_index)
Definition: netmap.c:113
u16 last_rx_ring
Definition: netmap.h:64
static void close_netmap_if(netmap_main_t *nm, netmap_if_t *nif)
Definition: netmap.c:55
u16 last_tx_ring
Definition: netmap.h:62
uword if_index
Definition: netmap.h:48
netmap_main_t netmap_main
Definition: netmap.h:99
vlib_node_registration_t netmap_input_node
(constructor) VLIB_REGISTER_NODE (netmap_input_node)
Definition: node.c:280
unsigned int u32
Definition: types.h:88
static uword * mhash_get(mhash_t *h, const void *key)
Definition: mhash.h:110
u16 mem_region
Definition: netmap.h:58
u8 * host_if_name
Definition: netmap.h:47
int netmap_worker_thread_disable()
Definition: netmap.c:100
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
Definition: interface.c:246
static clib_error_t * netmap_fd_read_ready(unix_file_t *uf)
Definition: netmap.c:39
#define clib_error_report(e)
Definition: error.h:125
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
Definition: node_funcs.h:146
uword * thread_registrations_by_name
Definition: threads.h:276
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u64 uword
Definition: types.h:112
u32 unix_file_index
Definition: netmap.h:51
u32 input_cpu_first_index
Definition: netmap.h:93
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
vnet_device_class_t netmap_device_class
Definition: unix.h:49
uint16_t nr_arg2
Definition: net_netmap.h:511
uword * pending_input_bitmap
Definition: netmap.h:81
#define hash_get_mem(h, key)
Definition: hash.h:268
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:117
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
u32 ** rx_buffers
Definition: netmap.h:84
u32 flags
Definition: vhost-user.h:78
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
static clib_error_t * netmap_init(vlib_main_t *vm)
Definition: netmap.c:278
uint32_t nr_flags
Definition: net_netmap.h:513
int netmap_delete_if(vlib_main_t *vm, u8 *host_if_name)
Definition: netmap.c:248
static void unix_file_del(unix_main_t *um, unix_file_t *f)
Definition: unix.h:146
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109