summaryrefslogtreecommitdiffstats
path: root/stacks/vpp/adapt
diff options
context:
space:
mode:
authorrainbow_0206 <jiangwenjiang@huawei.com>2018-08-14 20:04:16 +0800
committerrainbow_0206 <jiangwenjiang@huawei.com>2018-08-30 15:56:08 +0800
commit9f683fadb09aaea5a07f4673f8bbc3a7ddd38afc (patch)
treee3260f5799a8be882d7104f8b00f954f3c643863 /stacks/vpp/adapt
parent5686565ee3b379c590a1a09a05c92db50d206add (diff)
Feat: integrate VPP hoststack into dmm
Change-Id: I64c361cc93e02ed89ed40eb4440c36326d2dfa03 Signed-off-by: Qing Chang <qing.chang1@huawei.com> Signed-off-by: Yalei Wang <william.wangyalei@huawei.com> Signed-off-by: rainbow_0206 <jiangwenjiang@huawei.com>
Diffstat (limited to 'stacks/vpp/adapt')
-rw-r--r--stacks/vpp/adapt/dmm_vcl.h36
-rw-r--r--stacks/vpp/adapt/dmm_vcl_adpt.c172
2 files changed, 208 insertions, 0 deletions
diff --git a/stacks/vpp/adapt/dmm_vcl.h b/stacks/vpp/adapt/dmm_vcl.h
new file mode 100644
index 0000000..f0d8c85
--- /dev/null
+++ b/stacks/vpp/adapt/dmm_vcl.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+#ifndef included_dmm_vcl_h
+#define included_dmm_vcl_h
+
+#include "nstack_dmm_api.h"
+
+#define DMM_VCL_ENV_DEBUG "DMM_VCL_DEBUG"
+
+typedef struct dmm_vcl
+{
+ int epfd;
+ long unsigned int epoll_threadid;
+ nstack_event_cb regVal;
+ int (*p_epoll_create) (int size);
+ unsigned int (*p_epoll_ctl) (int epFD, int proFD, int ctl_ops,
+ struct epoll_event * events);
+ unsigned int (*p_epoll_wait) (int epfd, struct epoll_event * events,
+ int maxevents, int timeout);
+ int (*p_close) (int fd);
+} dmm_vcl_t;
+
+#endif /* included_dmm_vcl_h */
diff --git a/stacks/vpp/adapt/dmm_vcl_adpt.c b/stacks/vpp/adapt/dmm_vcl_adpt.c
new file mode 100644
index 0000000..1b2b9a9
--- /dev/null
+++ b/stacks/vpp/adapt/dmm_vcl_adpt.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <pthread.h>
+#include <dlfcn.h>
+#include <sys/epoll.h>
+#include "dmm_vcl.h"
+#include "nstack_dmm_api.h" // nstack_socket_ops*
+#include <vppinfra/error.h> // clib_warning()
+
+#define DMM_VCL_ADPT_DEBUG dmm_vcl_debug
+static unsigned int dmm_vcl_debug;
+dmm_vcl_t g_dmm_vcl;
+
+unsigned int
+vpphs_ep_ctl_ops (int epFD, int proFD, int ctl_ops,
+ struct epoll_event *events, void *pdata)
+{
+ struct epoll_event tmpEvt;
+ int ret = 0;
+ int dmm_epfd;
+
+ tmpEvt.data.ptr = pdata;
+ tmpEvt.events = events->events;
+
+ if (DMM_VCL_ADPT_DEBUG > 0)
+ clib_warning ("DMM VCL ADPT<%d>: epfd=%d,fd=%d,ops=%d, events=%u",
+ getpid (), epFD, proFD, ctl_ops, events->events);
+
+ dmm_epfd = g_dmm_vcl.epfd;
+ switch (ctl_ops)
+ {
+ case nstack_ep_triggle_add:
+ ret = g_dmm_vcl.p_epoll_ctl (dmm_epfd, EPOLL_CTL_ADD, proFD, &tmpEvt);
+ break;
+ case nstack_ep_triggle_mod:
+ ret = g_dmm_vcl.p_epoll_ctl (dmm_epfd, EPOLL_CTL_MOD, proFD, &tmpEvt);
+ break;
+ case nstack_ep_triggle_del:
+ ret = g_dmm_vcl.p_epoll_ctl (dmm_epfd, EPOLL_CTL_DEL, proFD, &tmpEvt);
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+ return ret;
+}
+
+#define DMM_VCL_MAX_EP_EVENT 1024
+
+static void *
+dmm_vcl_epoll_thread (void *arg)
+{
+ int num, i;
+
+ struct epoll_event events[DMM_VCL_MAX_EP_EVENT];
+
+ while (1)
+ {
+ num =
+ g_dmm_vcl.p_epoll_wait (g_dmm_vcl.epfd, events, DMM_VCL_MAX_EP_EVENT,
+ 100);
+
+ for (i = 0; i < num; ++i)
+ {
+ if (DMM_VCL_ADPT_DEBUG > 0)
+ clib_warning
+ ("DMM_VCL_ADPT<%d>: dmm_vcl_epoll i[%d] events=%u, epfd=%d, ptr=%d",
+ getpid (), i, events[i].events, events[i].data.fd,
+ events[i].data.ptr);
+
+ g_dmm_vcl.regVal.event_cb (events[i].data.ptr, events[i].events);
+
+ }
+ }
+
+ return NULL;
+}
+
+int
+dmm_vpphs_init ()
+{
+ char *env_var_str;
+ int rv = 0;
+
+ env_var_str = getenv (DMM_VCL_ENV_DEBUG);
+ if (env_var_str)
+ {
+ u32 tmp;
+ if (sscanf (env_var_str, "%u", &tmp) != 1)
+ clib_warning
+ ("DMM_VCL_ADPT<%d>: WARNING: Invalid debug level specified "
+ "in the environment variable " DMM_VCL_ENV_DEBUG " (%s)!\n",
+ getpid (), env_var_str);
+ else
+ {
+ dmm_vcl_debug = tmp;
+ if (DMM_VCL_ADPT_DEBUG > 0)
+ clib_warning
+ ("DMM_VCL_ADPT<%d>: configured DMM VCL ADPT debug (%u) from "
+ "DMM_VCL_ENV_DEBUG ", getpid (), dmm_vcl_debug);
+ }
+ }
+
+ g_dmm_vcl.epfd = g_dmm_vcl.p_epoll_create (1000);
+ if (g_dmm_vcl.epfd < 0)
+ return g_dmm_vcl.epfd;
+
+ rv =
+ pthread_create (&g_dmm_vcl.epoll_threadid, NULL, dmm_vcl_epoll_thread,
+ NULL);
+ if (rv != 0)
+ {
+ clib_warning ("dmm vcl epoll thread create fail, errno:%d!", errno);
+ g_dmm_vcl.p_close (g_dmm_vcl.epfd);
+ g_dmm_vcl.epfd = -1;
+ return rv;
+ }
+
+ rv = pthread_setname_np (g_dmm_vcl.epoll_threadid, "dmm_vcl_epoll");
+ if (rv != 0)
+ {
+ clib_warning
+ ("pthread_setname_np failed for dmm_vcl_epoll, rv=%d, errno:%d",
+ rv, errno);
+ }
+
+ return rv;
+}
+
+int
+vpphs_stack_register (nstack_proc_cb * ops, nstack_event_cb * val)
+{
+
+#undef NSTACK_MK_DECL
+#define NSTACK_MK_DECL(ret, fn, args) \
+ (ops->socket_ops).pf ## fn = (typeof(((nstack_socket_ops*)0)->pf ## fn))dlsym(val->handle, # fn);
+#include "declare_syscalls.h"
+ (ops->socket_ops).pfepoll_create = NULL;
+
+ g_dmm_vcl.p_epoll_ctl = dlsym (val->handle, "epoll_ctl");
+ g_dmm_vcl.p_epoll_create = dlsym (val->handle, "epoll_create1");
+ g_dmm_vcl.p_epoll_wait = dlsym (val->handle, "epoll_wait");
+ g_dmm_vcl.p_close = dlsym (val->handle, "close");
+ g_dmm_vcl.regVal = *val;
+
+ ops->extern_ops.module_init = dmm_vpphs_init;
+ ops->extern_ops.fork_init_child = NULL;
+ ops->extern_ops.fork_parent_fd = NULL;
+ ops->extern_ops.fork_child_fd = NULL;
+ ops->extern_ops.fork_free_fd = NULL;
+ ops->extern_ops.ep_ctl = vpphs_ep_ctl_ops;
+ ops->extern_ops.ep_prewait_proc = NULL;
+ ops->extern_ops.stack_fd_check = NULL;
+ ops->extern_ops.stack_alloc_fd = NULL;
+ ops->extern_ops.peak = NULL;
+
+ return 0;
+}