FD.io VPP  v20.05.1-6-gf53edbc3b
Vector Packet Processing
memif_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * memif_api.c - memif api
4  *
5  * Copyright (c) 2017 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 <vlib/vlib.h>
21 #include <vnet/ethernet/ethernet.h>
22 #include <vlib/unix/unix.h>
23 #include <memif/memif.h>
24 #include <memif/private.h>
25 
26 #include <vlibapi/api.h>
27 #include <vlibmemory/api.h>
28 
29 #include <vnet/ip/ip_types_api.h>
31 
32 /* define message IDs */
33 #include <vnet/format_fns.h>
34 #include <memif/memif.api_enum.h>
35 #include <memif/memif.api_types.h>
36 
37 #define REPLY_MSG_ID_BASE mm->msg_id_base
39 
40 /**
41  * @brief Message handler for memif_socket_filename_add_del API.
42  * @param mp the vl_api_memif_socket_filename_add_del_t API message
43  */
44 void
47 {
48  memif_main_t *mm = &memif_main;
49  u8 is_add;
50  u32 socket_id;
51  u32 len;
52  u8 *socket_filename;
53  vl_api_memif_socket_filename_add_del_reply_t *rmp;
54  int rv;
55 
56  /* is_add */
57  is_add = mp->is_add;
58 
59  /* socket_id */
60  socket_id = clib_net_to_host_u32 (mp->socket_id);
61  if (socket_id == 0 || socket_id == ~0)
62  {
63  rv = VNET_API_ERROR_INVALID_ARGUMENT;
64  goto reply;
65  }
66 
67  /* socket filename */
68  socket_filename = 0;
69  mp->socket_filename[ARRAY_LEN (mp->socket_filename) - 1] = 0;
70  len = strlen ((char *) mp->socket_filename);
71  if (mp->is_add)
72  {
73  vec_validate (socket_filename, len);
74  memcpy (socket_filename, mp->socket_filename, len);
75  }
76 
77  rv = memif_socket_filename_add_del (is_add, socket_id, socket_filename);
78 
79  vec_free (socket_filename);
80 
81 reply:
82  REPLY_MACRO (VL_API_MEMIF_SOCKET_FILENAME_ADD_DEL_REPLY);
83 }
84 
85 
86 /**
87  * @brief Message handler for memif_create API.
88  * @param mp vl_api_memif_create_t * mp the api message
89  */
90 void
92 {
93  memif_main_t *mm = &memif_main;
96  memif_create_if_args_t args = { 0 };
97  u32 ring_size = MEMIF_DEFAULT_RING_SIZE;
98  static const u8 empty_hw_addr[6];
99  int rv = 0;
101 
102  /* id */
103  args.id = clib_net_to_host_u32 (mp->id);
104 
105  /* socket-id */
106  args.socket_id = clib_net_to_host_u32 (mp->socket_id);
107 
108  /* secret */
109  mp->secret[ARRAY_LEN (mp->secret) - 1] = 0;
110  if (strlen ((char *) mp->secret) > 0)
111  {
112  vec_validate (args.secret, strlen ((char *) mp->secret));
113  strncpy ((char *) args.secret, (char *) mp->secret,
114  vec_len (args.secret));
115  }
116 
117  /* role */
118  args.is_master = (ntohl (mp->role) == MEMIF_ROLE_API_MASTER);
119 
120  /* mode */
121  args.mode = ntohl (mp->mode);
122 
123  args.is_zero_copy = mp->no_zero_copy ? 0 : 1;
124 
125  /* rx/tx queues */
126  if (args.is_master == 0)
127  {
130  if (mp->rx_queues)
131  {
132  args.rx_queues = mp->rx_queues;
133  }
134  if (mp->tx_queues)
135  {
136  args.tx_queues = mp->tx_queues;
137  }
138  }
139 
140  /* ring size */
141  if (mp->ring_size)
142  {
143  ring_size = ntohl (mp->ring_size);
144  }
145  if (!is_pow2 (ring_size))
146  {
147  rv = VNET_API_ERROR_INVALID_ARGUMENT;
148  goto reply;
149  }
150  args.log2_ring_size = min_log2 (ring_size);
151 
152  /* buffer size */
154  if (mp->buffer_size)
155  {
156  args.buffer_size = ntohs (mp->buffer_size);
157  }
158 
159  /* MAC address */
160  mac_address_decode (mp->hw_addr, &mac);
161  if (memcmp (&mac, empty_hw_addr, 6) != 0)
162  {
163  memcpy (args.hw_addr, &mac, 6);
164  args.hw_addr_set = 1;
165  }
166 
167  rv = memif_create_if (vm, &args);
168 
169  vec_free (args.secret);
170 
171 reply:
172  /* *INDENT-OFF* */
173  REPLY_MACRO2 (VL_API_MEMIF_CREATE_REPLY,
174  ({
175  rmp->sw_if_index = htonl (args.sw_if_index);
176  }));
177  /* *INDENT-ON* */
178 }
179 
180 /**
181  * @brief Message handler for memif_delete API.
182  * @param mp vl_api_memif_delete_t * mp the api message
183  */
184 void
186 {
187  memif_main_t *mm = &memif_main;
189  vnet_main_t *vnm = vnet_get_main ();
190  vl_api_memif_delete_reply_t *rmp;
192  memif_if_t *mif;
193  int rv = 0;
194 
195  hi =
197  ntohl (mp->sw_if_index));
198 
199  if (hi == NULL || memif_device_class.index != hi->dev_class_index)
200  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
201  else
202  {
203  mif = pool_elt_at_index (mm->interfaces, hi->dev_instance);
204  rv = memif_delete_if (vm, mif);
205  }
206 
207  REPLY_MACRO (VL_API_MEMIF_DELETE_REPLY);
208 }
209 
210 static void
212  memif_if_t * mif,
213  vnet_sw_interface_t * swif,
214  u8 * interface_name, u32 context)
215 {
217  vnet_main_t *vnm = vnet_get_main ();
218  memif_main_t *mm = &memif_main;
219  vnet_hw_interface_t *hwif;
220  memif_socket_file_t *msf;
221 
222  hwif = vnet_get_sup_hw_interface (vnm, swif->sw_if_index);
223 
224  mp = vl_msg_api_alloc (sizeof (*mp));
225  clib_memset (mp, 0, sizeof (*mp));
226 
227  mp->_vl_msg_id = htons (VL_API_MEMIF_DETAILS + mm->msg_id_base);
228  mp->context = context;
229 
230  mp->sw_if_index = htonl (swif->sw_if_index);
231  strncpy ((char *) mp->if_name,
232  (char *) interface_name, ARRAY_LEN (mp->if_name) - 1);
233 
234  if (hwif->hw_address)
235  {
237  }
238 
239  mp->id = clib_host_to_net_u32 (mif->id);
240 
242  mp->socket_id = clib_host_to_net_u32 (msf->socket_id);
243 
244  mp->role =
245  (mif->flags & MEMIF_IF_FLAG_IS_SLAVE) ? MEMIF_ROLE_API_SLAVE :
247  mp->role = htonl (mp->role);
248  mp->mode = htonl (mif->mode);
249  mp->ring_size = htonl (1 << mif->run.log2_ring_size);
250  mp->buffer_size = htons (mif->run.buffer_size);
251  mp->zero_copy = (mif->flags & MEMIF_IF_FLAG_ZERO_COPY) ? 1 : 0;
252 
253  mp->flags = 0;
254  mp->flags |= (swif->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
256  mp->flags |= (hwif->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) ?
258  mp->flags = htonl (mp->flags);
259 
260 
261  vl_api_send_msg (reg, (u8 *) mp);
262 }
263 
264 /**
265  * @brief Message handler for memif_dump API.
266  * @param mp vl_api_memif_dump_t * mp the api message
267  */
268 void
270 {
271  memif_main_t *mm = &memif_main;
272  vnet_main_t *vnm = vnet_get_main ();
273  vnet_sw_interface_t *swif;
274  memif_if_t *mif;
275  u8 *if_name = 0;
277 
279  if (!reg)
280  return;
281 
282  /* *INDENT-OFF* */
283  pool_foreach (mif, mm->interfaces,
284  ({
285  swif = vnet_get_sw_interface (vnm, mif->sw_if_index);
286 
287  if_name = format (if_name, "%U%c",
288  format_vnet_sw_interface_name,
289  vnm, swif, 0);
290 
291  send_memif_details (reg, mif, swif, if_name, mp->context);
292  _vec_len (if_name) = 0;
293  }));
294  /* *INDENT-ON* */
295 
296  vec_free (if_name);
297 }
298 
299 static void
301  u32 socket_id,
302  u8 * socket_filename, u32 context)
303 {
305  memif_main_t *mm = &memif_main;
306 
307  mp = vl_msg_api_alloc (sizeof (*mp));
308  clib_memset (mp, 0, sizeof (*mp));
309 
310  mp->_vl_msg_id = htons (VL_API_MEMIF_SOCKET_FILENAME_DETAILS
311  + mm->msg_id_base);
312  mp->context = context;
313 
314  mp->socket_id = clib_host_to_net_u32 (socket_id);
315  strncpy ((char *) mp->socket_filename,
316  (char *) socket_filename, ARRAY_LEN (mp->socket_filename) - 1);
317 
318  vl_api_send_msg (reg, (u8 *) mp);
319 }
320 
321 /**
322  * @brief Message handler for memif_socket_filename_dump API.
323  * @param mp vl_api_memif_socket_filename_dump_t api message
324  */
325 void
328 {
329  memif_main_t *mm = &memif_main;
331  u32 sock_id;
332  u32 msf_idx;
333 
335  if (!reg)
336  return;
337 
338  /* *INDENT-OFF* */
339  hash_foreach (sock_id, msf_idx, mm->socket_file_index_by_sock_id,
340  ({
341  memif_socket_file_t *msf;
342  u8 *filename;
343 
344  msf = pool_elt_at_index(mm->socket_files, msf_idx);
345  filename = msf->filename;
346  send_memif_socket_filename_details(reg, sock_id, filename, mp->context);
347  }));
348  /* *INDENT-ON* */
349 }
350 
351 /* Set up the API message handling tables */
352 #include <memif/memif.api.c>
353 clib_error_t *
355 {
356  memif_main_t *mm = &memif_main;
357 
358  /* Ask for a correctly-sized block of API message decode slots */
360  return 0;
361 }
362 
363 /*
364  * fd.io coding-style-patch-verification: ON
365  *
366  * Local Variables:
367  * eval: (c-set-style "gnu")
368  * End:
369  */
memif_if_t * interfaces
Definition: private.h:241
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:507
vl_api_mac_address_t hw_addr
Definition: memif.api:85
void vl_api_memif_dump_t_handler(vl_api_memif_dump_t *mp)
Message handler for memif_dump API.
Definition: memif_api.c:269
Create memory interface.
Definition: memif.api:71
vl_api_mac_address_t mac
Definition: l2.api:502
Memory interface details structure.
Definition: memif.api:121
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)
Create memory interface response.
Definition: memif.api:95
void mac_address_encode(const mac_address_t *in, u8 *out)
Create or remove named socket file for memif interfaces.
Definition: memif.api:44
memif_socket_file_t * socket_files
Definition: private.h:244
string if_name[64]
Definition: memif.api:172
memif_log2_ring_size_t log2_ring_size
Definition: private.h:183
#define REPLY_MACRO2(t, body)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
memif_interface_mode_t mode
Definition: private.h:271
vl_api_if_status_flags_t flags
Definition: memif.api:170
Delete memory interface.
Definition: memif.api:107
Dump all memory interfaces.
Definition: memif.api:179
void * vl_msg_api_alloc(int nbytes)
unsigned char u8
Definition: types.h:56
static uword min_log2(uword x)
Definition: clib.h:159
vl_api_memif_role_t role
Definition: memif.api:76
vl_api_interface_index_t sw_if_index
Definition: memif.api:99
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
clib_error_t * memif_plugin_api_hookup(vlib_main_t *vm)
Definition: memif_api.c:354
void vl_api_memif_socket_filename_dump_t_handler(vl_api_memif_socket_filename_dump_t *mp)
Message handler for memif_socket_filename_dump API.
Definition: memif_api.c:327
uword socket_file_index
Definition: private.h:168
u16 buffer_size
Definition: private.h:186
memif_log2_ring_size_t log2_ring_size
Definition: private.h:272
vnet_hw_interface_flags_t flags
Definition: interface.h:526
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:442
vnet_device_class_t memif_device_class
u16 msg_id_base
API message ID base.
Definition: private.h:238
unsigned int u32
Definition: types.h:88
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
int memif_delete_if(vlib_main_t *vm, memif_if_t *mif)
Definition: memif.c:739
void vl_api_memif_create_t_handler(vl_api_memif_create_t *mp)
Message handler for memif_create API.
Definition: memif_api.c:91
#define REPLY_MACRO(t)
vnet_sw_interface_flags_t flags
Definition: interface.h:724
memif_interface_id_t id
Definition: private.h:266
int memif_create_if(vlib_main_t *vm, memif_create_if_args_t *args)
Definition: memif.c:819
#define MEMIF_DEFAULT_TX_QUEUES
Definition: private.h:24
vlib_main_t * vm
Definition: in2out_ed.c:1599
static void send_memif_details(vl_api_registration_t *reg, memif_if_t *mif, vnet_sw_interface_t *swif, u8 *interface_name, u32 context)
Definition: memif_api.c:211
u8 len
Definition: ip_types.api:92
An API client registration, only in vpp/vlib.
Definition: api_common.h:47
vl_api_memif_role_t role
Definition: memif.api:163
Memory interface details structure.
Definition: memif.api:154
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
static vnet_hw_interface_t * vnet_get_sup_hw_interface_api_visible_or_null(vnet_main_t *vnm, u32 sw_if_index)
static void send_memif_socket_filename_details(vl_api_registration_t *reg, u32 socket_id, u8 *socket_filename, u32 context)
Definition: memif_api.c:300
int memif_socket_filename_add_del(u8 is_add, u32 sock_id, u8 *sock_filename)
Definition: memif.c:660
#define ARRAY_LEN(x)
Definition: clib.h:66
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:57
void vl_api_memif_delete_t_handler(vl_api_memif_delete_t *mp)
Message handler for memif_delete API.
Definition: memif_api.c:185
#define MEMIF_DEFAULT_BUFFER_SIZE
Definition: private.h:25
struct memif_if_t::@639 run
vl_api_interface_index_t sw_if_index
Definition: memif.api:112
u32 flags
Definition: private.h:157
vl_api_interface_index_t sw_if_index
Definition: memif.api:158
#define MEMIF_DEFAULT_RX_QUEUES
Definition: private.h:23
Dump the table of socket ids and corresponding filenames.
Definition: memif.api:132
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:250
vl_api_memif_mode_t mode
Definition: memif.api:164
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
memif_interface_id_t id
Definition: private.h:158
#define MEMIF_DEFAULT_RING_SIZE
Definition: private.h:22
vl_api_mac_address_t hw_addr
Definition: memif.api:159
static void setup_message_id_table(snat_main_t *sm, api_main_t *am)
Definition: nat_api.c:3256
vl_api_memif_mode_t mode
Definition: memif.api:77
uword * socket_file_index_by_sock_id
Definition: private.h:245
void vl_api_memif_socket_filename_add_del_t_handler(vl_api_memif_socket_filename_add_del_t *mp)
Message handler for memif_socket_filename_add_del API.
Definition: memif_api.c:46
memif_main_t memif_main
Definition: memif.c:43
void mac_address_decode(const u8 *in, mac_address_t *out)
Conversion functions to/from (decode/encode) API types to VPP internal types.
memif_interface_mode_t mode
Definition: private.h:162
string secret[24]
Definition: memif.api:86