udp: fix csum computation when offload disabled
[vpp.git] / src / plugins / memif / socket.c
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 #define _GNU_SOURCE
19 #include <stdint.h>
20 #include <net/if.h>
21 #include <sys/types.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <sys/uio.h>
27 #include <sys/mman.h>
28 #include <sys/eventfd.h>
29 #include <inttypes.h>
30 #include <limits.h>
31
32 #include <vlib/vlib.h>
33 #include <vlib/unix/unix.h>
34 #include <vnet/plugin/plugin.h>
35 #include <vnet/ethernet/ethernet.h>
36 #include <vpp/app/version.h>
37
38 #include <memif/memif.h>
39 #include <memif/private.h>
40
41 void
42 memif_socket_close (clib_socket_t ** s)
43 {
44   memif_file_del_by_index ((*s)->private_data);
45   clib_mem_free (*s);
46   *s = 0;
47 }
48
49 static u8 *
50 memif_str2vec (uint8_t * str, int len)
51 {
52   u8 *s = 0;
53   int i;
54
55   if (str[0] == 0)
56     return s;
57
58   for (i = 0; i < len; i++)
59     {
60       vec_add1 (s, str[i]);
61       if (str[i] == 0)
62         return s;
63     }
64   vec_add1 (s, 0);
65
66   return s;
67 }
68
69 static void
70 memif_msg_enq_ack (memif_if_t * mif)
71 {
72   memif_msg_fifo_elt_t *e;
73   clib_fifo_add2 (mif->msg_queue, e);
74
75   e->msg.type = MEMIF_MSG_TYPE_ACK;
76   e->fd = -1;
77 }
78
79 static void
80 memif_msg_strlcpy (u8 * dest, u32 len, const u8 * src)
81 {
82   len = clib_min (len - 1, vec_len (src));
83   memcpy (dest, src, len);
84   dest[len] = '\0';
85 }
86
87 static void
88 memif_msg_snprintf (u8 * dest, u32 len, const char *fmt, ...)
89 {
90   va_list va;
91   va_start (va, fmt);
92   u8 *s = va_format (0, fmt, &va);
93   va_end (va);
94   memif_msg_strlcpy (dest, len, s);
95   vec_free (s);
96 }
97
98 static clib_error_t *
99 memif_msg_enq_hello (clib_socket_t * sock)
100 {
101   memif_msg_t msg = { 0 };
102   memif_msg_hello_t *h = &msg.hello;
103   msg.type = MEMIF_MSG_TYPE_HELLO;
104   h->min_version = MEMIF_VERSION;
105   h->max_version = MEMIF_VERSION;
106   h->max_m2s_ring = MEMIF_MAX_M2S_RING;
107   h->max_s2m_ring = MEMIF_MAX_S2M_RING;
108   h->max_region = MEMIF_MAX_REGION;
109   h->max_log2_ring_size = MEMIF_MAX_LOG2_RING_SIZE;
110   memif_msg_snprintf (h->name, sizeof (h->name), "VPP %s", VPP_BUILD_VER);
111   return clib_socket_sendmsg (sock, &msg, sizeof (memif_msg_t), 0, 0);
112 }
113
114 static void
115 memif_msg_enq_init (memif_if_t * mif)
116 {
117   memif_msg_fifo_elt_t *e;
118   clib_fifo_add2 (mif->msg_queue, e);
119   memif_msg_init_t *i = &e->msg.init;
120
121   e->msg.type = MEMIF_MSG_TYPE_INIT;
122   e->fd = -1;
123   i->version = MEMIF_VERSION;
124   i->id = mif->id;
125   i->mode = mif->mode;
126   memif_msg_snprintf (i->name, sizeof (i->name), "VPP %s", VPP_BUILD_VER);
127   if (mif->secret)
128     memif_msg_strlcpy (i->secret, sizeof (i->secret), mif->secret);
129 }
130
131 static void
132 memif_msg_enq_add_region (memif_if_t * mif, u8 region)
133 {
134   memif_msg_fifo_elt_t *e;
135   clib_fifo_add2 (mif->msg_queue, e);
136   memif_msg_add_region_t *ar = &e->msg.add_region;
137
138   e->msg.type = MEMIF_MSG_TYPE_ADD_REGION;
139   e->fd = mif->regions[region].fd;
140   ar->index = region;
141   ar->size = mif->regions[region].region_size;
142 }
143
144 static void
145 memif_msg_enq_add_ring (memif_if_t * mif, u8 index, u8 direction)
146 {
147   memif_msg_fifo_elt_t *e;
148   clib_fifo_add2 (mif->msg_queue, e);
149   memif_msg_add_ring_t *ar = &e->msg.add_ring;
150   memif_queue_t *mq;
151
152   ASSERT ((mif->flags & MEMIF_IF_FLAG_IS_SLAVE) != 0);
153
154   e->msg.type = MEMIF_MSG_TYPE_ADD_RING;
155
156   if (direction == MEMIF_RING_M2S)
157     mq = vec_elt_at_index (mif->rx_queues, index);
158   else
159     mq = vec_elt_at_index (mif->tx_queues, index);
160
161   e->fd = mq->int_fd;
162   ar->index = index;
163   ar->region = mq->region;
164   ar->offset = mq->offset;
165   ar->log2_ring_size = mq->log2_ring_size;
166   ar->flags = (direction == MEMIF_RING_S2M) ? MEMIF_MSG_ADD_RING_FLAG_S2M : 0;
167   ar->private_hdr_size = 0;
168 }
169
170 static void
171 memif_msg_enq_connect (memif_if_t * mif)
172 {
173   memif_msg_fifo_elt_t *e;
174   clib_fifo_add2 (mif->msg_queue, e);
175   memif_msg_connect_t *c = &e->msg.connect;
176
177   e->msg.type = MEMIF_MSG_TYPE_CONNECT;
178   e->fd = -1;
179   memif_msg_snprintf (c->if_name, sizeof (c->if_name), "%U",
180                       format_memif_device_name, mif->dev_instance);
181 }
182
183 static void
184 memif_msg_enq_connected (memif_if_t * mif)
185 {
186   memif_msg_fifo_elt_t *e;
187   clib_fifo_add2 (mif->msg_queue, e);
188   memif_msg_connected_t *c = &e->msg.connected;
189
190   e->msg.type = MEMIF_MSG_TYPE_CONNECTED;
191   e->fd = -1;
192   memif_msg_snprintf (c->if_name, sizeof (c->if_name), "%U",
193                       format_memif_device_name, mif->dev_instance);
194 }
195
196 clib_error_t *
197 memif_msg_send_disconnect (memif_if_t * mif, clib_error_t * err)
198 {
199   memif_msg_t msg = { 0 };
200   msg.type = MEMIF_MSG_TYPE_DISCONNECT;
201   memif_msg_disconnect_t *d = &msg.disconnect;
202
203   d->code = err->code;
204   memif_msg_strlcpy (d->string, sizeof (d->string), err->what);
205
206   return clib_socket_sendmsg (mif->sock, &msg, sizeof (memif_msg_t), 0, 0);
207 }
208
209 static clib_error_t *
210 memif_msg_receive_hello (memif_if_t * mif, memif_msg_t * msg)
211 {
212   memif_msg_hello_t *h = &msg->hello;
213
214   if (msg->hello.min_version > MEMIF_VERSION ||
215       msg->hello.max_version < MEMIF_VERSION)
216     return clib_error_return (0, "incompatible protocol version");
217
218   mif->run.num_s2m_rings = clib_min (h->max_s2m_ring + 1,
219                                      mif->cfg.num_s2m_rings);
220   mif->run.num_m2s_rings = clib_min (h->max_m2s_ring + 1,
221                                      mif->cfg.num_m2s_rings);
222   mif->run.log2_ring_size = clib_min (h->max_log2_ring_size,
223                                       mif->cfg.log2_ring_size);
224   mif->run.buffer_size = mif->cfg.buffer_size;
225
226   mif->remote_name = memif_str2vec (h->name, sizeof (h->name));
227
228   return 0;
229 }
230
231 static clib_error_t *
232 memif_msg_receive_init (memif_if_t ** mifp, memif_msg_t * msg,
233                         clib_socket_t * sock, uword socket_file_index)
234 {
235   memif_main_t *mm = &memif_main;
236   memif_socket_file_t *msf =
237     vec_elt_at_index (mm->socket_files, socket_file_index);
238   memif_msg_init_t *i = &msg->init;
239   memif_if_t *mif, tmp;
240   clib_error_t *err;
241   uword *p;
242
243   if (i->version != MEMIF_VERSION)
244     {
245       memif_file_del_by_index (sock->private_data);
246       return clib_error_return (0, "unsupported version");
247     }
248
249   p = mhash_get (&msf->dev_instance_by_id, &i->id);
250
251   if (!p)
252     {
253       err = clib_error_return (0, "unmatched interface id");
254       goto error;
255     }
256
257   mif = vec_elt_at_index (mm->interfaces, p[0]);
258
259   if (mif->flags & MEMIF_IF_FLAG_IS_SLAVE)
260     {
261       err = clib_error_return (0, "cannot connect to slave");
262       goto error;
263     }
264
265   if (mif->sock)
266     {
267       err = clib_error_return (0, "already connected");
268       goto error;
269     }
270
271   if (i->mode != mif->mode)
272     {
273       err = clib_error_return (0, "mode mismatch");
274       goto error;
275     }
276
277   mif->sock = sock;
278   hash_set (msf->dev_instance_by_fd, mif->sock->fd, mif->dev_instance);
279   mif->remote_name = memif_str2vec (i->name, sizeof (i->name));
280   *mifp = mif;
281
282   if (mif->secret)
283     {
284       u8 *s;
285       int r;
286       s = memif_str2vec (i->secret, sizeof (i->secret));
287       if (s == 0)
288         return clib_error_return (0, "secret required");
289
290       r = vec_cmp (s, mif->secret);
291       vec_free (s);
292
293       if (r)
294         return clib_error_return (0, "incorrect secret");
295     }
296
297   return 0;
298
299 error:
300   tmp.sock = sock;
301   memif_msg_send_disconnect (&tmp, err);
302   memif_socket_close (&sock);
303   return err;
304 }
305
306 static clib_error_t *
307 memif_msg_receive_add_region (memif_if_t * mif, memif_msg_t * msg, int fd)
308 {
309   memif_msg_add_region_t *ar = &msg->add_region;
310   memif_region_t *mr;
311   if (fd < 0)
312     return clib_error_return (0, "missing memory region fd");
313
314   if (ar->index != vec_len (mif->regions))
315     return clib_error_return (0, "unexpected region index");
316
317   if (ar->index > MEMIF_MAX_REGION)
318     return clib_error_return (0, "too many regions");
319
320   vec_validate_aligned (mif->regions, ar->index, CLIB_CACHE_LINE_BYTES);
321   mr = vec_elt_at_index (mif->regions, ar->index);
322   mr->fd = fd;
323   mr->region_size = ar->size;
324
325   return 0;
326 }
327
328 static clib_error_t *
329 memif_msg_receive_add_ring (memif_if_t * mif, memif_msg_t * msg, int fd)
330 {
331   memif_msg_add_ring_t *ar = &msg->add_ring;
332   memif_queue_t *mq;
333
334   if (fd < 0)
335     return clib_error_return (0, "missing ring interrupt fd");
336
337   if (ar->private_hdr_size != 0)
338     return clib_error_return (0, "private headers not supported");
339
340   if (ar->flags & MEMIF_MSG_ADD_RING_FLAG_S2M)
341     {
342       if (ar->index != vec_len (mif->rx_queues))
343         return clib_error_return (0, "unexpected ring index");
344
345       if (ar->index > MEMIF_MAX_S2M_RING)
346         return clib_error_return (0, "too many rings");
347
348       vec_validate_aligned (mif->rx_queues, ar->index, CLIB_CACHE_LINE_BYTES);
349       mq = vec_elt_at_index (mif->rx_queues, ar->index);
350       mif->run.num_s2m_rings = vec_len (mif->rx_queues);
351     }
352   else
353     {
354       if (ar->index != vec_len (mif->tx_queues))
355         return clib_error_return (0, "unexpected ring index");
356
357       if (ar->index > MEMIF_MAX_M2S_RING)
358         return clib_error_return (0, "too many rings");
359
360       vec_validate_aligned (mif->tx_queues, ar->index, CLIB_CACHE_LINE_BYTES);
361       mq = vec_elt_at_index (mif->tx_queues, ar->index);
362       mif->run.num_m2s_rings = vec_len (mif->tx_queues);
363     }
364
365   // clear previous cache data if interface reconnected
366   clib_memset (mq, 0, sizeof (memif_queue_t));
367   mq->int_fd = fd;
368   mq->int_clib_file_index = ~0;
369   mq->log2_ring_size = ar->log2_ring_size;
370   mq->region = ar->region;
371   mq->offset = ar->offset;
372   mq->type =
373     (ar->flags & MEMIF_MSG_ADD_RING_FLAG_S2M) ? MEMIF_RING_S2M :
374     MEMIF_RING_M2S;
375
376   return 0;
377 }
378
379 static clib_error_t *
380 memif_msg_receive_connect (memif_if_t * mif, memif_msg_t * msg)
381 {
382   clib_error_t *err;
383   memif_msg_connect_t *c = &msg->connect;
384
385   if ((err = memif_connect (mif)))
386     return err;
387
388   mif->remote_if_name = memif_str2vec (c->if_name, sizeof (c->if_name));
389
390   return 0;
391 }
392
393 static clib_error_t *
394 memif_msg_receive_connected (memif_if_t * mif, memif_msg_t * msg)
395 {
396   clib_error_t *err;
397   memif_msg_connected_t *c = &msg->connected;
398
399   if ((err = memif_connect (mif)))
400     return err;
401
402   mif->remote_if_name = memif_str2vec (c->if_name, sizeof (c->if_name));
403   return 0;
404 }
405
406 static clib_error_t *
407 memif_msg_receive_disconnect (memif_if_t * mif, memif_msg_t * msg)
408 {
409   memif_msg_disconnect_t *d = &msg->disconnect;
410
411   mif->remote_disc_string = memif_str2vec (d->string, sizeof (d->string));
412   return clib_error_return (0, "disconnect received");
413 }
414
415 static clib_error_t *
416 memif_msg_receive (memif_if_t ** mifp, clib_socket_t * sock, clib_file_t * uf)
417 {
418   memif_msg_t msg = { 0 };
419   clib_error_t *err = 0;
420   int fd = -1;
421   int i;
422   memif_if_t *mif = *mifp;
423
424   err = clib_socket_recvmsg (sock, &msg, sizeof (memif_msg_t), &fd, 1);
425   if (err)
426     goto error;
427
428   if (mif == 0 && msg.type != MEMIF_MSG_TYPE_INIT)
429     {
430       memif_socket_close (&sock);
431       err = clib_error_return (0, "unexpected message received");
432       goto error;
433     }
434
435   memif_log_debug (mif, "Message type %u received", msg.type);
436   /* process the message based on its type */
437   switch (msg.type)
438     {
439     case MEMIF_MSG_TYPE_ACK:
440       break;
441
442     case MEMIF_MSG_TYPE_HELLO:
443       if ((err = memif_msg_receive_hello (mif, &msg)))
444         goto error;
445       if ((err = memif_init_regions_and_queues (mif)))
446         goto error;
447       memif_msg_enq_init (mif);
448       vec_foreach_index (i, mif->regions)
449         memif_msg_enq_add_region (mif, i);
450       vec_foreach_index (i, mif->tx_queues)
451         memif_msg_enq_add_ring (mif, i, MEMIF_RING_S2M);
452       vec_foreach_index (i, mif->rx_queues)
453         memif_msg_enq_add_ring (mif, i, MEMIF_RING_M2S);
454       memif_msg_enq_connect (mif);
455       break;
456
457     case MEMIF_MSG_TYPE_INIT:
458       if ((err = memif_msg_receive_init (mifp, &msg, sock, uf->private_data)))
459         goto error;
460       mif = *mifp;
461       vec_reset_length (uf->description);
462       uf->description = format (uf->description, "%U ctl",
463                                 format_memif_device_name, mif->dev_instance);
464       memif_msg_enq_ack (mif);
465       break;
466
467     case MEMIF_MSG_TYPE_ADD_REGION:
468       if ((err = memif_msg_receive_add_region (mif, &msg, fd)))
469         goto error;
470       memif_msg_enq_ack (mif);
471       break;
472
473     case MEMIF_MSG_TYPE_ADD_RING:
474       if ((err = memif_msg_receive_add_ring (mif, &msg, fd)))
475         goto error;
476       memif_msg_enq_ack (mif);
477       break;
478
479     case MEMIF_MSG_TYPE_CONNECT:
480       if ((err = memif_msg_receive_connect (mif, &msg)))
481         goto error;
482       memif_msg_enq_connected (mif);
483       break;
484
485     case MEMIF_MSG_TYPE_CONNECTED:
486       if ((err = memif_msg_receive_connected (mif, &msg)))
487         goto error;
488       break;
489
490     case MEMIF_MSG_TYPE_DISCONNECT:
491       if ((err = memif_msg_receive_disconnect (mif, &msg)))
492         goto error;
493       break;
494
495     default:
496       err = clib_error_return (0, "unknown message type (0x%x)", msg.type);
497       goto error;
498     }
499
500   if (clib_fifo_elts (mif->msg_queue))
501     clib_file_set_data_available_to_write (&file_main,
502                                            mif->sock->private_data, 1);
503   return 0;
504
505 error:
506   memif_log_err (mif, "%U", format_clib_error, err);
507   return err;
508 }
509
510 clib_error_t *
511 memif_master_conn_fd_read_ready (clib_file_t * uf)
512 {
513   memif_main_t *mm = &memif_main;
514   memif_socket_file_t *msf =
515     pool_elt_at_index (mm->socket_files, uf->private_data);
516   uword *p;
517   memif_if_t *mif = 0;
518   clib_socket_t *sock = 0;
519   clib_error_t *err = 0;
520
521   p = hash_get (msf->dev_instance_by_fd, uf->file_descriptor);
522   if (p)
523     {
524       mif = vec_elt_at_index (mm->interfaces, p[0]);
525       sock = mif->sock;
526     }
527   else
528     {
529       /* This is new connection, remove index from pending vector */
530       int i;
531       vec_foreach_index (i, msf->pending_clients)
532         if (msf->pending_clients[i]->fd == uf->file_descriptor)
533         {
534           sock = msf->pending_clients[i];
535           vec_del1 (msf->pending_clients, i);
536           break;
537         }
538       ASSERT (sock != 0);
539     }
540   err = memif_msg_receive (&mif, sock, uf);
541   if (err)
542     {
543       memif_disconnect (mif, err);
544       clib_error_free (err);
545     }
546   return 0;
547 }
548
549 clib_error_t *
550 memif_slave_conn_fd_read_ready (clib_file_t * uf)
551 {
552   memif_main_t *mm = &memif_main;
553   clib_error_t *err;
554   memif_if_t *mif = vec_elt_at_index (mm->interfaces, uf->private_data);
555   err = memif_msg_receive (&mif, mif->sock, uf);
556   if (err)
557     {
558       memif_disconnect (mif, err);
559       clib_error_free (err);
560     }
561   return 0;
562 }
563
564 static clib_error_t *
565 memif_conn_fd_write_ready (clib_file_t * uf, memif_if_t * mif)
566 {
567   memif_msg_fifo_elt_t *e;
568   clib_fifo_sub2 (mif->msg_queue, e);
569   clib_file_set_data_available_to_write (&file_main,
570                                          mif->sock->private_data, 0);
571   return clib_socket_sendmsg (mif->sock, &e->msg, sizeof (memif_msg_t),
572                               &e->fd, e->fd > -1 ? 1 : 0);
573 }
574
575 clib_error_t *
576 memif_master_conn_fd_write_ready (clib_file_t * uf)
577 {
578   memif_main_t *mm = &memif_main;
579   memif_socket_file_t *msf =
580     pool_elt_at_index (mm->socket_files, uf->private_data);
581   uword *p;
582   memif_if_t *mif;
583
584   p = hash_get (msf->dev_instance_by_fd, uf->file_descriptor);
585   if (!p)
586     return 0;
587
588   mif = vec_elt_at_index (mm->interfaces, p[0]);
589   return memif_conn_fd_write_ready (uf, mif);
590 }
591
592 clib_error_t *
593 memif_slave_conn_fd_write_ready (clib_file_t * uf)
594 {
595   memif_main_t *mm = &memif_main;
596   memif_if_t *mif = vec_elt_at_index (mm->interfaces, uf->private_data);
597   return memif_conn_fd_write_ready (uf, mif);
598 }
599
600 clib_error_t *
601 memif_slave_conn_fd_error (clib_file_t * uf)
602 {
603   memif_main_t *mm = &memif_main;
604   memif_if_t *mif = vec_elt_at_index (mm->interfaces, uf->private_data);
605   clib_error_t *err;
606
607   err = clib_error_return (0, "connection fd error");
608   memif_disconnect (mif, err);
609   clib_error_free (err);
610
611   return 0;
612 }
613
614 clib_error_t *
615 memif_master_conn_fd_error (clib_file_t * uf)
616 {
617   memif_main_t *mm = &memif_main;
618   memif_socket_file_t *msf =
619     pool_elt_at_index (mm->socket_files, uf->private_data);
620   uword *p;
621
622
623   p = hash_get (msf->dev_instance_by_fd, uf->file_descriptor);
624   if (p)
625     {
626       memif_if_t *mif;
627       clib_error_t *err;
628       mif = vec_elt_at_index (mm->interfaces, p[0]);
629       err = clib_error_return (0, "connection fd error");
630       memif_disconnect (mif, err);
631       clib_error_free (err);
632     }
633   else
634     {
635       int i;
636       vec_foreach_index (i, msf->pending_clients)
637         if (msf->pending_clients[i]->fd == uf->file_descriptor)
638         {
639           clib_socket_t *s = msf->pending_clients[i];
640           memif_socket_close (&s);
641           vec_del1 (msf->pending_clients, i);
642           return 0;
643         }
644     }
645
646   memif_log_warn (0, "Error on unknown file descriptor %d",
647                   uf->file_descriptor);
648   if (uf->file_descriptor != ~0)
649     memif_file_del (uf);
650   return 0;
651 }
652
653
654 clib_error_t *
655 memif_conn_fd_accept_ready (clib_file_t * uf)
656 {
657   memif_main_t *mm = &memif_main;
658   memif_socket_file_t *msf =
659     pool_elt_at_index (mm->socket_files, uf->private_data);
660   clib_file_t template = { 0 };
661   clib_error_t *err;
662   clib_socket_t *client;
663
664   client = clib_mem_alloc (sizeof (clib_socket_t));
665   clib_memset (client, 0, sizeof (clib_socket_t));
666   err = clib_socket_accept (msf->sock, client);
667   if (err)
668     goto error;
669
670   template.read_function = memif_master_conn_fd_read_ready;
671   template.write_function = memif_master_conn_fd_write_ready;
672   template.error_function = memif_master_conn_fd_error;
673   template.file_descriptor = client->fd;
674   template.private_data = uf->private_data;
675   template.description = format (0, "memif in conn on %s", msf->filename);
676
677   memif_file_add (&client->private_data, &template);
678
679   err = memif_msg_enq_hello (client);
680   if (err)
681     {
682       clib_socket_close (client);
683       goto error;
684     }
685
686   vec_add1 (msf->pending_clients, client);
687
688   return 0;
689
690 error:
691   memif_log_err (0, "%U", format_clib_error, err);
692   clib_mem_free (client);
693   return err;
694 }
695
696 /*
697  * fd.io coding-style-patch-verification: ON
698  *
699  * Local Variables:
700  * eval: (c-set-style "gnu")
701  * End:
702  */