FD.io VPP  v16.06
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 {
33  /* nothing for now */
34  return 0;
35 }
36 
38 {
39  vlib_main_t * vm = vlib_get_main();
40  netmap_main_t * nm = &netmap_main;
41  u32 idx = uf->private_data;
42 
44 
45  /* Schedule the rx node */
47 
48  return 0;
49 }
50 
51 static void
53 {
54  if (nif->unix_file_index != ~0) {
56  nif->unix_file_index = ~0;
57  }
58 
59  if (nif->fd > -1)
60  close(nif->fd);
61 
62  if (nif->mem_region)
63  {
64  netmap_mem_region_t * reg = &nm->mem_regions[nif->mem_region];
65  if (--reg->refcnt == 0)
66  {
67  munmap(reg->mem, reg->region_size);
68  reg->region_size = 0;
69  }
70  }
71 
72 
74  vec_free(nif->host_if_name);
75  vec_free(nif->req);
76 
77  memset(nif, 0, sizeof(*nif));
78  pool_put(nm->interfaces, nif);
79 }
80 
81 int
82 netmap_create_if(vlib_main_t * vm, u8 * if_name, u8 * hw_addr_set,
83  u8 is_pipe, u8 is_master)
84 {
85  netmap_main_t * nm = &netmap_main;
86  int ret = 0;
87  netmap_if_t * nif = 0;
88  u8 hw_addr[6];
89  clib_error_t * error = 0;
91  vnet_main_t *vnm = vnet_get_main();
92  uword * p;
93  struct nmreq * req = 0;
94  netmap_mem_region_t * reg;
95  int fd;
96 
97  p = mhash_get (&nm->if_index_by_host_if_name, if_name);
98  if (p)
99  return VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
100 
101  fd = open("/dev/netmap", O_RDWR);
102  if (fd < 0)
103  return VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
104 
105  pool_get (nm->interfaces, nif);
106  nif->if_index = nif - nm->interfaces;
107  nif->fd = fd;
108  nif->unix_file_index = ~0;
109 
110  vec_validate(req, 0);
111  nif->req = req;
112  req->nr_version = NETMAP_API;
113  req->nr_flags = NR_REG_ALL_NIC;
114 
115  if (is_pipe)
116  req->nr_flags = is_master ? NR_REG_PIPE_MASTER : NR_REG_PIPE_SLAVE;
117  else
118  req->nr_flags = NR_REG_ALL_NIC;
119 
121  snprintf(req->nr_name, IFNAMSIZ, "%s", if_name);
122  req->nr_name[IFNAMSIZ-1] = 0;
123 
124  if (ioctl(nif->fd, NIOCREGIF, req))
125  {
126  ret = VNET_API_ERROR_NOT_CONNECTED;
127  goto error;
128  }
129 
130  nif->mem_region = req->nr_arg2;
131  vec_validate (nm->mem_regions, nif->mem_region);
132  reg = &nm->mem_regions[nif->mem_region];
133  if (reg->region_size == 0)
134  {
135  reg->mem = mmap(NULL, req->nr_memsize, PROT_READ | PROT_WRITE,
136  MAP_SHARED, fd, 0);
137  clib_warning("mem %p", reg->mem);
138  if (reg->mem == MAP_FAILED)
139  {
140  ret = VNET_API_ERROR_NOT_CONNECTED;
141  goto error;
142  }
143  reg->region_size = req->nr_memsize;
144  }
145  reg->refcnt++;
146 
147  nif->nifp = NETMAP_IF(reg->mem, req->nr_offset);
148  nif->first_rx_ring = 0;
149  nif->last_rx_ring = 0;
150  nif->first_tx_ring = 0;
151  nif->last_tx_ring = 0;
152  nif->host_if_name = if_name;
153  nif->per_interface_next_index = ~0;
154 
155  {
156  unix_file_t template = {0};
158  template.file_descriptor = nif->fd;
159  template.private_data = nif->if_index;
160  nif->unix_file_index = unix_file_add (&unix_main, &template);
161  }
162 
163  /*use configured or generate random MAC address */
164  if (hw_addr_set)
165  memcpy(hw_addr, hw_addr_set, 6);
166  else
167  {
168  f64 now = vlib_time_now(vm);
169  u32 rnd;
170  rnd = (u32) (now * 1e6);
171  rnd = random_u32 (&rnd);
172 
173  memcpy (hw_addr+2, &rnd, sizeof(rnd));
174  hw_addr[0] = 2;
175  hw_addr[1] = 0xfe;
176  }
177 
179  nif->if_index, hw_addr, &nif->hw_if_index,
181 
182  if (error)
183  {
184  clib_error_report (error);
185  ret = VNET_API_ERROR_SYSCALL_ERROR_1;
186  goto error;
187  }
188 
189  sw = vnet_get_hw_sw_interface (vnm, nif->hw_if_index);
190  nif->sw_if_index = sw->sw_if_index;
191 
194 
195  mhash_set_mem (&nm->if_index_by_host_if_name, if_name, &nif->if_index, 0);
196 
197  return 0;
198 
199 error:
200  close_netmap_if(nm, nif);
201  return ret;
202 }
203 
204 int
205 netmap_delete_if(vlib_main_t *vm, u8 *host_if_name)
206 {
207  vnet_main_t *vnm = vnet_get_main();
208  netmap_main_t *nm = &netmap_main;
209  netmap_if_t *nif;
210  uword *p;
211 
212  p = mhash_get(&nm->if_index_by_host_if_name, host_if_name);
213  if (p == NULL) {
214  clib_warning("Host interface %s does not exist", host_if_name);
215  return VNET_API_ERROR_SYSCALL_ERROR_1;
216  }
217  nif = pool_elt_at_index(nm->interfaces, p[0]);
218 
219  /* bring down the interface */
221 
223 
224  close_netmap_if(nm, nif);
225  return 0;
226 }
227 
228 static clib_error_t *
230 {
231  netmap_main_t * nm = &netmap_main;
232 
233  memset (nm, 0, sizeof (netmap_main_t));
234 
236 
237  return 0;
238 }
239 
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:394
unix_file_t * file_pool
Definition: unix.h:85
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:454
unix_file_function_t * read_function
Definition: unix.h:61
netmap_if_t * interfaces
Definition: netmap.h:79
always_inline void mhash_init_vec_string(mhash_t *h, uword n_value_bytes)
Definition: mhash.h:81
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface.c:205
#define NULL
Definition: clib.h:55
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:350
always_inline uword unix_file_add(unix_main_t *um, unix_file_t *template)
Definition: unix.h:131
uint32_t nr_memsize
Definition: net_netmap.h:478
always_inline void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:134
#define clib_error_report(e)
Definition: error.h:126
#define VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:241
#define pool_get(P, E)
Definition: pool.h:186
always_inline vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u32 sw_if_index
Definition: netmap.h:53
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
#define NIOCREGIF
Definition: net_netmap.h:595
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
u32 per_interface_next_index
Definition: netmap.h:56
char nr_name[IFNAMSIZ]
Definition: net_netmap.h:475
#define clib_warning(format, args...)
Definition: error.h:59
always_inline u32 random_u32(u32 *seed)
32-bit random number generator
Definition: random.h:68
struct netmap_if * nifp
Definition: netmap.h:63
#define NETMAP_API
Definition: net_netmap.h:42
struct nmreq * req
Definition: netmap.h:60
#define pool_elt_at_index(p, i)
Definition: pool.h:346
uword private_data
Definition: unix.h:58
netmap_mem_region_t * mem_regions
Definition: netmap.h:91
uword mhash_set_mem(mhash_t *h, void *key, uword *new_value, uword *old_value)
Definition: mhash.c:272
#define pool_put(P, E)
Definition: pool.h:200
always_inline uword * clib_bitmap_set(uword *ai, uword i, uword value)
Definition: bitmap.h:132
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
u16 first_rx_ring
Definition: netmap.h:66
mhash_t if_index_by_host_if_name
Definition: netmap.h:88
int fd
Definition: netmap.h:62
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
u16 first_tx_ring
Definition: netmap.h:64
int netmap_create_if(vlib_main_t *vm, u8 *if_name, u8 *hw_addr_set, u8 is_pipe, u8 is_master)
Definition: netmap.c:82
#define NR_ACCEPT_VNET_HDR
Definition: net_netmap.h:543
u32 hw_if_index
Definition: netmap.h:52
u16 last_rx_ring
Definition: netmap.h:67
static void close_netmap_if(netmap_main_t *nm, netmap_if_t *nif)
Definition: netmap.c:52
u16 last_tx_ring
Definition: netmap.h:65
uword if_index
Definition: netmap.h:51
always_inline void unix_file_del(unix_main_t *um, unix_file_t *f)
Definition: unix.h:141
netmap_main_t netmap_main
Definition: netmap.h:94
vlib_node_registration_t netmap_input_node
(constructor) VLIB_REGISTER_NODE (netmap_input_node)
Definition: node.c:269
unsigned int u32
Definition: types.h:88
u16 mem_region
Definition: netmap.h:61
u8 * host_if_name
Definition: netmap.h:50
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:157
static clib_error_t * netmap_fd_read_ready(unix_file_t *uf)
Definition: netmap.c:37
unix_main_t unix_main
Definition: main.c:57
u64 uword
Definition: types.h:112
u32 unix_file_index
Definition: netmap.h:54
double f64
Definition: types.h:140
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:82
#define NETMAP_IF(_base, _ofs)
Definition: netmap.h:107
always_inline f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:182
u32 flags
Definition: vhost-user.h:73
static clib_error_t * netmap_init(vlib_main_t *vm)
Definition: netmap.c:229
uint32_t nr_flags
Definition: net_netmap.h:513
always_inline uword * mhash_get(mhash_t *h, void *key)
Definition: mhash.h:104
int netmap_delete_if(vlib_main_t *vm, u8 *host_if_name)
Definition: netmap.c:205
always_inline vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)