- (void) unformat_user (input, unformat_line_input, line_input);
- unformat_skip_white_space (line_input);
-
- if (unformat (line_input, "vcl {"))
- {
- vc_cfg_input = 1;
- continue;
- }
-
- if (vc_cfg_input)
- {
- if (unformat (line_input, "heapsize %s", &chroot_path))
- {
- vec_terminate_c_string (chroot_path);
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured heapsize %s, "
- "actual heapsize %lld (0x%llx)",
- getpid (), chroot_path, vcl_cfg->heapsize,
- vcl_cfg->heapsize);
- vec_free (chroot_path);
- }
- else if (unformat (line_input, "api-prefix %s", &chroot_path))
- {
- vec_terminate_c_string (chroot_path);
- vl_set_memory_root_path ((char *) chroot_path);
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured api-prefix %s",
- getpid (), chroot_path);
- chroot_path = 0; /* Don't vec_free() it! */
- }
- else if (unformat (line_input, "uid %d", &uid))
- {
- vl_set_memory_uid (uid);
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured uid %d", getpid (), uid);
- }
- else if (unformat (line_input, "gid %d", &gid))
- {
- vl_set_memory_gid (gid);
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured gid %d", getpid (), gid);
- }
- else if (unformat (line_input, "segment-baseva 0x%lx",
- &vcl_cfg->segment_baseva))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured segment_baseva 0x%lx",
- getpid (), vcl_cfg->segment_baseva);
- }
- else if (unformat (line_input, "segment-size 0x%lx",
- &vcl_cfg->segment_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured segment_size 0x%lx (%ld)",
- getpid (), vcl_cfg->segment_size,
- vcl_cfg->segment_size);
- }
- else if (unformat (line_input, "segment-size %ld",
- &vcl_cfg->segment_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured segment_size %ld (0x%lx)",
- getpid (), vcl_cfg->segment_size,
- vcl_cfg->segment_size);
- }
- else if (unformat (line_input, "add-segment-size 0x%lx",
- &vcl_cfg->add_segment_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning
- ("[%d] configured add_segment_size 0x%lx (%ld)",
- getpid (), vcl_cfg->add_segment_size,
- vcl_cfg->add_segment_size);
- }
- else if (unformat (line_input, "add-segment-size %ld",
- &vcl_cfg->add_segment_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning
- ("[%d] configured add_segment_size %ld (0x%lx)",
- getpid (), vcl_cfg->add_segment_size,
- vcl_cfg->add_segment_size);
- }
- else if (unformat (line_input, "preallocated-fifo-pairs %d",
- &vcl_cfg->preallocated_fifo_pairs))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured preallocated_fifo_pairs "
- "%d (0x%x)", getpid (),
- vcl_cfg->preallocated_fifo_pairs,
- vcl_cfg->preallocated_fifo_pairs);
- }
- else if (unformat (line_input, "rx-fifo-size 0x%lx",
- &vcl_cfg->rx_fifo_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured rx_fifo_size 0x%lx (%ld)",
- getpid (), vcl_cfg->rx_fifo_size,
- vcl_cfg->rx_fifo_size);
- }
- else if (unformat (line_input, "rx-fifo-size %ld",
- &vcl_cfg->rx_fifo_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured rx_fifo_size %ld (0x%lx)",
- getpid (), vcl_cfg->rx_fifo_size,
- vcl_cfg->rx_fifo_size);
- }
- else if (unformat (line_input, "tx-fifo-size 0x%lx",
- &vcl_cfg->tx_fifo_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured tx_fifo_size 0x%lx (%ld)",
- getpid (), vcl_cfg->tx_fifo_size,
- vcl_cfg->tx_fifo_size);
- }
- else if (unformat (line_input, "tx-fifo-size %ld",
- &vcl_cfg->tx_fifo_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured tx_fifo_size %ld (0x%lx)",
- getpid (), vcl_cfg->tx_fifo_size,
- vcl_cfg->tx_fifo_size);
- }
- else if (unformat (line_input, "event-queue-size 0x%lx",
- &vcl_cfg->event_queue_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured event_queue_size 0x%lx (%ld)",
- getpid (), vcl_cfg->event_queue_size,
- vcl_cfg->event_queue_size);
- }
- else if (unformat (line_input, "event-queue-size %ld",
- &vcl_cfg->event_queue_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured event_queue_size %ld (0x%lx)",
- getpid (), vcl_cfg->event_queue_size,
- vcl_cfg->event_queue_size);
- }
- else if (unformat (line_input, "listen-queue-size 0x%lx",
- &vcl_cfg->listen_queue_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured listen_queue_size 0x%lx (%ld)",
- getpid (), vcl_cfg->listen_queue_size,
- vcl_cfg->listen_queue_size);
- }
- else if (unformat (line_input, "listen-queue-size %ld",
- &vcl_cfg->listen_queue_size))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured listen_queue_size %ld (0x%lx)",
- getpid (), vcl_cfg->listen_queue_size,
- vcl_cfg->listen_queue_size);
- }
- else if (unformat (line_input, "app-timeout %f",
- &vcl_cfg->app_timeout))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured app_timeout %f",
- getpid (), vcl_cfg->app_timeout);
- }
- else if (unformat (line_input, "session-timeout %f",
- &vcl_cfg->session_timeout))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured session_timeout %f",
- getpid (), vcl_cfg->session_timeout);
- }
- else if (unformat (line_input, "accept-timeout %f",
- &vcl_cfg->accept_timeout))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured accept_timeout %f",
- getpid (), vcl_cfg->accept_timeout);
- }
- else if (unformat (line_input, "app-proxy-transport-tcp"))
- {
- vcl_cfg->app_proxy_transport_tcp = 1;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured app_proxy_transport_tcp (%d)",
- getpid (), vcl_cfg->app_proxy_transport_tcp);
- }
- else if (unformat (line_input, "app-proxy-transport-udp"))
- {
- vcl_cfg->app_proxy_transport_udp = 1;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured app_proxy_transport_udp (%d)",
- getpid (), vcl_cfg->app_proxy_transport_udp);
- }
- else if (unformat (line_input, "app-scope-local"))
- {
- vcl_cfg->app_scope_local = 1;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured app_scope_local (%d)",
- getpid (), vcl_cfg->app_scope_local);
- }
- else if (unformat (line_input, "app-scope-global"))
- {
- vcl_cfg->app_scope_global = 1;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured app_scope_global (%d)",
- getpid (), vcl_cfg->app_scope_global);
- }
- else if (unformat (line_input, "namespace-secret %lu",
- &vcl_cfg->namespace_secret))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning
- ("[%d] configured namespace_secret %lu (0x%lx)",
- getpid (), vcl_cfg->namespace_secret,
- vcl_cfg->namespace_secret);
- }
- else if (unformat (line_input, "namespace-id %v",
- &vcl_cfg->namespace_id))
- {
- vl_api_application_attach_t *mp;
- u32 max_nsid_vec_len = sizeof (mp->namespace_id) - 1;
- u32 nsid_vec_len = vec_len (vcl_cfg->namespace_id);
- if (nsid_vec_len > max_nsid_vec_len)
- {
- _vec_len (vcl_cfg->namespace_id) = max_nsid_vec_len;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured namespace_id is too long,"
- " truncated to %d characters!", getpid (),
- max_nsid_vec_len);
- }
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured namespace_id %v",
- getpid (), vcl_cfg->namespace_id);
- }
- else if (unformat (line_input, "}"))
- {
- vc_cfg_input = 0;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] completed parsing vppcom config!",
- getpid ());
- goto input_done;
- }
- else
- {
- if (line_input->buffer[line_input->index] != '#')
- {
- clib_warning ("[%d] Unknown vppcom config option: '%s'",
- getpid (), (char *)
- &line_input->buffer[line_input->index]);
- }
- }
- }
- }
-
-input_done:
- unformat_free (input);
-
-file_done:
- if (fd >= 0)
- close (fd);
-}
-
-/*
- * VPPCOM Public API functions
- */
-int
-vppcom_app_create (char *app_name)
-{
- vppcom_cfg_t *vcl_cfg = &vcm->cfg;
- u8 *heap;
- mheap_t *h;
- int rv;
-
- if (!vcm->init)
- {
- char *conf_fname;
- char *env_var_str;
-
- vcm->init = 1;
- vppcom_cfg_init (vcl_cfg);
- env_var_str = getenv (VPPCOM_ENV_DEBUG);
- if (env_var_str)
- {
- u32 tmp;
- if (sscanf (env_var_str, "%u", &tmp) != 1)
- clib_warning ("[%d] Invalid debug level specified in "
- "the environment variable "
- VPPCOM_ENV_DEBUG
- " (%s)!\n", getpid (), env_var_str);
- else
- {
- vcm->debug = tmp;
- clib_warning ("[%d] configured debug level (%u) from "
- VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug);
- }
- }
- conf_fname = getenv (VPPCOM_ENV_CONF);
- if (!conf_fname)
- {
- conf_fname = VPPCOM_CONF_DEFAULT;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] getenv '%s' failed!", getpid (),
- VPPCOM_ENV_CONF);
- }
- vppcom_cfg_heapsize (conf_fname);
- clib_fifo_validate (vcm->client_session_index_fifo,
- vcm->cfg.listen_queue_size);
- vppcom_cfg_read (conf_fname);
- env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_ID);
- if (env_var_str)
- {
- u32 ns_id_vec_len = strlen (env_var_str);
-
- vec_reset_length (vcm->cfg.namespace_id);
- vec_validate (vcm->cfg.namespace_id, ns_id_vec_len - 1);
- clib_memcpy (vcm->cfg.namespace_id, env_var_str, ns_id_vec_len);
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured namespace_id (%v) from "
- VPPCOM_ENV_APP_NAMESPACE_ID "!", getpid (),
- vcm->cfg.namespace_id);
- }
- env_var_str = getenv (VPPCOM_ENV_APP_NAMESPACE_SECRET);
- if (env_var_str)
- {
- u64 tmp;
- if (sscanf (env_var_str, "%lu", &tmp) != 1)
- clib_warning ("[%d] Invalid namespace secret specified in "
- "the environment variable "
- VPPCOM_ENV_APP_NAMESPACE_SECRET
- " (%s)!\n", getpid (), env_var_str);
- else
- {
- vcm->cfg.namespace_secret = tmp;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured namespace secret (%lu) from "
- VPPCOM_ENV_APP_NAMESPACE_ID "!", getpid (),
- vcm->cfg.namespace_secret);
- }
- }
- if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP))
- {
- vcm->cfg.app_proxy_transport_tcp = 1;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured app_proxy_transport_tcp (%u) from "
- VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP "!", getpid (),
- vcm->cfg.app_proxy_transport_tcp);
- }
- if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP))
- {
- vcm->cfg.app_proxy_transport_udp = 1;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured app_proxy_transport_udp (%u) from "
- VPPCOM_ENV_APP_PROXY_TRANSPORT_UDP "!", getpid (),
- vcm->cfg.app_proxy_transport_udp);
- }
- if (getenv (VPPCOM_ENV_APP_SCOPE_LOCAL))
- {
- vcm->cfg.app_scope_local = 1;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured app_scope_local (%u) from "
- VPPCOM_ENV_APP_SCOPE_LOCAL "!", getpid (),
- vcm->cfg.app_scope_local);
- }
- if (getenv (VPPCOM_ENV_APP_SCOPE_GLOBAL))
- {
- vcm->cfg.app_scope_global = 1;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] configured app_scope_global (%u) from "
- VPPCOM_ENV_APP_SCOPE_GLOBAL "!", getpid (),
- vcm->cfg.app_scope_global);
- }
-
- vcm->main_cpu = os_get_thread_index ();
- heap = clib_mem_get_per_cpu_heap ();
- h = mheap_header (heap);
-
- /* make the main heap thread-safe */
- h->flags |= MHEAP_FLAG_THREAD_SAFE;
-
- vcm->session_index_by_vpp_handles = hash_create (0, sizeof (uword));
-
- clib_time_init (&vcm->clib_time);
- vppcom_init_error_string_table ();
- svm_fifo_segment_init (vcl_cfg->segment_baseva,
- 20 /* timeout in secs */ );
- clib_spinlock_init (&vcm->sessions_lockp);
- vppcom_api_hookup ();
- }
-
- if (vcm->my_client_index == ~0)
- {
- vcm->app_state = STATE_APP_START;
- rv = vppcom_connect_to_vpp (app_name);
- if (rv)
- {
- clib_warning ("[%d] ERROR: couldn't connect to VPP!", getpid ());
- return rv;
- }
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sending session enable", getpid ());
-
- rv = vppcom_app_session_enable ();
- if (rv)
- {
- clib_warning ("[%d] ERROR: vppcom_app_session_enable() failed!",
- getpid ());
- return rv;
- }
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sending app attach", getpid ());
-
- rv = vppcom_app_attach ();
- if (rv)
- {
- clib_warning ("[%d] ERROR: vppcom_app_attach() failed!", getpid ());
- return rv;
- }
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] app_name '%s', my_client_index %d (0x%x)",
- getpid (), app_name, vcm->my_client_index,
- vcm->my_client_index);
- }
-
- return VPPCOM_OK;
-}
-
-void
-vppcom_app_destroy (void)
-{
- int rv;
-
- if (vcm->my_client_index == ~0)
- return;
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] detaching from VPP, my_client_index %d (0x%x)",
- getpid (), vcm->my_client_index, vcm->my_client_index);
-
- vppcom_app_detach ();
- rv = vppcom_wait_for_app_state_change (STATE_APP_ENABLED);
- if (PREDICT_FALSE (rv))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] application detach timed out, rv = %s (%d)",
- getpid (), vppcom_retval_str (rv), rv);
- }
- vl_client_disconnect_from_vlib ();
- vcm->my_client_index = ~0;
- vcm->app_state = STATE_APP_START;
-}
-
-int
-vppcom_session_create (u32 vrf, u8 proto, u8 is_nonblocking)
-{
- session_t *session;
- u32 session_index;
-
- clib_spinlock_lock (&vcm->sessions_lockp);
- pool_get (vcm->sessions, session);
- memset (session, 0, sizeof (*session));
- session_index = session - vcm->sessions;
-
- session->vrf = vrf;
- session->proto = proto;
- session->state = STATE_START;
- session->is_nonblocking = is_nonblocking ? 1 : 0;
- session->vpp_handle = ~0;
- clib_spinlock_unlock (&vcm->sessions_lockp);
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %u", getpid (), session_index);
-
- return (int) session_index;
-}
-
-int
-vppcom_session_close (uint32_t session_index)
-{
- session_t *session = 0;
- int rv;
- u8 is_listen;
- u8 is_vep;
- u8 is_vep_session;
- u32 next_sid;
- u32 vep_idx;
- uword *p;
- session_state_t state;
-
- VCL_LOCK_AND_GET_SESSION (session_index, &session);
- is_listen = session->is_listen;
- is_vep = session->is_vep;
- is_vep_session = session->is_vep_session;
- next_sid = session->vep.next_sid;
- vep_idx = session->vep.vep_idx;
- state = session->state;
- clib_spinlock_unlock (&vcm->sessions_lockp);
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %d: closing session...", getpid (),
- session_index);
-
- if (is_vep)
- {
- while (next_sid != ~0)
- {
- rv = vppcom_epoll_ctl (session_index, EPOLL_CTL_DEL, next_sid, 0);
- if ((VPPCOM_DEBUG > 0) && (rv < 0))
- clib_warning ("[%d] sid %u: EPOLL_CTL_DEL vep_idx %u failed, "
- "rv = %d (%s)", getpid (), next_sid, vep_idx,
- rv, vppcom_retval_str (rv));
-
- VCL_LOCK_AND_GET_SESSION (session_index, &session);
- next_sid = session->vep.next_sid;
- clib_spinlock_unlock (&vcm->sessions_lockp);
- }
- }
- else
- {
- if (is_vep_session)
- {
- rv = vppcom_epoll_ctl (vep_idx, EPOLL_CTL_DEL, session_index, 0);
- if ((VPPCOM_DEBUG > 0) && (rv < 0))
- clib_warning ("[%d] sid %u: EPOLL_CTL_DEL vep_idx %u failed! "
- "rv = %d (%s)", getpid (), session_index, vep_idx,
- rv, vppcom_retval_str (rv));
- }
-
- if (is_listen)
- {
- if (state == STATE_LISTEN)
- {
- rv = vppcom_session_unbind (session_index);
- if (PREDICT_FALSE (rv < 0))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %u: listener unbind failed! "
- "rv = %d (%s)",
- getpid (), session_index, rv,
- vppcom_retval_str (rv));
- }
- }
- }
-
- else if (state & (CLIENT_STATE_OPEN | SERVER_STATE_OPEN))
- {
- rv = vppcom_session_disconnect (session_index);
- if (PREDICT_FALSE (rv < 0))
- clib_warning ("[%d] ERROR: sid %u: session disconnect failed! "
- "rv %d (%s)", getpid (), session_index, rv,
- vppcom_retval_str (rv));
- }
- }
-
- VCL_LOCK_AND_GET_SESSION (session_index, &session);
-
- if (session->vpp_handle != ~0)
- {
- p = hash_get (vcm->session_index_by_vpp_handles, session->vpp_handle);
- if (p)
- hash_unset (vcm->session_index_by_vpp_handles, session->vpp_handle);
- }
- pool_put_index (vcm->sessions, session_index);
- clib_spinlock_unlock (&vcm->sessions_lockp);
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %u: session removed.", getpid (), session_index);
-
-done:
- return rv;
-}
-
-int
-vppcom_session_bind (uint32_t session_index, vppcom_endpt_t * ep)
-{
- session_t *session = 0;
- int rv;
-
- if (!ep || !ep->ip)
- return VPPCOM_EINVAL;
-
- VCL_LOCK_AND_GET_SESSION (session_index, &session);
-
- if (session->is_vep)
- {
- clib_spinlock_unlock (&vcm->sessions_lockp);
- clib_warning ("[%d] ERROR: sid %u: cannot bind to an epoll session!",
- getpid (), session_index);
- rv = VPPCOM_EBADFD;
- goto done;
- }
-
- session->vrf = ep->vrf;
- session->lcl_addr.is_ip4 = ep->is_ip4;
- session->lcl_addr.ip46 = to_ip46 (!ep->is_ip4, ep->ip);
- session->lcl_port = ep->port;
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %u: bound to local address %U "
- "port %u, proto %s",
- getpid (), session_index, format_ip46_address,
- &session->lcl_addr.ip46, session->lcl_addr.is_ip4,
- clib_net_to_host_u16 (session->lcl_port),
- session->proto ? "UDP" : "TCP");
-
- clib_spinlock_unlock (&vcm->sessions_lockp);
-done:
- return rv;
-}
-
-int
-vppcom_session_listen (uint32_t listen_session_index, uint32_t q_len)
-{
- session_t *listen_session = 0;
- int rv;
-
- VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
-
- if (listen_session->is_vep)
- {
- clib_spinlock_unlock (&vcm->sessions_lockp);
- clib_warning ("[%d] ERROR: sid %u: cannot listen on an "
- "epoll session!", getpid (), listen_session_index);
- rv = VPPCOM_EBADFD;
- goto done;
- }
-
- if (listen_session->is_listen)
- {
- clib_spinlock_unlock (&vcm->sessions_lockp);
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %u: already in listen state!",
- getpid (), listen_session_index);
- rv = VPPCOM_OK;
- goto done;
- }
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %u: sending bind request...",
- getpid (), listen_session_index);
-
- vppcom_send_bind_sock (listen_session, listen_session_index);
- clib_spinlock_unlock (&vcm->sessions_lockp);
- rv =
- vppcom_wait_for_session_state_change (listen_session_index, STATE_LISTEN,
- vcm->cfg.session_timeout);
- if (PREDICT_FALSE (rv))
- {
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %u: bind failed! returning %d (%d)",
- getpid (), vppcom_retval_str (rv), rv);
- return rv;
- }
-
- VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
- clib_fifo_validate (vcm->client_session_index_fifo, q_len);
- clib_spinlock_unlock (&vcm->sessions_lockp);
-done:
- return rv;
-}
-
-int
-vppcom_session_accept (uint32_t listen_session_index, vppcom_endpt_t * ep,
- uint32_t flags, double wait_for_time)
-{
- session_t *listen_session = 0;
- session_t *client_session = 0;
- u32 client_session_index = ~0;
- int rv;
- f64 wait_for;
- char *cut_thru_str;
-
- VCL_LOCK_AND_GET_SESSION (listen_session_index, &listen_session);
-
- if (listen_session->is_vep)
- {
- clib_spinlock_unlock (&vcm->sessions_lockp);
- clib_warning ("[%d] ERROR: sid %u: cannot accept on an "
- "epoll session!", getpid (), listen_session_index);
- rv = VPPCOM_EBADFD;
- goto done;
- }
-
- if (listen_session->state != STATE_LISTEN)
- {
- clib_spinlock_unlock (&vcm->sessions_lockp);
- clib_warning ("[%d] ERROR: sid %u: not in listen state! "
- "state 0x%x (%s)", getpid (), listen_session->state,
- vppcom_session_state_str (listen_session->state));
- rv = VPPCOM_EBADFD;
- goto done;
- }
- wait_for = ((listen_session->is_nonblocking) ? 0 :
- (wait_for_time < 0) ? vcm->cfg.accept_timeout : wait_for_time);
-
- clib_spinlock_unlock (&vcm->sessions_lockp);
-
- while (1)
- {
- rv = vppcom_wait_for_client_session_index (wait_for);
- if (rv)
- {
- if ((VPPCOM_DEBUG > 0))
- clib_warning ("[%d] sid %u: accept failed! "
- "returning = %d (%s)",
- getpid (), listen_session_index,
- rv, vppcom_retval_str (rv));
- if ((wait_for == 0) || (wait_for_time > 0))
- goto done;
- }
- else
- break;
- }
-
- clib_spinlock_lock (&vcm->sessions_lockp);
- clib_fifo_sub1 (vcm->client_session_index_fifo, client_session_index);
- rv = vppcom_session_at_index (client_session_index, &client_session);
- ASSERT (rv == VPPCOM_OK);
- ASSERT (client_session->peer_addr.is_ip4 ==
- listen_session->lcl_addr.is_ip4);
-
- client_session->is_nonblocking = (flags & O_NONBLOCK) ? 1 : 0;
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %u: Got a client request! flags %d, "
- "is_nonblocking %u", getpid (), client_session_index,
- flags, client_session->is_nonblocking);
-
- ep->vrf = client_session->vrf;
- ep->is_cut_thru = client_session->is_cut_thru;
- ep->is_ip4 = client_session->peer_addr.is_ip4;
- ep->port = client_session->peer_port;
- if (client_session->peer_addr.is_ip4)
- clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip4,
- sizeof (ip4_address_t));
- else
- clib_memcpy (ep->ip, &client_session->peer_addr.ip46.ip6,
- sizeof (ip6_address_t));
-
- if (client_session->is_server && client_session->is_cut_thru)
- {
- static svm_fifo_segment_create_args_t _a;
- svm_fifo_segment_create_args_t *a = &_a;
- svm_fifo_segment_private_t *seg;
-
- cut_thru_str = " cut-thru ";
-
- /* Create the segment */
- memset (a, 0, sizeof (*a));
- a->segment_name = (char *)
- format ((u8 *) a->segment_name, "%d:segment%d%c",
- getpid (), vcm->unique_segment_index++, 0);
- a->segment_size = vcm->cfg.segment_size;
- a->preallocated_fifo_pairs = vcm->cfg.preallocated_fifo_pairs;
- a->rx_fifo_size = vcm->cfg.rx_fifo_size;
- a->tx_fifo_size = vcm->cfg.tx_fifo_size;
-
- rv = svm_fifo_segment_create (a);
- if (PREDICT_FALSE (rv))
- {
- clib_warning ("[%d] ERROR: sid %u: "
- "svm_fifo_segment_create ('%s') failed! rv %d",
- getpid (), client_session_index, a->segment_name, rv);
- vec_reset_length (a->new_segment_indices);
- rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
- vppcom_send_connect_session_reply (client_session, rv);
- clib_spinlock_unlock (&vcm->sessions_lockp);
- rv = VPPCOM_ENOMEM;
- goto done;
- }
-
- client_session->segment_name = vec_dup ((u8 *) a->segment_name);
- client_session->sm_seg_index = a->new_segment_indices[0];
- vec_free (a->new_segment_indices);
-
- seg = svm_fifo_segment_get_segment (client_session->sm_seg_index);
- client_session->server_rx_fifo =
- svm_fifo_segment_alloc_fifo (seg, vcm->cfg.rx_fifo_size,
- FIFO_SEGMENT_RX_FREELIST);
- if (PREDICT_FALSE (!client_session->server_rx_fifo))
- {
- svm_fifo_segment_delete (seg);
- clib_warning ("[%d] ERROR: sid %u: rx fifo alloc failed! "
- "size %ld (0x%lx)", getpid (),
- client_session_index,
- vcm->cfg.rx_fifo_size, vcm->cfg.rx_fifo_size);
- rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
- vppcom_send_connect_session_reply (client_session, rv);
- clib_spinlock_unlock (&vcm->sessions_lockp);
- rv = VPPCOM_ENOMEM;
- goto done;
- }
- client_session->server_rx_fifo->master_session_index =
- client_session_index;
-
- client_session->server_tx_fifo =
- svm_fifo_segment_alloc_fifo (seg, vcm->cfg.tx_fifo_size,
- FIFO_SEGMENT_TX_FREELIST);
- if (PREDICT_FALSE (!client_session->server_tx_fifo))
- {
- svm_fifo_segment_delete (seg);
- clib_warning ("[%d] ERROR: sid %u: tx fifo alloc failed! "
- "size %ld (0x%lx)",
- getpid (), client_session_index,
- vcm->cfg.tx_fifo_size, vcm->cfg.tx_fifo_size);
- rv = VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
- vppcom_send_connect_session_reply (client_session, rv);
- clib_spinlock_unlock (&vcm->sessions_lockp);
- rv = VPPCOM_ENOMEM;
- goto done;
- }
- client_session->server_tx_fifo->master_session_index =
- client_session_index;
-
- if (VPPCOM_DEBUG > 1)
- clib_warning ("[%d] sid %u: created segment '%s', "
- "rx_fifo %p, tx_fifo %p",
- getpid (), client_session_index,
- client_session->segment_name,
- client_session->server_rx_fifo,
- client_session->server_tx_fifo);
-
-#ifdef CUT_THRU_EVENT_QUEUE /* TBD */
- {
- void *oldheap;
- ssvm_shared_header_t *sh = seg->ssvm.sh;
-
- ssvm_lock_non_recursive (sh, 1);
- oldheap = ssvm_push_heap (sh);
- event_q = client_session->vpp_event_queue =
- unix_shared_memory_queue_init (vcm->cfg.event_queue_size,
- sizeof (session_fifo_event_t),
- getpid (), 0 /* signal not sent */ );
- ssvm_pop_heap (oldheap);
- ssvm_unlock_non_recursive (sh);
- }
-#endif
- vppcom_send_connect_session_reply (client_session, 0);
- }
- else
- {
- cut_thru_str = " ";
- vppcom_send_accept_session_reply (client_session->vpp_handle, 0);
- }
-
- if (VPPCOM_DEBUG > 0)
- clib_warning ("[%d] sid %u: accepted%sconnection to local %s address "
- "%U port %u",
- getpid (), client_session_index, cut_thru_str,
- client_session->lcl_addr.is_ip4 ? "IPv4" : "IPv6",
- format_ip46_address, &client_session->lcl_addr.ip46,
- client_session->lcl_addr.is_ip4,
- clib_net_to_host_u16 (client_session->lcl_port));
-
- clib_spinlock_unlock (&vcm->sessions_lockp);
- rv = (int) client_session_index;
-done:
- return rv;
-}
-
-int
-vppcom_session_connect (uint32_t session_index, vppcom_endpt_t * server_ep)
-{
- session_t *session = 0;
- int rv;
-
- VCL_LOCK_AND_GET_SESSION (session_index, &session);
-
- if (PREDICT_FALSE (session->is_vep))
- {
- clib_spinlock_unlock (&vcm->sessions_lockp);
- clib_warning ("[%d] ERROR: sid %u: cannot connect on an epoll session!",
- getpid (), session_index);
- rv = VPPCOM_EBADFD;
- goto done;