- clib_spinlock_lock (&vcm->sessions_lockp);
- rv = vppcom_session_at_index (session_index, &session);
- if (PREDICT_FALSE (rv))
- {
- clib_spinlock_unlock (&vcm->sessions_lockp);
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] invalid session, sid (%u) has been closed!",
- getpid (), session_index);
- return;
- }
-
- ump = vl_msg_api_alloc (sizeof (*ump));
- memset (ump, 0, sizeof (*ump));
-
- ump->_vl_msg_id = ntohs (VL_API_UNBIND_SOCK);
- ump->client_index = vcm->my_client_index;
- ump->handle = session->vpp_handle;
- clib_spinlock_unlock (&vcm->sessions_lockp);
- vl_msg_api_send_shmem (vcm->vl_input_queue, (u8 *) & ump);
-}
-
-static int
-vppcom_session_unbind_cut_thru (session_t * session, u32 session_index)
-{
- svm_fifo_segment_main_t *sm = &svm_fifo_segment_main;
- svm_fifo_segment_private_t *seg;
- int rv = VPPCOM_OK;
-
- if (VPPCOM_DEBUG > 1)
- clib_warning ("[%d] sid %d, seg_nxd %d:\n"
- " server_rx_fifo %p, refcnt = %d\n"
- " server_tx_fifo %p, refcnt = %d",
- getpid (), session_index, session->sm_seg_index,
- session->server_rx_fifo, session->server_rx_fifo->refcnt,
- session->server_tx_fifo, session->server_tx_fifo->refcnt);
-
- seg = vec_elt_at_index (sm->segments, session->sm_seg_index);
- svm_fifo_segment_free_fifo (seg, session->server_rx_fifo,
- FIFO_SEGMENT_RX_FREELIST);
- svm_fifo_segment_free_fifo (seg, session->server_tx_fifo,
- FIFO_SEGMENT_TX_FREELIST);
- svm_fifo_segment_delete (seg);
-
- return rv;
-}
-
-static int
-vppcom_session_unbind (u32 session_index)
-{
- int rv;
-
- clib_spinlock_lock (&vcm->sessions_lockp);
- if (PREDICT_FALSE (pool_is_free_index (vcm->sessions, session_index)))
- {
- clib_spinlock_unlock (&vcm->sessions_lockp);
- if (VPPCOM_DEBUG > 1)
- clib_warning ("[%d] invalid session, sid (%u) has been closed!",
- getpid (), session_index);
- return VPPCOM_EBADFD;
- }
- clib_spinlock_unlock (&vcm->sessions_lockp);
-
- if (vcm->bind_session_index != session_index)
- clib_warning ("[%d] ERROR: unbinding a not bound listener %u (%u)",
- session_index, vcm->bind_session_index);
- vcm->bind_session_index = session_index;
- vppcom_send_unbind_sock (session_index);
- rv = vppcom_wait_for_session_state_change (session_index, STATE_START,
- vcm->cfg.session_timeout);
- if (PREDICT_FALSE (rv))
- {
- vcm->bind_session_index = ~0;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] server unbind timed out, rv = %s (%d)",
- getpid (), vppcom_retval_str (rv), rv);
- return rv;
- }
- return VPPCOM_OK;
-}
-
-static inline int
-vppcom_session_disconnect (u32 session_index)
-{
- int rv;
- session_t *session;
-
- clib_spinlock_lock (&vcm->sessions_lockp);
- rv = vppcom_session_at_index (session_index, &session);
- if (PREDICT_FALSE (rv))
- {
- clib_spinlock_unlock (&vcm->sessions_lockp);
- if (VPPCOM_DEBUG > 1)
- clib_warning ("[%d] invalid session, sid (%u) has been closed!",
- getpid (), session_index);
- return rv;
- }
-
- if (!session->is_cut_thru)
- {
- if (VPPCOM_DEBUG > 1)
- clib_warning ("[%d] disconnecting sid (%u)", getpid (),
- session_index);
- vppcom_send_disconnect (session);
- clib_spinlock_unlock (&vcm->sessions_lockp);
-
- rv = vppcom_wait_for_session_state_change (session_index,
- STATE_DISCONNECT, 1.0);
- /* TBD: Force clean up on error/timeout since there is no other
- * way to recover from a failed disconnect.
- */
- if ((VPPCOM_DEBUG > 0) && (rv < 0))
- clib_warning ("[%d] disconnect (session %d) failed, rv = %s (%d)",
- getpid (), session_index, vppcom_retval_str (rv), rv);
- }
- else
- {
- /* TBD: Handle cut-thru disconnect */
- clib_spinlock_unlock (&vcm->sessions_lockp);
- }
-
- return VPPCOM_OK;
-}
-
-#define foreach_sock_msg \
-_(SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply) \
-_(BIND_SOCK_REPLY, bind_sock_reply) \
-_(UNBIND_SOCK_REPLY, unbind_sock_reply) \
-_(ACCEPT_SESSION, accept_session) \
-_(CONNECT_SOCK, connect_sock) \
-_(CONNECT_SESSION_REPLY, connect_session_reply) \
-_(DISCONNECT_SESSION, disconnect_session) \
-_(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
-_(RESET_SESSION, reset_session) \
-_(APPLICATION_ATTACH_REPLY, application_attach_reply) \
-_(APPLICATION_DETACH_REPLY, application_detach_reply) \
-_(MAP_ANOTHER_SEGMENT, map_another_segment)
-
-static void
-vppcom_api_hookup (void)
-{
-#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N, #n, \
- vl_api_##n##_t_handler, \
- vl_noop_handler, \
- vl_api_##n##_t_endian, \
- vl_api_##n##_t_print, \
- sizeof(vl_api_##n##_t), 1);
- foreach_sock_msg;
-#undef _
-}
-
-static void
-vppcom_cfg_init (vppcom_cfg_t * vcl_cfg)
-{
- ASSERT (vcl_cfg);
-
- vcl_cfg->heapsize = (256ULL << 20);
- vcl_cfg->segment_baseva = 0x200000000ULL;
- vcl_cfg->segment_size = (256 << 20);
- vcl_cfg->add_segment_size = (128 << 20);
- vcl_cfg->preallocated_fifo_pairs = 8;
- vcl_cfg->rx_fifo_size = (1 << 20);
- vcl_cfg->tx_fifo_size = (1 << 20);
- vcl_cfg->event_queue_size = 2048;
- vcl_cfg->listen_queue_size = CLIB_CACHE_LINE_BYTES / sizeof (u32);
- vcl_cfg->app_timeout = 10 * 60.0;
- vcl_cfg->session_timeout = 10 * 60.0;
- vcl_cfg->accept_timeout = 60.0;
-}
-
-static void
-vppcom_cfg_heapsize (char *conf_fname)
-{
- vppcom_cfg_t *vcl_cfg = &vcm->cfg;
- FILE *fp;
- char inbuf[4096];
- int argc = 1;
- char **argv = NULL;
- char *arg = NULL;
- char *p;
- int i;
- u8 *sizep;
- u32 size;
- void *vcl_mem;
- void *heap;
-
- fp = fopen (conf_fname, "r");
- if (fp == NULL)
- {
- if (VPPCOM_DEBUG > 0)
- fprintf (stderr, "open configuration file '%s' failed\n", conf_fname);
- goto defaulted;
- }
- argv = calloc (1, sizeof (char *));
- if (argv == NULL)
- goto defaulted;
-
- while (1)
- {
- if (fgets (inbuf, 4096, fp) == 0)
- break;
- p = strtok (inbuf, " \t\n");
- while (p != NULL)
- {
- if (*p == '#')
- break;
- argc++;
- char **tmp = realloc (argv, argc * sizeof (char *));
- if (tmp == NULL)
- goto defaulted;
- argv = tmp;
- arg = strndup (p, 1024);
- if (arg == NULL)
- goto defaulted;
- argv[argc - 1] = arg;
- p = strtok (NULL, " \t\n");
- }
- }
-
- fclose (fp);
- fp = NULL;
-
- char **tmp = realloc (argv, (argc + 1) * sizeof (char *));
- if (tmp == NULL)
- goto defaulted;
- argv = tmp;
- argv[argc] = NULL;
-
- /*
- * Look for and parse the "heapsize" config parameter.
- * Manual since none of the clib infra has been bootstrapped yet.
- *
- * Format: heapsize <nn>[mM][gG]
- */
-
- for (i = 1; i < (argc - 1); i++)
- {
- if (!strncmp (argv[i], "heapsize", 8))
- {
- sizep = (u8 *) argv[i + 1];
- size = 0;
- while (*sizep >= '0' && *sizep <= '9')
- {
- size *= 10;
- size += *sizep++ - '0';
- }
- if (size == 0)
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] parse error '%s %s', "
- "using default heapsize %lld (0x%llx)",
- getpid (), argv[i], argv[i + 1],
- vcl_cfg->heapsize, vcl_cfg->heapsize);
- goto defaulted;
- }
-
- if (*sizep == 'g' || *sizep == 'G')
- vcl_cfg->heapsize = size << 30;
- else if (*sizep == 'm' || *sizep == 'M')
- vcl_cfg->heapsize = size << 20;
- else
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] parse error '%s %s', "
- "using default heapsize %lld (0x%llx)",
- getpid (), argv[i], argv[i + 1],
- vcl_cfg->heapsize, vcl_cfg->heapsize);
- goto defaulted;
- }
- }
- }
-
-defaulted:
- if (fp != NULL)
- fclose (fp);
- if (argv != NULL)
- free (argv);
-
- vcl_mem = mmap (0, vcl_cfg->heapsize, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS, -1, 0);
- if (vcl_mem == MAP_FAILED)
- {
- clib_unix_error ("[%d] ERROR: mmap(0, %lld == 0x%llx, "
- "PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, "
- "-1, 0) failed!",
- getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize);
- return;
- }
- heap = clib_mem_init (vcl_mem, vcl_cfg->heapsize);
- if (!heap)
- {
- clib_warning ("[%d] ERROR: clib_mem_init() failed!", getpid ());
- return;
- }
- vcl_mem = clib_mem_alloc (sizeof (_vppcom_main));
- if (!vcl_mem)
- {
- clib_warning ("[%d] ERROR: clib_mem_alloc() failed!", getpid ());
- return;
- }
-
- clib_memcpy (vcl_mem, &_vppcom_main, sizeof (_vppcom_main));
- vcm = vcl_mem;
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] allocated VCL heap = %p, size %lld (0x%llx)",
- getpid (), heap, vcl_cfg->heapsize, vcl_cfg->heapsize);
-}
-
-static void
-vppcom_cfg_read (char *conf_fname)
-{
- vppcom_cfg_t *vcl_cfg = &vcm->cfg;
- int fd;
- unformat_input_t _input, *input = &_input;
- unformat_input_t _line_input, *line_input = &_line_input;
- u8 vc_cfg_input = 0;
- u8 *chroot_path;
- struct stat s;
- u32 uid, gid;
-
- fd = open (conf_fname, O_RDONLY);
- if (fd < 0)
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] open configuration file '%s' failed!",
- getpid (), conf_fname);
- goto file_done;
- }
-
- if (fstat (fd, &s) < 0)
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] failed to stat `%s'", getpid (), conf_fname);
- goto file_done;
- }
-
- if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] not a regular file `%s'", getpid (), conf_fname);
- goto file_done;
- }
-
- unformat_init_clib_file (input, fd);
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)