LCOV - code coverage report
Current view: top level - plugins/memif - socket.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 303 385 78.7 %
Date: 2023-10-26 01:39:38 Functions: 26 28 92.9 %

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

Generated by: LCOV version 1.14