From 26f546256d5f9c981224b30f6b9988941d76d018 Mon Sep 17 00:00:00 2001 From: Xiaolong Jiang Date: Wed, 23 Sep 2020 09:29:24 +0800 Subject: modify vcl patch and remove ldp-lock patch Signed-off-by: Xiaolong Jiang Change-Id: I4fe5f4dc2121d952bd0a4394afe0b18ce6f93516 --- .gitmodules | 2 +- Makefile | 27 + README.md | 44 +- configs/nginx-test.conf | 80 ++ configs/nginx.conf | 112 +- configs/startup-test.conf | 28 + configs/vppset-test | 1 + packages/nginx_ldp.mk | 13 +- packages/nginx_vcl.mk | 15 +- packages/openssl.mk | 6 +- packages/verify.sh | 69 +- packages/vpp_ldp.mk | 58 +- packages/vpp_vcl.mk | 55 +- vpp_patches/other/0001-3.0.0.patch | 113 -- vpp_patches/other/2001/0001-3.0.0.patch | 113 ++ vpp_patches/other/2005/0001-3.0.0.patch | 113 ++ vpp_patches/other/2005/0001-picotls-patch.patch | 45 + vpp_patches/other/master/0001-3.0.0.patch | 114 ++ vpp_patches/vcl/0001-ngxvcl-api.patch | 1713 ----------------------- vpp_patches/vcl/master/0001-ngxvcl-api.patch | 1698 ++++++++++++++++++++++ vpp_patches/vcl/other/0001-ngxvcl-api.patch | 1713 +++++++++++++++++++++++ 21 files changed, 4116 insertions(+), 2016 deletions(-) create mode 100644 configs/nginx-test.conf create mode 100644 configs/startup-test.conf create mode 100644 configs/vppset-test delete mode 100644 vpp_patches/other/0001-3.0.0.patch create mode 100644 vpp_patches/other/2001/0001-3.0.0.patch create mode 100644 vpp_patches/other/2005/0001-3.0.0.patch create mode 100644 vpp_patches/other/2005/0001-picotls-patch.patch create mode 100644 vpp_patches/other/master/0001-3.0.0.patch delete mode 100644 vpp_patches/vcl/0001-ngxvcl-api.patch create mode 100644 vpp_patches/vcl/master/0001-ngxvcl-api.patch create mode 100644 vpp_patches/vcl/other/0001-ngxvcl-api.patch diff --git a/.gitmodules b/.gitmodules index 69878e6..7e346ce 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "vpp"] path = vpp - url = https://gerrit.fd.io/r/vpp + url = https://github.com/FDio/vpp.git diff --git a/Makefile b/Makefile index b11cc4d..16daa3f 100644 --- a/Makefile +++ b/Makefile @@ -29,10 +29,13 @@ vpp ?= master MAKE ?= make MAKE_ARGS ?= -j openssl3_enable ?= 0 +openssl3_lib_ready ?= 0 debug ?= 0 BUILD_DIR ?= $(CURDIR)/_build INSTALL_DIR ?= $(CURDIR)/_install +MAIN_BRANCH := master + B := $(BUILD_DIR) I := $(INSTALL_DIR) @@ -87,16 +90,40 @@ $(BR)/.deps.ok: @touch $@ .PHONY: build-vcl +ifeq ($(openssl3_enable)_$(openssl3_lib_ready), 1_1) +build-vcl: $(BR)/.deps.ok nginx-dl vpp_vcl-build nginx_vcl-build +else ifeq ($(openssl3_enable),1) build-vcl: $(BR)/.deps.ok openssl-dl nginx-dl openssl-build vpp_vcl-build nginx_vcl-build +else +build-vcl: $(BR)/.deps.ok nginx-dl vpp_vcl-build nginx_vcl-build +endif .PHONY: build-ldp +ifeq ($(openssl3_enable)_$(openssl3_lib_ready), 1_1) +build-ldp: $(BR)/.deps.ok nginx-dl vpp_ldp-build nginx_ldp-build +else ifeq ($(openssl3_enable),1) build-ldp: $(BR)/.deps.ok openssl-dl nginx-dl openssl-build vpp_ldp-build nginx_ldp-build +else +build-ldp: $(BR)/.deps.ok nginx-dl vpp_ldp-build nginx_ldp-build +endif .PHONY: deb-vcl +ifeq ($(openssl3_enable)_$(openssl3_lib_ready), 1_1) +deb-vcl: build-vcl vpp_vcl-deb nginx_vcl-deb +else ifeq ($(openssl3_enable),1) deb-vcl: build-vcl openssl-deb vpp_vcl-deb nginx_vcl-deb +else +deb-vcl: build-vcl vpp_vcl-deb nginx_vcl-deb +endif .PHONY: deb-ldp +ifeq ($(openssl3_enable)_$(openssl3_lib_ready), 1_1) +deb-ldp: build-ldp vpp_ldp-deb nginx_ldp-deb +else ifeq ($(openssl3_enable),1) deb-ldp: build-ldp openssl-deb vpp_ldp-deb nginx_ldp-deb +else +deb-ldp: build-ldp vpp_ldp-deb nginx_ldp-deb +endif .PHONY: verify-vcl verify-vcl: build-vcl diff --git a/README.md b/README.md index fc63d87..81b103c 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ This repository is to provide an optimized NGINX based on VPP host stack. We provide two ways of VPP host stack integration, i.e. LDP and VCL. LDP is basically un-modified NGINX with VPP via LD_PRELOAD, while VCL NGINX is to integrate VPP host stack directly with NGINX code change. -This repository provides the nginx build and openssl3.0.0 build, as well -as the integration of VPP host stacks, namely the LDP and VCL VPP and nginx -builds, and generates the installation deb packages to the specified location. +This repository provides the nginx build, as well as the integration of +VPP host stacks, namely the LDP and VCL VPP and nginx builds, and generates +the installation deb packages to the specified location. # 2 Repository Layout **configs**: configuration files for VPP, NGINX and VCL @@ -14,8 +14,6 @@ builds, and generates the installation deb packages to the specified location. **vpp_patches**: lock-free LDP and pinned-VPP patches -**openssl_patches**: openssl patches - **scripts**: scripts for VPP, NGINX and client test **packages**: Makefiles for building and downloading @@ -40,7 +38,7 @@ Build vcl DEB package and store the DEB files in folder '/path/to/this/repo/deb- $ make deb-vcl Build vcl vpp and vcl nginx -Nginx and Openssl are in folder '/path/to/this/repo/_install/local' +Nginx is in folder '/path/to/this/repo/_build/usr/local/nginx' Vpp is in '/path/to/this/repo/vpp' $ make build-vcl @@ -48,7 +46,7 @@ Build ldp DEB package and store the DEB files in folder '/path/to/this/repo/deb- $ make deb-ldp Build ldp vpp and ldp nginx -Nginx and Openssl are in folder '/path/to/this/repo/_install/local' +Nginx is in folder '/path/to/this/repo/_build/usr/local/nginx' Vpp is in '/path/to/this/repo/vpp' $ make build-ldp @@ -60,6 +58,13 @@ If you don't take the parameter, the default is master. For example: $ make deb-vcl +You can choose whether openssl3.0.0 is supported or not. +$ make deb-vcl openssl3_enable=1 + +If you already have OpensSL3.0 and don't want to compile Openssl3.0, +you can add the option 'openssl3_lib_ready' +$ make deb-vcl openssl3_enable=1 openssl3_lib_ready=1 + Verify that vcl starts properly $ make verify-vcl @@ -123,7 +128,7 @@ Now the original NGINX code has been modified to VCL-supporting code. Then you can configure and build NGINX. ```bash -$ ./configure --with-vcl --vpp-lib-path=/path/to/vpp/build-root/install-vpp-native/vpp/lib --vpp-src-path=/path/to/vpp/src +$ ./configure --with-vcl --vpp-lib-path=/path/to/this/repo/vpp/build-root/install-vpp-native/vpp/lib --vpp-src-path=/path/to/this/repo/vpp/src $ sudo make install ``` @@ -131,21 +136,21 @@ $ sudo make install - Run VPP first - Refer to startup.conf provided in "configs" to start VPP. (learn how to use startup.conf in section 4.1.1) - - If you choose to use the Makefile to build automatically, the VPP is stored in '/path/to/this/repo/_install/local/vpp' + - If you choose to use the Makefile to build automatically, the VPP is stored in '/path/to/this/repo/vpp' ```bash - ./vpp -c /path/to/startup.conf + ./vpp -c /path/to/this/repo/configs/startup.conf ``` Start NGINX - refer to vcl.conf and nginx.conf provided under "configs" - - If you choose to use the Makefile to build automatically, the NGINX is stored in '/path/to/this/repo/_install/local/nginx' + - If you choose to use the Makefile to build automatically, the NGINX is stored in '/path/to/this/repo/_build/usr/local/nginx' ``` - # export VCL_CONFIG=/path/to/vcl.conf - # export LD_LIBRARY_PATH=/path/to/vpp/build-root/install-vpp-native/vpp/lib - # /usr/local/nginx/sbin/nginx -c /path/to/nginx.conf + # export VCL_CONFIG=/path/to/this/repo/configs/vcl.conf + # export LD_LIBRARY_PATH=/path/to/this/repo/vpp/build-root/install-vpp-native/vpp/lib + # /path/to/this/repo/_build/usr/local/nginx/sbin/nginx -c /path/to/this/repo/configs/nginx.conf ``` ## 3.2 LDP NGINX @@ -160,17 +165,16 @@ This patch removes VLS session locks for saving approximately 100% CPU cycles on You may need root privilege. ```bash -$ cd /path/to/vpp -$ patch -p1 < /path/to/this/repo/vpp_patches/ldp/0001-LDP-remove-lock.patch +$ cd /path/to/this/repo/vpp $ make build && make build-release ``` **Start NGINX** -If you choose to use the Makefile to build automatically, the VPP is stored in '/path/to/this/repo/_install/local/vpp' -If you choose to use the Makefile to build automatically, the NGINX is stored in '/path/to/this/repo/_install/local/nginx' +If you choose to use the Makefile to build automatically, the VPP is stored in '/path/to/this/repo/vpp' +If you choose to use the Makefile to build automatically, the NGINX is stored in '/path/to/this/repo/_build/usr/local/nginx' ```bash -$ export VCL_CONFIG=path/to/vcl.conf -$ LD_PRELOAD=path/to/vpp/build-root/install-vpp-native/vpp/lib/libvcl_ldpreload.so /usr/local/nginx/sbin/nginx -c path/to/nginx.conf +$ export VCL_CONFIG=path/to/this/repo/vcl.conf +$ LD_PRELOAD=/path/to/this/repo/vpp/build-root/install-vpp-native/vpp/lib/libvcl_ldpreload.so /path/to/this/repo/_build/usr/local/nginx/sbin/nginx -c path/to/this/repo/configs/nginx.conf ``` ## 3.3 Enable VPP TLS diff --git a/configs/nginx-test.conf b/configs/nginx-test.conf new file mode 100644 index 0000000..e67e8fa --- /dev/null +++ b/configs/nginx-test.conf @@ -0,0 +1,80 @@ +#user xxx; +worker_processes 1; +#worker_processes 2; +#worker_processes 4; +#worker_processes 8; + +master_process on; +daemon off; + +worker_rlimit_nofile 10240; +events { + use epoll; + worker_connections 10240; + accept_mutex off; + multi_accept off; +} + + +http { + access_log off; + include mime.types; + default_type application/octet-stream; + sendfile on; + + + ##RPS test + keepalive_timeout 300s; + keepalive_requests 1000000; + + server { + listen 80; + root html; + index index.html index.htm; + location /return { + return 204; + } + location /64B.json { + return 200 '{"status":"success","result":"this is a 64Byte json file test!"}'; + } + location /1KB.json{ + return 201 '{"status":"success","result":"Hello from NGINX, 1KB test! \ + 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + "}'; + } + location /2KB.json{ + return 202 '{"status":"success","result":"Hello from NGINX, 2KB test! \ + 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + "}'; + } + } + } diff --git a/configs/nginx.conf b/configs/nginx.conf index d184b89..6770ea0 100644 --- a/configs/nginx.conf +++ b/configs/nginx.conf @@ -10,7 +10,6 @@ daemon off; worker_rlimit_nofile 10240; events { use epoll; - #epoll_events 512; worker_connections 10240; accept_mutex off; multi_accept off; @@ -29,88 +28,53 @@ http { keepalive_requests 1000000; server { - listen 443; - #ssl_protocols TLSv1.2; - #ssl_prefer_server_ciphers on; + listen 80; root html; index index.html index.htm; location /return { return 204; } location /64B.json { - return 200 '{"status":"success","result":"this is \ - a 64Byte json file test!"}'; - } + return 200 '{"status":"success","result":"this is a 64Byte json file test!"}'; + } location /1KB.json{ - return 201 '{"status":"success","result":"\ - Nanchang, which was the capital of Yuzhang \ - Prefecture during the HanDynasty, \ - now falls under the jurisdiction of Hongzhou. \ - It straddles the borderof the \ - influence of the Ye and Zhen constellations , \ - and is adjacent to theHeng \ - and the Lu mountains . The three rivers enfold \ - it like the frontpart \ - of a garment and the five lakes encircle it \ - like a girdle. Itcontrols \ - the savage Jing area and connects Ou and Yue, \ - and itsproducts are \ - nature’s jewels. The radiance of its legendary \ - sword shootsdirectly upward \ - between the constellations Niu and Dou. \ - Its talented peopleare outstanding,\ - and the spirit of intelligence pervades the \ - place. This wasthe place where Xu \ - Ru spent the night on his visit to Chen Fan (10). \ - The mightyHongzhou spreads \ - out immensely amid the fog, and the intellectual \ - luminariesare as numerous as\ - meteors chasing one another. \ + return 201 '{"status":"success","result":"Hello from NGINX, 1KB test! \ + 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ "}'; - } + } location /2KB.json{ - return 202 '{"status":"success","result":"\ - Hello from NGINX, 2KB test\ - Nanchang, which was the capital of Yuzhang \ - Prefecture during the HanDynasty, \ - now falls under the jurisdiction of Hongzhou. \ - It straddles the borderof the \ - influence of the Ye and Zhen constellations , \ - and is adjacent to theHeng \ - and the Lu mountains . The three rivers enfold \ - it like the frontpart \ - of a garment and the five lakes encircle it \ - like a girdle. Itcontrols \ - the savage Jing area and connects Ou and Yue, \ - and itsproducts are \ - nature’s jewels. The radiance of its legendary \ - sword shootsdirectly upward \ - between the constellations Niu and Dou. \ - Its talented peopleare outstanding,\ - and the spirit of intelligence pervades \ - the place. This wasthe place where Xu \ - Ru spent the night on his visit to \ - Chen Fan (10). The mightyHongzhou spreads \ - out immensely amid the fog, and the intellectual \ - luminariesare as numerous as\ - meteors chasing one another.\ - of a garment and the five lakes encircle \ - it like a girdle. Itcontrols \ - the savage Jing area and connects \ - Ou and Yue, and itsproducts are \ - nature’s jewels. The radiance of its \ - legendary sword shootsdirectly upward \ - between the constellations Niu and Dou. \ - Its talented peopleare outstanding,\ - and the spirit of intelligence pervades \ - the place. This wasthe place where Xu \ - Ru spent the night on his visit to \ - Chen Fan (10). The mightyHongzhou spreads \ - out immensely amid the fog, and the \ - intellectual luminariesare as numerous as\ - meteors chasing one another. \ + return 202 '{"status":"success","result":"Hello from NGINX, 2KB test! \ + 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 3xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 5xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 7xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 8xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ + 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \ "}'; - } - + } } } diff --git a/configs/startup-test.conf b/configs/startup-test.conf new file mode 100644 index 0000000..cf41cca --- /dev/null +++ b/configs/startup-test.conf @@ -0,0 +1,28 @@ +unix { + interactive + log /tmp/vpp.log + full-coredump + cli-listen /run/vpp/cli.sock + exec /tmp/vppset-test +} + +api-trace { + on +} + +session { + evt_qs_memfd_seg +} + +socksvr { + default +} + +cpu { + main-core 0 + ##Start 4 VPP workers + #corelist-workers 1-4 + ##start 1 VPP worker + corelist-workers 1 +} + diff --git a/configs/vppset-test b/configs/vppset-test new file mode 100644 index 0000000..082ac46 --- /dev/null +++ b/configs/vppset-test @@ -0,0 +1 @@ +set int state local0 up diff --git a/packages/nginx_ldp.mk b/packages/nginx_ldp.mk index f7756de..db9386a 100644 --- a/packages/nginx_ldp.mk +++ b/packages/nginx_ldp.mk @@ -41,14 +41,15 @@ endef define nginx_ldp_build_cmds @$(MAKE) -C $(nginx_ldp_src_dir) + @$(MAKE) -C $(nginx_ldp_src_dir) DESTDIR=$(B) install + @cp configs/mime.types $(B)$(nginx_ldp_install_dir)/conf/. + @cp configs/nginx.conf $(B)$(nginx_ldp_install_dir)/conf/. + @cp configs/tls-* $(B)$(nginx_ldp_install_dir)/conf/. + @cp configs/vcl.conf $(B)$(nginx_ldp_install_dir)/conf/. endef define nginx_ldp_install_cmds - @$(MAKE) -C $(nginx_ldp_src_dir) install - @cp configs/mime.types $(nginx_ldp_install_dir)/conf/. - @cp configs/nginx.conf $(nginx_ldp_install_dir)/conf/. - @cp configs/tls-* $(nginx_ldp_install_dir)/conf/. - @cp configs/vcl.conf $(nginx_ldp_install_dir)/conf/. + @true endef define nginx_ldp_pkg_deb_cmds @@ -56,7 +57,7 @@ define nginx_ldp_pkg_deb_cmds -t deb \ -n $(nginx_ldp_pkg_deb_name) \ -v $(nginx_ldp_version) \ - -C $(nginx_ldp_install_dir) \ + -C $(B)$(nginx_ldp_install_dir) \ -p $(nginx_ldp_pkg_deb_dir) \ --prefix $(nginx_ldp_deb_inst_dir) \ --license $(LICENSE) \ diff --git a/packages/nginx_vcl.mk b/packages/nginx_vcl.mk index 2b3425f..3f2f80d 100644 --- a/packages/nginx_vcl.mk +++ b/packages/nginx_vcl.mk @@ -16,6 +16,8 @@ nginx_vcl_patch_dir := $(CURDIR)/nginx_patches nginx_vcl_src_dir := $(B)/nginx_vcl vpp_vcl_src_dir := $(CURDIR)/vpp nginx_vcl_install_dir := /usr/local/nginx +nginx_vcl_tmp1_dir := $(B)/nginx_vcl_backup1 +nginx_vcl_tmp2_dir := $(B)/nginx_vcl_backup2 nginx_vcl_deb_inst_dir := /usr/local/nginx nginx_vcl_pkg_deb_name := nginx nginx_vcl_pkg_deb_dir := $(I)/deb-vcl @@ -46,14 +48,15 @@ endef define nginx_vcl_build_cmds @$(MAKE) -C $(nginx_vcl_src_dir) + @$(MAKE) -C $(nginx_vcl_src_dir) DESTDIR=$(B) install + @cp configs/mime.types $(B)$(nginx_vcl_install_dir)/conf/. + @cp configs/nginx.conf $(B)$(nginx_vcl_install_dir)/conf/. + @cp configs/tls-* $(B)$(nginx_vcl_install_dir)/conf/. + @cp configs/vcl.conf $(B)$(nginx_vcl_install_dir)/conf/. endef define nginx_vcl_install_cmds - @$(MAKE) -C $(nginx_vcl_src_dir) install - @cp configs/mime.types $(nginx_vcl_install_dir)/conf/. - @cp configs/nginx.conf $(nginx_vcl_install_dir)/conf/. - @cp configs/tls-* $(nginx_vcl_install_dir)/conf/. - @cp configs/vcl.conf $(nginx_vcl_install_dir)/conf/. + @true endef define nginx_vcl_pkg_deb_cmds @@ -61,7 +64,7 @@ define nginx_vcl_pkg_deb_cmds -t deb \ -n $(nginx_vcl_pkg_deb_name) \ -v $(nginx_vcl_version) \ - -C $(nginx_vcl_install_dir) \ + -C $(B)$(nginx_vcl_install_dir) \ -p $(nginx_vcl_pkg_deb_dir) \ --prefix $(nginx_vcl_deb_inst_dir) \ --license $(LICENSE) \ diff --git a/packages/openssl.mk b/packages/openssl.mk index b31257a..227dce8 100644 --- a/packages/openssl.mk +++ b/packages/openssl.mk @@ -33,9 +33,9 @@ define openssl_config_cmds endef define openssl_build_cmds - @$(MAKE) -C $(openssl_build_dir) depend - @$(MAKE) -C $(openssl_build_dir) - @$(MAKE) -C $(openssl_build_dir) install + $(MAKE) -C $(openssl_build_dir) depend + $(MAKE) -C $(openssl_build_dir) + $(MAKE) -C $(openssl_build_dir) install endef define openssl_install_cmds diff --git a/packages/verify.sh b/packages/verify.sh index 6b3d7a3..b849d68 100755 --- a/packages/verify.sh +++ b/packages/verify.sh @@ -3,21 +3,17 @@ ngxvcl=${BR}/_build/nginx_vcl ngxldp=${BR}/_build/nginx_ldp +tls_tcp=tls + function test_vcl(){ echo "" echo "====================================================================" echo "Testing ..." echo "" export LD_LIBRARY_PATH=/usr/local/ssl/lib - cp ${BR}/configs/startup.conf ${BR}/configs/startup-test.conf - - sed -i 's|/var/log/vpp/vpp.log|/tmp/vpp.log|' ${BR}/configs/startup-test.conf - sed -i 's|cli-vpp1.sock|cli.sock|' ${BR}/configs/startup-test.conf - sed -i 's|/path/to/configs/vppenvset|configs/vppset|' ${BR}/configs/startup-test.conf - sed -i 's|socket-name /path/to/vpp-api.sock|default|' ${BR}/configs/startup-test.conf - echo "set int state local0 up" > ${BR}/configs/vppset - ${BR}/vpp/build-root/install-vpp-native/vpp/bin/vpp -c configs/startup-test.conf & + cp ${BR}/configs/vppset-test /tmp/. + ${BR}/vpp/build-root/install-vpp-native/vpp/bin/vpp -c ${BR}/configs/startup-test.conf & vpp_pid=$! sleep 5 @@ -32,9 +28,16 @@ function test_vcl(){ sudo killall -v -s 9 nginx || echo "continue execute" - cp ${BR}/configs/nginx.conf ${BR}/configs/nginx-test.conf - sed -i 's|#worker_processes 1|worker_processes 1|' ${BR}/configs/nginx-test.conf - + mdir=0 + if [ ! -d /usr/local/nginx/logs ]; then + mdir=2 + if [ ! -d /usr/local/nginx ]; then + mdir=1 + fi + fi + if [ ${mdir} -ne 0 ]; then + mkdir -p /usr/local/nginx/logs + fi ${ngxvcl}/objs/nginx -c ${BR}/configs/nginx-test.conf & nginx_pid=$! sleep 5 @@ -60,10 +63,13 @@ function test_vcl(){ sudo killall -v -s 9 nginx || echo "" sudo kill -9 ${vpp_pid} || echo "" - rm -f ${BR}/configs/nginx-test.conf - rm -f ${BR}/configs/startup-test.conf - rm -f ${BR}/configs/vppset - rm -f /tmp/vpp.log + + rm /tmp/vppset-test + if [ ${mdir} -eq 1 ]; then + rm -rf /usr/local/nginx + elif [ ${mdir} -eq 2 ]; then + rm -rf /usr/local/nginx/logs + fi if [ ${ret} -eq 1 ]; then exit 1; @@ -77,21 +83,23 @@ function test_ldp(){ echo "" export LD_LIBRARY_PATH=/usr/local/ssl/lib - cp ${BR}/configs/startup.conf ${BR}/configs/startup-test.conf - - sed -i 's|/var/log/vpp/vpp.log|/tmp/vpp.log|' ${BR}/configs/startup-test.conf - sed -i 's|cli-vpp1.sock|cli.sock|' ${BR}/configs/startup-test.conf - sed -i 's|/path/to/configs/vppenvset|configs/vppset|' ${BR}/configs/startup-test.conf - sed -i 's|socket-name /path/to/vpp-api.sock|default|' ${BR}/configs/startup-test.conf - echo "set int state local0 up" > ${BR}/configs/vppset - ${BR}/vpp/build-root/install-vpp-native/vpp/bin/vpp -c configs/startup-test.conf & + cp ${BR}/configs/vppset-test /tmp/. + ${BR}/vpp/build-root/install-vpp-native/vpp/bin/vpp -c ${BR}/configs/startup-test.conf & vpp_pid=$! sleep 5 - cp ${BR}/configs/nginx.conf ${BR}/configs/nginx-test.conf - sed -i 's|#worker_processes 1|worker_processes 1|' ${BR}/configs/nginx-test.conf + mdir=0 + if [ ! -d /usr/local/nginx/logs ]; then + mdir=2 + if [ ! -d /usr/local/nginx ]; then + mdir=1 + fi + fi + if [ ${mdir} -ne 0 ]; then + mkdir -p /usr/local/nginx/logs + fi export VCL_CONFIG=${BR}/configs/vcl.conf export LDP_TRANSPARENT_TLS=1 @@ -113,7 +121,6 @@ function test_ldp(){ ret=1 fi - v=`ps -A|grep "${nginx_pid}" | wc -l` if [ ${v} -eq 1 ]; then echo "LDP test: nginx OK" @@ -126,10 +133,12 @@ function test_ldp(){ sudo killall -v -s 9 nginx || echo "" sudo kill -9 ${vpp_pid} || echo "" - rm -f ${BR}/configs/nginx-test.conf - rm -f ${BR}/configs/startup-test.conf - rm -f ${BR}/configs/vppset - rm -rf /tmp/vpp.log + rm /tmp/vppset-test + if [ ${mdir} -eq 1 ]; then + rm -rf /usr/local/nginx + elif [ ${mdir} -eq 2 ]; then + rm -rf /usr/local/nginx/logs + fi if [ ${ret} -eq 1 ]; then exit 1 diff --git a/packages/vpp_ldp.mk b/packages/vpp_ldp.mk index 8b1fd7a..05e8398 100644 --- a/packages/vpp_ldp.mk +++ b/packages/vpp_ldp.mk @@ -27,8 +27,8 @@ endef define vpp_ldp_patch_cmds @echo "--- ldp vpp patching ---" @cd $(vpp_ldp_src_dir); \ - git reset --hard; git clean -f; git checkout master; \ - if [ $(_VPP_VER) != "master" ] ; then \ + git reset --hard; git clean -f; git checkout $(MAIN_BRANCH); \ + if [ $(_VPP_VER) != $(MAIN_BRANCH) ] ; then \ echo "--- vpp version: $(_VPP_VER) ---"; \ if [ $(_VPP_VER) = "2005" ]; then \ git checkout v20.05; \ @@ -41,14 +41,20 @@ define vpp_ldp_patch_cmds echo Applying patch: $$(basename $$f) ; \ patch -p1 -d $(vpp_ldp_src_dir) < $$f ; \ done - @if [ $(openssl3_enable) = 1 ]; then \ + @if [ $(openssl3_enable) -eq 1 ]; then \ for f in $(CURDIR)/vpp_patches/other/*.patch ; do \ echo Applying patch: $$(basename $$f) ; \ patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \ done; \ - if [ $(_VPP_VER) = "master" -o $(_VPP_VER) = "2005" ]; then \ - echo "--- vpp master ---"; \ - for f in $(CURDIR)/vpp_patches/other/master/*; do \ + if [ $(_VPP_VER) = $(MAIN_BRANCH) ]; then \ + echo "--- vpp $(MAIN_BRANCH) ---"; \ + for f in $(CURDIR)/vpp_patches/other/$(MAIN_BRANCH)/*; do \ + echo Applying patch: $$(basename $$f) ; \ + patch -p1 -d $(vpp_ldp_src_dir) < $$f ; \ + done; \ + elif [ $(_VPP_VER) = "2005" ]; then \ + echo "--- vpp 20.05 ---"; \ + for f in $(CURDIR)/vpp_patches/other/2005/*; do \ echo Applying patch: $$(basename $$f) ; \ patch -p1 -d $(vpp_ldp_src_dir) < $$f ; \ done; \ @@ -60,25 +66,6 @@ define vpp_ldp_patch_cmds done; \ fi; \ fi - @if [ $(_VPP_VER) = "master" ]; then \ - echo "--- patch master ---"; \ - for f in $(CURDIR)/vpp_patches/ldp/master/*.patch ; do \ - echo Applying patch: $$(basename $$f) ; \ - patch -p1 -d $(vpp_ldp_src_dir) < $$f ; \ - done; \ - elif [ $(_VPP_VER) = "2005" ]; then \ - echo "--- patch v20.05 ---"; \ - for f in $(CURDIR)/vpp_patches/ldp/2005/*.patch ; do \ - echo Applying patch: $$(basename $$f) ; \ - patch -p1 -d $(vpp_ldp_src_dir) < $$f ; \ - done; \ - elif [ $(_VPP_VER) = "2001" ]; then \ - echo "--- patch 2001 ---"; \ - for f in $(CURDIR)/vpp_patches/ldp/2001/*.patch ; do \ - echo Applying patch: $$(basename $$f) ; \ - patch -p1 -d $(vpp_ldp_src_dir) < $$f ; \ - done; \ - fi @true endef @@ -90,16 +77,15 @@ endef define vpp_ldp_build_cmds @cd $(vpp_ldp_src_dir); \ echo "---build : $(vpp_ldp_src_dir)"; \ - if [ $(openssl3_enable) = 1 ]; then \ + if [ $(openssl3_enable) -eq 1 ]; then \ export OPENSSL_ROOT_DIR=$(openssl_install_dir); \ export LD_LIBRARY_PATH=$(openssl_install_dir)/lib; \ fi; \ $(MAKE) wipe-release; $(MAKE) wipe; \ cd build-root; $(MAKE) distclean; cd ..; \ - if [ $(debug) = 1 ]; then $(MAKE) build; \ + if [ $(debug) -eq 1 ]; then $(MAKE) build; \ else $(MAKE) build-release; \ - fi; \ - $(MAKE) pkg-deb; + fi endef define vpp_ldp_install_cmds @@ -107,15 +93,23 @@ define vpp_ldp_install_cmds endef define vpp_ldp_pkg_deb_cmds - @true + @cd $(vpp_ldp_src_dir); \ + echo "---build deb: $(vpp_ldp_src_dir)"; \ + if [ $(openssl3_enable) -eq 1 ]; then \ + export OPENSSL_ROOT_DIR=$(openssl_install_dir); \ + export LD_LIBRARY_PATH=$(openssl_install_dir)/lib; \ + fi; \ + $(MAKE) pkg-deb; endef define vpp_ldp_pkg_deb_cp_cmds @echo "--- move deb to $(CURDIR)/deb-ldp ---" @mkdir -p deb-ldp @ls deb-ldp/ ;rm -f deb-ldp/* - @mv $(I)/openssl-deb/*.deb . - @rm $(B)/.openssl.pkg-deb.ok + @if [ $(openssl3_enable) -eq 1 ]; then \ + mv $(I)/openssl-deb/*.deb .; \ + rm $(B)/.openssl.pkg-deb.ok; \ + fi @mv $(vpp_ldp_pkg_deb_dir)/*.deb deb-ldp/. endef diff --git a/packages/vpp_vcl.mk b/packages/vpp_vcl.mk index 2b2dd64..a923d01 100644 --- a/packages/vpp_vcl.mk +++ b/packages/vpp_vcl.mk @@ -27,8 +27,8 @@ endef define vpp_vcl_patch_cmds @echo "--- vpp patching ---" @cd $(vpp_vcl_src_dir); \ - git reset --hard; git clean -f; git checkout master; \ - if [ $(_VPP_VER) != "master" ]; then \ + git reset --hard; git clean -f; git checkout $(MAIN_BRANCH); \ + if [ $(_VPP_VER) != $(MAIN_BRANCH) ]; then \ echo "--- vpp version: $(_VPP_VER) ---"; \ if [ $(_VPP_VER) = "2005" ]; then \ git checkout v20.05; \ @@ -41,14 +41,20 @@ define vpp_vcl_patch_cmds echo Applying patch: $$(basename $$f) ; \ patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \ done - @if [ $(openssl3_enable) = 1 ]; then \ + @if [ $(openssl3_enable) -eq 1 ]; then \ for f in $(CURDIR)/vpp_patches/other/*.patch ; do \ echo Applying patch: $$(basename $$f) ; \ patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \ done; \ - if [ $(_VPP_VER) = "2005" -o $(_VPP_VER) = "master" ]; then \ - echo "--- vpp master ---"; \ - for f in $(CURDIR)/vpp_patches/other/master/*.patch;do\ + if [ $(_VPP_VER) = $(MAIN_BRANCH) ]; then \ + echo "--- vpp $(MAIN_BRANCH) ---"; \ + for f in $(CURDIR)/vpp_patches/other/$(MAIN_BRANCH)/*.patch;do\ + echo Applying patch: $$(basename $$f) ; \ + patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \ + done; \ + elif [ $(_VPP_VER) = "2005" ]; then \ + echo "--- vpp 20.05 ---"; \ + for f in $(CURDIR)/vpp_patches/other/2005/*.patch;do\ echo Applying patch: $$(basename $$f) ; \ patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \ done; \ @@ -60,11 +66,17 @@ define vpp_vcl_patch_cmds done; \ fi; \ fi - @for f in $(CURDIR)/vpp_patches/vcl/*.patch ; do \ - echo Applying patch: $$(basename $$f) ; \ - patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \ - done - + @if [ $(_VPP_VER) = $(MAIN_BRANCH) ]; then \ + for f in $(CURDIR)/vpp_patches/vcl/$(MAIN_BRANCH)/*.patch ; do \ + echo Applying patch: $$(basename $$f) ; \ + patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \ + done; \ + else \ + for f in $(CURDIR)/vpp_patches/vcl/other/*.patch ; do \ + echo Applying patch: $$(basename $$f) ; \ + patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \ + done; \ + fi @true endef @@ -76,16 +88,15 @@ endef define vpp_vcl_build_cmds @cd $(vpp_vcl_src_dir); \ echo "--- build : $(vpp_vcl_src_dir)"; \ - if [ $(openssl3_enable) = 1 ]; then \ + if [ $(openssl3_enable) -eq 1 ]; then \ export OPENSSL_ROOT_DIR=$(openssl_install_dir); \ export LD_LIBRARY_PATH=$(openssl_install_dir)/lib; \ fi; \ $(MAKE) wipe-release; $(MAKE) wipe; \ cd build-root; $(MAKE) distclean; cd ..; \ - if [ $(debug) = 1 ]; then $(MAKE) build;\ + if [ $(debug) -eq 1 ]; then $(MAKE) build;\ else $(MAKE) build-release; \ - fi; \ - $(MAKE) pkg-deb; + fi endef define vpp_vcl_install_cmds @@ -93,15 +104,23 @@ define vpp_vcl_install_cmds endef define vpp_vcl_pkg_deb_cmds - @true + @cd $(vpp_vcl_src_dir); \ + echo "--- build deb : $(vpp_vcl_src_dir)"; \ + if [ $(openssl3_enable) -eq 1 ]; then \ + export OPENSSL_ROOT_DIR=$(openssl_install_dir); \ + export LD_LIBRARY_PATH=$(openssl_install_dir)/lib; \ + fi; \ + $(MAKE) pkg-deb; endef define vpp_vcl_pkg_deb_cp_cmds @echo "--- move deb to $(CURDIR)/dev-vcl ---" @mkdir -p deb-vcl @rm -f deb-vcl/* - @mv $(I)/openssl-deb/*.deb . - @rm $(B)/.openssl.pkg-deb.ok + @if [ $(openssl3_enable) -eq 1 ]; then \ + mv $(I)/openssl-deb/*.deb .; \ + rm $(B)/.openssl.pkg-deb.ok; \ + fi @mv $(vpp_vcl_pkg_deb_dir)/*.deb deb-vcl/. endef diff --git a/vpp_patches/other/0001-3.0.0.patch b/vpp_patches/other/0001-3.0.0.patch deleted file mode 100644 index 69fd197..0000000 --- a/vpp_patches/other/0001-3.0.0.patch +++ /dev/null @@ -1,113 +0,0 @@ -From ff2148e2aec6c8fb9717f655aee424d9ec59f802 Mon Sep 17 00:00:00 2001 -From: "xiaolongx.jiang" -Date: Wed, 13 May 2020 09:42:07 +0000 -Subject: [PATCH] 3.0.0 - -Signed-off-by: xiaolongx.jiang ---- - src/plugins/crypto_openssl/CMakeLists.txt | 26 ---------------- - src/plugins/ikev2/CMakeLists.txt | 38 ----------------------- - src/plugins/tlsopenssl/tls_openssl.c | 2 -- - 3 files changed, 66 deletions(-) - delete mode 100644 src/plugins/crypto_openssl/CMakeLists.txt - delete mode 100644 src/plugins/ikev2/CMakeLists.txt - -diff --git a/src/plugins/crypto_openssl/CMakeLists.txt b/src/plugins/crypto_openssl/CMakeLists.txt -deleted file mode 100644 -index d014144ec..000000000 ---- a/src/plugins/crypto_openssl/CMakeLists.txt -+++ /dev/null -@@ -1,26 +0,0 @@ --# Copyright (c) 2018 Cisco and/or its affiliates. --# 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. -- --if(NOT OPENSSL_FOUND) -- return() --endif() -- --include_directories(${OPENSSL_INCLUDE_DIR}) -- --add_vpp_plugin(crypto_openssl -- SOURCES -- main.c -- -- LINK_LIBRARIES -- ${OPENSSL_LIBRARIES} --) -diff --git a/src/plugins/ikev2/CMakeLists.txt b/src/plugins/ikev2/CMakeLists.txt -deleted file mode 100644 -index dac246524..000000000 ---- a/src/plugins/ikev2/CMakeLists.txt -+++ /dev/null -@@ -1,38 +0,0 @@ --# Copyright (c) 2018 Cisco and/or its affiliates. --# 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. -- --add_definitions (-DWITH_LIBSSL=1) --include_directories(${OPENSSL_INCLUDE_DIR}) -- --add_vpp_plugin(ikev2 -- SOURCES -- ikev2.c -- ikev2_api.c -- ikev2_cli.c -- ikev2_crypto.c -- ikev2_format.c -- ikev2_payload.c -- -- API_FILES -- ikev2.api -- -- API_TEST_SOURCES -- ikev2_test.c -- -- INSTALL_HEADERS -- ikev2.h -- ikev2_priv.h -- -- LINK_LIBRARIES -- ${OPENSSL_LIBRARIES} --) -diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c -index 669a50348..a9799a21f 100644 ---- a/src/plugins/tlsopenssl/tls_openssl.c -+++ b/src/plugins/tlsopenssl/tls_openssl.c -@@ -564,7 +564,6 @@ openssl_ctx_init_client (tls_ctx_t * ctx) - return -1; - } - -- SSL_CTX_set_ecdh_auto (oc->ssl_ctx, 1); - SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); - #ifdef HAVE_OPENSSL_ASYNC - if (om->async) -@@ -680,7 +679,6 @@ openssl_start_listen (tls_ctx_t * lctx) - } - #endif - SSL_CTX_set_options (ssl_ctx, flags); -- SSL_CTX_set_ecdh_auto (ssl_ctx, 1); - - rv = SSL_CTX_set_cipher_list (ssl_ctx, (const char *) om->ciphers); - if (rv != 1) --- -2.17.1 - diff --git a/vpp_patches/other/2001/0001-3.0.0.patch b/vpp_patches/other/2001/0001-3.0.0.patch new file mode 100644 index 0000000..69fd197 --- /dev/null +++ b/vpp_patches/other/2001/0001-3.0.0.patch @@ -0,0 +1,113 @@ +From ff2148e2aec6c8fb9717f655aee424d9ec59f802 Mon Sep 17 00:00:00 2001 +From: "xiaolongx.jiang" +Date: Wed, 13 May 2020 09:42:07 +0000 +Subject: [PATCH] 3.0.0 + +Signed-off-by: xiaolongx.jiang +--- + src/plugins/crypto_openssl/CMakeLists.txt | 26 ---------------- + src/plugins/ikev2/CMakeLists.txt | 38 ----------------------- + src/plugins/tlsopenssl/tls_openssl.c | 2 -- + 3 files changed, 66 deletions(-) + delete mode 100644 src/plugins/crypto_openssl/CMakeLists.txt + delete mode 100644 src/plugins/ikev2/CMakeLists.txt + +diff --git a/src/plugins/crypto_openssl/CMakeLists.txt b/src/plugins/crypto_openssl/CMakeLists.txt +deleted file mode 100644 +index d014144ec..000000000 +--- a/src/plugins/crypto_openssl/CMakeLists.txt ++++ /dev/null +@@ -1,26 +0,0 @@ +-# Copyright (c) 2018 Cisco and/or its affiliates. +-# 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. +- +-if(NOT OPENSSL_FOUND) +- return() +-endif() +- +-include_directories(${OPENSSL_INCLUDE_DIR}) +- +-add_vpp_plugin(crypto_openssl +- SOURCES +- main.c +- +- LINK_LIBRARIES +- ${OPENSSL_LIBRARIES} +-) +diff --git a/src/plugins/ikev2/CMakeLists.txt b/src/plugins/ikev2/CMakeLists.txt +deleted file mode 100644 +index dac246524..000000000 +--- a/src/plugins/ikev2/CMakeLists.txt ++++ /dev/null +@@ -1,38 +0,0 @@ +-# Copyright (c) 2018 Cisco and/or its affiliates. +-# 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. +- +-add_definitions (-DWITH_LIBSSL=1) +-include_directories(${OPENSSL_INCLUDE_DIR}) +- +-add_vpp_plugin(ikev2 +- SOURCES +- ikev2.c +- ikev2_api.c +- ikev2_cli.c +- ikev2_crypto.c +- ikev2_format.c +- ikev2_payload.c +- +- API_FILES +- ikev2.api +- +- API_TEST_SOURCES +- ikev2_test.c +- +- INSTALL_HEADERS +- ikev2.h +- ikev2_priv.h +- +- LINK_LIBRARIES +- ${OPENSSL_LIBRARIES} +-) +diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c +index 669a50348..a9799a21f 100644 +--- a/src/plugins/tlsopenssl/tls_openssl.c ++++ b/src/plugins/tlsopenssl/tls_openssl.c +@@ -564,7 +564,6 @@ openssl_ctx_init_client (tls_ctx_t * ctx) + return -1; + } + +- SSL_CTX_set_ecdh_auto (oc->ssl_ctx, 1); + SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); + #ifdef HAVE_OPENSSL_ASYNC + if (om->async) +@@ -680,7 +679,6 @@ openssl_start_listen (tls_ctx_t * lctx) + } + #endif + SSL_CTX_set_options (ssl_ctx, flags); +- SSL_CTX_set_ecdh_auto (ssl_ctx, 1); + + rv = SSL_CTX_set_cipher_list (ssl_ctx, (const char *) om->ciphers); + if (rv != 1) +-- +2.17.1 + diff --git a/vpp_patches/other/2005/0001-3.0.0.patch b/vpp_patches/other/2005/0001-3.0.0.patch new file mode 100644 index 0000000..69fd197 --- /dev/null +++ b/vpp_patches/other/2005/0001-3.0.0.patch @@ -0,0 +1,113 @@ +From ff2148e2aec6c8fb9717f655aee424d9ec59f802 Mon Sep 17 00:00:00 2001 +From: "xiaolongx.jiang" +Date: Wed, 13 May 2020 09:42:07 +0000 +Subject: [PATCH] 3.0.0 + +Signed-off-by: xiaolongx.jiang +--- + src/plugins/crypto_openssl/CMakeLists.txt | 26 ---------------- + src/plugins/ikev2/CMakeLists.txt | 38 ----------------------- + src/plugins/tlsopenssl/tls_openssl.c | 2 -- + 3 files changed, 66 deletions(-) + delete mode 100644 src/plugins/crypto_openssl/CMakeLists.txt + delete mode 100644 src/plugins/ikev2/CMakeLists.txt + +diff --git a/src/plugins/crypto_openssl/CMakeLists.txt b/src/plugins/crypto_openssl/CMakeLists.txt +deleted file mode 100644 +index d014144ec..000000000 +--- a/src/plugins/crypto_openssl/CMakeLists.txt ++++ /dev/null +@@ -1,26 +0,0 @@ +-# Copyright (c) 2018 Cisco and/or its affiliates. +-# 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. +- +-if(NOT OPENSSL_FOUND) +- return() +-endif() +- +-include_directories(${OPENSSL_INCLUDE_DIR}) +- +-add_vpp_plugin(crypto_openssl +- SOURCES +- main.c +- +- LINK_LIBRARIES +- ${OPENSSL_LIBRARIES} +-) +diff --git a/src/plugins/ikev2/CMakeLists.txt b/src/plugins/ikev2/CMakeLists.txt +deleted file mode 100644 +index dac246524..000000000 +--- a/src/plugins/ikev2/CMakeLists.txt ++++ /dev/null +@@ -1,38 +0,0 @@ +-# Copyright (c) 2018 Cisco and/or its affiliates. +-# 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. +- +-add_definitions (-DWITH_LIBSSL=1) +-include_directories(${OPENSSL_INCLUDE_DIR}) +- +-add_vpp_plugin(ikev2 +- SOURCES +- ikev2.c +- ikev2_api.c +- ikev2_cli.c +- ikev2_crypto.c +- ikev2_format.c +- ikev2_payload.c +- +- API_FILES +- ikev2.api +- +- API_TEST_SOURCES +- ikev2_test.c +- +- INSTALL_HEADERS +- ikev2.h +- ikev2_priv.h +- +- LINK_LIBRARIES +- ${OPENSSL_LIBRARIES} +-) +diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c +index 669a50348..a9799a21f 100644 +--- a/src/plugins/tlsopenssl/tls_openssl.c ++++ b/src/plugins/tlsopenssl/tls_openssl.c +@@ -564,7 +564,6 @@ openssl_ctx_init_client (tls_ctx_t * ctx) + return -1; + } + +- SSL_CTX_set_ecdh_auto (oc->ssl_ctx, 1); + SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); + #ifdef HAVE_OPENSSL_ASYNC + if (om->async) +@@ -680,7 +679,6 @@ openssl_start_listen (tls_ctx_t * lctx) + } + #endif + SSL_CTX_set_options (ssl_ctx, flags); +- SSL_CTX_set_ecdh_auto (ssl_ctx, 1); + + rv = SSL_CTX_set_cipher_list (ssl_ctx, (const char *) om->ciphers); + if (rv != 1) +-- +2.17.1 + diff --git a/vpp_patches/other/2005/0001-picotls-patch.patch b/vpp_patches/other/2005/0001-picotls-patch.patch new file mode 100644 index 0000000..9811fbc --- /dev/null +++ b/vpp_patches/other/2005/0001-picotls-patch.patch @@ -0,0 +1,45 @@ +From 9f3edc2ca7eb417b46ab40beac45838ee58cc223 Mon Sep 17 00:00:00 2001 +From: "xiaolongx.jiang" +Date: Fri, 8 May 2020 10:01:36 +0000 +Subject: [PATCH] picotls: patch + +Signed-off-by: xiaolongx.jiang +--- + .../0001-picotls-openssl-3.0.0.patch | 25 +++++++++++++++++++ + 1 file changed, 25 insertions(+) + create mode 100644 build/external/patches/quicly_0.1.0-vpp/0001-picotls-openssl-3.0.0.patch + +diff --git a/build/external/patches/quicly_0.1.0-vpp/0001-picotls-openssl-3.0.0.patch b/build/external/patches/quicly_0.1.0-vpp/0001-picotls-openssl-3.0.0.patch +new file mode 100644 +index 000000000..d998fb852 +--- /dev/null ++++ b/build/external/patches/quicly_0.1.0-vpp/0001-picotls-openssl-3.0.0.patch +@@ -0,0 +1,25 @@ ++From e99a421de5a66bd4af275c1ff77c2a3764febdf4 Mon Sep 17 00:00:00 2001 ++From: "xiaolongx.jiang" ++Date: Fri, 8 May 2020 08:25:12 +0000 ++Subject: [PATCH] picotls: openssl-3.0.0 ++ ++Signed-off-by: xiaolongx.jiang ++--- ++ .../deps/picotls/CMakeLists.txt | 1 + ++ 1 file changed, 1 insertion(+) ++ ++diff --git a/deps/picotls/CMakeLists.txt b/deps/picotls/CMakeLists.txt ++index 14411e2ec..4e230c701 100644 ++--- a/deps/picotls/CMakeLists.txt +++++ b/deps/picotls/CMakeLists.txt ++@@ -95,6 +95,7 @@ ADD_EXECUTABLE(test-minicrypto.t ++ SET(TEST_EXES test-minicrypto.t) ++ ++ FIND_PACKAGE(OpenSSL) +++set(OPENSSL_VERSION 3.0.0) ++ IF (OPENSSL_FOUND AND NOT (OPENSSL_VERSION VERSION_LESS "1.0.1")) ++ MESSAGE(STATUS " Enabling OpenSSL support") ++ INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) ++-- ++2.17.1 ++ +-- +2.17.1 + diff --git a/vpp_patches/other/master/0001-3.0.0.patch b/vpp_patches/other/master/0001-3.0.0.patch new file mode 100644 index 0000000..89f2f66 --- /dev/null +++ b/vpp_patches/other/master/0001-3.0.0.patch @@ -0,0 +1,114 @@ +From e6aefe2a1fc3fbbf78945c07d5eb709cdf4d4241 Mon Sep 17 00:00:00 2001 +From: Xiaolong Jiang +Date: Fri, 25 Sep 2020 18:11:08 +0800 +Subject: [PATCH] 3.0.0 + +Signed-off-by: Xiaolong Jiang +--- + src/plugins/crypto_openssl/CMakeLists.txt | 26 --------------- + src/plugins/ikev2/CMakeLists.txt | 39 ----------------------- + src/plugins/tlsopenssl/tls_openssl.c | 2 -- + 3 files changed, 67 deletions(-) + delete mode 100644 src/plugins/crypto_openssl/CMakeLists.txt + delete mode 100644 src/plugins/ikev2/CMakeLists.txt + +diff --git a/src/plugins/crypto_openssl/CMakeLists.txt b/src/plugins/crypto_openssl/CMakeLists.txt +deleted file mode 100644 +index d014144ec..000000000 +--- a/src/plugins/crypto_openssl/CMakeLists.txt ++++ /dev/null +@@ -1,26 +0,0 @@ +-# Copyright (c) 2018 Cisco and/or its affiliates. +-# 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. +- +-if(NOT OPENSSL_FOUND) +- return() +-endif() +- +-include_directories(${OPENSSL_INCLUDE_DIR}) +- +-add_vpp_plugin(crypto_openssl +- SOURCES +- main.c +- +- LINK_LIBRARIES +- ${OPENSSL_LIBRARIES} +-) +diff --git a/src/plugins/ikev2/CMakeLists.txt b/src/plugins/ikev2/CMakeLists.txt +deleted file mode 100644 +index 6f2e5a681..000000000 +--- a/src/plugins/ikev2/CMakeLists.txt ++++ /dev/null +@@ -1,39 +0,0 @@ +-# Copyright (c) 2018 Cisco and/or its affiliates. +-# 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. +- +-add_definitions (-DWITH_LIBSSL=1) +-include_directories(${OPENSSL_INCLUDE_DIR}) +- +-add_vpp_plugin(ikev2 +- SOURCES +- ikev2.c +- ikev2_api.c +- ikev2_cli.c +- ikev2_crypto.c +- ikev2_format.c +- ikev2_payload.c +- +- API_FILES +- ikev2_types.api +- ikev2.api +- +- API_TEST_SOURCES +- ikev2_test.c +- +- INSTALL_HEADERS +- ikev2.h +- ikev2_priv.h +- +- LINK_LIBRARIES +- ${OPENSSL_LIBRARIES} +-) +diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c +index 669a50348..a9799a21f 100644 +--- a/src/plugins/tlsopenssl/tls_openssl.c ++++ b/src/plugins/tlsopenssl/tls_openssl.c +@@ -564,7 +564,6 @@ openssl_ctx_init_client (tls_ctx_t * ctx) + return -1; + } + +- SSL_CTX_set_ecdh_auto (oc->ssl_ctx, 1); + SSL_CTX_set_mode (oc->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); + #ifdef HAVE_OPENSSL_ASYNC + if (om->async) +@@ -680,7 +679,6 @@ openssl_start_listen (tls_ctx_t * lctx) + } + #endif + SSL_CTX_set_options (ssl_ctx, flags); +- SSL_CTX_set_ecdh_auto (ssl_ctx, 1); + + rv = SSL_CTX_set_cipher_list (ssl_ctx, (const char *) om->ciphers); + if (rv != 1) +-- +2.17.1 + diff --git a/vpp_patches/vcl/0001-ngxvcl-api.patch b/vpp_patches/vcl/0001-ngxvcl-api.patch deleted file mode 100644 index f294b36..0000000 --- a/vpp_patches/vcl/0001-ngxvcl-api.patch +++ /dev/null @@ -1,1713 +0,0 @@ -From 1c07c530f6308362f32c686a571a577380a1b7d8 Mon Sep 17 00:00:00 2001 -From: Zeyu Zhang -Date: Wed, 16 Oct 2019 16:51:22 +0800 -Subject: [PATCH] ngxvcl - ---- - src/vcl/CMakeLists.txt | 10 +- - src/vcl/ngxvcl.c | 1590 ++++++++++++++++++++++++++++++++++++++++ - src/vcl/ngxvcl.h | 70 ++ - 3 files changed, 1669 insertions(+), 1 deletion(-) - create mode 100644 src/vcl/ngxvcl.c - create mode 100644 src/vcl/ngxvcl.h - -diff --git a/src/vcl/CMakeLists.txt b/src/vcl/CMakeLists.txt -index ab0a6ad6a..1b6a9f351 100644 ---- a/src/vcl/CMakeLists.txt -+++ b/src/vcl/CMakeLists.txt -@@ -38,10 +38,18 @@ add_vpp_library(vcl_ldpreload - vppinfra svm vlibmemoryclient rt pthread vppcom dl - ) - -+add_vpp_library(ngxvcl -+ SOURCES -+ ngxvcl.c -+ -+ LINK_LIBRARIES -+ vppinfra svm vlibmemoryclient rt pthread vppcom dl -+) -+ - add_vpp_headers(vcl - ldp.h - ldp_glibc_socket.h - vppcom.h - vcl_locked.h - ldp_socket_wrapper.h --) -\ No newline at end of file -+) -diff --git a/src/vcl/ngxvcl.c b/src/vcl/ngxvcl.c -new file mode 100644 -index 000000000..157c05246 ---- /dev/null -+++ b/src/vcl/ngxvcl.c -@@ -0,0 +1,1590 @@ -+#include -+#include -+ -+#define MAX_NGX_WORKERS 100 -+#define VFD_OFFSET 0X003F3F3F -+#define NGXVCL_TLS_ON "NGXVCL_TLS_ON" -+#define NGXVCL_TLS_CERT "NGXVCL_TLS_CERT" -+#define NGXVCL_TLS_KEY "NGXVCL_TLS_KEY" -+ -+typedef unsigned char u8; -+typedef unsigned short u16; -+typedef unsigned int u32; -+ -+typedef struct ngxvcl_main_t_ -+{ -+ u32 listen_session_index; -+ u32 master_worker_index; -+ /** Not include master worker index. */ -+ u32 *workers_subscribed_by_ls; -+ clib_bitmap_t *listeners; -+ uword *worker_index_by_pid; -+ int wait_vep_only; -+ int intercepted_sigchld; -+ u8 transparent_tls; -+} ngxvcl_main_t; -+ -+static ngxvcl_main_t *nvm = NULL; -+ -+static u8 *sendfile_io_buffer = NULL; -+ -+static int epoll_fd_for_evtfd = 0; -+ -+static u8 use_mq_eventfd = 0; -+ -+static int wait_kep_next = 0; -+ -+static inline _Bool is_offset_vfd(int fd) -+{ -+ return fd >= VFD_OFFSET; -+} -+static inline int vfd_to_offset_vfd(int vfd) -+{ -+ return vfd + VFD_OFFSET; -+} -+static inline int offset_vfd_to_vfd(int offset_fd) -+{ -+ int vfd = offset_fd - VFD_OFFSET; -+ -+ return (vcl_get_worker_index () << 24) | (vfd & 0X00FFFFFF); -+} -+ -+static int copy_ep_to_sockaddr(struct sockaddr *addr, socklen_t *len, -+ vppcom_endpt_t *ep) -+{ -+ int rv = 0; -+ int sa_len, copy_len; -+ -+ if (addr && len && ep) -+ { -+ addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6; -+ -+ switch (addr->sa_family) -+ { -+ case AF_INET: -+ ((struct sockaddr_in *)addr)->sin_port = ep->port; -+ if (*len > sizeof(struct sockaddr_in)) -+ *len = sizeof(struct sockaddr_in); -+ sa_len = sizeof(struct sockaddr_in) - sizeof(struct in_addr); -+ copy_len = *len - sa_len; -+ if (copy_len > 0) -+ memcpy(&((struct sockaddr_in *)addr)->sin_addr, ep->ip, -+ copy_len); -+ break; -+ -+ case AF_INET6: -+ ((struct sockaddr_in6 *)addr)->sin6_port = ep->port; -+ if (*len > sizeof(struct sockaddr_in6)) -+ *len = sizeof(struct sockaddr_in6); -+ sa_len = sizeof(struct sockaddr_in6) - sizeof(struct in6_addr); -+ copy_len = *len - sa_len; -+ if (copy_len > 0) -+ memcpy( -+ ((struct sockaddr_in6 *)addr)->sin6_addr.__in6_u.__u6_addr8, -+ ep->ip, copy_len); -+ break; -+ -+ default: -+ /* Not possible */ -+ rv = -EAFNOSUPPORT; -+ break; -+ } -+ } -+ -+ return rv; -+} -+ -+static void listener_wrk_stop_listen(u32 wrk_index) { -+ vcl_worker_t *wrk; -+ vcl_session_t *s; -+ -+ wrk = vcl_worker_get(wrk_index); -+ s = vcl_session_get (wrk, nvm->listen_session_index); -+ if (s->session_state != STATE_LISTEN) -+ return; -+ vcl_send_session_unlisten(wrk, s); -+ s->session_state = STATE_LISTEN_NO_MQ; -+ clib_bitmap_set(nvm->listeners, wrk_index, 0); -+} -+ -+static void -+share_listen_session (vcl_worker_t * wrk) -+{ -+ vcl_session_t *s; -+ -+ s = vcl_session_get (wrk, nvm->listen_session_index); -+ s->session_state = STATE_LISTEN_NO_MQ; -+ vppcom_session_listen((vcl_get_worker_index() << 24 | nvm->listen_session_index), ~0); -+ clib_bitmap_set(nvm->listeners, vcl_get_worker_index(), 1); -+ if (clib_bitmap_get(nvm->listeners, 0) == 1) -+ listener_wrk_stop_listen (0); -+ vec_add1 (nvm->workers_subscribed_by_ls, wrk->wrk_index); -+} -+ -+static void -+worker_copy_on_fork (vcl_worker_t * parent_wrk) -+{ -+ vcl_worker_t *wrk = vcl_worker_get_current (); -+ -+ wrk->vpp_event_queues = vec_dup (parent_wrk->vpp_event_queues); -+ wrk->sessions = pool_dup (parent_wrk->sessions); -+ wrk->session_index_by_vpp_handles = -+ hash_dup (parent_wrk->session_index_by_vpp_handles); -+ -+ share_listen_session (wrk); -+} -+ -+static void -+ngxvcl_cleanup_child_worker (u32 child_wrk_index) -+{ -+ vcl_worker_t *child_wrk = vcl_worker_get(child_wrk_index); -+ vcl_session_t *s; -+ -+ /** Unshare listen session. */ -+ s = vcl_session_get (child_wrk, nvm->listen_session_index); -+ clib_bitmap_set (nvm->listeners, child_wrk_index, 0); -+ vec_del1 (nvm->workers_subscribed_by_ls, child_wrk_index); -+ vcl_session_cleanup (child_wrk, s, vcl_session_handle (s), 1); -+ -+ hash_unset (nvm->worker_index_by_pid, child_wrk->current_pid); -+ vcl_worker_cleanup (child_wrk, 1 /* notify vpp */); -+} -+ -+static struct sigaction old_sa; -+ -+static void -+ngxvcl_intercept_sigchld_handler (int signum, siginfo_t * si, void *uc) -+{ -+ vcl_worker_t *wrk; -+ u32 child_wrk_index; -+ -+ if (vcl_get_worker_index () == ~0) -+ return; -+ -+ if (sigaction (SIGCHLD, &old_sa, 0)) -+ { -+ VERR ("couldn't restore sigchld"); -+ exit (-1); -+ } -+ -+ wrk = vcl_worker_get_current (); -+ child_wrk_index = *(hash_get (nvm->worker_index_by_pid, si->si_pid)); -+ -+ if (si->si_pid != vcl_worker_get(child_wrk_index)->current_pid) -+ { -+ VDBG (0, "unexpected child pid %u", si->si_pid); -+ goto done; -+ } -+ -+ ngxvcl_cleanup_child_worker (child_wrk_index); -+ wrk->forked_child = ~0; -+ -+done: -+ if (old_sa.sa_flags & SA_SIGINFO) -+ { -+ void (*fn) (int, siginfo_t *, void *) = old_sa.sa_sigaction; -+ fn (signum, si, uc); -+ } -+ else -+ { -+ void (*fn) (int) = old_sa.sa_handler; -+ if (fn) -+ fn (signum); -+ } -+} -+ -+static void -+ngxvcl_incercept_sigchld () -+{ -+ if (!nvm->intercepted_sigchld) -+ { -+ struct sigaction sa; -+ clib_memset (&sa, 0, sizeof (sa)); -+ sa.sa_sigaction = ngxvcl_intercept_sigchld_handler; -+ sa.sa_flags = SA_SIGINFO; -+ if (sigaction (SIGCHLD, &sa, &old_sa)) -+ { -+ VERR ("couldn't intercept sigchld"); -+ exit (-1); -+ } -+ nvm->intercepted_sigchld = 1; -+ } -+} -+ -+static void -+app_pre_fork (void) -+{ -+ ngxvcl_incercept_sigchld (); -+ vcl_flush_mq_events (); -+} -+ -+static void -+app_fork_parent_handler (void) -+{ -+ vcm->forking = 1; -+ while (vcm->forking) -+ ; -+} -+ -+static void -+app_fork_child_handler (void) -+{ -+ vcl_worker_t *parent_wrk; -+ int rv, parent_wrk_index; -+ u8 *child_name; -+ -+ parent_wrk_index = vcl_get_worker_index (); -+ VDBG (0, "initializing forked child %u with parent wrk %u", getpid (), -+ parent_wrk_index); -+ -+ /* -+ * Allocate worker -+ */ -+ vcl_set_worker_index (~0); -+ if (!vcl_worker_alloc_and_init ()) -+ VERR ("couldn't allocate new worker"); -+ -+ /* -+ * Attach to binary api -+ */ -+ child_name = format (0, "%v-child-%u%c", vcm->app_name, getpid (), 0); -+ vcl_cleanup_bapi (); -+ vppcom_api_hookup (); -+ vcm->app_state = STATE_APP_START; -+ rv = vppcom_connect_to_vpp ((char *) child_name); -+ vec_free (child_name); -+ if (rv) -+ { -+ VERR ("couldn't connect to VPP!"); -+ return; -+ } -+ -+ /* -+ * Register worker with vpp and share listen session -+ */ -+ vcl_worker_register_with_vpp (); -+ parent_wrk = vcl_worker_get (parent_wrk_index); -+ worker_copy_on_fork (parent_wrk); -+ hash_set(nvm->worker_index_by_pid, getpid(), vcl_get_worker_index()); -+ parent_wrk->forked_child = vcl_get_worker_index (); -+ -+ sendfile_io_buffer = NULL; -+ -+ VDBG (0, "forked child main worker initialized"); -+ vcm->forking = 0; -+} -+ -+static void -+sendfile_io_buffer_free (void) -+{ -+ vec_free (sendfile_io_buffer); -+} -+ -+void ngxvcl_wait_vep_only() -+{ -+ if (use_mq_eventfd) -+ return; -+ nvm->wait_vep_only = 1; -+} -+ -+void ngxvcl_wait_kep_and_vep() -+{ -+ if (use_mq_eventfd) -+ return; -+ nvm->wait_vep_only = 0; -+} -+ -+void ngxvcl_app_create(char *app_name) -+{ -+ int rv = vppcom_app_create(app_name); -+ -+ if (rv) -+ { -+ errno = -rv; -+ perror("ERROR when calling ngxvcl_app_create()!"); -+ fprintf(stderr, "\nERROR: ngxvcl_app_create() failed (errno = %d)!\n", -rv); -+ exit(1); -+ } -+ -+ pthread_atfork(app_pre_fork, app_fork_parent_handler, -+ app_fork_child_handler); -+ atexit(sendfile_io_buffer_free); -+ -+ nvm = clib_mem_alloc (sizeof (ngxvcl_main_t)); -+ if (!nvm) -+ { -+ clib_warning ("NgxVCL<%d>: ERROR: clib_mem_alloc() failed!", getpid ()); -+ ASSERT (nvm); -+ return; -+ } -+ clib_memset(nvm, 0, sizeof(ngxvcl_main_t)); -+ clib_bitmap_validate(nvm->listeners, MAX_NGX_WORKERS + 1); -+ clib_bitmap_set(nvm->listeners, vcl_get_worker_index(), 1); -+ hash_set(nvm->worker_index_by_pid, getpid(), vcl_get_worker_index()); -+ -+ if (getenv (NGXVCL_TLS_ON)) -+ nvm->transparent_tls = 1; -+ -+ use_mq_eventfd = vcm->cfg.use_mq_eventfd; -+} -+ -+void ngxvcl_app_destroy(void) -+{ -+ vec_free(nvm->workers_subscribed_by_ls); -+ clib_bitmap_free(nvm->listeners); -+ hash_free(nvm->worker_index_by_pid); -+ clib_mem_free(nvm); -+ vppcom_app_destroy(); -+} -+ -+static int -+ngxvcl_load_tls_cert (uint32_t sh) -+{ -+ char *env_var_str = getenv (NGXVCL_TLS_CERT); -+ char inbuf[4096]; -+ char *tls_cert; -+ int cert_size; -+ FILE *fp; -+ -+ if (env_var_str) -+ { -+ fp = fopen (env_var_str, "r"); -+ if (fp == NULL) -+ { -+ VDBG (0, "ERROR: failed to open cert file %s \n", env_var_str); -+ return -1; -+ } -+ cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp); -+ tls_cert = inbuf; -+ vppcom_session_tls_add_cert (sh, tls_cert, -+ cert_size); -+ fclose (fp); -+ } -+ else -+ { -+ VDBG (0, "ERROR: failed to read LDP environment %s\n", -+ NGXVCL_TLS_CERT); -+ return -1; -+ } -+ return 0; -+} -+ -+static int -+ngxvcl_load_tls_key (uint32_t sh) -+{ -+ char *env_var_str = getenv (NGXVCL_TLS_KEY); -+ char inbuf[4096]; -+ char *tls_key; -+ int key_size; -+ FILE *fp; -+ -+ if (env_var_str) -+ { -+ fp = fopen (env_var_str, "r"); -+ if (fp == NULL) -+ { -+ VDBG (0, "ERROR: failed to open key file %s \n", env_var_str); -+ return -1; -+ } -+ key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp); -+ tls_key = inbuf; -+ vppcom_session_tls_add_key (sh, tls_key, -+ key_size); -+ fclose (fp); -+ } -+ else -+ { -+ VDBG (0, "ERROR: failed to read NGXVCL environment %s\n", NGXVCL_TLS_KEY); -+ return -1; -+ } -+ return 0; -+} -+ -+int ngxvcl_socket(int domain, int type, int protocol) -+{ -+ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); -+ u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0; -+ -+ if (((domain == AF_INET) || (domain == AF_INET6)) && -+ ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM))) -+ { -+ u8 proto; -+ -+ if (nvm->transparent_tls) -+ proto = VPPCOM_PROTO_TLS; -+ else -+ proto = ((sock_type == SOCK_DGRAM) ? VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP); -+ -+ rv = vppcom_session_create(proto, is_nonblocking); -+ -+ if (rv < 0) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ else { -+ if (nvm->transparent_tls) -+ if (ngxvcl_load_tls_cert (rv) < 0 || ngxvcl_load_tls_key (rv) < 0) -+ return -1; -+ -+ rv = vfd_to_offset_vfd(rv); -+ } -+ } -+ else -+ { -+ rv = -1; -+ } -+ -+ return rv; -+} -+ -+int ngxvcl_close(int offset_vfd) -+{ -+ int rv, epfd, vfd = offset_vfd_to_vfd(offset_vfd); -+ -+ epfd = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); -+ if (epfd > 0) { -+ rv = close(epfd); -+ if (rv < 0) { -+ u32 size = sizeof(epfd); -+ epfd = 0; -+ vppcom_session_attr(vfd, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size); -+ } -+ } -+ else if (epfd < 0) { -+ errno = -epfd; -+ rv = -1; -+ return rv; -+ } -+ -+ rv = vppcom_session_close(offset_vfd_to_vfd(offset_vfd)); -+ -+ if (rv != VPPCOM_OK) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ -+ return rv; -+} -+ -+int ngxvcl_kvfd_close(int fd) -+{ -+ int rv; -+ -+ if (is_offset_vfd(fd)) -+ rv = ngxvcl_close(fd); -+ else -+ rv = close(fd); -+ -+ return rv; -+} -+ -+int ngxvcl_bind(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen) -+{ -+ int rv; -+ vppcom_endpt_t ep; -+ -+ switch (addr->sa_family) -+ { -+ case AF_INET: -+ if (addrlen != sizeof(struct sockaddr_in)) -+ { -+ errno = EINVAL; -+ rv = -1; -+ goto done; -+ } -+ ep.is_ip4 = VPPCOM_IS_IP4; -+ ep.ip = (u8 *)&((const struct sockaddr_in *)addr)->sin_addr; -+ ep.port = (u16)((const struct sockaddr_in *)addr)->sin_port; -+ break; -+ case AF_INET6: -+ if (addrlen != sizeof(struct sockaddr_in6)) -+ { -+ errno = EINVAL; -+ rv = -1; -+ goto done; -+ } -+ ep.is_ip4 = VPPCOM_IS_IP6; -+ ep.ip = (u8 *)&((const struct sockaddr_in6 *)addr)->sin6_addr; -+ ep.port = (u16)((const struct sockaddr_in6 *)addr)->sin6_port; -+ break; -+ default: -+ errno = EAFNOSUPPORT; -+ rv = -1; -+ goto done; -+ } -+ -+ rv = vppcom_session_bind(offset_vfd_to_vfd(offset_vfd), &ep); -+ -+ if (rv != VPPCOM_OK) -+ { -+ errno = -rv; -+ rv = -1; -+ goto done; -+ } -+ -+ nvm->master_worker_index = offset_vfd_to_vfd(offset_vfd) >> 24; -+ nvm->listen_session_index = offset_vfd_to_vfd(offset_vfd) & 0X00FFFFFF; -+ -+done: -+ return rv; -+} -+ -+int ngxvcl_listen(int offset_vfd, int backlog) -+{ -+ int rv; -+ -+ ASSERT((u32)(offset_vfd_to_vfd(offset_vfd) & 0X00FFFFFF) == nvm->listen_session_index); -+ -+ rv = vppcom_session_listen(offset_vfd_to_vfd(offset_vfd), backlog); -+ -+ if (rv != VPPCOM_OK) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ -+ return rv; -+} -+ -+int ngxvcl_accept4(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen, -+ int flags) -+{ -+ int accepted_fd, rv; -+ vppcom_endpt_t ep; -+ u8 src_addr[sizeof(struct sockaddr_in6)]; -+ memset(&ep, 0, sizeof(ep)); -+ ep.ip = src_addr; -+ -+ accepted_fd = vppcom_session_accept(offset_vfd_to_vfd(offset_vfd), &ep, flags); -+ -+ if (accepted_fd < 0) -+ { -+ errno = -accepted_fd; -+ rv = -1; -+ } -+ else -+ { -+ rv = copy_ep_to_sockaddr(addr, addrlen, &ep); -+ -+ if (rv != VPPCOM_OK) -+ { -+ (void)vppcom_session_close(accepted_fd); -+ errno = -rv; -+ rv = -1; -+ } -+ else -+ { -+ rv = vfd_to_offset_vfd(accepted_fd); -+ } -+ } -+ -+ return rv; -+} -+ -+int ngxvcl_accept(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen) -+{ -+ return ngxvcl_accept4(offset_vfd, addr, addrlen, 0); -+} -+ -+int ngxvcl_connect(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen) -+{ -+ int rv; -+ -+ if (!addr) -+ { -+ errno = EINVAL; -+ rv = -1; -+ goto done; -+ } -+ -+ vppcom_endpt_t ep; -+ -+ switch (addr->sa_family) -+ { -+ case AF_INET: -+ if (addrlen != sizeof(struct sockaddr_in)) -+ { -+ errno = EINVAL; -+ rv = -1; -+ goto done; -+ } -+ ep.is_ip4 = VPPCOM_IS_IP4; -+ ep.ip = (u8 *)&((const struct sockaddr_in *)addr)->sin_addr; -+ ep.port = (u16)((const struct sockaddr_in *)addr)->sin_port; -+ break; -+ case AF_INET6: -+ if (addrlen != sizeof(struct sockaddr_in6)) -+ { -+ errno = EINVAL; -+ rv = -1; -+ goto done; -+ } -+ ep.is_ip4 = VPPCOM_IS_IP6; -+ ep.ip = (u8 *)&((const struct sockaddr_in6 *)addr)->sin6_addr; -+ ep.port = (u16)((const struct sockaddr_in6 *)addr)->sin6_port; -+ break; -+ default: -+ errno = EAFNOSUPPORT; -+ rv = -1; -+ goto done; -+ } -+ -+ rv = vppcom_session_connect(offset_vfd_to_vfd(offset_vfd), &ep); -+ -+ if (rv != VPPCOM_OK) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ -+done: -+ return rv; -+} -+ -+int ngxvcl_read(int offset_vfd, void *buf, size_t count) -+{ -+ ssize_t size; -+ -+ size = vppcom_session_read(offset_vfd_to_vfd(offset_vfd), buf, count); -+ -+ if (size < 0) -+ { -+ errno = -size; -+ size = -1; -+ } -+ -+ return size; -+} -+ -+int ngxvcl_write(int offset_vfd, const void *buf, size_t count) -+{ -+ ssize_t size = 0; -+ -+ size = vppcom_session_write_msg(offset_vfd_to_vfd(offset_vfd), (void *)buf, count); -+ -+ if (size < 0) -+ { -+ errno = -size; -+ size = -1; -+ } -+ -+ return size; -+} -+ -+int ngxvcl_epoll_create(int size) -+{ -+ int rv, vepfd; -+ -+ rv = vppcom_epoll_create(); -+ -+ if (rv < 0) -+ { -+ errno = -rv; -+ return -1; -+ } -+ else -+ vepfd = rv; -+ -+ if (use_mq_eventfd) { -+ int libc_epfd; -+ u32 size = sizeof (u32); -+ struct epoll_event e = { 0 }; -+ -+ libc_epfd = epoll_create1 (EPOLL_CLOEXEC); -+ if (libc_epfd < 0) -+ return libc_epfd; -+ rv = vppcom_session_attr (vepfd, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd, &size); -+ if (rv < 0) -+ { -+ errno = -rv; -+ return -1; -+ } -+ e.events = EPOLLIN; -+ if (epoll_ctl (libc_epfd, EPOLL_CTL_ADD, vcl_worker_get_current ()->app_event_queue->q->consumer_evtfd, &e) < 0) -+ return -1; -+ epoll_fd_for_evtfd = libc_epfd; -+ } -+ -+ return vfd_to_offset_vfd (vepfd); -+} -+ -+int ngxvcl_kvfd_epoll_ctl(int offset_vepfd, int op, int fd, struct epoll_event *event) -+{ -+ int rv, vepfd = offset_vfd_to_vfd(offset_vepfd); -+ -+ if (is_offset_vfd(fd)) { -+ rv = vppcom_epoll_ctl(vepfd, op, offset_vfd_to_vfd(fd), -+ event); -+ -+ if (rv != VPPCOM_OK) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ } -+ else { -+ int libc_epfd; -+ u32 size = sizeof (vepfd); -+ -+ libc_epfd = vppcom_session_attr (vepfd, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); -+ if (!libc_epfd) { -+ libc_epfd = epoll_create1 (EPOLL_CLOEXEC); -+ if (libc_epfd < 0) -+ { -+ rv = libc_epfd; -+ return rv; -+ } -+ rv = vppcom_session_attr (vepfd, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd, &size); -+ if (rv < 0) -+ { -+ errno = -rv; -+ rv = -1; -+ return rv; -+ } -+ } -+ else if (libc_epfd < 0) { -+ errno = -vepfd; -+ rv = -1; -+ return rv; -+ } -+ -+ rv = epoll_ctl (libc_epfd, op, fd, event); -+ } -+ -+ return rv; -+} -+ -+int ngxvcl_kvfd_epoll_wait(int offset_vepfd, struct epoll_event *events, int maxevents, -+ int timeout) -+{ -+ int rv = 0, vepfd = offset_vfd_to_vfd (offset_vepfd); -+ -+ if (use_mq_eventfd) { -+ int i, n_evts = 0, veprv; -+ struct epoll_event temp_evts[2]; -+ -+again: -+ rv = epoll_wait (epoll_fd_for_evtfd, temp_evts, 2, timeout); -+ -+ if (PREDICT_TRUE (rv > 0)) -+ for (i = 0; i < rv; i++) { -+ if (PREDICT_FALSE (n_evts == maxevents)) -+ return n_evts; -+ if (PREDICT_TRUE (temp_evts[i].data.u32 == 0)) { -+ veprv = vppcom_epoll_wait(vepfd, events + n_evts, maxevents - n_evts, 0); -+ if (PREDICT_FALSE (veprv < 0)) { -+ errno = -veprv; -+ return -1; -+ } -+ n_evts += veprv; -+ } -+ else { -+ events[n_evts] = temp_evts[i]; -+ n_evts += 1; -+ } -+ } -+ -+ if (PREDICT_FALSE (!n_evts && rv > 0)) -+ goto again; -+ -+ return n_evts; -+ } -+ -+ if (nvm->wait_vep_only) -+ { -+ rv = vppcom_epoll_wait(vepfd, events, maxevents, timeout); -+ -+ if (rv < 0) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ -+ return rv; -+ } -+ else -+ { -+ double time_to_wait = (double) 0, max_time; -+ int libc_epfd; -+ clib_time_t clib_time = {}; -+ -+ if (clib_time.init_cpu_time == 0) -+ clib_time_init (&clib_time); -+ time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0); -+ max_time = clib_time_now (&clib_time) + time_to_wait; -+ -+ libc_epfd = vppcom_session_attr (vepfd, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); -+ if (libc_epfd < 0) -+ { -+ errno = -libc_epfd; -+ rv = -1; -+ return rv; -+ } -+ -+ do { -+ if (nvm->wait_vep_only) { -+ int time_remained = 0; -+ if (timeout > 0) { -+ time_remained = (int)(1000 * (max_time - clib_time_now (&clib_time))); -+ } -+ else -+ time_remained = timeout; -+ rv = vppcom_epoll_wait(vepfd, events, maxevents, time_remained); -+ if (rv < 0) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ return rv; -+ } -+ -+ if (!wait_kep_next) -+ { -+ rv = vppcom_epoll_wait(vepfd, events, maxevents, 0); -+ -+ if (rv < 0) -+ { -+ errno = -rv; -+ rv = -1; -+ return rv; -+ } -+ else if (rv > 0) -+ { -+ wait_kep_next = 1; -+ return rv; -+ } -+ } -+ else -+ wait_kep_next = 0; -+ -+ if (libc_epfd > 0) { -+ rv = epoll_wait(libc_epfd, events, maxevents, 0); -+ if (rv != 0) -+ return rv; -+ } -+ } while ((timeout == -1) || (clib_time_now (&clib_time) < max_time)); -+ -+ return rv; -+ } -+} -+ -+ssize_t ngxvcl_readv(int offset_vfd, const struct iovec *iov, int iovcnt) -+{ -+ int rv = 0, i, total = 0; -+ ssize_t size = 0; -+ -+ do -+ { -+ for (i = 0; i < iovcnt; ++i) -+ { -+ rv = vppcom_session_read(offset_vfd_to_vfd(offset_vfd), iov[i].iov_base, -+ iov[i].iov_len); -+ if (rv < 0) -+ break; -+ else -+ { -+ total += rv; -+ if ((size_t)rv < iov[i].iov_len) -+ break; -+ } -+ } -+ } while ((rv >= 0) && (total == 0)); -+ -+ if (rv < 0) -+ { -+ errno = -rv; -+ size = -1; -+ } -+ else -+ size = total; -+ -+ return size; -+} -+ -+ssize_t ngxvcl_writev(int offset_vfd, const struct iovec *iov, int iovcnt) -+{ -+ ssize_t size = 0, total = 0; -+ int i, rv = 0; -+ -+ do -+ { -+ for (i = 0; i < iovcnt; ++i) -+ { -+ rv = vppcom_session_write_msg(offset_vfd_to_vfd(offset_vfd), -+ iov[i].iov_base, iov[i].iov_len); -+ if (rv < 0) -+ break; -+ else -+ { -+ total += rv; -+ if ((size_t)rv < iov[i].iov_len) -+ break; -+ } -+ } -+ } while ((rv >= 0) && (total == 0)); -+ -+ if (rv < 0) -+ { -+ errno = -rv; -+ size = -1; -+ } -+ else -+ size = total; -+ -+ return size; -+} -+ -+int ngxvcl_kvfd_fcntl(int fd, int cmd, ...) -+{ -+ int rv = 0; -+ va_list ap; -+ -+ va_start(ap, cmd); -+ -+ if (is_offset_vfd(fd)) -+ { -+ int flags = va_arg(ap, int), vfd = offset_vfd_to_vfd(fd); -+ u32 size; -+ -+ size = sizeof(flags); -+ rv = -EOPNOTSUPP; -+ -+ switch (cmd) -+ { -+ case F_SETFL: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_FLAGS, &flags, &size); -+ break; -+ case F_GETFL: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_FLAGS, &flags, &size); -+ if (rv == VPPCOM_OK) -+ rv = flags; -+ break; -+ case F_SETFD: -+ /* TODO handle this */ -+ rv = 0; -+ break; -+ default: -+ rv = -EOPNOTSUPP; -+ break; -+ } -+ -+ if (rv < 0) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ } -+ else -+ { -+ long int args[4]; -+ -+ for (int i = 0; i < 4; i++) -+ args[i] = va_arg(ap, long int); -+ -+ rv = fcntl(fd, cmd, args[0], args[1], args[2], args[3]); -+ } -+ -+ va_end(ap); -+ -+ return rv; -+} -+ -+int ngxvcl_kvfd_ioctl(int fd, unsigned long int cmd, ...) -+{ -+ va_list ap; -+ int rv; -+ -+ va_start(ap, cmd); -+ -+ if (is_offset_vfd(fd)) -+ { -+ int vfd = offset_vfd_to_vfd(fd); -+ -+ switch (cmd) -+ { -+ case FIONREAD: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_NREAD, 0, 0); -+ break; -+ -+ case FIONBIO: -+ { -+ u32 flags = va_arg(ap, int) ? O_NONBLOCK : 0; -+ u32 size = sizeof(flags); -+ -+ /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than -+ * non-blocking, the flags should be read here and merged -+ * with O_NONBLOCK. -+ */ -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_FLAGS, &flags, &size); -+ } -+ break; -+ -+ default: -+ rv = -EOPNOTSUPP; -+ break; -+ } -+ -+ if (rv < 0) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ } -+ else -+ { -+ long int args[4]; -+ -+ for (int i = 0; i < 4; i++) -+ args[i] = va_arg(ap, long int); -+ -+ rv = ioctl(fd, cmd, args[0], args[1], args[2], args[3]); -+ } -+ -+ va_end(ap); -+ -+ return rv; -+} -+ -+int ngxvcl_socketpair(int domain, int type, int protocol, int fds[2]) -+{ -+ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); -+ -+ if (((domain == AF_INET) || (domain == AF_INET6)) && -+ ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM))) -+ { -+ errno = ENOSYS; -+ rv = -1; -+ } -+ else -+ { -+ rv = socketpair(domain, type, protocol, fds); -+ } -+ -+ return rv; -+} -+ -+int ngxvcl_kvfd_getsockname(int fd, struct sockaddr *addr, socklen_t *len) -+{ -+ int rv; -+ -+ if (is_offset_vfd(fd)) -+ { -+ vppcom_endpt_t ep; -+ u8 addr_buf[sizeof(struct in6_addr)]; -+ u32 size = sizeof(ep); -+ -+ ep.ip = addr_buf; -+ -+ rv = vppcom_session_attr(offset_vfd_to_vfd(fd), -+ VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size); -+ -+ if (rv != VPPCOM_OK) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ else -+ { -+ rv = copy_ep_to_sockaddr(addr, len, &ep); -+ -+ if (rv != VPPCOM_OK) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ } -+ } -+ else -+ { -+ rv = getsockname(fd, addr, len); -+ } -+ -+ return rv; -+} -+ -+int ngxvcl_kvfd_getsockopt(int fd, int level, int optname, void *optval, -+ socklen_t *optlen) -+{ -+ int rv; -+ -+ if (is_offset_vfd(fd)) -+ { -+ int vfd = offset_vfd_to_vfd(fd); -+ -+ rv = -EOPNOTSUPP; -+ -+ switch (level) -+ { -+ case SOL_TCP: -+ switch (optname) -+ { -+ case TCP_NODELAY: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_NODELAY, -+ optval, optlen); -+ break; -+ case TCP_MAXSEG: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_USER_MSS, -+ optval, optlen); -+ break; -+ case TCP_KEEPIDLE: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_KEEPIDLE, -+ optval, optlen); -+ break; -+ case TCP_KEEPINTVL: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_KEEPINTVL, -+ optval, optlen); -+ break; -+ case TCP_INFO: -+ if (optval && optlen && (*optlen == sizeof(struct tcp_info))) -+ { -+ memset(optval, 0, *optlen); -+ rv = VPPCOM_OK; -+ } -+ else -+ rv = -EFAULT; -+ break; -+ case TCP_CONGESTION: -+ strcpy(optval, "cubic"); -+ *optlen = strlen("cubic"); -+ rv = 0; -+ break; -+ default: -+ break; -+ } -+ break; -+ case SOL_IPV6: -+ switch (optname) -+ { -+ case IPV6_V6ONLY: -+ rv = -+ vppcom_session_attr(vfd, VPPCOM_ATTR_GET_V6ONLY, -+ optval, optlen); -+ break; -+ default: -+ break; -+ } -+ break; -+ case SOL_SOCKET: -+ switch (optname) -+ { -+ case SO_ACCEPTCONN: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_LISTEN, -+ optval, optlen); -+ break; -+ case SO_KEEPALIVE: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_KEEPALIVE, -+ optval, optlen); -+ break; -+ case SO_PROTOCOL: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_PROTOCOL, -+ optval, optlen); -+ *(int *)optval = *(int *)optval ? SOCK_DGRAM : SOCK_STREAM; -+ break; -+ case SO_SNDBUF: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TX_FIFO_LEN, -+ optval, optlen); -+ break; -+ case SO_RCVBUF: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_RX_FIFO_LEN, -+ optval, optlen); -+ break; -+ case SO_REUSEADDR: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_REUSEADDR, -+ optval, optlen); -+ break; -+ case SO_BROADCAST: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_BROADCAST, -+ optval, optlen); -+ break; -+ case SO_ERROR: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_ERROR, -+ optval, optlen); -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ if (rv != VPPCOM_OK) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ } -+ else -+ { -+ rv = getsockopt(fd, level, optname, optval, optlen); -+ } -+ -+ return rv; -+} -+ -+int ngxvcl_kvfd_setsockopt(int fd, int level, int optname, const void *optval, -+ socklen_t optlen) -+{ -+ int rv; -+ -+ if (is_offset_vfd(fd)) -+ { -+ int vfd = offset_vfd_to_vfd(fd); -+ -+ rv = -EOPNOTSUPP; -+ -+ switch (level) -+ { -+ case SOL_TCP: -+ switch (optname) -+ { -+ case TCP_NODELAY: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_NODELAY, -+ (void *)optval, &optlen); -+ break; -+ case TCP_MAXSEG: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_USER_MSS, -+ (void *)optval, &optlen); -+ break; -+ case TCP_KEEPIDLE: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_KEEPIDLE, -+ (void *)optval, &optlen); -+ break; -+ case TCP_KEEPINTVL: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_KEEPINTVL, -+ (void *)optval, &optlen); -+ break; -+ case TCP_CONGESTION: -+ case TCP_CORK: -+ /* Ignore */ -+ rv = 0; -+ break; -+ default: -+ break; -+ } -+ break; -+ case SOL_IPV6: -+ switch (optname) -+ { -+ case IPV6_V6ONLY: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_V6ONLY, -+ (void *)optval, &optlen); -+ break; -+ default: -+ break; -+ } -+ break; -+ case SOL_SOCKET: -+ switch (optname) -+ { -+ case SO_KEEPALIVE: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_KEEPALIVE, -+ (void *)optval, &optlen); -+ break; -+ case SO_REUSEADDR: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_REUSEADDR, -+ (void *)optval, &optlen); -+ break; -+ case SO_BROADCAST: -+ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_BROADCAST, -+ (void *)optval, &optlen); -+ break; -+ default: -+ break; -+ } -+ break; -+ default: -+ break; -+ } -+ -+ if (rv != VPPCOM_OK) -+ { -+ errno = -rv; -+ rv = -1; -+ } -+ } -+ else -+ { -+ rv = setsockopt(fd, level, optname, optval, optlen); -+ } -+ -+ return rv; -+} -+ -+ssize_t ngxvcl_send(int offset_vfd, const void *buf, size_t n, int flags) -+{ -+ ssize_t size; -+ -+ size = vppcom_session_sendto(offset_vfd_to_vfd(offset_vfd), (void *)buf, -+ n, flags, NULL); -+ -+ if (size < VPPCOM_OK) -+ { -+ errno = -size; -+ size = -1; -+ } -+ -+ return size; -+} -+ -+ssize_t ngxvcl_sendfile(int out_offset_vfd, int in_kfd, off_t *offset, size_t len) -+{ -+ ssize_t size = 0; -+ int rv, out_vfd = offset_vfd_to_vfd(out_offset_vfd); -+ ssize_t results = 0; -+ size_t n_bytes_left = len; -+ size_t bytes_to_read; -+ int nbytes; -+ u8 eagain = 0; -+ u32 flags, flags_len = sizeof(flags); -+ -+ rv = vppcom_session_attr(out_vfd, VPPCOM_ATTR_GET_FLAGS, &flags, -+ &flags_len); -+ -+ if (rv != VPPCOM_OK) -+ { -+ vec_reset_length (sendfile_io_buffer); -+ errno = -rv; -+ size = -1; -+ goto done; -+ } -+ -+ if (offset) -+ { -+ off_t off = lseek(in_kfd, *offset, SEEK_SET); -+ -+ if (off == -1) -+ { -+ size = -1; -+ goto done; -+ } -+ } -+ -+ do -+ { -+ size = vppcom_session_attr(out_vfd, VPPCOM_ATTR_GET_NWRITE, 0, 0); -+ -+ if (size < 0) -+ { -+ vec_reset_length (sendfile_io_buffer); -+ errno = -size; -+ size = -1; -+ goto done; -+ } -+ -+ bytes_to_read = size; -+ -+ if (bytes_to_read == 0) -+ { -+ if (flags & O_NONBLOCK) -+ { -+ if (!results) -+ eagain = 1; -+ goto update_offset; -+ } -+ else -+ continue; -+ } -+ -+ bytes_to_read = clib_min (n_bytes_left, bytes_to_read); -+ vec_validate (sendfile_io_buffer, bytes_to_read); -+ nbytes = read (in_kfd, sendfile_io_buffer, bytes_to_read); -+ -+ if (nbytes < 0) -+ { -+ if (results == 0) -+ { -+ vec_reset_length (sendfile_io_buffer); -+ size = -1; -+ goto done; -+ } -+ goto update_offset; -+ } -+ -+ size = vppcom_session_write(out_vfd, sendfile_io_buffer, nbytes); -+ -+ if (size < 0) -+ { -+ if (size == VPPCOM_EAGAIN) -+ { -+ if (flags & O_NONBLOCK) -+ { -+ if (!results) -+ eagain = 1; -+ goto update_offset; -+ } -+ else -+ continue; -+ } -+ if (results == 0) -+ { -+ vec_reset_length (sendfile_io_buffer); -+ errno = -size; -+ size = -1; -+ goto done; -+ } -+ goto update_offset; -+ } -+ -+ results += nbytes; -+ n_bytes_left = n_bytes_left - nbytes; -+ } while (n_bytes_left > 0); -+ -+update_offset: -+ vec_reset_length (sendfile_io_buffer); -+ if (offset) -+ { -+ off_t off = lseek(in_kfd, *offset, SEEK_SET); -+ -+ if (off == -1) -+ { -+ size = -1; -+ goto done; -+ } -+ -+ *offset += results + 1; -+ } -+ if (eagain) -+ { -+ errno = EAGAIN; -+ size = -1; -+ } -+ else -+ size = results; -+ -+done: -+ return size; -+} -+ -+ssize_t ngxvcl_recv(int offset_vfd, void *buf, size_t n, int flags) -+{ -+ ssize_t size; -+ -+ size = vppcom_session_recvfrom(offset_vfd_to_vfd(offset_vfd), buf, n, flags, NULL); -+ -+ if (size < 0) -+ errno = -size; -+ -+ return size; -+} -+ -+ssize_t ngxvcl_sendto(int offset_vfd, const void *buf, size_t n, int flags, -+ const struct sockaddr *addr, socklen_t addr_len) -+{ -+ ssize_t size; -+ -+ vppcom_endpt_t *ep = 0; -+ vppcom_endpt_t _ep; -+ -+ if (addr) -+ { -+ ep = &_ep; -+ switch (addr->sa_family) -+ { -+ case AF_INET: -+ ep->is_ip4 = VPPCOM_IS_IP4; -+ ep->ip = (uint8_t *)&((const struct sockaddr_in *)addr)->sin_addr; -+ ep->port = (uint16_t)((const struct sockaddr_in *)addr)->sin_port; -+ break; -+ case AF_INET6: -+ ep->is_ip4 = VPPCOM_IS_IP6; -+ ep->ip = (uint8_t *)&((const struct sockaddr_in6 *)addr)->sin6_addr; -+ ep->port = (uint16_t)((const struct sockaddr_in6 *)addr)->sin6_port; -+ break; -+ default: -+ errno = EAFNOSUPPORT; -+ size = -1; -+ goto done; -+ } -+ } -+ -+ size = vppcom_session_sendto(offset_vfd_to_vfd(offset_vfd), (void *)buf, n, flags, ep); -+ -+ if (size < 0) -+ { -+ errno = -size; -+ size = -1; -+ } -+ -+done: -+ return size; -+} -+ -+ssize_t ngxvcl_recvfrom(int offset_vfd, void *buf, size_t n, int flags, -+ struct sockaddr *addr, socklen_t *addr_len) -+{ -+ int vfd = offset_vfd_to_vfd(offset_vfd); -+ ssize_t size, rv; -+ -+ vppcom_endpt_t ep; -+ u8 src_addr[sizeof(struct sockaddr_in6)]; -+ -+ if (addr) -+ { -+ ep.ip = src_addr; -+ size = vppcom_session_recvfrom(vfd, buf, n, flags, &ep); -+ -+ if (size > 0) -+ { -+ rv = copy_ep_to_sockaddr(addr, addr_len, &ep); -+ -+ if (rv < 0) -+ size = rv; -+ } -+ } -+ else -+ size = vppcom_session_recvfrom(vfd, buf, n, flags, NULL); -+ -+ if (size < 0) -+ { -+ errno = -size; -+ size = -1; -+ } -+ -+ return size; -+} -+ -+ssize_t ngxvcl_sendmsg(int offset_vfd, const struct msghdr *message, int flags) -+{ -+ ssize_t size; -+ -+ errno = ENOSYS; -+ size = -1; -+ -+ return size; -+} -+ -+ssize_t ngxvcl_recvmsg(int offset_vfd, struct msghdr *message, int flags) -+{ -+ ssize_t size; -+ -+ errno = ENOSYS; -+ size = -1; -+ -+ return size; -+} -+ -+int ngxvcl_shutdown(int offset_vfd, int how) -+{ -+ int rv = 0, flags, vfd = offset_vfd_to_vfd(offset_vfd); -+ u32 flags_len = sizeof(flags); -+ -+ if (vppcom_session_attr(vfd, VPPCOM_ATTR_SET_SHUT, &how, &flags_len)) -+ { -+ vppcom_session_close(vfd); -+ return -1; -+ } -+ -+ if (vppcom_session_attr(vfd, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len)) -+ { -+ vppcom_session_close(vfd); -+ return -1; -+ } -+ -+ if (flags == SHUT_RDWR) -+ rv = vppcom_session_close(vfd); -+ -+ return rv; -+} -diff --git a/src/vcl/ngxvcl.h b/src/vcl/ngxvcl.h -new file mode 100644 -index 000000000..60b5116a8 ---- /dev/null -+++ b/src/vcl/ngxvcl.h -@@ -0,0 +1,70 @@ -+#ifndef _NGXVCL_H_ -+#define _NGXVCL_H_ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+void ngxvcl_wait_vep_only(); -+void ngxvcl_wait_kep_and_vep(); -+ -+void ngxvcl_app_create(char *app_name); -+void ngxvcl_app_destroy(void); -+ -+int ngxvcl_socket(int domain, int type, int protocol); -+int ngxvcl_close(int offset_vfd); -+int ngxvcl_kvfd_close(int fd); -+int ngxvcl_bind(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen); -+int ngxvcl_listen(int offset_vfd, int backlog); -+ -+int ngxvcl_accept4(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen, -+ int flags); -+int ngxvcl_accept(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen); -+ -+int ngxvcl_connect(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen); -+int ngxvcl_read(int offset_vfd, void *buf, size_t count); -+int ngxvcl_write(int offset_vfd, const void *buf, size_t count); -+ -+int ngxvcl_epoll_create(int size); -+int ngxvcl_kvfd_epoll_ctl(int offset_vepfd, int op, int fd, struct epoll_event *event); -+int ngxvcl_kvfd_epoll_wait(int offset_vepfd, struct epoll_event *events, int maxevents, -+ int timeout); -+ -+ssize_t ngxvcl_readv(int offset_vfd, const struct iovec *iov, int iovcnt); -+ssize_t ngxvcl_writev(int offset_vfd, const struct iovec *iov, int iovcnt); -+ -+int ngxvcl_kvfd_fcntl(int fd, int cmd, ...); -+int ngxvcl_kvfd_ioctl(int fd, unsigned long int cmd, ...); -+ -+int ngxvcl_socketpair(int domain, int type, int protocol, int fds[2]); -+int ngxvcl_kvfd_getsockname(int fd, struct sockaddr *addr, socklen_t *len); -+int ngxvcl_kvfd_getsockopt(int fd, int level, int optname, void *optval, -+ socklen_t *optlen); -+int ngxvcl_kvfd_setsockopt(int fd, int level, int optname, const void *optval, -+ socklen_t optlen); -+ -+ssize_t ngxvcl_send(int fd, const void *buf, size_t n, int flags); -+ssize_t ngxvcl_sendfile(int out_offset_vfd, int in_kfd, off_t *offset, size_t len); -+ssize_t ngxvcl_recv(int offset_vfd, void *buf, size_t n, int flags); -+ssize_t ngxvcl_sendto(int offset_vfd, const void *buf, size_t n, int flags, -+ const struct sockaddr *addr, socklen_t addr_len); -+ssize_t ngxvcl_recvfrom(int offset_vfd, void *buf, size_t n, int flags, -+ struct sockaddr *addr, socklen_t *addr_len); -+ssize_t ngxvcl_sendmsg(int offset_vfd, const struct msghdr *message, int flags); -+ssize_t ngxvcl_recvmsg(int offset_vfd, struct msghdr *message, int flags); -+ -+int ngxvcl_shutdown(int offset_vfd, int how); -+ -+#endif --- -2.17.1 - diff --git a/vpp_patches/vcl/master/0001-ngxvcl-api.patch b/vpp_patches/vcl/master/0001-ngxvcl-api.patch new file mode 100644 index 0000000..6200295 --- /dev/null +++ b/vpp_patches/vcl/master/0001-ngxvcl-api.patch @@ -0,0 +1,1698 @@ +From e4d25bd08881a6805faa4d3a4716e84f48c0540c Mon Sep 17 00:00:00 2001 +From: "xiaolongx.jiang" +Date: Mon, 21 Sep 2020 13:19:21 +0800 +Subject: [PATCH] ngxvcl api + +Signed-off-by: xiaolongx.jiang +--- + src/vcl/CMakeLists.txt | 10 +- + src/vcl/ngxvcl.c | 1574 ++++++++++++++++++++++++++++++++++++++++ + src/vcl/ngxvcl.h | 70 ++ + 3 files changed, 1653 insertions(+), 1 deletion(-) + create mode 100644 src/vcl/ngxvcl.c + create mode 100644 src/vcl/ngxvcl.h + +diff --git a/src/vcl/CMakeLists.txt b/src/vcl/CMakeLists.txt +index e6d8f98ff..8a878f49f 100644 +--- a/src/vcl/CMakeLists.txt ++++ b/src/vcl/CMakeLists.txt +@@ -39,10 +39,18 @@ add_vpp_library(vcl_ldpreload + vppinfra svm vlibmemoryclient rt pthread vppcom dl + ) + ++add_vpp_library(ngxvcl ++ SOURCES ++ ngxvcl.c ++ ++ LINK_LIBRARIES ++ vppinfra svm vlibmemoryclient rt pthread vppcom dl ++) ++ + add_vpp_headers(vcl + ldp.h + ldp_glibc_socket.h + vppcom.h + vcl_locked.h + ldp_socket_wrapper.h +-) +\ No newline at end of file ++) +diff --git a/src/vcl/ngxvcl.c b/src/vcl/ngxvcl.c +new file mode 100644 +index 000000000..8cfa6ba8f +--- /dev/null ++++ b/src/vcl/ngxvcl.c +@@ -0,0 +1,1574 @@ ++#include ++#include ++ ++#define MAX_NGX_WORKERS 100 ++#define VFD_OFFSET 0X003F3F3F ++#define NGXVCL_TLS_ON "NGXVCL_TLS_ON" ++#define NGXVCL_TLS_CERT "NGXVCL_TLS_CERT" ++#define NGXVCL_TLS_KEY "NGXVCL_TLS_KEY" ++ ++typedef unsigned char u8; ++typedef unsigned short u16; ++typedef unsigned int u32; ++ ++typedef struct ngxvcl_main_t_ ++{ ++ u32 listen_session_index; ++ u32 master_worker_index; ++ /** Not include master worker index. */ ++ u32 *workers_subscribed_by_ls; ++ clib_bitmap_t *listeners; ++ uword *worker_index_by_pid; ++ int wait_vep_only; ++ int intercepted_sigchld; ++ u8 transparent_tls; ++} ngxvcl_main_t; ++ ++static ngxvcl_main_t *nvm = NULL; ++ ++static u8 *sendfile_io_buffer = NULL; ++ ++static int epoll_fd_for_evtfd = 0; ++ ++static u8 use_mq_eventfd = 0; ++ ++static int wait_kep_next = 0; ++ ++static inline _Bool is_offset_vfd(int fd) ++{ ++ return fd >= VFD_OFFSET; ++} ++static inline int vfd_to_offset_vfd(int vfd) ++{ ++ return vfd + VFD_OFFSET; ++} ++static inline int offset_vfd_to_vfd(int offset_fd) ++{ ++ int vfd = offset_fd - VFD_OFFSET; ++ ++ return (vcl_get_worker_index () << 24) | (vfd & 0X00FFFFFF); ++} ++ ++static int copy_ep_to_sockaddr(struct sockaddr *addr, socklen_t *len, ++ vppcom_endpt_t *ep) ++{ ++ int rv = 0; ++ int sa_len, copy_len; ++ ++ if (addr && len && ep) ++ { ++ addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6; ++ ++ switch (addr->sa_family) ++ { ++ case AF_INET: ++ ((struct sockaddr_in *)addr)->sin_port = ep->port; ++ if (*len > sizeof(struct sockaddr_in)) ++ *len = sizeof(struct sockaddr_in); ++ sa_len = sizeof(struct sockaddr_in) - sizeof(struct in_addr); ++ copy_len = *len - sa_len; ++ if (copy_len > 0) ++ memcpy(&((struct sockaddr_in *)addr)->sin_addr, ep->ip, ++ copy_len); ++ break; ++ ++ case AF_INET6: ++ ((struct sockaddr_in6 *)addr)->sin6_port = ep->port; ++ if (*len > sizeof(struct sockaddr_in6)) ++ *len = sizeof(struct sockaddr_in6); ++ sa_len = sizeof(struct sockaddr_in6) - sizeof(struct in6_addr); ++ copy_len = *len - sa_len; ++ if (copy_len > 0) ++ memcpy( ++ ((struct sockaddr_in6 *)addr)->sin6_addr.__in6_u.__u6_addr8, ++ ep->ip, copy_len); ++ break; ++ ++ default: ++ /* Not possible */ ++ rv = -EAFNOSUPPORT; ++ break; ++ } ++ } ++ ++ return rv; ++} ++ ++static void listener_wrk_stop_listen(u32 wrk_index) { ++ vcl_worker_t *wrk; ++ vcl_session_t *s; ++ ++ wrk = vcl_worker_get(wrk_index); ++ s = vcl_session_get (wrk, nvm->listen_session_index); ++ if (s->session_state != VCL_STATE_LISTEN) ++ return; ++ vcl_send_session_unlisten(wrk, s); ++ s->session_state = VCL_STATE_LISTEN_NO_MQ; ++ clib_bitmap_set(nvm->listeners, wrk_index, 0); ++} ++ ++static void ++share_listen_session (vcl_worker_t * wrk) ++{ ++ vcl_session_t *s; ++ ++ s = vcl_session_get (wrk, nvm->listen_session_index); ++ s->session_state = VCL_STATE_LISTEN_NO_MQ; ++ vppcom_session_listen((vcl_get_worker_index() << 24 | nvm->listen_session_index), ~0); ++ clib_bitmap_set(nvm->listeners, vcl_get_worker_index(), 1); ++ if (clib_bitmap_get(nvm->listeners, 0) == 1) ++ listener_wrk_stop_listen (0); ++ vec_add1 (nvm->workers_subscribed_by_ls, wrk->wrk_index); ++} ++ ++static void ++worker_copy_on_fork (vcl_worker_t * parent_wrk) ++{ ++ vcl_worker_t *wrk = vcl_worker_get_current (); ++ ++ wrk->vpp_event_queues = vec_dup (parent_wrk->vpp_event_queues); ++ wrk->sessions = pool_dup (parent_wrk->sessions); ++ wrk->session_index_by_vpp_handles = ++ hash_dup (parent_wrk->session_index_by_vpp_handles); ++ ++ share_listen_session (wrk); ++} ++ ++static void ++ngxvcl_cleanup_child_worker (u32 child_wrk_index) ++{ ++ vcl_worker_t *child_wrk = vcl_worker_get(child_wrk_index); ++ vcl_session_t *s; ++ ++ /** Unshare listen session. */ ++ s = vcl_session_get (child_wrk, nvm->listen_session_index); ++ clib_bitmap_set (nvm->listeners, child_wrk_index, 0); ++ vec_del1 (nvm->workers_subscribed_by_ls, child_wrk_index); ++ vcl_session_cleanup (child_wrk, s, vcl_session_handle (s), 1); ++ ++ hash_unset (nvm->worker_index_by_pid, child_wrk->current_pid); ++ vcl_worker_cleanup (child_wrk, 1 /* notify vpp */); ++} ++ ++static struct sigaction old_sa; ++ ++static void ++ngxvcl_intercept_sigchld_handler (int signum, siginfo_t * si, void *uc) ++{ ++ vcl_worker_t *wrk; ++ u32 child_wrk_index; ++ ++ if (vcl_get_worker_index () == ~0) ++ return; ++ ++ if (sigaction (SIGCHLD, &old_sa, 0)) ++ { ++ VERR ("couldn't restore sigchld"); ++ exit (-1); ++ } ++ ++ wrk = vcl_worker_get_current (); ++ child_wrk_index = *(hash_get (nvm->worker_index_by_pid, si->si_pid)); ++ ++ if (si->si_pid != vcl_worker_get(child_wrk_index)->current_pid) ++ { ++ VDBG (0, "unexpected child pid %u", si->si_pid); ++ goto done; ++ } ++ ++ ngxvcl_cleanup_child_worker (child_wrk_index); ++ wrk->forked_child = ~0; ++ ++done: ++ if (old_sa.sa_flags & SA_SIGINFO) ++ { ++ void (*fn) (int, siginfo_t *, void *) = old_sa.sa_sigaction; ++ fn (signum, si, uc); ++ } ++ else ++ { ++ void (*fn) (int) = old_sa.sa_handler; ++ if (fn) ++ fn (signum); ++ } ++} ++ ++static void ++ngxvcl_incercept_sigchld () ++{ ++ if (!nvm->intercepted_sigchld) ++ { ++ struct sigaction sa; ++ clib_memset (&sa, 0, sizeof (sa)); ++ sa.sa_sigaction = ngxvcl_intercept_sigchld_handler; ++ sa.sa_flags = SA_SIGINFO; ++ if (sigaction (SIGCHLD, &sa, &old_sa)) ++ { ++ VERR ("couldn't intercept sigchld"); ++ exit (-1); ++ } ++ nvm->intercepted_sigchld = 1; ++ } ++} ++ ++static void ++app_pre_fork (void) ++{ ++ ngxvcl_incercept_sigchld (); ++ vcl_flush_mq_events (); ++} ++ ++static void ++app_fork_parent_handler (void) ++{ ++ vcm->forking = 1; ++ while (vcm->forking) ++ ; ++} ++ ++static void ++app_fork_child_handler (void) ++{ ++ vcl_worker_t *parent_wrk; ++ int parent_wrk_index; ++ ++ parent_wrk_index = vcl_get_worker_index (); ++ VDBG (0, "initializing forked child %u with parent wrk %u", getpid (), ++ parent_wrk_index); ++ ++ vcl_set_worker_index (~0); ++ ++ /* ++ * Register worker with vpp and share listen session ++ */ ++ if (vppcom_worker_register ()) ++ { ++ VDBG (0, "couldn't register new worker!"); ++ return; ++ } ++ ++ parent_wrk = vcl_worker_get (parent_wrk_index); ++ worker_copy_on_fork (parent_wrk); ++ hash_set(nvm->worker_index_by_pid, getpid(), vcl_get_worker_index()); ++ parent_wrk->forked_child = vcl_get_worker_index (); ++ ++ sendfile_io_buffer = NULL; ++ ++ VDBG (0, "forked child main worker initialized"); ++ vcm->forking = 0; ++} ++ ++static void ++sendfile_io_buffer_free (void) ++{ ++ vec_free (sendfile_io_buffer); ++} ++ ++void ngxvcl_wait_vep_only() ++{ ++ if (use_mq_eventfd) ++ return; ++ nvm->wait_vep_only = 1; ++} ++ ++void ngxvcl_wait_kep_and_vep() ++{ ++ if (use_mq_eventfd) ++ return; ++ nvm->wait_vep_only = 0; ++} ++ ++void ngxvcl_app_create(char *app_name) ++{ ++ int rv = vppcom_app_create(app_name); ++ ++ if (rv) ++ { ++ errno = -rv; ++ perror("ERROR when calling ngxvcl_app_create()!"); ++ fprintf(stderr, "\nERROR: ngxvcl_app_create() failed (errno = %d)!\n", -rv); ++ exit(1); ++ } ++ ++ pthread_atfork(app_pre_fork, app_fork_parent_handler, ++ app_fork_child_handler); ++ atexit(sendfile_io_buffer_free); ++ ++ nvm = clib_mem_alloc (sizeof (ngxvcl_main_t)); ++ if (!nvm) ++ { ++ clib_warning ("NgxVCL<%d>: ERROR: clib_mem_alloc() failed!", getpid ()); ++ ASSERT (nvm); ++ return; ++ } ++ clib_memset(nvm, 0, sizeof(ngxvcl_main_t)); ++ clib_bitmap_validate(nvm->listeners, MAX_NGX_WORKERS + 1); ++ clib_bitmap_set(nvm->listeners, vcl_get_worker_index(), 1); ++ hash_set(nvm->worker_index_by_pid, getpid(), vcl_get_worker_index()); ++ ++ if (getenv (NGXVCL_TLS_ON)) ++ nvm->transparent_tls = 1; ++ ++ use_mq_eventfd = vcm->cfg.use_mq_eventfd; ++} ++ ++void ngxvcl_app_destroy(void) ++{ ++ vec_free(nvm->workers_subscribed_by_ls); ++ clib_bitmap_free(nvm->listeners); ++ hash_free(nvm->worker_index_by_pid); ++ clib_mem_free(nvm); ++ vppcom_app_destroy(); ++} ++ ++static int ++ngxvcl_load_tls_cert (uint32_t sh) ++{ ++ char *env_var_str = getenv (NGXVCL_TLS_CERT); ++ char inbuf[4096]; ++ char *tls_cert; ++ int cert_size; ++ FILE *fp; ++ ++ if (env_var_str) ++ { ++ fp = fopen (env_var_str, "r"); ++ if (fp == NULL) ++ { ++ VDBG (0, "ERROR: failed to open cert file %s \n", env_var_str); ++ return -1; ++ } ++ cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp); ++ tls_cert = inbuf; ++ vppcom_session_tls_add_cert (sh, tls_cert, ++ cert_size); ++ fclose (fp); ++ } ++ else ++ { ++ VDBG (0, "ERROR: failed to read LDP environment %s\n", ++ NGXVCL_TLS_CERT); ++ return -1; ++ } ++ return 0; ++} ++ ++static int ++ngxvcl_load_tls_key (uint32_t sh) ++{ ++ char *env_var_str = getenv (NGXVCL_TLS_KEY); ++ char inbuf[4096]; ++ char *tls_key; ++ int key_size; ++ FILE *fp; ++ ++ if (env_var_str) ++ { ++ fp = fopen (env_var_str, "r"); ++ if (fp == NULL) ++ { ++ VDBG (0, "ERROR: failed to open key file %s \n", env_var_str); ++ return -1; ++ } ++ key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp); ++ tls_key = inbuf; ++ vppcom_session_tls_add_key (sh, tls_key, ++ key_size); ++ fclose (fp); ++ } ++ else ++ { ++ VDBG (0, "ERROR: failed to read NGXVCL environment %s\n", NGXVCL_TLS_KEY); ++ return -1; ++ } ++ return 0; ++} ++ ++int ngxvcl_socket(int domain, int type, int protocol) ++{ ++ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); ++ u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0; ++ ++ if (((domain == AF_INET) || (domain == AF_INET6)) && ++ ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM))) ++ { ++ u8 proto; ++ ++ if (nvm->transparent_tls) ++ proto = VPPCOM_PROTO_TLS; ++ else ++ proto = ((sock_type == SOCK_DGRAM) ? VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP); ++ ++ rv = vppcom_session_create(proto, is_nonblocking); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ else { ++ if (nvm->transparent_tls) ++ if (ngxvcl_load_tls_cert (rv) < 0 || ngxvcl_load_tls_key (rv) < 0) ++ return -1; ++ ++ rv = vfd_to_offset_vfd(rv); ++ } ++ } ++ else ++ { ++ rv = -1; ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_close(int offset_vfd) ++{ ++ int rv, epfd, vfd = offset_vfd_to_vfd(offset_vfd); ++ ++ epfd = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); ++ if (epfd > 0) { ++ rv = close(epfd); ++ if (rv < 0) { ++ u32 size = sizeof(epfd); ++ epfd = 0; ++ vppcom_session_attr(vfd, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size); ++ } ++ } ++ else if (epfd < 0) { ++ errno = -epfd; ++ rv = -1; ++ return rv; ++ } ++ ++ rv = vppcom_session_close(offset_vfd_to_vfd(offset_vfd)); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_close(int fd) ++{ ++ int rv; ++ ++ if (is_offset_vfd(fd)) ++ rv = ngxvcl_close(fd); ++ else ++ rv = close(fd); ++ ++ return rv; ++} ++ ++int ngxvcl_bind(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen) ++{ ++ int rv; ++ vppcom_endpt_t ep; ++ ++ switch (addr->sa_family) ++ { ++ case AF_INET: ++ if (addrlen != sizeof(struct sockaddr_in)) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ep.is_ip4 = VPPCOM_IS_IP4; ++ ep.ip = (u8 *)&((const struct sockaddr_in *)addr)->sin_addr; ++ ep.port = (u16)((const struct sockaddr_in *)addr)->sin_port; ++ break; ++ case AF_INET6: ++ if (addrlen != sizeof(struct sockaddr_in6)) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ep.is_ip4 = VPPCOM_IS_IP6; ++ ep.ip = (u8 *)&((const struct sockaddr_in6 *)addr)->sin6_addr; ++ ep.port = (u16)((const struct sockaddr_in6 *)addr)->sin6_port; ++ break; ++ default: ++ errno = EAFNOSUPPORT; ++ rv = -1; ++ goto done; ++ } ++ ++ rv = vppcom_session_bind(offset_vfd_to_vfd(offset_vfd), &ep); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ goto done; ++ } ++ ++ nvm->master_worker_index = offset_vfd_to_vfd(offset_vfd) >> 24; ++ nvm->listen_session_index = offset_vfd_to_vfd(offset_vfd) & 0X00FFFFFF; ++ ++done: ++ return rv; ++} ++ ++int ngxvcl_listen(int offset_vfd, int backlog) ++{ ++ int rv; ++ ++ ASSERT((u32)(offset_vfd_to_vfd(offset_vfd) & 0X00FFFFFF) == nvm->listen_session_index); ++ ++ rv = vppcom_session_listen(offset_vfd_to_vfd(offset_vfd), backlog); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_accept4(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen, ++ int flags) ++{ ++ int accepted_fd, rv; ++ vppcom_endpt_t ep; ++ u8 src_addr[sizeof(struct sockaddr_in6)]; ++ memset(&ep, 0, sizeof(ep)); ++ ep.ip = src_addr; ++ ++ accepted_fd = vppcom_session_accept(offset_vfd_to_vfd(offset_vfd), &ep, flags); ++ ++ if (accepted_fd < 0) ++ { ++ errno = -accepted_fd; ++ rv = -1; ++ } ++ else ++ { ++ rv = copy_ep_to_sockaddr(addr, addrlen, &ep); ++ ++ if (rv != VPPCOM_OK) ++ { ++ (void)vppcom_session_close(accepted_fd); ++ errno = -rv; ++ rv = -1; ++ } ++ else ++ { ++ rv = vfd_to_offset_vfd(accepted_fd); ++ } ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_accept(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen) ++{ ++ return ngxvcl_accept4(offset_vfd, addr, addrlen, 0); ++} ++ ++int ngxvcl_connect(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen) ++{ ++ int rv; ++ ++ if (!addr) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ++ vppcom_endpt_t ep; ++ ++ switch (addr->sa_family) ++ { ++ case AF_INET: ++ if (addrlen != sizeof(struct sockaddr_in)) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ep.is_ip4 = VPPCOM_IS_IP4; ++ ep.ip = (u8 *)&((const struct sockaddr_in *)addr)->sin_addr; ++ ep.port = (u16)((const struct sockaddr_in *)addr)->sin_port; ++ break; ++ case AF_INET6: ++ if (addrlen != sizeof(struct sockaddr_in6)) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ep.is_ip4 = VPPCOM_IS_IP6; ++ ep.ip = (u8 *)&((const struct sockaddr_in6 *)addr)->sin6_addr; ++ ep.port = (u16)((const struct sockaddr_in6 *)addr)->sin6_port; ++ break; ++ default: ++ errno = EAFNOSUPPORT; ++ rv = -1; ++ goto done; ++ } ++ ++ rv = vppcom_session_connect(offset_vfd_to_vfd(offset_vfd), &ep); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ ++done: ++ return rv; ++} ++ ++int ngxvcl_read(int offset_vfd, void *buf, size_t count) ++{ ++ ssize_t size; ++ ++ size = vppcom_session_read(offset_vfd_to_vfd(offset_vfd), buf, count); ++ ++ if (size < 0) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++ return size; ++} ++ ++int ngxvcl_write(int offset_vfd, const void *buf, size_t count) ++{ ++ ssize_t size = 0; ++ ++ size = vppcom_session_write_msg(offset_vfd_to_vfd(offset_vfd), (void *)buf, count); ++ ++ if (size < 0) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++ return size; ++} ++ ++int ngxvcl_epoll_create(int size) ++{ ++ int rv, vepfd; ++ ++ rv = vppcom_epoll_create(); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ return -1; ++ } ++ else ++ vepfd = rv; ++ ++ if (use_mq_eventfd) { ++ int libc_epfd; ++ u32 size = sizeof (u32); ++ struct epoll_event e = { 0 }; ++ ++ libc_epfd = epoll_create1 (EPOLL_CLOEXEC); ++ if (libc_epfd < 0) ++ return libc_epfd; ++ rv = vppcom_session_attr (vepfd, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd, &size); ++ if (rv < 0) ++ { ++ errno = -rv; ++ return -1; ++ } ++ e.events = EPOLLIN; ++ if (epoll_ctl (libc_epfd, EPOLL_CTL_ADD, vcl_worker_get_current ()->app_event_queue->q->consumer_evtfd, &e) < 0) ++ return -1; ++ epoll_fd_for_evtfd = libc_epfd; ++ } ++ ++ return vfd_to_offset_vfd (vepfd); ++} ++ ++int ngxvcl_kvfd_epoll_ctl(int offset_vepfd, int op, int fd, struct epoll_event *event) ++{ ++ int rv, vepfd = offset_vfd_to_vfd(offset_vepfd); ++ ++ if (is_offset_vfd(fd)) { ++ rv = vppcom_epoll_ctl(vepfd, op, offset_vfd_to_vfd(fd), ++ event); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else { ++ int libc_epfd; ++ u32 size = sizeof (vepfd); ++ ++ libc_epfd = vppcom_session_attr (vepfd, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); ++ if (!libc_epfd) { ++ libc_epfd = epoll_create1 (EPOLL_CLOEXEC); ++ if (libc_epfd < 0) ++ { ++ rv = libc_epfd; ++ return rv; ++ } ++ rv = vppcom_session_attr (vepfd, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd, &size); ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ return rv; ++ } ++ } ++ else if (libc_epfd < 0) { ++ errno = -vepfd; ++ rv = -1; ++ return rv; ++ } ++ ++ rv = epoll_ctl (libc_epfd, op, fd, event); ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_epoll_wait(int offset_vepfd, struct epoll_event *events, int maxevents, ++ int timeout) ++{ ++ int rv = 0, vepfd = offset_vfd_to_vfd (offset_vepfd); ++ ++ if (use_mq_eventfd) { ++ int i, n_evts = 0, veprv; ++ struct epoll_event temp_evts[2]; ++ ++again: ++ rv = epoll_wait (epoll_fd_for_evtfd, temp_evts, 2, timeout); ++ ++ if (PREDICT_TRUE (rv > 0)) ++ for (i = 0; i < rv; i++) { ++ if (PREDICT_FALSE (n_evts == maxevents)) ++ return n_evts; ++ if (PREDICT_TRUE (temp_evts[i].data.u32 == 0)) { ++ veprv = vppcom_epoll_wait(vepfd, events + n_evts, maxevents - n_evts, 0); ++ if (PREDICT_FALSE (veprv < 0)) { ++ errno = -veprv; ++ return -1; ++ } ++ n_evts += veprv; ++ } ++ else { ++ events[n_evts] = temp_evts[i]; ++ n_evts += 1; ++ } ++ } ++ ++ if (PREDICT_FALSE (!n_evts && rv > 0)) ++ goto again; ++ ++ return n_evts; ++ } ++ ++ if (nvm->wait_vep_only) ++ { ++ rv = vppcom_epoll_wait(vepfd, events, maxevents, timeout); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ ++ return rv; ++ } ++ else ++ { ++ double time_to_wait = (double) 0, max_time; ++ int libc_epfd; ++ clib_time_t clib_time = {}; ++ ++ if (clib_time.init_cpu_time == 0) ++ clib_time_init (&clib_time); ++ time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0); ++ max_time = clib_time_now (&clib_time) + time_to_wait; ++ ++ libc_epfd = vppcom_session_attr (vepfd, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); ++ if (libc_epfd < 0) ++ { ++ errno = -libc_epfd; ++ rv = -1; ++ return rv; ++ } ++ ++ do { ++ if (nvm->wait_vep_only) { ++ int time_remained = 0; ++ if (timeout > 0) { ++ time_remained = (int)(1000 * (max_time - clib_time_now (&clib_time))); ++ } ++ else ++ time_remained = timeout; ++ rv = vppcom_epoll_wait(vepfd, events, maxevents, time_remained); ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ return rv; ++ } ++ ++ if (!wait_kep_next) ++ { ++ rv = vppcom_epoll_wait(vepfd, events, maxevents, 0); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ return rv; ++ } ++ else if (rv > 0) ++ { ++ wait_kep_next = 1; ++ return rv; ++ } ++ } ++ else ++ wait_kep_next = 0; ++ ++ if (libc_epfd > 0) { ++ rv = epoll_wait(libc_epfd, events, maxevents, 0); ++ if (rv != 0) ++ return rv; ++ } ++ } while ((timeout == -1) || (clib_time_now (&clib_time) < max_time)); ++ ++ return rv; ++ } ++} ++ ++ssize_t ngxvcl_readv(int offset_vfd, const struct iovec *iov, int iovcnt) ++{ ++ int rv = 0, i, total = 0; ++ ssize_t size = 0; ++ ++ do ++ { ++ for (i = 0; i < iovcnt; ++i) ++ { ++ rv = vppcom_session_read(offset_vfd_to_vfd(offset_vfd), iov[i].iov_base, ++ iov[i].iov_len); ++ if (rv < 0) ++ break; ++ else ++ { ++ total += rv; ++ if ((size_t)rv < iov[i].iov_len) ++ break; ++ } ++ } ++ } while ((rv >= 0) && (total == 0)); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ size = -1; ++ } ++ else ++ size = total; ++ ++ return size; ++} ++ ++ssize_t ngxvcl_writev(int offset_vfd, const struct iovec *iov, int iovcnt) ++{ ++ ssize_t size = 0, total = 0; ++ int i, rv = 0; ++ ++ do ++ { ++ for (i = 0; i < iovcnt; ++i) ++ { ++ rv = vppcom_session_write_msg(offset_vfd_to_vfd(offset_vfd), ++ iov[i].iov_base, iov[i].iov_len); ++ if (rv < 0) ++ break; ++ else ++ { ++ total += rv; ++ if ((size_t)rv < iov[i].iov_len) ++ break; ++ } ++ } ++ } while ((rv >= 0) && (total == 0)); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ size = -1; ++ } ++ else ++ size = total; ++ ++ return size; ++} ++ ++int ngxvcl_kvfd_fcntl(int fd, int cmd, ...) ++{ ++ int rv = 0; ++ va_list ap; ++ ++ va_start(ap, cmd); ++ ++ if (is_offset_vfd(fd)) ++ { ++ int flags = va_arg(ap, int), vfd = offset_vfd_to_vfd(fd); ++ u32 size; ++ ++ size = sizeof(flags); ++ rv = -EOPNOTSUPP; ++ ++ switch (cmd) ++ { ++ case F_SETFL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_FLAGS, &flags, &size); ++ break; ++ case F_GETFL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_FLAGS, &flags, &size); ++ if (rv == VPPCOM_OK) ++ rv = flags; ++ break; ++ case F_SETFD: ++ /* TODO handle this */ ++ rv = 0; ++ break; ++ default: ++ rv = -EOPNOTSUPP; ++ break; ++ } ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else ++ { ++ long int args[4]; ++ ++ for (int i = 0; i < 4; i++) ++ args[i] = va_arg(ap, long int); ++ ++ rv = fcntl(fd, cmd, args[0], args[1], args[2], args[3]); ++ } ++ ++ va_end(ap); ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_ioctl(int fd, unsigned long int cmd, ...) ++{ ++ va_list ap; ++ int rv; ++ ++ va_start(ap, cmd); ++ ++ if (is_offset_vfd(fd)) ++ { ++ int vfd = offset_vfd_to_vfd(fd); ++ ++ switch (cmd) ++ { ++ case FIONREAD: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_NREAD, 0, 0); ++ break; ++ ++ case FIONBIO: ++ { ++ u32 flags = va_arg(ap, int) ? O_NONBLOCK : 0; ++ u32 size = sizeof(flags); ++ ++ /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than ++ * non-blocking, the flags should be read here and merged ++ * with O_NONBLOCK. ++ */ ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_FLAGS, &flags, &size); ++ } ++ break; ++ ++ default: ++ rv = -EOPNOTSUPP; ++ break; ++ } ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else ++ { ++ long int args[4]; ++ ++ for (int i = 0; i < 4; i++) ++ args[i] = va_arg(ap, long int); ++ ++ rv = ioctl(fd, cmd, args[0], args[1], args[2], args[3]); ++ } ++ ++ va_end(ap); ++ ++ return rv; ++} ++ ++int ngxvcl_socketpair(int domain, int type, int protocol, int fds[2]) ++{ ++ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); ++ ++ if (((domain == AF_INET) || (domain == AF_INET6)) && ++ ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM))) ++ { ++ errno = ENOSYS; ++ rv = -1; ++ } ++ else ++ { ++ rv = socketpair(domain, type, protocol, fds); ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_getsockname(int fd, struct sockaddr *addr, socklen_t *len) ++{ ++ int rv; ++ ++ if (is_offset_vfd(fd)) ++ { ++ vppcom_endpt_t ep; ++ u8 addr_buf[sizeof(struct in6_addr)]; ++ u32 size = sizeof(ep); ++ ++ ep.ip = addr_buf; ++ ++ rv = vppcom_session_attr(offset_vfd_to_vfd(fd), ++ VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ else ++ { ++ rv = copy_ep_to_sockaddr(addr, len, &ep); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ } ++ else ++ { ++ rv = getsockname(fd, addr, len); ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_getsockopt(int fd, int level, int optname, void *optval, ++ socklen_t *optlen) ++{ ++ int rv; ++ ++ if (is_offset_vfd(fd)) ++ { ++ int vfd = offset_vfd_to_vfd(fd); ++ ++ rv = -EOPNOTSUPP; ++ ++ switch (level) ++ { ++ case SOL_TCP: ++ switch (optname) ++ { ++ case TCP_NODELAY: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_NODELAY, ++ optval, optlen); ++ break; ++ case TCP_MAXSEG: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_USER_MSS, ++ optval, optlen); ++ break; ++ case TCP_KEEPIDLE: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_KEEPIDLE, ++ optval, optlen); ++ break; ++ case TCP_KEEPINTVL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_KEEPINTVL, ++ optval, optlen); ++ break; ++ case TCP_INFO: ++ if (optval && optlen && (*optlen == sizeof(struct tcp_info))) ++ { ++ memset(optval, 0, *optlen); ++ rv = VPPCOM_OK; ++ } ++ else ++ rv = -EFAULT; ++ break; ++ case TCP_CONGESTION: ++ strcpy(optval, "cubic"); ++ *optlen = strlen("cubic"); ++ rv = 0; ++ break; ++ default: ++ break; ++ } ++ break; ++ case SOL_IPV6: ++ switch (optname) ++ { ++ case IPV6_V6ONLY: ++ rv = ++ vppcom_session_attr(vfd, VPPCOM_ATTR_GET_V6ONLY, ++ optval, optlen); ++ break; ++ default: ++ break; ++ } ++ break; ++ case SOL_SOCKET: ++ switch (optname) ++ { ++ case SO_ACCEPTCONN: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_LISTEN, ++ optval, optlen); ++ break; ++ case SO_KEEPALIVE: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_KEEPALIVE, ++ optval, optlen); ++ break; ++ case SO_PROTOCOL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_PROTOCOL, ++ optval, optlen); ++ *(int *)optval = *(int *)optval ? SOCK_DGRAM : SOCK_STREAM; ++ break; ++ case SO_SNDBUF: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TX_FIFO_LEN, ++ optval, optlen); ++ break; ++ case SO_RCVBUF: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_RX_FIFO_LEN, ++ optval, optlen); ++ break; ++ case SO_REUSEADDR: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_REUSEADDR, ++ optval, optlen); ++ break; ++ case SO_BROADCAST: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_BROADCAST, ++ optval, optlen); ++ break; ++ case SO_ERROR: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_ERROR, ++ optval, optlen); ++ break; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else ++ { ++ rv = getsockopt(fd, level, optname, optval, optlen); ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_setsockopt(int fd, int level, int optname, const void *optval, ++ socklen_t optlen) ++{ ++ int rv; ++ ++ if (is_offset_vfd(fd)) ++ { ++ int vfd = offset_vfd_to_vfd(fd); ++ ++ rv = -EOPNOTSUPP; ++ ++ switch (level) ++ { ++ case SOL_TCP: ++ switch (optname) ++ { ++ case TCP_NODELAY: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_NODELAY, ++ (void *)optval, &optlen); ++ break; ++ case TCP_MAXSEG: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_USER_MSS, ++ (void *)optval, &optlen); ++ break; ++ case TCP_KEEPIDLE: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_KEEPIDLE, ++ (void *)optval, &optlen); ++ break; ++ case TCP_KEEPINTVL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_KEEPINTVL, ++ (void *)optval, &optlen); ++ break; ++ case TCP_CONGESTION: ++ case TCP_CORK: ++ /* Ignore */ ++ rv = 0; ++ break; ++ default: ++ break; ++ } ++ break; ++ case SOL_IPV6: ++ switch (optname) ++ { ++ case IPV6_V6ONLY: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_V6ONLY, ++ (void *)optval, &optlen); ++ break; ++ default: ++ break; ++ } ++ break; ++ case SOL_SOCKET: ++ switch (optname) ++ { ++ case SO_KEEPALIVE: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_KEEPALIVE, ++ (void *)optval, &optlen); ++ break; ++ case SO_REUSEADDR: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_REUSEADDR, ++ (void *)optval, &optlen); ++ break; ++ case SO_BROADCAST: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_BROADCAST, ++ (void *)optval, &optlen); ++ break; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else ++ { ++ rv = setsockopt(fd, level, optname, optval, optlen); ++ } ++ ++ return rv; ++} ++ ++ssize_t ngxvcl_send(int offset_vfd, const void *buf, size_t n, int flags) ++{ ++ ssize_t size; ++ ++ size = vppcom_session_sendto(offset_vfd_to_vfd(offset_vfd), (void *)buf, ++ n, flags, NULL); ++ ++ if (size < VPPCOM_OK) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++ return size; ++} ++ ++ssize_t ngxvcl_sendfile(int out_offset_vfd, int in_kfd, off_t *offset, size_t len) ++{ ++ ssize_t size = 0; ++ int rv, out_vfd = offset_vfd_to_vfd(out_offset_vfd); ++ ssize_t results = 0; ++ size_t n_bytes_left = len; ++ size_t bytes_to_read; ++ int nbytes; ++ u8 eagain = 0; ++ u32 flags, flags_len = sizeof(flags); ++ ++ rv = vppcom_session_attr(out_vfd, VPPCOM_ATTR_GET_FLAGS, &flags, ++ &flags_len); ++ ++ if (rv != VPPCOM_OK) ++ { ++ vec_reset_length (sendfile_io_buffer); ++ errno = -rv; ++ size = -1; ++ goto done; ++ } ++ ++ if (offset) ++ { ++ off_t off = lseek(in_kfd, *offset, SEEK_SET); ++ ++ if (off == -1) ++ { ++ size = -1; ++ goto done; ++ } ++ } ++ ++ do ++ { ++ size = vppcom_session_attr(out_vfd, VPPCOM_ATTR_GET_NWRITE, 0, 0); ++ ++ if (size < 0) ++ { ++ vec_reset_length (sendfile_io_buffer); ++ errno = -size; ++ size = -1; ++ goto done; ++ } ++ ++ bytes_to_read = size; ++ ++ if (bytes_to_read == 0) ++ { ++ if (flags & O_NONBLOCK) ++ { ++ if (!results) ++ eagain = 1; ++ goto update_offset; ++ } ++ else ++ continue; ++ } ++ ++ bytes_to_read = clib_min (n_bytes_left, bytes_to_read); ++ vec_validate (sendfile_io_buffer, bytes_to_read); ++ nbytes = read (in_kfd, sendfile_io_buffer, bytes_to_read); ++ ++ if (nbytes < 0) ++ { ++ if (results == 0) ++ { ++ vec_reset_length (sendfile_io_buffer); ++ size = -1; ++ goto done; ++ } ++ goto update_offset; ++ } ++ ++ size = vppcom_session_write(out_vfd, sendfile_io_buffer, nbytes); ++ ++ if (size < 0) ++ { ++ if (size == VPPCOM_EAGAIN) ++ { ++ if (flags & O_NONBLOCK) ++ { ++ if (!results) ++ eagain = 1; ++ goto update_offset; ++ } ++ else ++ continue; ++ } ++ if (results == 0) ++ { ++ vec_reset_length (sendfile_io_buffer); ++ errno = -size; ++ size = -1; ++ goto done; ++ } ++ goto update_offset; ++ } ++ ++ results += nbytes; ++ n_bytes_left = n_bytes_left - nbytes; ++ } while (n_bytes_left > 0); ++ ++update_offset: ++ vec_reset_length (sendfile_io_buffer); ++ if (offset) ++ { ++ off_t off = lseek(in_kfd, *offset, SEEK_SET); ++ ++ if (off == -1) ++ { ++ size = -1; ++ goto done; ++ } ++ ++ *offset += results + 1; ++ } ++ if (eagain) ++ { ++ errno = EAGAIN; ++ size = -1; ++ } ++ else ++ size = results; ++ ++done: ++ return size; ++} ++ ++ssize_t ngxvcl_recv(int offset_vfd, void *buf, size_t n, int flags) ++{ ++ ssize_t size; ++ ++ size = vppcom_session_recvfrom(offset_vfd_to_vfd(offset_vfd), buf, n, flags, NULL); ++ ++ if (size < 0) ++ errno = -size; ++ ++ return size; ++} ++ ++ssize_t ngxvcl_sendto(int offset_vfd, const void *buf, size_t n, int flags, ++ const struct sockaddr *addr, socklen_t addr_len) ++{ ++ ssize_t size; ++ ++ vppcom_endpt_t *ep = 0; ++ vppcom_endpt_t _ep; ++ ++ if (addr) ++ { ++ ep = &_ep; ++ switch (addr->sa_family) ++ { ++ case AF_INET: ++ ep->is_ip4 = VPPCOM_IS_IP4; ++ ep->ip = (uint8_t *)&((const struct sockaddr_in *)addr)->sin_addr; ++ ep->port = (uint16_t)((const struct sockaddr_in *)addr)->sin_port; ++ break; ++ case AF_INET6: ++ ep->is_ip4 = VPPCOM_IS_IP6; ++ ep->ip = (uint8_t *)&((const struct sockaddr_in6 *)addr)->sin6_addr; ++ ep->port = (uint16_t)((const struct sockaddr_in6 *)addr)->sin6_port; ++ break; ++ default: ++ errno = EAFNOSUPPORT; ++ size = -1; ++ goto done; ++ } ++ } ++ ++ size = vppcom_session_sendto(offset_vfd_to_vfd(offset_vfd), (void *)buf, n, flags, ep); ++ ++ if (size < 0) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++done: ++ return size; ++} ++ ++ssize_t ngxvcl_recvfrom(int offset_vfd, void *buf, size_t n, int flags, ++ struct sockaddr *addr, socklen_t *addr_len) ++{ ++ int vfd = offset_vfd_to_vfd(offset_vfd); ++ ssize_t size, rv; ++ ++ vppcom_endpt_t ep; ++ u8 src_addr[sizeof(struct sockaddr_in6)]; ++ ++ if (addr) ++ { ++ ep.ip = src_addr; ++ size = vppcom_session_recvfrom(vfd, buf, n, flags, &ep); ++ ++ if (size > 0) ++ { ++ rv = copy_ep_to_sockaddr(addr, addr_len, &ep); ++ ++ if (rv < 0) ++ size = rv; ++ } ++ } ++ else ++ size = vppcom_session_recvfrom(vfd, buf, n, flags, NULL); ++ ++ if (size < 0) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++ return size; ++} ++ ++ssize_t ngxvcl_sendmsg(int offset_vfd, const struct msghdr *message, int flags) ++{ ++ ssize_t size; ++ ++ errno = ENOSYS; ++ size = -1; ++ ++ return size; ++} ++ ++ssize_t ngxvcl_recvmsg(int offset_vfd, struct msghdr *message, int flags) ++{ ++ ssize_t size; ++ ++ errno = ENOSYS; ++ size = -1; ++ ++ return size; ++} ++ ++int ngxvcl_shutdown(int offset_vfd, int how) ++{ ++ int rv = 0, flags, vfd = offset_vfd_to_vfd(offset_vfd); ++ u32 flags_len = sizeof(flags); ++ ++ if (vppcom_session_attr(vfd, VPPCOM_ATTR_SET_SHUT, &how, &flags_len)) ++ { ++ vppcom_session_close(vfd); ++ return -1; ++ } ++ ++ if (vppcom_session_attr(vfd, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len)) ++ { ++ vppcom_session_close(vfd); ++ return -1; ++ } ++ ++ if (flags == SHUT_RDWR) ++ rv = vppcom_session_close(vfd); ++ ++ return rv; ++} +diff --git a/src/vcl/ngxvcl.h b/src/vcl/ngxvcl.h +new file mode 100644 +index 000000000..60b5116a8 +--- /dev/null ++++ b/src/vcl/ngxvcl.h +@@ -0,0 +1,70 @@ ++#ifndef _NGXVCL_H_ ++#define _NGXVCL_H_ ++ ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void ngxvcl_wait_vep_only(); ++void ngxvcl_wait_kep_and_vep(); ++ ++void ngxvcl_app_create(char *app_name); ++void ngxvcl_app_destroy(void); ++ ++int ngxvcl_socket(int domain, int type, int protocol); ++int ngxvcl_close(int offset_vfd); ++int ngxvcl_kvfd_close(int fd); ++int ngxvcl_bind(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen); ++int ngxvcl_listen(int offset_vfd, int backlog); ++ ++int ngxvcl_accept4(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen, ++ int flags); ++int ngxvcl_accept(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen); ++ ++int ngxvcl_connect(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen); ++int ngxvcl_read(int offset_vfd, void *buf, size_t count); ++int ngxvcl_write(int offset_vfd, const void *buf, size_t count); ++ ++int ngxvcl_epoll_create(int size); ++int ngxvcl_kvfd_epoll_ctl(int offset_vepfd, int op, int fd, struct epoll_event *event); ++int ngxvcl_kvfd_epoll_wait(int offset_vepfd, struct epoll_event *events, int maxevents, ++ int timeout); ++ ++ssize_t ngxvcl_readv(int offset_vfd, const struct iovec *iov, int iovcnt); ++ssize_t ngxvcl_writev(int offset_vfd, const struct iovec *iov, int iovcnt); ++ ++int ngxvcl_kvfd_fcntl(int fd, int cmd, ...); ++int ngxvcl_kvfd_ioctl(int fd, unsigned long int cmd, ...); ++ ++int ngxvcl_socketpair(int domain, int type, int protocol, int fds[2]); ++int ngxvcl_kvfd_getsockname(int fd, struct sockaddr *addr, socklen_t *len); ++int ngxvcl_kvfd_getsockopt(int fd, int level, int optname, void *optval, ++ socklen_t *optlen); ++int ngxvcl_kvfd_setsockopt(int fd, int level, int optname, const void *optval, ++ socklen_t optlen); ++ ++ssize_t ngxvcl_send(int fd, const void *buf, size_t n, int flags); ++ssize_t ngxvcl_sendfile(int out_offset_vfd, int in_kfd, off_t *offset, size_t len); ++ssize_t ngxvcl_recv(int offset_vfd, void *buf, size_t n, int flags); ++ssize_t ngxvcl_sendto(int offset_vfd, const void *buf, size_t n, int flags, ++ const struct sockaddr *addr, socklen_t addr_len); ++ssize_t ngxvcl_recvfrom(int offset_vfd, void *buf, size_t n, int flags, ++ struct sockaddr *addr, socklen_t *addr_len); ++ssize_t ngxvcl_sendmsg(int offset_vfd, const struct msghdr *message, int flags); ++ssize_t ngxvcl_recvmsg(int offset_vfd, struct msghdr *message, int flags); ++ ++int ngxvcl_shutdown(int offset_vfd, int how); ++ ++#endif +-- +2.17.1 + diff --git a/vpp_patches/vcl/other/0001-ngxvcl-api.patch b/vpp_patches/vcl/other/0001-ngxvcl-api.patch new file mode 100644 index 0000000..f294b36 --- /dev/null +++ b/vpp_patches/vcl/other/0001-ngxvcl-api.patch @@ -0,0 +1,1713 @@ +From 1c07c530f6308362f32c686a571a577380a1b7d8 Mon Sep 17 00:00:00 2001 +From: Zeyu Zhang +Date: Wed, 16 Oct 2019 16:51:22 +0800 +Subject: [PATCH] ngxvcl + +--- + src/vcl/CMakeLists.txt | 10 +- + src/vcl/ngxvcl.c | 1590 ++++++++++++++++++++++++++++++++++++++++ + src/vcl/ngxvcl.h | 70 ++ + 3 files changed, 1669 insertions(+), 1 deletion(-) + create mode 100644 src/vcl/ngxvcl.c + create mode 100644 src/vcl/ngxvcl.h + +diff --git a/src/vcl/CMakeLists.txt b/src/vcl/CMakeLists.txt +index ab0a6ad6a..1b6a9f351 100644 +--- a/src/vcl/CMakeLists.txt ++++ b/src/vcl/CMakeLists.txt +@@ -38,10 +38,18 @@ add_vpp_library(vcl_ldpreload + vppinfra svm vlibmemoryclient rt pthread vppcom dl + ) + ++add_vpp_library(ngxvcl ++ SOURCES ++ ngxvcl.c ++ ++ LINK_LIBRARIES ++ vppinfra svm vlibmemoryclient rt pthread vppcom dl ++) ++ + add_vpp_headers(vcl + ldp.h + ldp_glibc_socket.h + vppcom.h + vcl_locked.h + ldp_socket_wrapper.h +-) +\ No newline at end of file ++) +diff --git a/src/vcl/ngxvcl.c b/src/vcl/ngxvcl.c +new file mode 100644 +index 000000000..157c05246 +--- /dev/null ++++ b/src/vcl/ngxvcl.c +@@ -0,0 +1,1590 @@ ++#include ++#include ++ ++#define MAX_NGX_WORKERS 100 ++#define VFD_OFFSET 0X003F3F3F ++#define NGXVCL_TLS_ON "NGXVCL_TLS_ON" ++#define NGXVCL_TLS_CERT "NGXVCL_TLS_CERT" ++#define NGXVCL_TLS_KEY "NGXVCL_TLS_KEY" ++ ++typedef unsigned char u8; ++typedef unsigned short u16; ++typedef unsigned int u32; ++ ++typedef struct ngxvcl_main_t_ ++{ ++ u32 listen_session_index; ++ u32 master_worker_index; ++ /** Not include master worker index. */ ++ u32 *workers_subscribed_by_ls; ++ clib_bitmap_t *listeners; ++ uword *worker_index_by_pid; ++ int wait_vep_only; ++ int intercepted_sigchld; ++ u8 transparent_tls; ++} ngxvcl_main_t; ++ ++static ngxvcl_main_t *nvm = NULL; ++ ++static u8 *sendfile_io_buffer = NULL; ++ ++static int epoll_fd_for_evtfd = 0; ++ ++static u8 use_mq_eventfd = 0; ++ ++static int wait_kep_next = 0; ++ ++static inline _Bool is_offset_vfd(int fd) ++{ ++ return fd >= VFD_OFFSET; ++} ++static inline int vfd_to_offset_vfd(int vfd) ++{ ++ return vfd + VFD_OFFSET; ++} ++static inline int offset_vfd_to_vfd(int offset_fd) ++{ ++ int vfd = offset_fd - VFD_OFFSET; ++ ++ return (vcl_get_worker_index () << 24) | (vfd & 0X00FFFFFF); ++} ++ ++static int copy_ep_to_sockaddr(struct sockaddr *addr, socklen_t *len, ++ vppcom_endpt_t *ep) ++{ ++ int rv = 0; ++ int sa_len, copy_len; ++ ++ if (addr && len && ep) ++ { ++ addr->sa_family = (ep->is_ip4 == VPPCOM_IS_IP4) ? AF_INET : AF_INET6; ++ ++ switch (addr->sa_family) ++ { ++ case AF_INET: ++ ((struct sockaddr_in *)addr)->sin_port = ep->port; ++ if (*len > sizeof(struct sockaddr_in)) ++ *len = sizeof(struct sockaddr_in); ++ sa_len = sizeof(struct sockaddr_in) - sizeof(struct in_addr); ++ copy_len = *len - sa_len; ++ if (copy_len > 0) ++ memcpy(&((struct sockaddr_in *)addr)->sin_addr, ep->ip, ++ copy_len); ++ break; ++ ++ case AF_INET6: ++ ((struct sockaddr_in6 *)addr)->sin6_port = ep->port; ++ if (*len > sizeof(struct sockaddr_in6)) ++ *len = sizeof(struct sockaddr_in6); ++ sa_len = sizeof(struct sockaddr_in6) - sizeof(struct in6_addr); ++ copy_len = *len - sa_len; ++ if (copy_len > 0) ++ memcpy( ++ ((struct sockaddr_in6 *)addr)->sin6_addr.__in6_u.__u6_addr8, ++ ep->ip, copy_len); ++ break; ++ ++ default: ++ /* Not possible */ ++ rv = -EAFNOSUPPORT; ++ break; ++ } ++ } ++ ++ return rv; ++} ++ ++static void listener_wrk_stop_listen(u32 wrk_index) { ++ vcl_worker_t *wrk; ++ vcl_session_t *s; ++ ++ wrk = vcl_worker_get(wrk_index); ++ s = vcl_session_get (wrk, nvm->listen_session_index); ++ if (s->session_state != STATE_LISTEN) ++ return; ++ vcl_send_session_unlisten(wrk, s); ++ s->session_state = STATE_LISTEN_NO_MQ; ++ clib_bitmap_set(nvm->listeners, wrk_index, 0); ++} ++ ++static void ++share_listen_session (vcl_worker_t * wrk) ++{ ++ vcl_session_t *s; ++ ++ s = vcl_session_get (wrk, nvm->listen_session_index); ++ s->session_state = STATE_LISTEN_NO_MQ; ++ vppcom_session_listen((vcl_get_worker_index() << 24 | nvm->listen_session_index), ~0); ++ clib_bitmap_set(nvm->listeners, vcl_get_worker_index(), 1); ++ if (clib_bitmap_get(nvm->listeners, 0) == 1) ++ listener_wrk_stop_listen (0); ++ vec_add1 (nvm->workers_subscribed_by_ls, wrk->wrk_index); ++} ++ ++static void ++worker_copy_on_fork (vcl_worker_t * parent_wrk) ++{ ++ vcl_worker_t *wrk = vcl_worker_get_current (); ++ ++ wrk->vpp_event_queues = vec_dup (parent_wrk->vpp_event_queues); ++ wrk->sessions = pool_dup (parent_wrk->sessions); ++ wrk->session_index_by_vpp_handles = ++ hash_dup (parent_wrk->session_index_by_vpp_handles); ++ ++ share_listen_session (wrk); ++} ++ ++static void ++ngxvcl_cleanup_child_worker (u32 child_wrk_index) ++{ ++ vcl_worker_t *child_wrk = vcl_worker_get(child_wrk_index); ++ vcl_session_t *s; ++ ++ /** Unshare listen session. */ ++ s = vcl_session_get (child_wrk, nvm->listen_session_index); ++ clib_bitmap_set (nvm->listeners, child_wrk_index, 0); ++ vec_del1 (nvm->workers_subscribed_by_ls, child_wrk_index); ++ vcl_session_cleanup (child_wrk, s, vcl_session_handle (s), 1); ++ ++ hash_unset (nvm->worker_index_by_pid, child_wrk->current_pid); ++ vcl_worker_cleanup (child_wrk, 1 /* notify vpp */); ++} ++ ++static struct sigaction old_sa; ++ ++static void ++ngxvcl_intercept_sigchld_handler (int signum, siginfo_t * si, void *uc) ++{ ++ vcl_worker_t *wrk; ++ u32 child_wrk_index; ++ ++ if (vcl_get_worker_index () == ~0) ++ return; ++ ++ if (sigaction (SIGCHLD, &old_sa, 0)) ++ { ++ VERR ("couldn't restore sigchld"); ++ exit (-1); ++ } ++ ++ wrk = vcl_worker_get_current (); ++ child_wrk_index = *(hash_get (nvm->worker_index_by_pid, si->si_pid)); ++ ++ if (si->si_pid != vcl_worker_get(child_wrk_index)->current_pid) ++ { ++ VDBG (0, "unexpected child pid %u", si->si_pid); ++ goto done; ++ } ++ ++ ngxvcl_cleanup_child_worker (child_wrk_index); ++ wrk->forked_child = ~0; ++ ++done: ++ if (old_sa.sa_flags & SA_SIGINFO) ++ { ++ void (*fn) (int, siginfo_t *, void *) = old_sa.sa_sigaction; ++ fn (signum, si, uc); ++ } ++ else ++ { ++ void (*fn) (int) = old_sa.sa_handler; ++ if (fn) ++ fn (signum); ++ } ++} ++ ++static void ++ngxvcl_incercept_sigchld () ++{ ++ if (!nvm->intercepted_sigchld) ++ { ++ struct sigaction sa; ++ clib_memset (&sa, 0, sizeof (sa)); ++ sa.sa_sigaction = ngxvcl_intercept_sigchld_handler; ++ sa.sa_flags = SA_SIGINFO; ++ if (sigaction (SIGCHLD, &sa, &old_sa)) ++ { ++ VERR ("couldn't intercept sigchld"); ++ exit (-1); ++ } ++ nvm->intercepted_sigchld = 1; ++ } ++} ++ ++static void ++app_pre_fork (void) ++{ ++ ngxvcl_incercept_sigchld (); ++ vcl_flush_mq_events (); ++} ++ ++static void ++app_fork_parent_handler (void) ++{ ++ vcm->forking = 1; ++ while (vcm->forking) ++ ; ++} ++ ++static void ++app_fork_child_handler (void) ++{ ++ vcl_worker_t *parent_wrk; ++ int rv, parent_wrk_index; ++ u8 *child_name; ++ ++ parent_wrk_index = vcl_get_worker_index (); ++ VDBG (0, "initializing forked child %u with parent wrk %u", getpid (), ++ parent_wrk_index); ++ ++ /* ++ * Allocate worker ++ */ ++ vcl_set_worker_index (~0); ++ if (!vcl_worker_alloc_and_init ()) ++ VERR ("couldn't allocate new worker"); ++ ++ /* ++ * Attach to binary api ++ */ ++ child_name = format (0, "%v-child-%u%c", vcm->app_name, getpid (), 0); ++ vcl_cleanup_bapi (); ++ vppcom_api_hookup (); ++ vcm->app_state = STATE_APP_START; ++ rv = vppcom_connect_to_vpp ((char *) child_name); ++ vec_free (child_name); ++ if (rv) ++ { ++ VERR ("couldn't connect to VPP!"); ++ return; ++ } ++ ++ /* ++ * Register worker with vpp and share listen session ++ */ ++ vcl_worker_register_with_vpp (); ++ parent_wrk = vcl_worker_get (parent_wrk_index); ++ worker_copy_on_fork (parent_wrk); ++ hash_set(nvm->worker_index_by_pid, getpid(), vcl_get_worker_index()); ++ parent_wrk->forked_child = vcl_get_worker_index (); ++ ++ sendfile_io_buffer = NULL; ++ ++ VDBG (0, "forked child main worker initialized"); ++ vcm->forking = 0; ++} ++ ++static void ++sendfile_io_buffer_free (void) ++{ ++ vec_free (sendfile_io_buffer); ++} ++ ++void ngxvcl_wait_vep_only() ++{ ++ if (use_mq_eventfd) ++ return; ++ nvm->wait_vep_only = 1; ++} ++ ++void ngxvcl_wait_kep_and_vep() ++{ ++ if (use_mq_eventfd) ++ return; ++ nvm->wait_vep_only = 0; ++} ++ ++void ngxvcl_app_create(char *app_name) ++{ ++ int rv = vppcom_app_create(app_name); ++ ++ if (rv) ++ { ++ errno = -rv; ++ perror("ERROR when calling ngxvcl_app_create()!"); ++ fprintf(stderr, "\nERROR: ngxvcl_app_create() failed (errno = %d)!\n", -rv); ++ exit(1); ++ } ++ ++ pthread_atfork(app_pre_fork, app_fork_parent_handler, ++ app_fork_child_handler); ++ atexit(sendfile_io_buffer_free); ++ ++ nvm = clib_mem_alloc (sizeof (ngxvcl_main_t)); ++ if (!nvm) ++ { ++ clib_warning ("NgxVCL<%d>: ERROR: clib_mem_alloc() failed!", getpid ()); ++ ASSERT (nvm); ++ return; ++ } ++ clib_memset(nvm, 0, sizeof(ngxvcl_main_t)); ++ clib_bitmap_validate(nvm->listeners, MAX_NGX_WORKERS + 1); ++ clib_bitmap_set(nvm->listeners, vcl_get_worker_index(), 1); ++ hash_set(nvm->worker_index_by_pid, getpid(), vcl_get_worker_index()); ++ ++ if (getenv (NGXVCL_TLS_ON)) ++ nvm->transparent_tls = 1; ++ ++ use_mq_eventfd = vcm->cfg.use_mq_eventfd; ++} ++ ++void ngxvcl_app_destroy(void) ++{ ++ vec_free(nvm->workers_subscribed_by_ls); ++ clib_bitmap_free(nvm->listeners); ++ hash_free(nvm->worker_index_by_pid); ++ clib_mem_free(nvm); ++ vppcom_app_destroy(); ++} ++ ++static int ++ngxvcl_load_tls_cert (uint32_t sh) ++{ ++ char *env_var_str = getenv (NGXVCL_TLS_CERT); ++ char inbuf[4096]; ++ char *tls_cert; ++ int cert_size; ++ FILE *fp; ++ ++ if (env_var_str) ++ { ++ fp = fopen (env_var_str, "r"); ++ if (fp == NULL) ++ { ++ VDBG (0, "ERROR: failed to open cert file %s \n", env_var_str); ++ return -1; ++ } ++ cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp); ++ tls_cert = inbuf; ++ vppcom_session_tls_add_cert (sh, tls_cert, ++ cert_size); ++ fclose (fp); ++ } ++ else ++ { ++ VDBG (0, "ERROR: failed to read LDP environment %s\n", ++ NGXVCL_TLS_CERT); ++ return -1; ++ } ++ return 0; ++} ++ ++static int ++ngxvcl_load_tls_key (uint32_t sh) ++{ ++ char *env_var_str = getenv (NGXVCL_TLS_KEY); ++ char inbuf[4096]; ++ char *tls_key; ++ int key_size; ++ FILE *fp; ++ ++ if (env_var_str) ++ { ++ fp = fopen (env_var_str, "r"); ++ if (fp == NULL) ++ { ++ VDBG (0, "ERROR: failed to open key file %s \n", env_var_str); ++ return -1; ++ } ++ key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp); ++ tls_key = inbuf; ++ vppcom_session_tls_add_key (sh, tls_key, ++ key_size); ++ fclose (fp); ++ } ++ else ++ { ++ VDBG (0, "ERROR: failed to read NGXVCL environment %s\n", NGXVCL_TLS_KEY); ++ return -1; ++ } ++ return 0; ++} ++ ++int ngxvcl_socket(int domain, int type, int protocol) ++{ ++ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); ++ u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0; ++ ++ if (((domain == AF_INET) || (domain == AF_INET6)) && ++ ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM))) ++ { ++ u8 proto; ++ ++ if (nvm->transparent_tls) ++ proto = VPPCOM_PROTO_TLS; ++ else ++ proto = ((sock_type == SOCK_DGRAM) ? VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP); ++ ++ rv = vppcom_session_create(proto, is_nonblocking); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ else { ++ if (nvm->transparent_tls) ++ if (ngxvcl_load_tls_cert (rv) < 0 || ngxvcl_load_tls_key (rv) < 0) ++ return -1; ++ ++ rv = vfd_to_offset_vfd(rv); ++ } ++ } ++ else ++ { ++ rv = -1; ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_close(int offset_vfd) ++{ ++ int rv, epfd, vfd = offset_vfd_to_vfd(offset_vfd); ++ ++ epfd = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); ++ if (epfd > 0) { ++ rv = close(epfd); ++ if (rv < 0) { ++ u32 size = sizeof(epfd); ++ epfd = 0; ++ vppcom_session_attr(vfd, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size); ++ } ++ } ++ else if (epfd < 0) { ++ errno = -epfd; ++ rv = -1; ++ return rv; ++ } ++ ++ rv = vppcom_session_close(offset_vfd_to_vfd(offset_vfd)); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_close(int fd) ++{ ++ int rv; ++ ++ if (is_offset_vfd(fd)) ++ rv = ngxvcl_close(fd); ++ else ++ rv = close(fd); ++ ++ return rv; ++} ++ ++int ngxvcl_bind(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen) ++{ ++ int rv; ++ vppcom_endpt_t ep; ++ ++ switch (addr->sa_family) ++ { ++ case AF_INET: ++ if (addrlen != sizeof(struct sockaddr_in)) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ep.is_ip4 = VPPCOM_IS_IP4; ++ ep.ip = (u8 *)&((const struct sockaddr_in *)addr)->sin_addr; ++ ep.port = (u16)((const struct sockaddr_in *)addr)->sin_port; ++ break; ++ case AF_INET6: ++ if (addrlen != sizeof(struct sockaddr_in6)) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ep.is_ip4 = VPPCOM_IS_IP6; ++ ep.ip = (u8 *)&((const struct sockaddr_in6 *)addr)->sin6_addr; ++ ep.port = (u16)((const struct sockaddr_in6 *)addr)->sin6_port; ++ break; ++ default: ++ errno = EAFNOSUPPORT; ++ rv = -1; ++ goto done; ++ } ++ ++ rv = vppcom_session_bind(offset_vfd_to_vfd(offset_vfd), &ep); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ goto done; ++ } ++ ++ nvm->master_worker_index = offset_vfd_to_vfd(offset_vfd) >> 24; ++ nvm->listen_session_index = offset_vfd_to_vfd(offset_vfd) & 0X00FFFFFF; ++ ++done: ++ return rv; ++} ++ ++int ngxvcl_listen(int offset_vfd, int backlog) ++{ ++ int rv; ++ ++ ASSERT((u32)(offset_vfd_to_vfd(offset_vfd) & 0X00FFFFFF) == nvm->listen_session_index); ++ ++ rv = vppcom_session_listen(offset_vfd_to_vfd(offset_vfd), backlog); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_accept4(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen, ++ int flags) ++{ ++ int accepted_fd, rv; ++ vppcom_endpt_t ep; ++ u8 src_addr[sizeof(struct sockaddr_in6)]; ++ memset(&ep, 0, sizeof(ep)); ++ ep.ip = src_addr; ++ ++ accepted_fd = vppcom_session_accept(offset_vfd_to_vfd(offset_vfd), &ep, flags); ++ ++ if (accepted_fd < 0) ++ { ++ errno = -accepted_fd; ++ rv = -1; ++ } ++ else ++ { ++ rv = copy_ep_to_sockaddr(addr, addrlen, &ep); ++ ++ if (rv != VPPCOM_OK) ++ { ++ (void)vppcom_session_close(accepted_fd); ++ errno = -rv; ++ rv = -1; ++ } ++ else ++ { ++ rv = vfd_to_offset_vfd(accepted_fd); ++ } ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_accept(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen) ++{ ++ return ngxvcl_accept4(offset_vfd, addr, addrlen, 0); ++} ++ ++int ngxvcl_connect(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen) ++{ ++ int rv; ++ ++ if (!addr) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ++ vppcom_endpt_t ep; ++ ++ switch (addr->sa_family) ++ { ++ case AF_INET: ++ if (addrlen != sizeof(struct sockaddr_in)) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ep.is_ip4 = VPPCOM_IS_IP4; ++ ep.ip = (u8 *)&((const struct sockaddr_in *)addr)->sin_addr; ++ ep.port = (u16)((const struct sockaddr_in *)addr)->sin_port; ++ break; ++ case AF_INET6: ++ if (addrlen != sizeof(struct sockaddr_in6)) ++ { ++ errno = EINVAL; ++ rv = -1; ++ goto done; ++ } ++ ep.is_ip4 = VPPCOM_IS_IP6; ++ ep.ip = (u8 *)&((const struct sockaddr_in6 *)addr)->sin6_addr; ++ ep.port = (u16)((const struct sockaddr_in6 *)addr)->sin6_port; ++ break; ++ default: ++ errno = EAFNOSUPPORT; ++ rv = -1; ++ goto done; ++ } ++ ++ rv = vppcom_session_connect(offset_vfd_to_vfd(offset_vfd), &ep); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ ++done: ++ return rv; ++} ++ ++int ngxvcl_read(int offset_vfd, void *buf, size_t count) ++{ ++ ssize_t size; ++ ++ size = vppcom_session_read(offset_vfd_to_vfd(offset_vfd), buf, count); ++ ++ if (size < 0) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++ return size; ++} ++ ++int ngxvcl_write(int offset_vfd, const void *buf, size_t count) ++{ ++ ssize_t size = 0; ++ ++ size = vppcom_session_write_msg(offset_vfd_to_vfd(offset_vfd), (void *)buf, count); ++ ++ if (size < 0) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++ return size; ++} ++ ++int ngxvcl_epoll_create(int size) ++{ ++ int rv, vepfd; ++ ++ rv = vppcom_epoll_create(); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ return -1; ++ } ++ else ++ vepfd = rv; ++ ++ if (use_mq_eventfd) { ++ int libc_epfd; ++ u32 size = sizeof (u32); ++ struct epoll_event e = { 0 }; ++ ++ libc_epfd = epoll_create1 (EPOLL_CLOEXEC); ++ if (libc_epfd < 0) ++ return libc_epfd; ++ rv = vppcom_session_attr (vepfd, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd, &size); ++ if (rv < 0) ++ { ++ errno = -rv; ++ return -1; ++ } ++ e.events = EPOLLIN; ++ if (epoll_ctl (libc_epfd, EPOLL_CTL_ADD, vcl_worker_get_current ()->app_event_queue->q->consumer_evtfd, &e) < 0) ++ return -1; ++ epoll_fd_for_evtfd = libc_epfd; ++ } ++ ++ return vfd_to_offset_vfd (vepfd); ++} ++ ++int ngxvcl_kvfd_epoll_ctl(int offset_vepfd, int op, int fd, struct epoll_event *event) ++{ ++ int rv, vepfd = offset_vfd_to_vfd(offset_vepfd); ++ ++ if (is_offset_vfd(fd)) { ++ rv = vppcom_epoll_ctl(vepfd, op, offset_vfd_to_vfd(fd), ++ event); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else { ++ int libc_epfd; ++ u32 size = sizeof (vepfd); ++ ++ libc_epfd = vppcom_session_attr (vepfd, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); ++ if (!libc_epfd) { ++ libc_epfd = epoll_create1 (EPOLL_CLOEXEC); ++ if (libc_epfd < 0) ++ { ++ rv = libc_epfd; ++ return rv; ++ } ++ rv = vppcom_session_attr (vepfd, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd, &size); ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ return rv; ++ } ++ } ++ else if (libc_epfd < 0) { ++ errno = -vepfd; ++ rv = -1; ++ return rv; ++ } ++ ++ rv = epoll_ctl (libc_epfd, op, fd, event); ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_epoll_wait(int offset_vepfd, struct epoll_event *events, int maxevents, ++ int timeout) ++{ ++ int rv = 0, vepfd = offset_vfd_to_vfd (offset_vepfd); ++ ++ if (use_mq_eventfd) { ++ int i, n_evts = 0, veprv; ++ struct epoll_event temp_evts[2]; ++ ++again: ++ rv = epoll_wait (epoll_fd_for_evtfd, temp_evts, 2, timeout); ++ ++ if (PREDICT_TRUE (rv > 0)) ++ for (i = 0; i < rv; i++) { ++ if (PREDICT_FALSE (n_evts == maxevents)) ++ return n_evts; ++ if (PREDICT_TRUE (temp_evts[i].data.u32 == 0)) { ++ veprv = vppcom_epoll_wait(vepfd, events + n_evts, maxevents - n_evts, 0); ++ if (PREDICT_FALSE (veprv < 0)) { ++ errno = -veprv; ++ return -1; ++ } ++ n_evts += veprv; ++ } ++ else { ++ events[n_evts] = temp_evts[i]; ++ n_evts += 1; ++ } ++ } ++ ++ if (PREDICT_FALSE (!n_evts && rv > 0)) ++ goto again; ++ ++ return n_evts; ++ } ++ ++ if (nvm->wait_vep_only) ++ { ++ rv = vppcom_epoll_wait(vepfd, events, maxevents, timeout); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ ++ return rv; ++ } ++ else ++ { ++ double time_to_wait = (double) 0, max_time; ++ int libc_epfd; ++ clib_time_t clib_time = {}; ++ ++ if (clib_time.init_cpu_time == 0) ++ clib_time_init (&clib_time); ++ time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0); ++ max_time = clib_time_now (&clib_time) + time_to_wait; ++ ++ libc_epfd = vppcom_session_attr (vepfd, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0); ++ if (libc_epfd < 0) ++ { ++ errno = -libc_epfd; ++ rv = -1; ++ return rv; ++ } ++ ++ do { ++ if (nvm->wait_vep_only) { ++ int time_remained = 0; ++ if (timeout > 0) { ++ time_remained = (int)(1000 * (max_time - clib_time_now (&clib_time))); ++ } ++ else ++ time_remained = timeout; ++ rv = vppcom_epoll_wait(vepfd, events, maxevents, time_remained); ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ return rv; ++ } ++ ++ if (!wait_kep_next) ++ { ++ rv = vppcom_epoll_wait(vepfd, events, maxevents, 0); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ return rv; ++ } ++ else if (rv > 0) ++ { ++ wait_kep_next = 1; ++ return rv; ++ } ++ } ++ else ++ wait_kep_next = 0; ++ ++ if (libc_epfd > 0) { ++ rv = epoll_wait(libc_epfd, events, maxevents, 0); ++ if (rv != 0) ++ return rv; ++ } ++ } while ((timeout == -1) || (clib_time_now (&clib_time) < max_time)); ++ ++ return rv; ++ } ++} ++ ++ssize_t ngxvcl_readv(int offset_vfd, const struct iovec *iov, int iovcnt) ++{ ++ int rv = 0, i, total = 0; ++ ssize_t size = 0; ++ ++ do ++ { ++ for (i = 0; i < iovcnt; ++i) ++ { ++ rv = vppcom_session_read(offset_vfd_to_vfd(offset_vfd), iov[i].iov_base, ++ iov[i].iov_len); ++ if (rv < 0) ++ break; ++ else ++ { ++ total += rv; ++ if ((size_t)rv < iov[i].iov_len) ++ break; ++ } ++ } ++ } while ((rv >= 0) && (total == 0)); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ size = -1; ++ } ++ else ++ size = total; ++ ++ return size; ++} ++ ++ssize_t ngxvcl_writev(int offset_vfd, const struct iovec *iov, int iovcnt) ++{ ++ ssize_t size = 0, total = 0; ++ int i, rv = 0; ++ ++ do ++ { ++ for (i = 0; i < iovcnt; ++i) ++ { ++ rv = vppcom_session_write_msg(offset_vfd_to_vfd(offset_vfd), ++ iov[i].iov_base, iov[i].iov_len); ++ if (rv < 0) ++ break; ++ else ++ { ++ total += rv; ++ if ((size_t)rv < iov[i].iov_len) ++ break; ++ } ++ } ++ } while ((rv >= 0) && (total == 0)); ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ size = -1; ++ } ++ else ++ size = total; ++ ++ return size; ++} ++ ++int ngxvcl_kvfd_fcntl(int fd, int cmd, ...) ++{ ++ int rv = 0; ++ va_list ap; ++ ++ va_start(ap, cmd); ++ ++ if (is_offset_vfd(fd)) ++ { ++ int flags = va_arg(ap, int), vfd = offset_vfd_to_vfd(fd); ++ u32 size; ++ ++ size = sizeof(flags); ++ rv = -EOPNOTSUPP; ++ ++ switch (cmd) ++ { ++ case F_SETFL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_FLAGS, &flags, &size); ++ break; ++ case F_GETFL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_FLAGS, &flags, &size); ++ if (rv == VPPCOM_OK) ++ rv = flags; ++ break; ++ case F_SETFD: ++ /* TODO handle this */ ++ rv = 0; ++ break; ++ default: ++ rv = -EOPNOTSUPP; ++ break; ++ } ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else ++ { ++ long int args[4]; ++ ++ for (int i = 0; i < 4; i++) ++ args[i] = va_arg(ap, long int); ++ ++ rv = fcntl(fd, cmd, args[0], args[1], args[2], args[3]); ++ } ++ ++ va_end(ap); ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_ioctl(int fd, unsigned long int cmd, ...) ++{ ++ va_list ap; ++ int rv; ++ ++ va_start(ap, cmd); ++ ++ if (is_offset_vfd(fd)) ++ { ++ int vfd = offset_vfd_to_vfd(fd); ++ ++ switch (cmd) ++ { ++ case FIONREAD: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_NREAD, 0, 0); ++ break; ++ ++ case FIONBIO: ++ { ++ u32 flags = va_arg(ap, int) ? O_NONBLOCK : 0; ++ u32 size = sizeof(flags); ++ ++ /* TBD: When VPPCOM_ATTR_[GS]ET_FLAGS supports flags other than ++ * non-blocking, the flags should be read here and merged ++ * with O_NONBLOCK. ++ */ ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_FLAGS, &flags, &size); ++ } ++ break; ++ ++ default: ++ rv = -EOPNOTSUPP; ++ break; ++ } ++ ++ if (rv < 0) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else ++ { ++ long int args[4]; ++ ++ for (int i = 0; i < 4; i++) ++ args[i] = va_arg(ap, long int); ++ ++ rv = ioctl(fd, cmd, args[0], args[1], args[2], args[3]); ++ } ++ ++ va_end(ap); ++ ++ return rv; ++} ++ ++int ngxvcl_socketpair(int domain, int type, int protocol, int fds[2]) ++{ ++ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK); ++ ++ if (((domain == AF_INET) || (domain == AF_INET6)) && ++ ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM))) ++ { ++ errno = ENOSYS; ++ rv = -1; ++ } ++ else ++ { ++ rv = socketpair(domain, type, protocol, fds); ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_getsockname(int fd, struct sockaddr *addr, socklen_t *len) ++{ ++ int rv; ++ ++ if (is_offset_vfd(fd)) ++ { ++ vppcom_endpt_t ep; ++ u8 addr_buf[sizeof(struct in6_addr)]; ++ u32 size = sizeof(ep); ++ ++ ep.ip = addr_buf; ++ ++ rv = vppcom_session_attr(offset_vfd_to_vfd(fd), ++ VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ else ++ { ++ rv = copy_ep_to_sockaddr(addr, len, &ep); ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ } ++ else ++ { ++ rv = getsockname(fd, addr, len); ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_getsockopt(int fd, int level, int optname, void *optval, ++ socklen_t *optlen) ++{ ++ int rv; ++ ++ if (is_offset_vfd(fd)) ++ { ++ int vfd = offset_vfd_to_vfd(fd); ++ ++ rv = -EOPNOTSUPP; ++ ++ switch (level) ++ { ++ case SOL_TCP: ++ switch (optname) ++ { ++ case TCP_NODELAY: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_NODELAY, ++ optval, optlen); ++ break; ++ case TCP_MAXSEG: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_USER_MSS, ++ optval, optlen); ++ break; ++ case TCP_KEEPIDLE: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_KEEPIDLE, ++ optval, optlen); ++ break; ++ case TCP_KEEPINTVL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TCP_KEEPINTVL, ++ optval, optlen); ++ break; ++ case TCP_INFO: ++ if (optval && optlen && (*optlen == sizeof(struct tcp_info))) ++ { ++ memset(optval, 0, *optlen); ++ rv = VPPCOM_OK; ++ } ++ else ++ rv = -EFAULT; ++ break; ++ case TCP_CONGESTION: ++ strcpy(optval, "cubic"); ++ *optlen = strlen("cubic"); ++ rv = 0; ++ break; ++ default: ++ break; ++ } ++ break; ++ case SOL_IPV6: ++ switch (optname) ++ { ++ case IPV6_V6ONLY: ++ rv = ++ vppcom_session_attr(vfd, VPPCOM_ATTR_GET_V6ONLY, ++ optval, optlen); ++ break; ++ default: ++ break; ++ } ++ break; ++ case SOL_SOCKET: ++ switch (optname) ++ { ++ case SO_ACCEPTCONN: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_LISTEN, ++ optval, optlen); ++ break; ++ case SO_KEEPALIVE: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_KEEPALIVE, ++ optval, optlen); ++ break; ++ case SO_PROTOCOL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_PROTOCOL, ++ optval, optlen); ++ *(int *)optval = *(int *)optval ? SOCK_DGRAM : SOCK_STREAM; ++ break; ++ case SO_SNDBUF: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_TX_FIFO_LEN, ++ optval, optlen); ++ break; ++ case SO_RCVBUF: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_RX_FIFO_LEN, ++ optval, optlen); ++ break; ++ case SO_REUSEADDR: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_REUSEADDR, ++ optval, optlen); ++ break; ++ case SO_BROADCAST: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_BROADCAST, ++ optval, optlen); ++ break; ++ case SO_ERROR: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_GET_ERROR, ++ optval, optlen); ++ break; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else ++ { ++ rv = getsockopt(fd, level, optname, optval, optlen); ++ } ++ ++ return rv; ++} ++ ++int ngxvcl_kvfd_setsockopt(int fd, int level, int optname, const void *optval, ++ socklen_t optlen) ++{ ++ int rv; ++ ++ if (is_offset_vfd(fd)) ++ { ++ int vfd = offset_vfd_to_vfd(fd); ++ ++ rv = -EOPNOTSUPP; ++ ++ switch (level) ++ { ++ case SOL_TCP: ++ switch (optname) ++ { ++ case TCP_NODELAY: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_NODELAY, ++ (void *)optval, &optlen); ++ break; ++ case TCP_MAXSEG: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_USER_MSS, ++ (void *)optval, &optlen); ++ break; ++ case TCP_KEEPIDLE: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_KEEPIDLE, ++ (void *)optval, &optlen); ++ break; ++ case TCP_KEEPINTVL: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_TCP_KEEPINTVL, ++ (void *)optval, &optlen); ++ break; ++ case TCP_CONGESTION: ++ case TCP_CORK: ++ /* Ignore */ ++ rv = 0; ++ break; ++ default: ++ break; ++ } ++ break; ++ case SOL_IPV6: ++ switch (optname) ++ { ++ case IPV6_V6ONLY: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_V6ONLY, ++ (void *)optval, &optlen); ++ break; ++ default: ++ break; ++ } ++ break; ++ case SOL_SOCKET: ++ switch (optname) ++ { ++ case SO_KEEPALIVE: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_KEEPALIVE, ++ (void *)optval, &optlen); ++ break; ++ case SO_REUSEADDR: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_REUSEADDR, ++ (void *)optval, &optlen); ++ break; ++ case SO_BROADCAST: ++ rv = vppcom_session_attr(vfd, VPPCOM_ATTR_SET_BROADCAST, ++ (void *)optval, &optlen); ++ break; ++ default: ++ break; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ if (rv != VPPCOM_OK) ++ { ++ errno = -rv; ++ rv = -1; ++ } ++ } ++ else ++ { ++ rv = setsockopt(fd, level, optname, optval, optlen); ++ } ++ ++ return rv; ++} ++ ++ssize_t ngxvcl_send(int offset_vfd, const void *buf, size_t n, int flags) ++{ ++ ssize_t size; ++ ++ size = vppcom_session_sendto(offset_vfd_to_vfd(offset_vfd), (void *)buf, ++ n, flags, NULL); ++ ++ if (size < VPPCOM_OK) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++ return size; ++} ++ ++ssize_t ngxvcl_sendfile(int out_offset_vfd, int in_kfd, off_t *offset, size_t len) ++{ ++ ssize_t size = 0; ++ int rv, out_vfd = offset_vfd_to_vfd(out_offset_vfd); ++ ssize_t results = 0; ++ size_t n_bytes_left = len; ++ size_t bytes_to_read; ++ int nbytes; ++ u8 eagain = 0; ++ u32 flags, flags_len = sizeof(flags); ++ ++ rv = vppcom_session_attr(out_vfd, VPPCOM_ATTR_GET_FLAGS, &flags, ++ &flags_len); ++ ++ if (rv != VPPCOM_OK) ++ { ++ vec_reset_length (sendfile_io_buffer); ++ errno = -rv; ++ size = -1; ++ goto done; ++ } ++ ++ if (offset) ++ { ++ off_t off = lseek(in_kfd, *offset, SEEK_SET); ++ ++ if (off == -1) ++ { ++ size = -1; ++ goto done; ++ } ++ } ++ ++ do ++ { ++ size = vppcom_session_attr(out_vfd, VPPCOM_ATTR_GET_NWRITE, 0, 0); ++ ++ if (size < 0) ++ { ++ vec_reset_length (sendfile_io_buffer); ++ errno = -size; ++ size = -1; ++ goto done; ++ } ++ ++ bytes_to_read = size; ++ ++ if (bytes_to_read == 0) ++ { ++ if (flags & O_NONBLOCK) ++ { ++ if (!results) ++ eagain = 1; ++ goto update_offset; ++ } ++ else ++ continue; ++ } ++ ++ bytes_to_read = clib_min (n_bytes_left, bytes_to_read); ++ vec_validate (sendfile_io_buffer, bytes_to_read); ++ nbytes = read (in_kfd, sendfile_io_buffer, bytes_to_read); ++ ++ if (nbytes < 0) ++ { ++ if (results == 0) ++ { ++ vec_reset_length (sendfile_io_buffer); ++ size = -1; ++ goto done; ++ } ++ goto update_offset; ++ } ++ ++ size = vppcom_session_write(out_vfd, sendfile_io_buffer, nbytes); ++ ++ if (size < 0) ++ { ++ if (size == VPPCOM_EAGAIN) ++ { ++ if (flags & O_NONBLOCK) ++ { ++ if (!results) ++ eagain = 1; ++ goto update_offset; ++ } ++ else ++ continue; ++ } ++ if (results == 0) ++ { ++ vec_reset_length (sendfile_io_buffer); ++ errno = -size; ++ size = -1; ++ goto done; ++ } ++ goto update_offset; ++ } ++ ++ results += nbytes; ++ n_bytes_left = n_bytes_left - nbytes; ++ } while (n_bytes_left > 0); ++ ++update_offset: ++ vec_reset_length (sendfile_io_buffer); ++ if (offset) ++ { ++ off_t off = lseek(in_kfd, *offset, SEEK_SET); ++ ++ if (off == -1) ++ { ++ size = -1; ++ goto done; ++ } ++ ++ *offset += results + 1; ++ } ++ if (eagain) ++ { ++ errno = EAGAIN; ++ size = -1; ++ } ++ else ++ size = results; ++ ++done: ++ return size; ++} ++ ++ssize_t ngxvcl_recv(int offset_vfd, void *buf, size_t n, int flags) ++{ ++ ssize_t size; ++ ++ size = vppcom_session_recvfrom(offset_vfd_to_vfd(offset_vfd), buf, n, flags, NULL); ++ ++ if (size < 0) ++ errno = -size; ++ ++ return size; ++} ++ ++ssize_t ngxvcl_sendto(int offset_vfd, const void *buf, size_t n, int flags, ++ const struct sockaddr *addr, socklen_t addr_len) ++{ ++ ssize_t size; ++ ++ vppcom_endpt_t *ep = 0; ++ vppcom_endpt_t _ep; ++ ++ if (addr) ++ { ++ ep = &_ep; ++ switch (addr->sa_family) ++ { ++ case AF_INET: ++ ep->is_ip4 = VPPCOM_IS_IP4; ++ ep->ip = (uint8_t *)&((const struct sockaddr_in *)addr)->sin_addr; ++ ep->port = (uint16_t)((const struct sockaddr_in *)addr)->sin_port; ++ break; ++ case AF_INET6: ++ ep->is_ip4 = VPPCOM_IS_IP6; ++ ep->ip = (uint8_t *)&((const struct sockaddr_in6 *)addr)->sin6_addr; ++ ep->port = (uint16_t)((const struct sockaddr_in6 *)addr)->sin6_port; ++ break; ++ default: ++ errno = EAFNOSUPPORT; ++ size = -1; ++ goto done; ++ } ++ } ++ ++ size = vppcom_session_sendto(offset_vfd_to_vfd(offset_vfd), (void *)buf, n, flags, ep); ++ ++ if (size < 0) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++done: ++ return size; ++} ++ ++ssize_t ngxvcl_recvfrom(int offset_vfd, void *buf, size_t n, int flags, ++ struct sockaddr *addr, socklen_t *addr_len) ++{ ++ int vfd = offset_vfd_to_vfd(offset_vfd); ++ ssize_t size, rv; ++ ++ vppcom_endpt_t ep; ++ u8 src_addr[sizeof(struct sockaddr_in6)]; ++ ++ if (addr) ++ { ++ ep.ip = src_addr; ++ size = vppcom_session_recvfrom(vfd, buf, n, flags, &ep); ++ ++ if (size > 0) ++ { ++ rv = copy_ep_to_sockaddr(addr, addr_len, &ep); ++ ++ if (rv < 0) ++ size = rv; ++ } ++ } ++ else ++ size = vppcom_session_recvfrom(vfd, buf, n, flags, NULL); ++ ++ if (size < 0) ++ { ++ errno = -size; ++ size = -1; ++ } ++ ++ return size; ++} ++ ++ssize_t ngxvcl_sendmsg(int offset_vfd, const struct msghdr *message, int flags) ++{ ++ ssize_t size; ++ ++ errno = ENOSYS; ++ size = -1; ++ ++ return size; ++} ++ ++ssize_t ngxvcl_recvmsg(int offset_vfd, struct msghdr *message, int flags) ++{ ++ ssize_t size; ++ ++ errno = ENOSYS; ++ size = -1; ++ ++ return size; ++} ++ ++int ngxvcl_shutdown(int offset_vfd, int how) ++{ ++ int rv = 0, flags, vfd = offset_vfd_to_vfd(offset_vfd); ++ u32 flags_len = sizeof(flags); ++ ++ if (vppcom_session_attr(vfd, VPPCOM_ATTR_SET_SHUT, &how, &flags_len)) ++ { ++ vppcom_session_close(vfd); ++ return -1; ++ } ++ ++ if (vppcom_session_attr(vfd, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len)) ++ { ++ vppcom_session_close(vfd); ++ return -1; ++ } ++ ++ if (flags == SHUT_RDWR) ++ rv = vppcom_session_close(vfd); ++ ++ return rv; ++} +diff --git a/src/vcl/ngxvcl.h b/src/vcl/ngxvcl.h +new file mode 100644 +index 000000000..60b5116a8 +--- /dev/null ++++ b/src/vcl/ngxvcl.h +@@ -0,0 +1,70 @@ ++#ifndef _NGXVCL_H_ ++#define _NGXVCL_H_ ++ ++#define _GNU_SOURCE ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++void ngxvcl_wait_vep_only(); ++void ngxvcl_wait_kep_and_vep(); ++ ++void ngxvcl_app_create(char *app_name); ++void ngxvcl_app_destroy(void); ++ ++int ngxvcl_socket(int domain, int type, int protocol); ++int ngxvcl_close(int offset_vfd); ++int ngxvcl_kvfd_close(int fd); ++int ngxvcl_bind(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen); ++int ngxvcl_listen(int offset_vfd, int backlog); ++ ++int ngxvcl_accept4(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen, ++ int flags); ++int ngxvcl_accept(int offset_vfd, struct sockaddr *addr, socklen_t *addrlen); ++ ++int ngxvcl_connect(int offset_vfd, const struct sockaddr *addr, socklen_t addrlen); ++int ngxvcl_read(int offset_vfd, void *buf, size_t count); ++int ngxvcl_write(int offset_vfd, const void *buf, size_t count); ++ ++int ngxvcl_epoll_create(int size); ++int ngxvcl_kvfd_epoll_ctl(int offset_vepfd, int op, int fd, struct epoll_event *event); ++int ngxvcl_kvfd_epoll_wait(int offset_vepfd, struct epoll_event *events, int maxevents, ++ int timeout); ++ ++ssize_t ngxvcl_readv(int offset_vfd, const struct iovec *iov, int iovcnt); ++ssize_t ngxvcl_writev(int offset_vfd, const struct iovec *iov, int iovcnt); ++ ++int ngxvcl_kvfd_fcntl(int fd, int cmd, ...); ++int ngxvcl_kvfd_ioctl(int fd, unsigned long int cmd, ...); ++ ++int ngxvcl_socketpair(int domain, int type, int protocol, int fds[2]); ++int ngxvcl_kvfd_getsockname(int fd, struct sockaddr *addr, socklen_t *len); ++int ngxvcl_kvfd_getsockopt(int fd, int level, int optname, void *optval, ++ socklen_t *optlen); ++int ngxvcl_kvfd_setsockopt(int fd, int level, int optname, const void *optval, ++ socklen_t optlen); ++ ++ssize_t ngxvcl_send(int fd, const void *buf, size_t n, int flags); ++ssize_t ngxvcl_sendfile(int out_offset_vfd, int in_kfd, off_t *offset, size_t len); ++ssize_t ngxvcl_recv(int offset_vfd, void *buf, size_t n, int flags); ++ssize_t ngxvcl_sendto(int offset_vfd, const void *buf, size_t n, int flags, ++ const struct sockaddr *addr, socklen_t addr_len); ++ssize_t ngxvcl_recvfrom(int offset_vfd, void *buf, size_t n, int flags, ++ struct sockaddr *addr, socklen_t *addr_len); ++ssize_t ngxvcl_sendmsg(int offset_vfd, const struct msghdr *message, int flags); ++ssize_t ngxvcl_recvmsg(int offset_vfd, struct msghdr *message, int flags); ++ ++int ngxvcl_shutdown(int offset_vfd, int how); ++ ++#endif +-- +2.17.1 + -- cgit 1.2.3-korg