diff options
Diffstat (limited to 'src/vcl/vcl_cfg.c')
-rw-r--r-- | src/vcl/vcl_cfg.c | 610 |
1 files changed, 610 insertions, 0 deletions
diff --git a/src/vcl/vcl_cfg.c b/src/vcl/vcl_cfg.c new file mode 100644 index 00000000000..338a6fa6165 --- /dev/null +++ b/src/vcl/vcl_cfg.c @@ -0,0 +1,610 @@ +/* + * Copyright (c) 2018 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <vcl/vcl_private.h> + +/* NOTE: _vppcom_main is only used until the heap is allocated. + * Do not access it directly -- use vcm which will point to + * the heap allocated copy after init. + */ +static vppcom_main_t _vppcom_main = { + .debug = VPPCOM_DEBUG_INIT, + .my_client_index = ~0 +}; + +vppcom_main_t *vcm = &_vppcom_main; + +void +vppcom_cfg_init (vppcom_cfg_t * vcl_cfg) +{ + char *env_var_str; + + ASSERT (vcl_cfg); + + vcl_cfg->heapsize = (256ULL << 20); + vcl_cfg->vpp_api_q_length = 1024; + 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; + vcl_cfg->event_ring_size = (128 << 10); + vcl_cfg->event_log_path = "/dev/shm"; + + env_var_str = getenv (VPPCOM_ENV_DEBUG); + if (env_var_str) + { + u32 tmp; + if (sscanf (env_var_str, "%u", &tmp) != 1) + clib_warning ("VCL<%d>: WARNING: Invalid debug level specified in the" + " environment variable " VPPCOM_ENV_DEBUG " (%s)!\n", + getpid (), env_var_str); + else + { + vcm->debug = tmp; + VDBG (0, "VCL<%d>: configured VCL debug level (%u) from " + VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug); + } + } +} + +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) + { + VDBG (0, "VCL<%d>: using default heapsize %lld (0x%llx)", getpid (), + vcl_cfg->heapsize, vcl_cfg->heapsize); + goto defaulted; + } + + argv = calloc (1, sizeof (char *)); + if (argv == NULL) + { + VDBG (0, "VCL<%d>: calloc failed, using default heapsize %lld (0x%llx)", + getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize); + 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) + { + VDBG (0, "VCL<%d>: realloc failed, using default heapsize %lld " + "(0x%llx)", getpid (), vcl_cfg->heapsize, + vcl_cfg->heapsize); + goto defaulted; + } + argv = tmp; + arg = strndup (p, 1024); + if (arg == NULL) + { + VDBG (0, "VCL<%d>: strndup failed, using default heapsize %lld " + "(0x%llx)", getpid (), vcl_cfg->heapsize, + vcl_cfg->heapsize); + 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) + { + VDBG (0, "VCL<%d>: realloc failed, using default heapsize %lld " + "(0x%llx)", getpid (), vcl_cfg->heapsize, vcl_cfg->heapsize); + 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) + { + VDBG (0, "VCL<%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 + { + VDBG (0, "VCL<%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 ("VCL<%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); + ASSERT (vcl_mem != MAP_FAILED); + return; + } + heap = clib_mem_init (vcl_mem, vcl_cfg->heapsize); + if (!heap) + { + clib_warning ("VCL<%d>: ERROR: clib_mem_init() failed!", getpid ()); + ASSERT (heap); + return; + } + vcl_mem = clib_mem_alloc (sizeof (_vppcom_main)); + if (!vcl_mem) + { + clib_warning ("VCL<%d>: ERROR: clib_mem_alloc() failed!", getpid ()); + ASSERT (vcl_mem); + return; + } + + clib_memcpy (vcl_mem, &_vppcom_main, sizeof (_vppcom_main)); + vcm = vcl_mem; + + VDBG (0, "VCL<%d>: allocated VCL heap = %p, size %lld (0x%llx)", getpid (), + heap, vcl_cfg->heapsize, vcl_cfg->heapsize); +} + +void +vppcom_cfg_read_file (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, q_len; + + fd = open (conf_fname, O_RDONLY); + if (fd < 0) + { + VDBG (0, "VCL<%d>: using default configuration.", getpid (), + conf_fname); + goto file_done; + } + + if (fstat (fd, &s) < 0) + { + VDBG (0, "VCL<%d>: failed to stat `%s', using default configuration", + getpid (), conf_fname); + goto file_done; + } + + if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode))) + { + VDBG (0, "VCL<%d>: not a regular file `%s', using default " + "configuration", getpid (), conf_fname); + goto file_done; + } + + unformat_init_clib_file (input, fd); + + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + { + (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); + VDBG (0, "VCL<%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); + if (vcl_cfg->vpp_api_filename) + vec_free (vcl_cfg->vpp_api_filename); + vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c", + chroot_path, 0); + vl_set_memory_root_path ((char *) chroot_path); + + VDBG (0, "VCL<%d>: configured api-prefix (%s) and api filename" + " (%s)", getpid (), chroot_path, + vcl_cfg->vpp_api_filename); + chroot_path = 0; /* Don't vec_free() it! */ + } + else if (unformat (line_input, "vpp-api-q-length %d", &q_len)) + { + if (q_len < vcl_cfg->vpp_api_q_length) + { + clib_warning ("VCL<%d>: ERROR: configured vpp-api-q-length " + "(%u) is too small! Using default: %u ", + getpid (), q_len, vcl_cfg->vpp_api_q_length); + } + else + { + vcl_cfg->vpp_api_q_length = q_len; + + VDBG (0, "VCL<%d>: configured vpp-api-q-length %u", + getpid (), vcl_cfg->vpp_api_q_length); + } + } + else if (unformat (line_input, "uid %d", &uid)) + { + vl_set_memory_uid (uid); + VDBG (0, "VCL<%d>: configured uid %d", getpid (), uid); + } + else if (unformat (line_input, "gid %d", &gid)) + { + vl_set_memory_gid (gid); + VDBG (0, "VCL<%d>: configured gid %d", getpid (), gid); + } + else if (unformat (line_input, "segment-baseva 0x%lx", + &vcl_cfg->segment_baseva)) + { + VDBG (0, "VCL<%d>: configured segment_baseva 0x%lx", getpid (), + vcl_cfg->segment_baseva); + } + else if (unformat (line_input, "segment-size 0x%lx", + &vcl_cfg->segment_size)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%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)) + { + VDBG (0, "VCL<%d>: configured app_timeout %f", + getpid (), vcl_cfg->app_timeout); + } + else if (unformat (line_input, "session-timeout %f", + &vcl_cfg->session_timeout)) + { + VDBG (0, "VCL<%d>: configured session_timeout %f", + getpid (), vcl_cfg->session_timeout); + } + else if (unformat (line_input, "accept-timeout %f", + &vcl_cfg->accept_timeout)) + { + VDBG (0, "VCL<%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; + VDBG (0, "VCL<%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; + VDBG (0, "VCL<%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; + VDBG (0, "VCL<%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; + VDBG (0, "VCL<%d>: configured app_scope_global (%d)", + getpid (), vcl_cfg->app_scope_global); + } + else if (unformat (line_input, "namespace-secret %lu", + &vcl_cfg->namespace_secret)) + { + VDBG (0, "VCL<%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)) + { + u32 max_nsid_vec_len = vcl_max_nsid_len (); + 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; + VDBG (0, "VCL<%d>: configured namespace_id is too long," + " truncated to %d characters!", + getpid (), max_nsid_vec_len); + } + + VDBG (0, "VCL<%d>: configured namespace_id %v", + getpid (), vcl_cfg->namespace_id); + } + else if (unformat (line_input, "}")) + { + vc_cfg_input = 0; + VDBG (0, "VCL<%d>: completed parsing vppcom config!", + getpid ()); + goto input_done; + } + else + { + if (line_input->buffer[line_input->index] != '#') + { + clib_warning ("VCL<%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); +} + +void +vppcom_cfg (vppcom_cfg_t * vcl_cfg) +{ + char *conf_fname, *env_var_str; + + 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 ("VCL<%d>: WARNING: Invalid debug level specified " + "in the environment variable " VPPCOM_ENV_DEBUG + " (%s)!\n", getpid (), env_var_str); + else + { + vcm->debug = tmp; + VDBG (0, "VCL<%d>: configured VCL debug level (%u) from " + VPPCOM_ENV_DEBUG "!", getpid (), vcm->debug); + } + } + conf_fname = getenv (VPPCOM_ENV_CONF); + if (!conf_fname) + conf_fname = VPPCOM_CONF_DEFAULT; + vppcom_cfg_heapsize (conf_fname); + vppcom_cfg_read_file (conf_fname); + + env_var_str = getenv (VPPCOM_ENV_API_PREFIX); + if (env_var_str) + { + if (vcl_cfg->vpp_api_filename) + vec_free (vcl_cfg->vpp_api_filename); + vcl_cfg->vpp_api_filename = format (0, "/%s-vpe-api%c", env_var_str, 0); + vl_set_memory_root_path ((char *) env_var_str); + + VDBG (0, "VCL<%d>: configured api prefix (%s) and filename (%s) " + "from " VPPCOM_ENV_API_PREFIX "!", + getpid (), env_var_str, vcl_cfg->vpp_api_filename); + } + 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); + + VDBG (0, "VCL<%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 ("VCL<%d>: WARNING: 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; + VDBG (0, "VCL<%d>: configured namespace secret (%lu) from " + VPPCOM_ENV_APP_NAMESPACE_SECRET "!", getpid (), + vcm->cfg.namespace_secret); + } + } + if (getenv (VPPCOM_ENV_APP_PROXY_TRANSPORT_TCP)) + { + vcm->cfg.app_proxy_transport_tcp = 1; + VDBG (0, "VCL<%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; + VDBG (0, "VCL<%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; + VDBG (0, "VCL<%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; + VDBG (0, "VCL<%d>: configured app_scope_global (%u) from " + VPPCOM_ENV_APP_SCOPE_GLOBAL "!", getpid (), + vcm->cfg.app_scope_global); + } +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ |