aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorxiaolongx.jiang <xiaolongx.jiang@intel.com>2020-05-12 05:07:26 +0000
committerxiaolongx.jiang <xiaolongx.jiang@intel.com>2020-05-15 16:42:40 +0000
commit5fad054675b47633f5ba1e33f775e34be4917c06 (patch)
tree49a3eafb868726c4478c18f7dc732799228c3c4b
parent1e75471aed27194fb8ee0b2c07c64fb8a8f55279 (diff)
add makefile
Signed-off-by: xiaolongx.jiang <xiaolongx.jiang@intel.com> Change-Id: Iaf6ec4d79538f8810d0c0ebc69b458d40ffb9c53
-rw-r--r--.gitmodules3
-rw-r--r--Makefile104
-rw-r--r--README.md43
-rw-r--r--configs/mime.types95
-rw-r--r--configs/nginx.conf104
-rw-r--r--configs/tls-test-cert23
-rw-r--r--configs/tls-test-key28
-rw-r--r--openssl_patches/0001-openssl3.0.0-alpha1.patch24
-rw-r--r--packages/nginx-dl.mk20
-rw-r--r--packages/nginx_ldp.mk69
-rw-r--r--packages/nginx_vcl.mk74
-rw-r--r--packages/openssl-dl.mk19
-rw-r--r--packages/openssl.mk46
-rw-r--r--packages/package.mk64
-rw-r--r--packages/packages.mk173
-rw-r--r--packages/pre-install9
-rw-r--r--packages/vpp_ldp.mk105
-rw-r--r--packages/vpp_vcl.mk96
m---------vpp0
-rw-r--r--vpp_patches/common/0001-3.0.0.patch113
-rw-r--r--vpp_patches/common/0002-src-pkg-debian-rules.in.patch27
-rw-r--r--vpp_patches/common/2001/0001-quick-0.0.9.patch45
-rw-r--r--vpp_patches/common/master/0001-picotls-patch.patch45
-rw-r--r--vpp_patches/ldp/2001/0001-LDP-remove-lock.patch (renamed from vpp_patches/ldp/0001-LDP-remove-lock.patch)0
-rw-r--r--vpp_patches/ldp/master/0001-LDP-remove-lock.patch4909
25 files changed, 6204 insertions, 34 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..69878e6
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "vpp"]
+ path = vpp
+ url = https://gerrit.fd.io/r/vpp
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..9cf7a3f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,104 @@
+# Copyright (c) 2020 Intel 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.
+
+ifneq ($(shell uname),Darwin)
+ OS_ID := $(shell grep '^ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g')
+ OS_VERSION_ID:= $(shell grep '^VERSION_ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g')
+else
+ $(warning exit)
+ @exit 1;
+endif
+
+# Scripts require non-POSIX parts of bash
+SHELL := /bin/bash
+
+export BR=$(CURDIR)
+
+DL_CACHE_DIR = $(CURDIR)/downloads
+MAKE ?= make
+MAKE_ARGS ?= -j
+BUILD_DIR ?= $(CURDIR)/_build
+INSTALL_DIR ?= $(CURDIR)/_install
+
+B := $(BUILD_DIR)
+I := $(INSTALL_DIR)
+
+_VPP_VER := $(vpp)
+
+
+LINUX_ITER := $(OS_ID)$(OS_VERSION_ID)
+LICENSE := BSD
+
+.PHONY: help
+help:
+ @echo "Make Targets:"
+ @echo " dep - install software dependencies"
+ @echo " deb-vcl - build vcl DEB package"
+ @echo " build-vcl - build vcl vpp and vcl nginx"
+ @echo " deb-ldp - build ldp DEB package"
+ @echo " build-ldp - build ldp vpp and ldp nginx"
+ @echo " clean - clean up build environment."
+ @echo " clean-vcl - clean up build vcl environment."
+ @echo " clean-ldp - clean up build ldp environment."
+ @echo ""
+
+include packages/packages.mk
+include packages/package.mk
+include packages/openssl-dl.mk
+include packages/nginx-dl.mk
+include packages/openssl.mk
+include packages/vpp_vcl.mk
+include packages/vpp_ldp.mk
+include packages/nginx_vcl.mk
+include packages/nginx_ldp.mk
+
+.PHONY: clean
+clean:
+ @rm -rf $(B) $(I)
+
+.PHONY: clean-vcl
+clean-vcl:
+ @rm -f $(B)/.vcl*
+
+.PHONY: clean-ldp
+clean-ldp:
+ @rm -f $(B)/.ldp*
+
+$(BR)/.deps.ok:
+ make dep
+ @touch $@
+
+.PHONY: build-vcl
+build-vcl: $(BR)/.deps.ok openssl-dl nginx-dl openssl-build vpp_vcl-build nginx_vcl-build
+
+.PHONY: build-ldp
+build-ldp: $(BR)/.deps.ok openssl-dl nginx-dl openssl-build vpp_ldp-build nginx_ldp-build
+
+
+.PHONY: deb-vcl
+deb-vcl: build-vcl openssl-deb vpp_vcl-deb nginx_vcl-deb
+
+.PHONY: deb-ldp
+deb-ldp: build-ldp openssl-deb vpp_ldp-deb nginx_ldp-deb
+
+.PHONY: dep
+dep:
+ifeq ($(OS_ID),ubuntu)
+ @sudo -E apt-get update
+ @sudo -E apt-get install git gcc make \
+ ruby ruby-dev libpam0g-dev \
+ libmariadb-client-lgpl-dev \
+ libmysqlclient-dev -y
+ @sudo -E gem install fpm
+ @cd vpp; echo yes|make install-dep;
+endif
diff --git a/README.md b/README.md
index 5ed9ad4..880a115 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +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.
# 2 Repository Layout
**configs**: configuration files for VPP, NGINX and VCL
@@ -11,8 +14,44 @@ to integrate VPP host stack directly with NGINX code change.
**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
+
# 3 Building on top of distinct patches
+You can choose to use the Makefile to build automatically, and there are some Makefile options for you.
+
+```bash
+$ git clone https://gerrit.fd.io/r/vsap
+$ cd vsap
+$ git submodule init
+$ git submodule update
+
+Help
+$ make help
+
+Install software dependencies
+$ make dep
+
+Build vcl DEB package and store the DEB files in folder '/path/to/this/repo/deb-vcl'
+$ make deb-vcl
+
+Build vcl vpp and vcl nginx and store the vcl files in folder '/path/to/this/repo/_install/local'
+$ make build-vcl
+
+Build ldp DEB package and store the DEB files in folder '/path/to/this/repo/deb-ldp'
+$ make deb-ldp
+
+Build ldp vpp and ldp nginx and store the vcl files in folder '/path/to/this/repo/_install/local'
+$ make build-ldp
+
+Clean all packages
+$ make clean
+```
+
## 3.0 Basic patch
### 3.0.1 Application Worker Partition
@@ -68,6 +107,7 @@ $ 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'
```bash
./vpp -c /path/to/startup.conf
@@ -76,6 +116,7 @@ $ sudo make install
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'
```
# export VCL_CONFIG=/path/to/vcl.conf
@@ -100,6 +141,8 @@ $ patch -p1 < /path/to/this/repo/vpp_patches/ldp/0001-LDP-remove-lock.patch
$ 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'
```bash
$ export VCL_CONFIG=path/to/vcl.conf
diff --git a/configs/mime.types b/configs/mime.types
new file mode 100644
index 0000000..8a2348a
--- /dev/null
+++ b/configs/mime.types
@@ -0,0 +1,95 @@
+
+types {
+ text/html html htm shtml;
+ text/css css;
+ text/xml xml;
+ image/gif gif;
+ image/jpeg jpeg jpg;
+ application/javascript js;
+ application/atom+xml atom;
+ application/rss+xml rss;
+
+ text/mathml mml;
+ text/plain txt;
+ text/vnd.sun.j2me.app-descriptor jad;
+ text/vnd.wap.wml wml;
+ text/x-component htc;
+
+ image/png png;
+ image/svg+xml svg svgz;
+ image/tiff tif tiff;
+ image/vnd.wap.wbmp wbmp;
+ image/webp webp;
+ image/x-icon ico;
+ image/x-jng jng;
+ image/x-ms-bmp bmp;
+
+ application/font-woff woff;
+ application/java-archive jar war ear;
+ application/json json;
+ application/mac-binhex40 hqx;
+ application/msword doc;
+ application/pdf pdf;
+ application/postscript ps eps ai;
+ application/rtf rtf;
+ application/vnd.apple.mpegurl m3u8;
+ application/vnd.google-earth.kml+xml kml;
+ application/vnd.google-earth.kmz kmz;
+ application/vnd.ms-excel xls;
+ application/vnd.ms-fontobject eot;
+ application/vnd.ms-powerpoint ppt;
+ application/vnd.oasis.opendocument.graphics odg;
+ application/vnd.oasis.opendocument.presentation odp;
+ application/vnd.oasis.opendocument.spreadsheet ods;
+ application/vnd.oasis.opendocument.text odt;
+ application/vnd.openxmlformats-officedocument.presentationml.presentation
+ pptx;
+ application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
+ xlsx;
+ application/vnd.openxmlformats-officedocument.wordprocessingml.document
+ docx;
+ application/vnd.wap.wmlc wmlc;
+ application/x-7z-compressed 7z;
+ application/x-cocoa cco;
+ application/x-java-archive-diff jardiff;
+ application/x-java-jnlp-file jnlp;
+ application/x-makeself run;
+ application/x-perl pl pm;
+ application/x-pilot prc pdb;
+ application/x-rar-compressed rar;
+ application/x-redhat-package-manager rpm;
+ application/x-sea sea;
+ application/x-shockwave-flash swf;
+ application/x-stuffit sit;
+ application/x-tcl tcl tk;
+ application/x-x509-ca-cert der pem crt;
+ application/x-xpinstall xpi;
+ application/xhtml+xml xhtml;
+ application/xspf+xml xspf;
+ application/zip zip;
+
+ application/octet-stream bin exe dll;
+ application/octet-stream deb;
+ application/octet-stream dmg;
+ application/octet-stream iso img;
+ application/octet-stream msi msp msm;
+
+ audio/midi mid midi kar;
+ audio/mpeg mp3;
+ audio/ogg ogg;
+ audio/x-m4a m4a;
+ audio/x-realaudio ra;
+
+ video/3gpp 3gpp 3gp;
+ video/mp2t ts;
+ video/mp4 mp4;
+ video/mpeg mpeg mpg;
+ video/quicktime mov;
+ video/webm webm;
+ video/x-flv flv;
+ video/x-m4v m4v;
+ video/x-mng mng;
+ video/x-ms-asf asx asf;
+ video/x-ms-wmv wmv;
+ video/x-msvideo avi;
+}
diff --git a/configs/nginx.conf b/configs/nginx.conf
index 0466aeb..d184b89 100644
--- a/configs/nginx.conf
+++ b/configs/nginx.conf
@@ -1,5 +1,8 @@
-user xxx;
-worker_processes 1;
+#user xxx;
+#worker_processes 1;
+#worker_processes 2;
+#worker_processes 4;
+#worker_processes 8;
master_process on;
daemon off;
@@ -7,6 +10,7 @@ daemon off;
worker_rlimit_nofile 10240;
events {
use epoll;
+ #epoll_events 512;
worker_connections 10240;
accept_mutex off;
multi_accept off;
@@ -25,53 +29,85 @@ http {
keepalive_requests 1000000;
server {
- listen 8000;
- root /path/to/root/;
+ listen 443;
+ #ssl_protocols TLSv1.2;
+ #ssl_prefer_server_ciphers on;
+ 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\
+ 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. \
"}';
}
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\
+ 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\
+ 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. \
"}';
}
diff --git a/configs/tls-test-cert b/configs/tls-test-cert
new file mode 100644
index 0000000..53ae6da
--- /dev/null
+++ b/configs/tls-test-cert
@@ -0,0 +1,23 @@
+-----BEGIN CERTIFICATE-----
+MIID5zCCAs+gAwIBAgIJALeMYCEHrTtJMA0GCSqGSIb3DQEBCwUAMIGJMQswCQYD
+VQQGEwJVUzELMAkGA1UECAwCQ0ExETAPBgNVBAcMCFNhbiBKb3NlMQ4wDAYDVQQK
+DAVDaXNjbzEOMAwGA1UECwwFZmQuaW8xFjAUBgNVBAMMDXRlc3R0bHMuZmQuaW8x
+IjAgBgkqhkiG9w0BCQEWE3ZwcC1kZXZAbGlzdHMuZmQuaW8wHhcNMTgwMzA1MjEx
+NTEyWhcNMjgwMzAyMjExNTEyWjCBiTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNB
+MREwDwYDVQQHDAhTYW4gSm9zZTEOMAwGA1UECgwFQ2lzY28xDjAMBgNVBAsMBWZk
+LmlvMRYwFAYDVQQDDA10ZXN0dGxzLmZkLmlvMSIwIAYJKoZIhvcNAQkBFhN2cHAt
+ZGV2QGxpc3RzLmZkLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+4C1k8a1DuStgggqT4o09fP9sJ2dC54bxhS/Xk2VEfaIZ222WSo4X/syRVfVy9Yah
+cpI1zJ/RDxaZSFhgA+nPZBrFMsrULkrdAOpOVj8eDEp9JuWdO2ODSoFnCvLxcYWB
+Yc5kHryJpEaGJl1sFQSesnzMFty/59ta0stk0Fp8r5NhIjWvSovGzPo6Bhz+VS2c
+ebIZh4x1t2hHaFcgm0qJoJ6DceReWCW8w+yOVovTolGGq+bpb2Hn7MnRSZ2K2NdL
++aLXpkZbS/AODP1FF2vTO1mYL290LO7/51vJmPXNKSDYMy5EvILr5/VqtjsFCwRL
+Q4jcM/+GeHSAFWx4qIv0BwIDAQABo1AwTjAdBgNVHQ4EFgQUWa1SOB37xmT53tZQ
+aXuLLhRI7U8wHwYDVR0jBBgwFoAUWa1SOB37xmT53tZQaXuLLhRI7U8wDAYDVR0T
+BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAoUht13W4ya27NVzQuCMvqPWL3VM4
+3xbPFk02FaGz/WupPu276zGlzJAZrbuDcQowwwU1Ni1Yygxl96s1c2M5rHDTrOKG
+rK0hbkSFBo+i6I8u4HiiQ4rYmG0Hv6+sXn3of0HsbtDPGgWZoipPWDljPYEURu3e
+3HRe/Dtsj9CakBoSDzs8ndWaBR+f4sM9Tk1cjD46Gq2T/qpSPXqKxEUXlzhdCAn4
+twub17Bq2kykHpppCwPg5M+v30tHG/R2Go15MeFWbEJthFk3TZMjKL7UFs7fH+x2
+wSonXb++jY+KmCb93C+soABBizE57g/KmiR2IxQ/LMjDik01RSUIaM0lLA==
+-----END CERTIFICATE-----
diff --git a/configs/tls-test-key b/configs/tls-test-key
new file mode 100644
index 0000000..59d441b
--- /dev/null
+++ b/configs/tls-test-key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgLWTxrUO5K2CC
+CpPijT18/2wnZ0LnhvGFL9eTZUR9ohnbbZZKjhf+zJFV9XL1hqFykjXMn9EPFplI
+WGAD6c9kGsUyytQuSt0A6k5WPx4MSn0m5Z07Y4NKgWcK8vFxhYFhzmQevImkRoYm
+XWwVBJ6yfMwW3L/n21rSy2TQWnyvk2EiNa9Ki8bM+joGHP5VLZx5shmHjHW3aEdo
+VyCbSomgnoNx5F5YJbzD7I5Wi9OiUYar5ulvYefsydFJnYrY10v5otemRltL8A4M
+/UUXa9M7WZgvb3Qs7v/nW8mY9c0pINgzLkS8guvn9Wq2OwULBEtDiNwz/4Z4dIAV
+bHioi/QHAgMBAAECggEBAMzGipP8+oT166U+NlJXRFifFVN1DvdhG9PWnOxGL+c3
+ILmBBC08WQzmHshPemBvR6DZkA1H23cV5JTiLWrFtC00CvhXsLRMrE5+uWotI6yE
+iofybMroHvD6/X5R510UX9hQ6MHu5ShLR5VZ9zXHz5MpTmB/60jG5dLx+jgcwBK8
+LuGv2YB/WCUwT9QJ3YU2eaingnXtz/MrFbkbltrqlnBdlD+kTtw6Yac9y1XuuQXc
+BPeulLNDuPolJVWbUvDBZrpt2dXTgz8ws1sv+wCNE0xwQJsqW4Nx3QkpibUL9RUr
+CVbKlNfa9lopT6nGKlgX69R/uH35yh9AOsfasro6w0ECgYEA82UJ8u/+ORah+0sF
+Q0FfW5MTdi7OAUHOz16pUsGlaEv0ERrjZxmAkHA/VRwpvDBpx4alCv0Hc39PFLIk
+nhSsM2BEuBkTAs6/GaoNAiBtQVE/hN7awNRWVmlieS0go3Y3dzaE9IUMyj8sPOFT
+5JdJ6BM69PHKCkY3dKdnnfpFEuECgYEA68mRpteunF1mdZgXs+WrN+uLlRrQR20F
+ZyMYiUCH2Dtn26EzA2moy7FipIIrQcX/j+KhYNGM3e7MU4LymIO29E18mn8JODnH
+sQOXzBTsf8A4yIVMkcuQD3bfb0JiUGYUPOidTp2N7IJA7+6Yc3vQOyb74lnKnJoO
+gougPT2wS+cCgYAn7muzb6xFsXDhyW0Tm6YJYBfRS9yAWEuVufINobeBZPSl2cN1
+Jrnw+HlrfTNbrJWuJmjtZJXUXQ6cVp2rUbjutNyRV4vG6iRwEXYQ40EJdkr1gZpi
+CHQhuShuuPih2MNAy7EEbM+sXrDjTBR3bFqzuHPzu7dp+BshCFX3lRfAAQKBgGQt
+K5i7IhCFDjb/+3IPLgOAK7mZvsvZ4eXD33TQ2eZgtut1PXtBtNl17/b85uv293Fm
+VDISVcsk3eLNS8zIiT6afUoWlxAwXEs0v5WRfjl4radkGvgGiJpJYvyeM67877RB
+EDSKc/X8ESLfOB44iGvZUEMG6zJFscx9DgN25iQZAoGAbyd+JEWwdVH9/K3IH1t2
+PBkZX17kNWv+iVM1WyFjbe++vfKZCrOJiyiqhDeEqgrP3AuNMlaaduC3VRC3G5oV
+Mj1tlhDWQ/qhvKdCKNdIVQYDE75nw+FRWV8yYkHAnXYW3tNoweDIwixE0hkPR1bc
+oEjPLVNtx8SOj/M4rhaPT3I=
+-----END PRIVATE KEY-----
diff --git a/openssl_patches/0001-openssl3.0.0-alpha1.patch b/openssl_patches/0001-openssl3.0.0-alpha1.patch
new file mode 100644
index 0000000..f639104
--- /dev/null
+++ b/openssl_patches/0001-openssl3.0.0-alpha1.patch
@@ -0,0 +1,24 @@
+From 47904f922ac042c24d3c8d4ecfda15d902c48c2e Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <xiaolongx.jiang@intel.com>
+Date: Fri, 8 May 2020 07:06:30 +0000
+Subject: [PATCH] openssl3.0.0-alpha1
+
+Signed-off-by: xiaolongx.jiang <xiaolongx.jiang@intel.com>
+---
+ VERSION | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/VERSION b/VERSION
+index b7529b4..bfcd4fc 100644
+--- a/VERSION
++++ b/VERSION
+@@ -3,5 +3,5 @@ MINOR=0
+ PATCH=0
+ PRE_RELEASE_TAG=alpha1
+ BUILD_METADATA=
+-RELEASE_DATE="23 Apr 2020"
++RELEASE_DATE=23 Apr 2020
+ SHLIB_VERSION=3
+--
+2.17.1
+
diff --git a/packages/nginx-dl.mk b/packages/nginx-dl.mk
new file mode 100644
index 0000000..7fc7bd3
--- /dev/null
+++ b/packages/nginx-dl.mk
@@ -0,0 +1,20 @@
+# Copyright (c) 2020 Intel 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.
+
+nginx_version := 1.14.2
+nginx_tarball := nginx-$(nginx_version).tar.gz
+nginx_tarball_md5sum := 239b829a13cea1d244c1044e830bd9c2
+nginx_url := http://nginx.org/download/$(nginx_tarball)
+
+
+$(eval $(call download,nginx))
diff --git a/packages/nginx_ldp.mk b/packages/nginx_ldp.mk
new file mode 100644
index 0000000..cde52a2
--- /dev/null
+++ b/packages/nginx_ldp.mk
@@ -0,0 +1,69 @@
+# Copyright (c) 2020 Intel 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.
+
+nginx_ldp_version := 1.14.2
+nginx_ldp_src_dir := $(B)/nginx_ldp
+nginx_ldp_install_dir := $(I)/local/nginx
+nginx_ldp_deb_inst_dir := /usr/local/nginx
+nginx_ldp_pkg_deb_name := nginx
+nginx_ldp_pkg_deb_dir := $(I)/deb-ldp
+nginx_ldp_tarball := nginx-$(nginx_ldp_version).tar.gz
+nginx_ldp_tarball_strip_dirs := 1
+nginx_ldp_desc := "ldp nginx"
+
+
+define nginx_ldp_patch_cmds
+ @true
+endef
+
+define nginx_ldp_config_cmds
+ @cd $(nginx_ldp_src_dir); \
+ ./configure --prefix=$(nginx_ldp_install_dir) \
+ --with-http_stub_status_module \
+ --with-http_ssl_module
+endef
+
+define nginx_ldp_build_cmds
+ @$(MAKE) -C $(nginx_ldp_src_dir)
+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/.
+endef
+
+define nginx_ldp_pkg_deb_cmds
+ @fpm -f -s dir \
+ -t deb \
+ -n $(nginx_ldp_pkg_deb_name) \
+ -v $(nginx_ldp_version) \
+ -C $(nginx_ldp_install_dir) \
+ -p $(nginx_ldp_pkg_deb_dir) \
+ --prefix $(nginx_ldp_deb_inst_dir) \
+ --license $(LICENSE) \
+ --iteration $(LINUX_ITER) \
+ --vendor Intel \
+ --description $(nginx_ldp_desc) \
+ --deb-no-default-config-files \
+ --pre-install packages/pre-install
+endef
+
+define nginx_ldp_pkg_deb_cp_cmds
+ @echo "--- copy deb to $(CURDIR)/deb-ldp ---"
+ @cp $(nginx_ldp_pkg_deb_dir)/*.deb deb-ldp/.
+endef
+
+$(eval $(call package,nginx_ldp))
diff --git a/packages/nginx_vcl.mk b/packages/nginx_vcl.mk
new file mode 100644
index 0000000..031ada9
--- /dev/null
+++ b/packages/nginx_vcl.mk
@@ -0,0 +1,74 @@
+# Copyright (c) 2020 Intel 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.
+
+nginx_vcl_version := 1.14.2
+nginx_vcl_patch_dir := $(CURDIR)/nginx_patches
+nginx_vcl_src_dir := $(B)/nginx_vcl
+vpp_vcl_src_dir := $(CURDIR)/vpp
+nginx_vcl_install_dir := $(I)/local/nginx
+nginx_vcl_deb_inst_dir := /usr/local/nginx
+nginx_vcl_pkg_deb_name := nginx
+nginx_vcl_pkg_deb_dir := $(I)/deb-vcl
+nginx_vcl_tarball := nginx-$(nginx_vcl_version).tar.gz
+nginx_vcl_tarball_strip_dirs := 1
+nginx_vcl_desc := "vcl nginx"
+
+
+define nginx_vcl_patch_cmds
+ @for f in $(nginx_vcl_patch_dir)/*.patch ; do \
+ echo "Applying patch: $$(basename $$f)" ; \
+ patch -p2 -d $(nginx_vcl_src_dir) < $$f ; \
+ done
+endef
+
+define nginx_vcl_config_cmds
+ @cd $(nginx_vcl_src_dir); \
+ ./configure --prefix=$(nginx_vcl_install_dir) --with-vcl \
+ --vpp-lib-path=$(vpp_vcl_src_dir)/build-root/install-vpp-native/vpp/lib \
+ --vpp-src-path=$(vpp_vcl_src_dir)/src
+endef
+
+define nginx_vcl_build_cmds
+ @$(MAKE) -C $(nginx_vcl_src_dir)
+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/.
+endef
+
+define nginx_vcl_pkg_deb_cmds
+ @fpm -f -s dir \
+ -t deb \
+ -n $(nginx_vcl_pkg_deb_name) \
+ -v $(nginx_vcl_version) \
+ -C $(nginx_vcl_install_dir) \
+ -p $(nginx_vcl_pkg_deb_dir) \
+ --prefix $(nginx_vcl_deb_inst_dir) \
+ --license $(LICENSE) \
+ --iteration $(LINUX_ITER) \
+ --vendor Intel \
+ --description $(nginx_vcl_desc) \
+ --deb-no-default-config-files \
+ --pre-install packages/pre-install
+endef
+
+define nginx_vcl_pkg_deb_cp_cmds
+ @echo "--- copy deb to $(CURDIR)/deb-vcl ---"
+ @cp $(nginx_vcl_pkg_deb_dir)/*.deb deb-vcl/.
+endef
+
+$(eval $(call package,nginx_vcl))
diff --git a/packages/openssl-dl.mk b/packages/openssl-dl.mk
new file mode 100644
index 0000000..e7b8d5b
--- /dev/null
+++ b/packages/openssl-dl.mk
@@ -0,0 +1,19 @@
+# Copyright (c) 2020 Intel 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.
+
+openssl_version := 3.0.0-alpha1
+openssl_tarball := openssl-$(openssl_version).tar.gz
+openssl_tarball_md5sum := d9326bd068a0382193ab0cb1c6e4685b
+openssl_url := https://www.openssl.org/source/$(openssl_tarball)
+
+$(eval $(call download,openssl))
diff --git a/packages/openssl.mk b/packages/openssl.mk
new file mode 100644
index 0000000..37f2c84
--- /dev/null
+++ b/packages/openssl.mk
@@ -0,0 +1,46 @@
+# Copyright (c) 2020 Intel 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.
+
+openssl_version := 3.0.0-alpha1
+openssl_patch_dir := $(CURDIR)/openssl_patches
+openssl_install_dir := $(I)/local/ssl
+openssl_deb_inst_dir := /usr/local/ssl
+openssl_pkg_deb_name := openssl3
+openssl_pkg_deb_dir := $(I)/openssl-deb
+openssl_rpm_inst_dir := /usr/local/ssl
+openssl_pkg_rpm_name := openssl3
+openssl_pkg_rpm_dir := $(I)/openssl-rpm
+openssl_tarball := openssl-$(openssl_version).tar.gz
+openssl_tarball_md5sum := d9326bd068a0382193ab0cb1c6e4685b
+openssl_tarball_strip_dirs := 1
+openssl_url := https://www.openssl.org/source/$(openssl_tarball)
+openssl_desc := "openssl3.0.0"
+
+define openssl_config_cmds
+ @cd $(openssl_build_dir) && \
+ $(openssl_src_dir)/config \
+ --prefix=$(openssl_install_dir) shared zlib
+endef
+
+define openssl_build_cmds
+ @$(MAKE) -C $(openssl_build_dir) depend
+ @$(MAKE) -C $(openssl_build_dir)
+ @$(MAKE) -C $(openssl_build_dir) install
+endef
+
+define openssl_install_cmds
+ @true
+endef
+
+
+$(eval $(call package,openssl))
diff --git a/packages/package.mk b/packages/package.mk
new file mode 100644
index 0000000..95f5f34
--- /dev/null
+++ b/packages/package.mk
@@ -0,0 +1,64 @@
+# Copyright (c) 2020 Intel 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.
+define h1
+ @echo "--- $(1)"
+endef
+
+define download
+
+##############################################################################
+# Download
+##############################################################################
+ifeq ($$(call $1_download_cmds),)
+define $1_download_cmds
+ @if [ -e $(DL_CACHE_DIR)/$($1_tarball) ] ; \
+ then cp $(DL_CACHE_DIR)/$($1_tarball) $$@ ; \
+ else \
+ echo "Downloading $($1_url)" ; \
+ curl -o $$@ -LO $($1_url) ; \
+ fi
+endef
+endif
+
+downloads/$($1_tarball):
+ mkdir -p downloads
+ $$(call h1,"download $($1_tarball) ")
+ $$(call $1_download_cmds)
+ @rm -f $(B)/.$1.download.ok
+
+ifeq ($$(call $1_checksum_cmds),)
+define $1_checksum_cmds
+ $$(call h1,"validating $1 $($1_version) checksum")
+ @SUM=$$(shell openssl md5 $$< | cut -f 2 -d " " -) ; \
+ ([ "$$$${SUM}" = "$($1_tarball_md5sum)" ] || \
+ ( echo "========================================================" && \
+ echo "Bad Checksum!" && \
+ echo "Expected: $($1_tarball_md5sum)" && \
+ echo "Calculated: $$$${SUM}" && \
+ echo "Please remove $$< and retry" && \
+ echo "========================================================" && \
+ false ))
+endef
+endif
+
+$(B)/.$1.download.ok: downloads/$($1_tarball)
+ @mkdir -p $(B)
+ $$(call $1_checksum_cmds)
+ @touch $$@
+
+.PHONY: $1-dl
+$1-dl: $(B)/.$1.download.ok
+
+
+ALL_TARGETS += $1-dl
+endef
diff --git a/packages/packages.mk b/packages/packages.mk
new file mode 100644
index 0000000..79aed56
--- /dev/null
+++ b/packages/packages.mk
@@ -0,0 +1,173 @@
+# Copyright (c) 2020 Intel 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.
+define h1
+ @echo "--- $(1)"
+endef
+
+define package
+$1_tarball_strip_dirs ?= 0
+$1_src_dir ?= $(B)/src-$1
+$1_patch_dir ?= $(CURDIR)/patches/$1_$($1_version)
+$1_build_dir ?= $(B)/build-$1
+$1_install_dir ?= $(I)
+$1_pkg_deb_name ?= $1
+$1_pkg_deb_dir ?= $(I)/deb-$1
+$1_deb_inst_dir ?= $(I)
+$1_config_log ?= $(B)/$1.config.log
+$1_build_log ?= $(B)/$1.build.log
+$1_install_log ?= $(B)/$1.install.log
+$1_pkg_deb_log ?= $(B)/$1.pkgdeb.log
+$1_pkg_rpm_log ?= $(B)/$1.pkgrpm.log
+
+
+##############################################################################
+# Extract
+##############################################################################
+ifeq ($$(call $1_extract_cmds),)
+define $1_extract_cmds
+ $$(call h1,"extracting $1 $($1_version)")
+ @mkdir -p $$($1_src_dir)
+ tar \
+ --directory $$($1_src_dir) \
+ --extract \
+ --strip-components=$$($1_tarball_strip_dirs) \
+ --file downloads/$($1_tarball)
+endef
+endif
+
+$(B)/.$1.extract.ok:
+ $$(call h1,"extracting $1 $($1_version)")
+ $$(call $1_extract_cmds)
+ @touch $$@
+
+.PHONY: $1-extract
+$1-extract: $(B)/.$1.extract.ok
+
+##############################################################################
+# Patch
+##############################################################################
+ifeq ($$(call $1_patch_cmds),)
+define $1_patch_cmds
+#ifneq ($$(wildcard $$($1_patch_dir)/*.patch),)
+ @for f in $$($1_patch_dir)/*.patch ; do \
+ echo "Applying patch: $$$$(basename $$$$f)" ; \
+ patch -p1 -d $$($1_src_dir) < $$$$f ; \
+ done
+#endif
+ @true
+endef
+endif
+
+$(B)/.$1.patch.ok: $(B)/.$1.extract.ok
+ $$(call h1,"patching $1 $$($1_patch_dir)")
+ $$(call $1_patch_cmds)
+ @touch $$@
+
+.PHONY: $1-patch
+$1-patch: $(B)/.$1.patch.ok
+
+##############################################################################
+# Config
+##############################################################################
+
+ifeq ($$(call $1_config_cmds),)
+define $1_config_cmds
+ @cd $$($1_build_dir) && \
+ CFLAGS="$$($1_cflags)" \
+ $$($1_src_dir)/configure \
+ --prefix=$$($1_install_dir) \
+ $$($1_configure_args) > $$($1_config_log)
+endef
+endif
+
+$(B)/.$1.config.ok: $(B)/.$1.patch.ok $(addsuffix -install,$($1_depends))
+ $$(call h1,"configuring $1 - log: $$($1_config_log)")
+ @mkdir -p $$($1_build_dir)
+ $$(call $1_config_cmds)
+ @touch $$@
+
+.PHONY: $1-config
+$1-config: $(B)/.$1.config.ok
+
+##############################################################################
+# Build
+##############################################################################
+
+ifeq ($$(call $1_build_cmds),)
+define $1_build_cmds
+ @$(MAKE) $(MAKE_ARGS) -C $$($1_build_dir) > $$($1_build_log)
+endef
+endif
+
+$(B)/.$1.build.ok: $(B)/.$1.config.ok
+ $$(call h1,"building $1 $($1_version) - log: $$($1_build_log)")
+ $$(call $1_build_cmds)
+ @touch $$@
+
+.PHONY: $1-build
+$1-build: $(B)/.$1.build.ok
+
+##############################################################################
+# Install
+##############################################################################
+
+ifeq ($$(call $1_install_cmds),)
+define $1_install_cmds
+ @$(MAKE) $(MAKE_ARGS) -C $$($1_build_dir) install > $$($1_install_log)
+endef
+endif
+
+$(B)/.$1.install.ok: $(B)/.$1.build.ok
+ $$(call h1,"installing $1 $($1_version) - log: $$($1_install_log)")
+ $$(call $1_install_cmds)
+ @touch $$@
+
+.PHONY: $1-install
+$1-install: $(B)/.$1.install.ok
+
+ifeq ($$(call $1_pkg_deb_cmds),)
+define $1_pkg_deb_cmds
+ @fpm -f -s dir \
+ -t deb \
+ -n $$($1_pkg_deb_name) \
+ -v $$($1_version) \
+ -C $$($1_install_dir) \
+ -p $$($1_pkg_deb_dir) \
+ --prefix $$($1_deb_inst_dir) \
+ --license $(LICENSE) \
+ --iteration $(LINUX_ITER) \
+ --vendor Intel \
+ --description $$($1_desc) \
+ --deb-no-default-config-files
+ @true
+endef
+endif
+
+ifeq ($$(call $1_pkg_deb_cp_cmds),)
+define $1_pkg_deb_cp_cmds
+ @true
+endef
+endif
+
+$(B)/.$1.pkg-deb.ok: $(B)/.$1.install.ok
+ $$(call h1,"package $1 $($1_version) - log: $$($1_pkg_deb_log)")
+ @mkdir -p $$($1_pkg_deb_dir)
+ $$(call $1_pkg_deb_cmds)
+ $$(call $1_pkg_deb_cp_cmds)
+ @touch $$@
+
+.PHONY: $1-deb
+$1-deb: $(B)/.$1.pkg-deb.ok
+
+ALL_TARGETS += $1-deb
+endef
diff --git a/packages/pre-install b/packages/pre-install
new file mode 100644
index 0000000..a7f6471
--- /dev/null
+++ b/packages/pre-install
@@ -0,0 +1,9 @@
+#!/bin/bash
+set -x
+
+# kill nginx.
+retval=$(ps -A | grep nginx | grep -v grep | awk '{print $1}' | wc -l)
+if [[ $retval -ne 0 ]]; then
+ ps -A | grep nginx | grep -v grep | awk '{print $1}' | xargs kill -9
+fi
+
diff --git a/packages/vpp_ldp.mk b/packages/vpp_ldp.mk
new file mode 100644
index 0000000..cdf6307
--- /dev/null
+++ b/packages/vpp_ldp.mk
@@ -0,0 +1,105 @@
+# Copyright (c) 2020 Intel 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.
+
+vpp_ldp_patch_dir := $(CURDIR)/vpp_patches
+vpp_ldp_src_dir := $(CURDIR)/vpp
+vpp_ldp_install_dir := $(I)/local
+vpp_ldp_pkg_deb_name := vpp
+vpp_ldp_pkg_deb_dir := $(CURDIR)/vpp/build-root
+vpp_ldp_desc := "ldp vpp"
+
+
+define vpp_ldp_extract_cmds
+ @true
+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 [ ! -z $(_VPP_VER) ] ; then \
+ echo "--- vpp version: $(_VPP_VER) ---"; \
+ git checkout remotes/origin/stable/$(_VPP_VER); \
+ git reset --hard; git clean -f; \
+ fi
+ @for f in $(CURDIR)/vpp_patches/common/*.patch ; do \
+ echo Applying patch: $$(basename $$f) ; \
+ patch -p1 -d $(vpp_ldp_src_dir) < $$f ; \
+ done
+ @if [ -z $(_VPP_VER) ]; then \
+ echo "--- vpp master ---"; \
+ for f in $(CURDIR)/vpp_patches/common/master/*.patch ; do \
+ echo Applying patch: $$(basename $$f) ; \
+ patch -p1 -d $(vpp_ldp_src_dir) < $$f ; \
+ done; \
+ elif [ $(_VPP_VER) = "2001" ]; then \
+ echo "--- vpp 20.01 ---"; \
+ for f in $(CURDIR)/vpp_patches/common/2001/*.patch ; do \
+ echo Applying patch: $$(basename $$f) ; \
+ patch -p1 -d $(vpp_ldp_src_dir) < $$f ; \
+ done; \
+ fi
+ @if [ -z $(_VPP_VER) ]; 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) = "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
+
+
+define vpp_ldp_config_cmds
+ @true
+endef
+
+define vpp_ldp_build_cmds
+ @cd $(vpp_ldp_src_dir); \
+ echo "---build : $(vpp_ldp_src_dir)"; \
+ export OPENSSL_ROOT_DIR=$(I)/local/ssl; \
+ export LD_LIBRARY_PATH=$(I)/local/ssl/lib; \
+ $(MAKE) wipe-release; \
+ rm -f $(vpp_ldp_pkg_deb_dir)/*.deb; \
+ $(MAKE) build-release; \
+ $(MAKE) pkg-deb; \
+ echo "--- Please wait for the final completion ..."; \
+ cd ..; rm -rf $(vcl_vpp_install_dir)/vpp; \
+ cp -rf vpp $(vcl_vpp_install_dir); \
+ echo "--- Completed! ---"
+
+endef
+
+define vpp_ldp_install_cmds
+ @true
+endef
+
+define vpp_ldp_pkg_deb_cmds
+ @true
+endef
+
+define vpp_ldp_pkg_deb_cp_cmds
+ @echo "--- copy deb to $(CURDIR)/deb-ldp ---"
+ @mkdir -p deb-ldp
+ @ls deb-ldp/ ;rm -f deb-ldp/*
+ @cp $(I)/openssl-deb/*.deb deb-ldp/.
+ @cp $(vpp_ldp_pkg_deb_dir)/*.deb deb-ldp/.
+endef
+
+$(eval $(call package,vpp_ldp))
diff --git a/packages/vpp_vcl.mk b/packages/vpp_vcl.mk
new file mode 100644
index 0000000..9b83678
--- /dev/null
+++ b/packages/vpp_vcl.mk
@@ -0,0 +1,96 @@
+# Copyright (c) 2020 Intel 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.
+
+vpp_vcl_patch_dir := $(CURDIR)/vpp_patches
+vpp_vcl_src_dir := $(CURDIR)/vpp
+vpp_vcl_install_dir := $(I)/local
+vpp_vcl_pkg_deb_name := vpp
+vpp_vcl_pkg_deb_dir := $(CURDIR)/vpp/build-root
+vpp_vcl_desc := "vcl vpp"
+
+
+define vpp_vcl_extract_cmds
+ @true
+endef
+
+define vpp_vcl_patch_cmds
+ @echo "--- vpp patching ---"
+ @cd $(vpp_vcl_src_dir); \
+ git reset --hard; git clean -f; git checkout master; \
+ if [ ! -z $(_VPP_VER) ]; then \
+ echo "--- vpp version: $(_VPP_VER) ---"; \
+ git checkout origin/stable/$(_VPP_VER); \
+ git reset --hard; git clean -f; \
+ fi
+ @for f in $(CURDIR)/vpp_patches/common/*.patch ; do \
+ echo Applying patch: $$(basename $$f) ; \
+ patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \
+ done
+ @if [ -z $(_VPP_VER) ]; then \
+ echo "--- vpp master ---"; \
+ for f in $(CURDIR)/vpp_patches/common/master/*.patch ; do \
+ echo Applying patch: $$(basename $$f) ; \
+ patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \
+ done; \
+ elif [ $(_VPP_VER) = "2001" ]; then \
+ echo "--- vpp 20.01 ---"; \
+ for f in $(CURDIR)/vpp_patches/common/2001/*.patch ; do \
+ echo Applying patch: $$(basename $$f) ; \
+ patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \
+ done; \
+ fi
+ @for f in $(CURDIR)/vpp_patches/vcl/*.patch ; do \
+ echo Applying patch: $$(basename $$f) ; \
+ patch -p1 -d $(vpp_vcl_src_dir) < $$f ; \
+ done
+
+ @true
+endef
+
+
+define vpp_vcl_config_cmds
+ @true
+endef
+
+define vpp_vcl_build_cmds
+ @cd $(vpp_vcl_src_dir); \
+ echo "--- build : $(vpp_vcl_src_dir)"; \
+ export OPENSSL_ROOT_DIR=$(I)/local/ssl; \
+ export LD_LIBRARY_PATH=$(I)/local/ssl/lib; \
+ $(MAKE) wipe-release; \
+ rm -f $(vpp_vcl_pkg_deb_dir)/*.deb; \
+ $(MAKE) build-release; \
+ $(MAKE) pkg-deb; \
+ echo "--- Please wait for the final completion ..."; \
+ cd ..; rm -rf $(vpp_vcl_install_dir)/vpp; \
+ cp -rf vpp $(vpp_vcl_install_dir); \
+ echo "--- Completed! ---"
+endef
+
+define vpp_vcl_install_cmds
+ @true
+endef
+
+define vpp_vcl_pkg_deb_cmds
+ @true
+endef
+
+define vpp_vcl_pkg_deb_cp_cmds
+ @echo "--- copy deb to $(CURDIR)/dev-vcl ---"
+ @mkdir -p deb-vcl
+ @rm -f deb-vcl/*
+ @cp $(I)/openssl-deb/*.deb deb-vcl/.
+ @cp $(vpp_vcl_pkg_deb_dir)/*.deb deb-vcl/.
+endef
+
+$(eval $(call package,vpp_vcl))
diff --git a/vpp b/vpp
new file mode 160000
+Subproject 73a60b2da44847f3725d362a49207330d4d22aa
diff --git a/vpp_patches/common/0001-3.0.0.patch b/vpp_patches/common/0001-3.0.0.patch
new file mode 100644
index 0000000..69fd197
--- /dev/null
+++ b/vpp_patches/common/0001-3.0.0.patch
@@ -0,0 +1,113 @@
+From ff2148e2aec6c8fb9717f655aee424d9ec59f802 Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <xiaolongx.jiang@intel.com>
+Date: Wed, 13 May 2020 09:42:07 +0000
+Subject: [PATCH] 3.0.0
+
+Signed-off-by: xiaolongx.jiang <xiaolongx.jiang@intel.com>
+---
+ 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/common/0002-src-pkg-debian-rules.in.patch b/vpp_patches/common/0002-src-pkg-debian-rules.in.patch
new file mode 100644
index 0000000..7010b5d
--- /dev/null
+++ b/vpp_patches/common/0002-src-pkg-debian-rules.in.patch
@@ -0,0 +1,27 @@
+From 8b808809f3608470f0df77f73aed784d2b160a9e Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <xiaolongx.jiang@intel.com>
+Date: Sun, 22 Mar 2020 12:23:44 +0000
+Subject: [PATCH] src-pkg-debian-rules.in
+
+---
+ src/pkg/debian/rules.in | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/pkg/debian/rules.in b/src/pkg/debian/rules.in
+index ceef46a29..83d6f66fe 100755
+--- a/src/pkg/debian/rules.in
++++ b/src/pkg/debian/rules.in
+@@ -27,6 +27,10 @@ override_dh_strip:
+
+ DEB_HOST_MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
+
++override_dh_shlibdeps:
++ dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info
++
++
+ override_dh_install:
+ @for c in @VPP_COMPONENTS@; do \
+ @CMAKE_COMMAND@ \
+--
+2.17.1
+
diff --git a/vpp_patches/common/2001/0001-quick-0.0.9.patch b/vpp_patches/common/2001/0001-quick-0.0.9.patch
new file mode 100644
index 0000000..4f8a082
--- /dev/null
+++ b/vpp_patches/common/2001/0001-quick-0.0.9.patch
@@ -0,0 +1,45 @@
+From b20dfd9f921be04b03899959bdf3feba5376c4c3 Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <xiaolongx.jiang@intel.com>
+Date: Wed, 13 May 2020 06:22:06 +0000
+Subject: [PATCH] quick 0.0.9
+
+Signed-off-by: xiaolongx.jiang <xiaolongx.jiang@intel.com>
+---
+ .../0001-picotls-openssl-3.0.0.patch | 25 +++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+ create mode 100644 build/external/patches/quicly_0.0.9-vpp/0001-picotls-openssl-3.0.0.patch
+
+diff --git a/build/external/patches/quicly_0.0.9-vpp/0001-picotls-openssl-3.0.0.patch b/build/external/patches/quicly_0.0.9-vpp/0001-picotls-openssl-3.0.0.patch
+new file mode 100644
+index 000000000..d998fb852
+--- /dev/null
++++ b/build/external/patches/quicly_0.0.9-vpp/0001-picotls-openssl-3.0.0.patch
+@@ -0,0 +1,25 @@
++From e99a421de5a66bd4af275c1ff77c2a3764febdf4 Mon Sep 17 00:00:00 2001
++From: "xiaolongx.jiang" <xiaolongx.jiang@intel.com>
++Date: Fri, 8 May 2020 08:25:12 +0000
++Subject: [PATCH] picotls: openssl-3.0.0
++
++Signed-off-by: xiaolongx.jiang <xiaolongx.jiang@intel.com>
++---
++ .../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/common/master/0001-picotls-patch.patch b/vpp_patches/common/master/0001-picotls-patch.patch
new file mode 100644
index 0000000..9811fbc
--- /dev/null
+++ b/vpp_patches/common/master/0001-picotls-patch.patch
@@ -0,0 +1,45 @@
+From 9f3edc2ca7eb417b46ab40beac45838ee58cc223 Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <xiaolongx.jiang@intel.com>
+Date: Fri, 8 May 2020 10:01:36 +0000
+Subject: [PATCH] picotls: patch
+
+Signed-off-by: xiaolongx.jiang <xiaolongx.jiang@intel.com>
+---
+ .../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" <xiaolongx.jiang@intel.com>
++Date: Fri, 8 May 2020 08:25:12 +0000
++Subject: [PATCH] picotls: openssl-3.0.0
++
++Signed-off-by: xiaolongx.jiang <xiaolongx.jiang@intel.com>
++---
++ .../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/ldp/0001-LDP-remove-lock.patch b/vpp_patches/ldp/2001/0001-LDP-remove-lock.patch
index 091bc78..091bc78 100644
--- a/vpp_patches/ldp/0001-LDP-remove-lock.patch
+++ b/vpp_patches/ldp/2001/0001-LDP-remove-lock.patch
diff --git a/vpp_patches/ldp/master/0001-LDP-remove-lock.patch b/vpp_patches/ldp/master/0001-LDP-remove-lock.patch
new file mode 100644
index 0000000..feb3502
--- /dev/null
+++ b/vpp_patches/ldp/master/0001-LDP-remove-lock.patch
@@ -0,0 +1,4909 @@
+From d9fffb4761489abc5976df0eac82fa6280a187cc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=E2=80=9Czsj=E2=80=9D?= <“reGliming@gmail.com”>
+Date: Mon, 27 Apr 2020 15:00:15 +0800
+Subject: [PATCH] LDP remove lock
+
+---
+ src/vcl/CMakeLists.txt | 5 +-
+ src/vcl/ldp.c | 740 +++++++----
+ src/vcl/ldp.c.orig | 2520 ++++++++++++++++++++++++++++++++++++
+ src/vcl/ldp.h | 2 +-
+ src/vcl/vcl_private.h | 7 +-
+ src/vcl/vcl_private.h.orig | 679 ++++++++++
+ 6 files changed, 3693 insertions(+), 260 deletions(-)
+ create mode 100644 src/vcl/ldp.c.orig
+ create mode 100644 src/vcl/vcl_private.h.orig
+
+diff --git a/src/vcl/CMakeLists.txt b/src/vcl/CMakeLists.txt
+index ab0a6ad6a..0d30eb6af 100644
+--- a/src/vcl/CMakeLists.txt
++++ b/src/vcl/CMakeLists.txt
+@@ -20,7 +20,6 @@ add_vpp_library(vppcom
+ vcl_bapi.c
+ vcl_cfg.c
+ vcl_private.c
+- vcl_locked.c
+
+ LINK_LIBRARIES
+ vppinfra svm vlibmemoryclient rt pthread
+@@ -41,7 +40,7 @@ add_vpp_library(vcl_ldpreload
+ add_vpp_headers(vcl
+ ldp.h
+ ldp_glibc_socket.h
++ vcl_private.h
+ vppcom.h
+- vcl_locked.h
+ ldp_socket_wrapper.h
+-)
+\ No newline at end of file
++)
+diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c
+index c23f995d5..bbd8adff9 100644
+--- a/src/vcl/ldp.c
++++ b/src/vcl/ldp.c
+@@ -24,9 +24,10 @@
+
+ #include <vcl/ldp_socket_wrapper.h>
+ #include <vcl/ldp.h>
++#include <vcl/vppcom.h>
++#include <vcl/vcl_private.h>
+ #include <sys/time.h>
+
+-#include <vcl/vcl_locked.h>
+ #include <vppinfra/time.h>
+ #include <vppinfra/bitmap.h>
+ #include <vppinfra/lock.h>
+@@ -96,8 +97,8 @@ typedef struct
+ ldp_worker_ctx_t *workers;
+ int init;
+ char app_name[LDP_APP_NAME_MAX];
+- u32 vlsh_bit_val;
+- u32 vlsh_bit_mask;
++ u32 vcl_bit_val;
++ u32 vcl_bit_mask;
+ u32 debug;
+ u8 transparent_tls;
+
+@@ -116,8 +117,8 @@ typedef struct
+ }
+
+ static ldp_main_t ldp_main = {
+- .vlsh_bit_val = (1 << LDP_SID_BIT_MIN),
+- .vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
++ .vcl_bit_val = (1 << LDP_SID_BIT_MIN),
++ .vcl_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
+ .debug = LDP_DEBUG_INIT,
+ .transparent_tls = 0,
+ };
+@@ -150,18 +151,18 @@ ldp_get_app_name ()
+ }
+
+ static inline int
+-ldp_vlsh_to_fd (vls_handle_t vlsh)
++ldp_vclsh_to_fd (vcl_session_handle_t vclsh)
+ {
+- return (vlsh + ldp->vlsh_bit_val);
++ return (vclsh + ldp->vcl_bit_val);
+ }
+
+-static inline vls_handle_t
+-ldp_fd_to_vlsh (int fd)
++static inline vcl_session_handle_t
++ldp_fd_to_vclsh (int fd)
+ {
+- if (fd < ldp->vlsh_bit_val)
+- return VLS_INVALID_HANDLE;
++ if (fd < (ldp->vcl_bit_val))
++ return INVALID_SESSION_ID;
+
+- return (fd - ldp->vlsh_bit_val);
++ return (fd - ldp->vcl_bit_val);
+ }
+
+ static void
+@@ -172,6 +173,194 @@ ldp_alloc_workers (void)
+ pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
+ }
+
++static void
++ldp_share_listen_session (vcl_worker_t * parent_wrk,
++ vcl_worker_t * child_wrk,
++ vcl_session_t * listen_session)
++{
++/*Find the listen session of parent worker*/
++ if (listen_session->session_index == parent_wrk->listen_session_index)
++ {
++ listen_session->session_state = STATE_LISTEN_NO_MQ;
++ vppcom_session_listen (vcl_session_handle_from_index
++ (parent_wrk->listen_session_index),
++ parent_wrk->listen_queue_size);
++ }
++}
++
++void
++ldp_vcl_worker_copy_on_fork (vcl_worker_t * parent_wrk)
++{
++ vcl_worker_t *wrk = vcl_worker_get_current ();
++ vcl_session_t *listen_session;
++ 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);
++/*Update listen session for child*/
++ pool_foreach (listen_session, wrk->sessions, (
++ {
++ ldp_share_listen_session
++ (parent_wrk, wrk,
++ listen_session);}));
++}
++
++static void
++ldp_cleanup_vcl_worker (vcl_worker_t * wrk)
++{
++ vcl_worker_cleanup (wrk, 1 /* notify vpp */ );
++}
++
++static void
++ldp_cleanup_forked_child (vcl_worker_t * wrk, vcl_worker_t * child_wrk)
++{
++ vcl_worker_t *sub_child;
++ int tries = 0;
++
++ if (child_wrk->forked_child != ~0)
++ {
++ sub_child = vcl_worker_get_if_valid (child_wrk->forked_child);
++ if (sub_child)
++ {
++ /* Wait a bit, maybe the process is going away */
++ while (kill (sub_child->current_pid, 0) >= 0 && tries++ < 50)
++ usleep (1e3);
++ if (kill (sub_child->current_pid, 0) < 0)
++ ldp_cleanup_forked_child (child_wrk, sub_child);
++ }
++ }
++ ldp_cleanup_vcl_worker (child_wrk);
++ VDBG (0, "Cleaned up forked child wrk %u", child_wrk->wrk_index);
++ wrk->forked_child = ~0;
++}
++
++static struct sigaction old_sa;
++
++static void
++ldp_intercept_sigchld_handler (int signum, siginfo_t * si, void *uc)
++{
++ vcl_worker_t *wrk, *child_wrk;
++
++ if (vcl_get_worker_index () == ~0)
++ return;
++
++ /*restore sigchld */
++ if (sigaction (SIGCHLD, &old_sa, 0))
++ {
++ VERR ("couldn't restore sigchld");
++ exit (-1);
++ }
++
++ wrk = vcl_worker_get_current ();
++ if (wrk->forked_child == ~0)
++ return;
++
++ child_wrk = vcl_worker_get_if_valid (wrk->forked_child);
++ if (!child_wrk)
++ goto done;
++
++ if (si && si->si_pid != child_wrk->current_pid)
++ {
++ VDBG (0, "unexpected child pid %u", si->si_pid);
++ goto done;
++ }
++ ldp_cleanup_forked_child (wrk, child_wrk);
++
++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);
++ }
++}
++
++/*Intercept signal SIGCHLD*/
++static void
++ldp_intercept_sigchld ()
++{
++ struct sigaction sa;
++ clib_memset (&sa, 0, sizeof (sa));
++ /*set SA_SIGINFO to validate sa.sa_sigaction rather than sa.sa_handler */
++ sa.sa_sigaction = ldp_intercept_sigchld_handler;
++ sa.sa_flags = SA_SIGINFO;
++ /*When current process receive the SIGCHLD signal, it would call
++ **ldp_intercept_sigchld_handler.
++ */
++ if (sigaction (SIGCHLD, &sa, &old_sa))
++ {
++ VERR ("couldn't intercept sigchld");
++ exit (-1);
++ }
++}
++
++static void
++ldp_app_pre_fork (void)
++{
++ ldp_intercept_sigchld ();
++ vcl_flush_mq_events ();
++}
++
++static void
++ldp_app_fork_parent_handler (void)
++{
++ vcl_session_t *listen_session;
++ vcl_worker_t *wrk = vcl_worker_get_current ();
++ listen_session = vcl_session_get (wrk, wrk->listen_session_index);
++ listen_session->session_state = STATE_LISTEN_NO_MQ;
++ vcl_send_session_unlisten (wrk, listen_session);
++ vcm->forking = 1;
++ while (vcm->forking)
++ ;
++
++}
++
++static void
++ldp_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 (pid) %u with parent wrk (vcl worker index) %u",
++ getpid (), parent_wrk_index);
++
++/*Allocate vcl worker for child*/
++ vcl_set_worker_index (~0);
++ if (!vcl_worker_alloc_and_init ())
++ VERR ("couldn't allocate new worker for child process %u", getpid ());
++
++/*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 new allocated vcl worker with VPP
++*/
++ vcl_worker_register_with_vpp ();
++ parent_wrk = vcl_worker_get (parent_wrk_index);
++ ldp_vcl_worker_copy_on_fork (parent_wrk);
++ parent_wrk->forked_child = vcl_get_worker_index ();
++ VDBG (0, "forked child main worker initialized");
++ vcm->forking = 0;
++}
++
+ static inline int
+ ldp_init (void)
+ {
+@@ -183,7 +372,9 @@ ldp_init (void)
+
+ ldp->init = 1;
+ ldp->vcl_needs_real_epoll = 1;
+- rv = vls_app_create (ldp_get_app_name ());
++ rv = vppcom_app_create (ldp_get_app_name ());
++ pthread_atfork (ldp_app_pre_fork, ldp_app_fork_parent_handler,
++ ldp_app_fork_child_handler);
+ if (rv != VPPCOM_OK)
+ {
+ ldp->vcl_needs_real_epoll = 0;
+@@ -230,43 +421,43 @@ ldp_init (void)
+ {
+ LDBG (0, "WARNING: Invalid LDP sid bit specified in the env var "
+ LDP_ENV_SID_BIT " (%s)! sid bit value %d (0x%x)", env_var_str,
+- ldp->vlsh_bit_val, ldp->vlsh_bit_val);
++ ldp->vcl_bit_val, ldp->vcl_bit_val);
+ }
+ else if (sb < LDP_SID_BIT_MIN)
+ {
+- ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MIN);
+- ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
++ ldp->vcl_bit_val = (1 << LDP_SID_BIT_MIN);
++ ldp->vcl_bit_mask = ldp->vcl_bit_val - 1;
+
+ LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
+ LDP_ENV_SID_BIT " (%s) is too small. Using LDP_SID_BIT_MIN"
+ " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
+- LDP_SID_BIT_MIN, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
++ LDP_SID_BIT_MIN, ldp->vcl_bit_val, ldp->vcl_bit_val);
+ }
+ else if (sb > LDP_SID_BIT_MAX)
+ {
+- ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MAX);
+- ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
++ ldp->vcl_bit_val = (1 << LDP_SID_BIT_MAX);
++ ldp->vcl_bit_mask = ldp->vcl_bit_val - 1;
+
+ LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
+ LDP_ENV_SID_BIT " (%s) is too big. Using LDP_SID_BIT_MAX"
+ " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
+- LDP_SID_BIT_MAX, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
++ LDP_SID_BIT_MAX, ldp->vcl_bit_val, ldp->vcl_bit_val);
+ }
+ else
+ {
+- ldp->vlsh_bit_val = (1 << sb);
+- ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
++ ldp->vcl_bit_val = (1 << sb);
++ ldp->vcl_bit_mask = ldp->vcl_bit_val - 1;
+
+ LDBG (0, "configured LDP sid bit (%u) from "
+ LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", sb,
+- ldp->vlsh_bit_val, ldp->vlsh_bit_val);
++ ldp->vcl_bit_val, ldp->vcl_bit_val);
+ }
+
+ /* Make sure there are enough bits in the fd set for vcl sessions */
+- if (ldp->vlsh_bit_val > FD_SETSIZE / 2)
++ if (ldp->vcl_bit_val > FD_SETSIZE / 2)
+ {
+- LDBG (0, "ERROR: LDP vlsh bit value %d > FD_SETSIZE/2 %d!",
+- ldp->vlsh_bit_val, FD_SETSIZE / 2);
++ LDBG (0, "ERROR: LDP vclsh bit value %d > FD_SETSIZE/2 %d!",
++ ldp->vcl_bit_val, FD_SETSIZE / 2);
+ ldp->init = 0;
+ return -1;
+ }
+@@ -291,16 +482,16 @@ ldp_init (void)
+ int
+ close (int fd)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv, epfd;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+- epfd = vls_attr (vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
++ epfd = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ if (epfd > 0)
+ {
+ LDBG (0, "fd %d: calling libc_close: epfd %u", fd, epfd);
+@@ -311,7 +502,8 @@ close (int fd)
+ u32 size = sizeof (epfd);
+ epfd = 0;
+
+- (void) vls_attr (vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size);
++ (void) vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_LIBC_EPFD,
++ &epfd, &size);
+ }
+ }
+ else if (PREDICT_FALSE (epfd < 0))
+@@ -321,9 +513,9 @@ close (int fd)
+ goto done;
+ }
+
+- LDBG (0, "fd %d: calling vls_close: vlsh %u", fd, vlsh);
++ LDBG (0, "fd %d: calling vppcom_session_close: vclsh %u", fd, vclsh);
+
+- rv = vls_close (vlsh);
++ rv = vppcom_session_close (vclsh);
+ if (rv != VPPCOM_OK)
+ {
+ errno = -rv;
+@@ -343,16 +535,16 @@ done:
+ ssize_t
+ read (int fd, void *buf, size_t nbytes)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ ssize_t size;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+- size = vls_read (vlsh, buf, nbytes);
++ size = vppcom_session_read (vclsh, buf, nbytes);
+ if (size < 0)
+ {
+ errno = -size;
+@@ -371,18 +563,18 @@ ssize_t
+ readv (int fd, const struct iovec * iov, int iovcnt)
+ {
+ int rv = 0, i, total = 0;
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ ssize_t size = 0;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ for (i = 0; i < iovcnt; ++i)
+ {
+- rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
++ rv = vppcom_session_read (vclsh, iov[i].iov_base, iov[i].iov_len);
+ if (rv <= 0)
+ break;
+ else
+@@ -411,16 +603,16 @@ readv (int fd, const struct iovec * iov, int iovcnt)
+ ssize_t
+ write (int fd, const void *buf, size_t nbytes)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ ssize_t size = 0;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+- size = vls_write_msg (vlsh, (void *) buf, nbytes);
++ size = vppcom_session_write_msg (vclsh, (void *) buf, nbytes);
+ if (size < 0)
+ {
+ errno = -size;
+@@ -439,18 +631,19 @@ ssize_t
+ writev (int fd, const struct iovec * iov, int iovcnt)
+ {
+ ssize_t size = 0, total = 0;
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int i, rv = 0;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ for (i = 0; i < iovcnt; ++i)
+ {
+- rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
++ rv = vppcom_session_write_msg (vclsh, iov[i].iov_base,
++ iov[i].iov_len);
+ if (rv < 0)
+ break;
+ else
+@@ -485,7 +678,7 @@ int
+ fcntl (int fd, int cmd, ...)
+ #endif
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv = 0;
+ va_list ap;
+
+@@ -494,9 +687,9 @@ fcntl (int fd, int cmd, ...)
+
+ va_start (ap, cmd);
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- LDBG (0, "fd %u vlsh %d, cmd %u", fd, vlsh, cmd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ LDBG (0, "fd %u vclsh %d, cmd %u", fd, vclsh, cmd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ int flags = va_arg (ap, int);
+ u32 size;
+@@ -506,11 +699,13 @@ fcntl (int fd, int cmd, ...)
+ switch (cmd)
+ {
+ case F_SETFL:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
+ break;
+
+ case F_GETFL:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
+ if (rv == VPPCOM_OK)
+ rv = flags;
+ break;
+@@ -546,7 +741,7 @@ fcntl (int fd, int cmd, ...)
+ int
+ ioctl (int fd, unsigned long int cmd, ...)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ va_list ap;
+ int rv;
+
+@@ -555,13 +750,13 @@ ioctl (int fd, unsigned long int cmd, ...)
+
+ va_start (ap, cmd);
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ switch (cmd)
+ {
+ case FIONREAD:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_NREAD, 0, 0);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_NREAD, 0, 0);
+ break;
+
+ case FIONBIO:
+@@ -573,7 +768,9 @@ ioctl (int fd, unsigned long int cmd, ...)
+ * non-blocking, the flags should be read here and merged
+ * with O_NONBLOCK.
+ */
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_FLAGS, &flags,
++ &size);
+ }
+ break;
+
+@@ -603,7 +800,7 @@ ldp_select_init_maps (fd_set * __restrict original,
+ u32 n_bytes, uword * si_bits, uword * libc_bits)
+ {
+ uword si_bits_set, libc_bits_set;
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int fd;
+
+ clib_bitmap_validate (*vclb, minbits);
+@@ -616,11 +813,11 @@ ldp_select_init_maps (fd_set * __restrict original,
+ clib_bitmap_foreach (fd, *resultb, ({
+ if (fd > nfds)
+ break;
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh == VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh == INVALID_SESSION_ID)
+ clib_bitmap_set_no_check (*libcb, fd, 1);
+ else
+- *vclb = clib_bitmap_set (*vclb, vlsh_to_session_index (vlsh), 1);
++ *vclb = clib_bitmap_set (*vclb, vppcom_session_index (vclsh), 1);
+ }));
+ /* *INDENT-ON* */
+
+@@ -635,7 +832,7 @@ ldp_select_init_maps (fd_set * __restrict original,
+ always_inline int
+ ldp_select_vcl_map_to_libc (clib_bitmap_t * vclb, fd_set * __restrict libcb)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ uword si;
+ int fd;
+
+@@ -644,9 +841,9 @@ ldp_select_vcl_map_to_libc (clib_bitmap_t * vclb, fd_set * __restrict libcb)
+
+ /* *INDENT-OFF* */
+ clib_bitmap_foreach (si, vclb, ({
+- vlsh = vls_session_index_to_vlsh (si);
+- ASSERT (vlsh != VLS_INVALID_HANDLE);
+- fd = ldp_vlsh_to_fd (vlsh);
++ vclsh = vcl_session_handle_from_index (si);
++ ASSERT (vclsh != INVALID_SESSION_ID);
++ fd = ldp_vclsh_to_fd (vclsh);
+ if (PREDICT_FALSE (fd < 0))
+ {
+ errno = EBADFD;
+@@ -719,7 +916,7 @@ ldp_pselect (int nfds, fd_set * __restrict readfds,
+ else
+ time_out = -1;
+
+- if (nfds <= ldp->vlsh_bit_val)
++ if (nfds <= ldp->vcl_bit_val)
+ {
+ rv = libc_pselect (nfds, readfds, writefds, exceptfds,
+ timeout, sigmask);
+@@ -769,9 +966,10 @@ ldp_pselect (int nfds, fd_set * __restrict readfds,
+ vec_len (ldpw->si_ex_bitmap) *
+ sizeof (clib_bitmap_t));
+
+- rv = vls_select (si_bits, readfds ? ldpw->rd_bitmap : NULL,
+- writefds ? ldpw->wr_bitmap : NULL,
+- exceptfds ? ldpw->ex_bitmap : NULL, vcl_timeout);
++ rv = vppcom_select (si_bits, readfds ? ldpw->rd_bitmap : NULL,
++ writefds ? ldpw->wr_bitmap : NULL,
++ exceptfds ? ldpw->ex_bitmap : NULL,
++ vcl_timeout);
+ if (rv < 0)
+ {
+ errno = -rv;
+@@ -883,7 +1081,7 @@ pselect (int nfds, fd_set * __restrict readfds,
+ /* If transparent TLS mode is turned on, then ldp will load key and cert.
+ */
+ static int
+-load_tls_cert (vls_handle_t vlsh)
++load_tls_cert (vcl_session_handle_t vclsh)
+ {
+ char *env_var_str = getenv (LDP_ENV_TLS_CERT);
+ char inbuf[4096];
+@@ -901,7 +1099,7 @@ load_tls_cert (vls_handle_t vlsh)
+ }
+ cert_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
+ tls_cert = inbuf;
+- vppcom_session_tls_add_cert (vlsh_to_session_index (vlsh), tls_cert,
++ vppcom_session_tls_add_cert (vppcom_session_index (vclsh), tls_cert,
+ cert_size);
+ fclose (fp);
+ }
+@@ -915,7 +1113,7 @@ load_tls_cert (vls_handle_t vlsh)
+ }
+
+ static int
+-load_tls_key (vls_handle_t vlsh)
++load_tls_key (vcl_session_handle_t vclsh)
+ {
+ char *env_var_str = getenv (LDP_ENV_TLS_KEY);
+ char inbuf[4096];
+@@ -933,7 +1131,7 @@ load_tls_key (vls_handle_t vlsh)
+ }
+ key_size = fread (inbuf, sizeof (char), sizeof (inbuf), fp);
+ tls_key = inbuf;
+- vppcom_session_tls_add_key (vlsh_to_session_index (vlsh), tls_key,
++ vppcom_session_tls_add_key (vppcom_session_index (vclsh), tls_key,
+ key_size);
+ fclose (fp);
+ }
+@@ -950,7 +1148,7 @@ socket (int domain, int type, int protocol)
+ {
+ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
+ u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+@@ -967,25 +1165,26 @@ socket (int domain, int type, int protocol)
+ proto = ((sock_type == SOCK_DGRAM) ?
+ VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
+
+- LDBG (0, "calling vls_create: proto %u (%s), is_nonblocking %u",
++ LDBG (0,
++ "calling vppcom_session_create: proto %u (%s), is_nonblocking %u",
+ proto, vppcom_proto_str (proto), is_nonblocking);
+
+- vlsh = vls_create (proto, is_nonblocking);
+- if (vlsh < 0)
++ vclsh = vppcom_session_create (proto, is_nonblocking);
++ if (vclsh < 0)
+ {
+- errno = -vlsh;
++ errno = -vclsh;
+ rv = -1;
+ }
+ else
+ {
+ if (ldp->transparent_tls)
+ {
+- if (load_tls_cert (vlsh) < 0 || load_tls_key (vlsh) < 0)
++ if (load_tls_cert (vclsh) < 0 || load_tls_key (vclsh) < 0)
+ {
+ return -1;
+ }
+ }
+- rv = ldp_vlsh_to_fd (vlsh);
++ rv = ldp_vclsh_to_fd (vclsh);
+ }
+ }
+ else
+@@ -1031,14 +1230,14 @@ socketpair (int domain, int type, int protocol, int fds[2])
+ int
+ bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ vppcom_endpt_t ep;
+
+@@ -1047,8 +1246,8 @@ bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+ case AF_INET:
+ if (len != sizeof (struct sockaddr_in))
+ {
+- LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET addr len %u!",
+- fd, vlsh, len);
++ LDBG (0, "ERROR: fd %d: vclsh %u: Invalid AF_INET addr len %u!",
++ fd, vclsh, len);
+ errno = EINVAL;
+ rv = -1;
+ goto done;
+@@ -1061,8 +1260,9 @@ bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+ case AF_INET6:
+ if (len != sizeof (struct sockaddr_in6))
+ {
+- LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET6 addr len %u!",
+- fd, vlsh, len);
++ LDBG (0,
++ "ERROR: fd %d: vclsh %u: Invalid AF_INET6 addr len %u!",
++ fd, vclsh, len);
+ errno = EINVAL;
+ rv = -1;
+ goto done;
+@@ -1073,16 +1273,17 @@ bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+ break;
+
+ default:
+- LDBG (0, "ERROR: fd %d: vlsh %u: Unsupported address family %u!",
+- fd, vlsh, addr->sa_family);
++ LDBG (0, "ERROR: fd %d: vclsh %u: Unsupported address family %u!",
++ fd, vclsh, addr->sa_family);
+ errno = EAFNOSUPPORT;
+ rv = -1;
+ goto done;
+ }
+- LDBG (0, "fd %d: calling vls_bind: vlsh %u, addr %p, len %u", fd, vlsh,
+- addr, len);
++ LDBG (0,
++ "fd %d: calling vppcom_session_bind: vclsh %u, addr %p, len %u",
++ fd, vclsh, addr, len);
+
+- rv = vls_bind (vlsh, &ep);
++ rv = vppcom_session_bind (vclsh, &ep);
+ if (rv != VPPCOM_OK)
+ {
+ errno = -rv;
+@@ -1150,14 +1351,14 @@ ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
+ int
+ getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ vppcom_endpt_t ep;
+ u8 addr_buf[sizeof (struct in6_addr)];
+@@ -1165,7 +1366,7 @@ getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
+
+ ep.ip = addr_buf;
+
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
+ if (rv != VPPCOM_OK)
+ {
+ errno = -rv;
+@@ -1192,7 +1393,7 @@ getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
+ int
+ connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv;
+
+ if ((errno = -ldp_init ()))
+@@ -1206,8 +1407,8 @@ connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+ goto done;
+ }
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ vppcom_endpt_t ep;
+
+@@ -1216,8 +1417,8 @@ connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+ case AF_INET:
+ if (len != sizeof (struct sockaddr_in))
+ {
+- LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET addr len %u!",
+- fd, vlsh, len);
++ LDBG (0, "fd %d: ERROR vclsh %u: Invalid AF_INET addr len %u!",
++ fd, vclsh, len);
+ errno = EINVAL;
+ rv = -1;
+ goto done;
+@@ -1230,8 +1431,8 @@ connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+ case AF_INET6:
+ if (len != sizeof (struct sockaddr_in6))
+ {
+- LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET6 addr len %u!",
+- fd, vlsh, len);
++ LDBG (0, "fd %d: ERROR vclsh %u: Invalid AF_INET6 addr len %u!",
++ fd, vclsh, len);
+ errno = EINVAL;
+ rv = -1;
+ goto done;
+@@ -1242,16 +1443,17 @@ connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
+ break;
+
+ default:
+- LDBG (0, "fd %d: ERROR vlsh %u: Unsupported address family %u!",
+- fd, vlsh, addr->sa_family);
++ LDBG (0, "fd %d: ERROR vclsh %u: Unsupported address family %u!",
++ fd, vclsh, addr->sa_family);
+ errno = EAFNOSUPPORT;
+ rv = -1;
+ goto done;
+ }
+- LDBG (0, "fd %d: calling vls_connect(): vlsh %u addr %p len %u", fd,
+- vlsh, addr, len);
++ LDBG (0,
++ "fd %d: calling vppcom_session_connect(): vclsh %u addr %p len %u",
++ fd, vclsh, addr, len);
+
+- rv = vls_connect (vlsh, &ep);
++ rv = vppcom_session_connect (vclsh, &ep);
+ if (rv != VPPCOM_OK)
+ {
+ errno = -rv;
+@@ -1274,21 +1476,21 @@ done:
+ int
+ getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ vppcom_endpt_t ep;
+ u8 addr_buf[sizeof (struct in6_addr)];
+ u32 size = sizeof (ep);
+
+ ep.ip = addr_buf;
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
+ if (rv != VPPCOM_OK)
+ {
+ errno = -rv;
+@@ -1315,15 +1517,15 @@ getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
+ ssize_t
+ send (int fd, const void *buf, size_t n, int flags)
+ {
+- vls_handle_t vlsh = ldp_fd_to_vlsh (fd);
++ vcl_session_handle_t vclsh = ldp_fd_to_vclsh (fd);
+ ssize_t size;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- if (vlsh != VLS_INVALID_HANDLE)
++ if (vclsh != INVALID_SESSION_ID)
+ {
+- size = vls_sendto (vlsh, (void *) buf, n, flags, NULL);
++ size = vppcom_session_sendto (vclsh, (void *) buf, n, flags, NULL);
+ if (size < VPPCOM_OK)
+ {
+ errno = -size;
+@@ -1342,14 +1544,14 @@ ssize_t
+ sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
+ {
+ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ ssize_t size = 0;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (out_fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (out_fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ int rv;
+ ssize_t results = 0;
+@@ -1359,11 +1561,14 @@ sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
+ u8 eagain = 0;
+ u32 flags, flags_len = sizeof (flags);
+
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &flags_len);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_FLAGS, &flags,
++ &flags_len);
+ if (PREDICT_FALSE (rv != VPPCOM_OK))
+ {
+- LDBG (0, "ERROR: out fd %d: vls_attr: vlsh %u, returned %d (%s)!",
+- out_fd, vlsh, rv, vppcom_retval_str (rv));
++ LDBG (0,
++ "ERROR: out fd %d: vppcom_session_attr: vclsh %u, returned %d (%s)!",
++ out_fd, vclsh, rv, vppcom_retval_str (rv));
+
+ vec_reset_length (ldpw->io_buffer);
+ errno = -rv;
+@@ -1385,11 +1590,12 @@ sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
+
+ do
+ {
+- size = vls_attr (vlsh, VPPCOM_ATTR_GET_NWRITE, 0, 0);
++ size = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_NWRITE, 0, 0);
+ if (size < 0)
+ {
+- LDBG (0, "ERROR: fd %d: vls_attr: vlsh %u returned %d (%s)!",
+- out_fd, vlsh, size, vppcom_retval_str (size));
++ LDBG (0,
++ "ERROR: fd %d: voocom_session_attr: vclsh %u returned %d (%s)!",
++ out_fd, vclsh, size, vppcom_retval_str (size));
+ vec_reset_length (ldpw->io_buffer);
+ errno = -size;
+ size = -1;
+@@ -1422,7 +1628,7 @@ sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
+ goto update_offset;
+ }
+
+- size = vls_write (vlsh, ldpw->io_buffer, nbytes);
++ size = vppcom_session_write (vclsh, ldpw->io_buffer, nbytes);
+ if (size < 0)
+ {
+ if (size == VPPCOM_EAGAIN)
+@@ -1492,16 +1698,16 @@ sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
+ ssize_t
+ recv (int fd, void *buf, size_t n, int flags)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ ssize_t size;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+- size = vls_recvfrom (vlsh, buf, n, flags, NULL);
++ size = vppcom_session_recvfrom (vclsh, buf, n, flags, NULL);
+ if (size < 0)
+ {
+ errno = -size;
+@@ -1520,14 +1726,14 @@ ssize_t
+ sendto (int fd, const void *buf, size_t n, int flags,
+ __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ ssize_t size;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != INVALID_SESSION_ID)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ vppcom_endpt_t *ep = 0;
+ vppcom_endpt_t _ep;
+@@ -1560,7 +1766,7 @@ sendto (int fd, const void *buf, size_t n, int flags,
+ }
+ }
+
+- size = vls_sendto (vlsh, (void *) buf, n, flags, ep);
++ size = vppcom_session_sendto (vclsh, (void *) buf, n, flags, ep);
+ if (size < 0)
+ {
+ errno = -size;
+@@ -1580,14 +1786,14 @@ ssize_t
+ recvfrom (int fd, void *__restrict buf, size_t n, int flags,
+ __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
+ {
+- vls_handle_t sid;
++ vcl_session_handle_t sid;
+ ssize_t size, rv;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- sid = ldp_fd_to_vlsh (fd);
+- if (sid != VLS_INVALID_HANDLE)
++ sid = ldp_fd_to_vclsh (fd);
++ if (sid != INVALID_SESSION_ID)
+ {
+ vppcom_endpt_t ep;
+ u8 src_addr[sizeof (struct sockaddr_in6)];
+@@ -1595,7 +1801,7 @@ recvfrom (int fd, void *__restrict buf, size_t n, int flags,
+ if (addr)
+ {
+ ep.ip = src_addr;
+- size = vls_recvfrom (sid, buf, n, flags, &ep);
++ size = vppcom_session_recvfrom (sid, buf, n, flags, &ep);
+
+ if (size > 0)
+ {
+@@ -1605,7 +1811,7 @@ recvfrom (int fd, void *__restrict buf, size_t n, int flags,
+ }
+ }
+ else
+- size = vls_recvfrom (sid, buf, n, flags, NULL);
++ size = vppcom_session_recvfrom (sid, buf, n, flags, NULL);
+
+ if (size < 0)
+ {
+@@ -1624,14 +1830,14 @@ recvfrom (int fd, void *__restrict buf, size_t n, int flags,
+ ssize_t
+ sendmsg (int fd, const struct msghdr * message, int flags)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ ssize_t size;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ LDBG (0, "LDP-TBD");
+ errno = ENOSYS;
+@@ -1651,7 +1857,7 @@ sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
+ {
+ ssize_t size;
+ const char *func_str;
+- u32 sh = ldp_fd_to_vlsh (fd);
++ u32 sh = ldp_fd_to_vclsh (fd);
+
+ if ((errno = -ldp_init ()))
+ return -1;
+@@ -1696,14 +1902,14 @@ sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
+ ssize_t
+ recvmsg (int fd, struct msghdr * message, int flags)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ ssize_t size;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ LDBG (0, "LDP-TBD");
+ errno = ENOSYS;
+@@ -1724,7 +1930,7 @@ recvmmsg (int fd, struct mmsghdr *vmessages,
+ {
+ ssize_t size;
+ const char *func_str;
+- u32 sh = ldp_fd_to_vlsh (fd);
++ u32 sh = ldp_fd_to_vclsh (fd);
+
+ if ((errno = -ldp_init ()))
+ return -1;
+@@ -1771,14 +1977,14 @@ int
+ getsockopt (int fd, int level, int optname,
+ void *__restrict optval, socklen_t * __restrict optlen)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ rv = -EOPNOTSUPP;
+
+@@ -1788,26 +1994,26 @@ getsockopt (int fd, int level, int optname,
+ switch (optname)
+ {
+ case TCP_NODELAY:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_NODELAY,
+- optval, optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_TCP_NODELAY,
++ optval, optlen);
+ break;
+ case TCP_MAXSEG:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_USER_MSS,
+- optval, optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_TCP_USER_MSS,
++ optval, optlen);
+ break;
+ case TCP_KEEPIDLE:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
+- optval, optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
++ optval, optlen);
+ break;
+ case TCP_KEEPINTVL:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
+- optval, optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
++ optval, optlen);
+ break;
+ case TCP_INFO:
+ if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
+ {
+- LDBG (1, "fd %d: vlsh %u SOL_TCP, TCP_INFO, optval %p, "
+- "optlen %d: #LDP-NOP#", fd, vlsh, optval, *optlen);
++ LDBG (1, "fd %d: vclsh %u SOL_TCP, TCP_INFO, optval %p, "
++ "optlen %d: #LDP-NOP#", fd, vclsh, optval, *optlen);
+ memset (optval, 0, *optlen);
+ rv = VPPCOM_OK;
+ }
+@@ -1821,7 +2027,7 @@ getsockopt (int fd, int level, int optname,
+ break;
+ default:
+ LDBG (0, "ERROR: fd %d: getsockopt SOL_TCP: sid %u, "
+- "optname %d unsupported!", fd, vlsh, optname);
++ "optname %d unsupported!", fd, vclsh, optname);
+ break;
+ }
+ break;
+@@ -1829,11 +2035,13 @@ getsockopt (int fd, int level, int optname,
+ switch (optname)
+ {
+ case IPV6_V6ONLY:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_V6ONLY, optval, optlen);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_V6ONLY, optval,
++ optlen);
+ break;
+ default:
+- LDBG (0, "ERROR: fd %d: getsockopt SOL_IPV6: vlsh %u "
+- "optname %d unsupported!", fd, vlsh, optname);
++ LDBG (0, "ERROR: fd %d: getsockopt SOL_IPV6: vclsh %u "
++ "optname %d unsupported!", fd, vclsh, optname);
+ break;
+ }
+ break;
+@@ -1841,35 +2049,47 @@ getsockopt (int fd, int level, int optname,
+ switch (optname)
+ {
+ case SO_ACCEPTCONN:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LISTEN, optval, optlen);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_LISTEN, optval,
++ optlen);
+ break;
+ case SO_KEEPALIVE:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_KEEPALIVE, optval, optlen);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_KEEPALIVE, optval,
++ optlen);
+ break;
+ case SO_PROTOCOL:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PROTOCOL, optval, optlen);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_PROTOCOL, optval,
++ optlen);
+ *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
+ break;
+ case SO_SNDBUF:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TX_FIFO_LEN,
+- optval, optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_TX_FIFO_LEN,
++ optval, optlen);
+ break;
+ case SO_RCVBUF:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_RX_FIFO_LEN,
+- optval, optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_RX_FIFO_LEN,
++ optval, optlen);
+ break;
+ case SO_REUSEADDR:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_REUSEADDR, optval, optlen);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_REUSEADDR, optval,
++ optlen);
+ break;
+ case SO_BROADCAST:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_BROADCAST, optval, optlen);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_BROADCAST, optval,
++ optlen);
+ break;
+ case SO_ERROR:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_GET_ERROR, optval, optlen);
++ rv =
++ vppcom_session_attr (vclsh, VPPCOM_ATTR_GET_ERROR, optval,
++ optlen);
+ break;
+ default:
+- LDBG (0, "ERROR: fd %d: getsockopt SOL_SOCKET: vlsh %u "
+- "optname %d unsupported!", fd, vlsh, optname);
++ LDBG (0, "ERROR: fd %d: getsockopt SOL_SOCKET: vclsh %u "
++ "optname %d unsupported!", fd, vclsh, optname);
+ break;
+ }
+ break;
+@@ -1895,14 +2115,14 @@ int
+ setsockopt (int fd, int level, int optname,
+ const void *optval, socklen_t optlen)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ rv = -EOPNOTSUPP;
+
+@@ -1912,20 +2132,20 @@ setsockopt (int fd, int level, int optname,
+ switch (optname)
+ {
+ case TCP_NODELAY:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_NODELAY,
+- (void *) optval, &optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_TCP_NODELAY,
++ (void *) optval, &optlen);
+ break;
+ case TCP_MAXSEG:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_USER_MSS,
+- (void *) optval, &optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_TCP_USER_MSS,
++ (void *) optval, &optlen);
+ break;
+ case TCP_KEEPIDLE:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
+- (void *) optval, &optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
++ (void *) optval, &optlen);
+ break;
+ case TCP_KEEPINTVL:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
+- (void *) optval, &optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
++ (void *) optval, &optlen);
+ break;
+ case TCP_CONGESTION:
+ case TCP_CORK:
+@@ -1933,8 +2153,8 @@ setsockopt (int fd, int level, int optname,
+ rv = 0;
+ break;
+ default:
+- LDBG (0, "ERROR: fd %d: setsockopt() SOL_TCP: vlsh %u"
+- "optname %d unsupported!", fd, vlsh, optname);
++ LDBG (0, "ERROR: fd %d: setsockopt() SOL_TCP: vclsh %u"
++ "optname %d unsupported!", fd, vclsh, optname);
+ break;
+ }
+ break;
+@@ -1942,12 +2162,12 @@ setsockopt (int fd, int level, int optname,
+ switch (optname)
+ {
+ case IPV6_V6ONLY:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_V6ONLY,
+- (void *) optval, &optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_V6ONLY,
++ (void *) optval, &optlen);
+ break;
+ default:
+- LDBG (0, "ERROR: fd %d: setsockopt SOL_IPV6: vlsh %u"
+- "optname %d unsupported!", fd, vlsh, optname);
++ LDBG (0, "ERROR: fd %d: setsockopt SOL_IPV6: vclsh %u"
++ "optname %d unsupported!", fd, vclsh, optname);
+ break;
+ }
+ break;
+@@ -1955,20 +2175,20 @@ setsockopt (int fd, int level, int optname,
+ switch (optname)
+ {
+ case SO_KEEPALIVE:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_KEEPALIVE,
+- (void *) optval, &optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_KEEPALIVE,
++ (void *) optval, &optlen);
+ break;
+ case SO_REUSEADDR:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_REUSEADDR,
+- (void *) optval, &optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_REUSEADDR,
++ (void *) optval, &optlen);
+ break;
+ case SO_BROADCAST:
+- rv = vls_attr (vlsh, VPPCOM_ATTR_SET_BROADCAST,
+- (void *) optval, &optlen);
++ rv = vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_BROADCAST,
++ (void *) optval, &optlen);
+ break;
+ default:
+- LDBG (0, "ERROR: fd %d: setsockopt SOL_SOCKET: vlsh %u "
+- "optname %d unsupported!", fd, vlsh, optname);
++ LDBG (0, "ERROR: fd %d: setsockopt SOL_SOCKET: vclsh %u "
++ "optname %d unsupported!", fd, vclsh, optname);
+ break;
+ }
+ break;
+@@ -1993,18 +2213,20 @@ setsockopt (int fd, int level, int optname,
+ int
+ listen (int fd, int n)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
++ vcl_worker_t *wrk = vcl_worker_get_current ();
+ int rv;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+- LDBG (0, "fd %d: calling vls_listen: vlsh %u, n %d", fd, vlsh, n);
++ LDBG (0, "fd %d: calling vppcom_session_listen: vclsh %u, n %d", fd,
++ vclsh, n);
+
+- rv = vls_listen (vlsh, n);
++ rv = vppcom_session_listen (vclsh, n);
+ if (rv != VPPCOM_OK)
+ {
+ errno = -rv;
+@@ -2018,6 +2240,10 @@ listen (int fd, int n)
+ }
+
+ LDBG (1, "fd %d: returning %d", fd, rv);
++/*Update listen info in vcl worker*/
++ wrk->listen_fd = fd;
++ wrk->listen_queue_size = n;
++ wrk->listen_session_index = vppcom_session_index (vclsh);
+ return rv;
+ }
+
+@@ -2025,14 +2251,14 @@ static inline int
+ ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
+ socklen_t * __restrict addr_len, int flags)
+ {
+- vls_handle_t listen_vlsh, accept_vlsh;
++ vcl_session_handle_t listen_vclsh, accept_vclsh;
+ int rv;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- listen_vlsh = ldp_fd_to_vlsh (listen_fd);
+- if (listen_vlsh != VLS_INVALID_HANDLE)
++ listen_vclsh = ldp_fd_to_vclsh (listen_fd);
++ if (listen_vclsh != INVALID_SESSION_ID)
+ {
+ vppcom_endpt_t ep;
+ u8 src_addr[sizeof (struct sockaddr_in6)];
+@@ -2040,12 +2266,12 @@ ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
+ ep.ip = src_addr;
+
+ LDBG (0, "listen fd %d: calling vppcom_session_accept: listen sid %u,"
+- " ep %p, flags 0x%x", listen_fd, listen_vlsh, ep, flags);
++ " ep %p, flags 0x%x", listen_fd, listen_vclsh, ep, flags);
+
+- accept_vlsh = vls_accept (listen_vlsh, &ep, flags);
+- if (accept_vlsh < 0)
++ accept_vclsh = vppcom_session_accept (listen_vclsh, &ep, flags);
++ if (accept_vclsh < 0)
+ {
+- errno = -accept_vlsh;
++ errno = -accept_vclsh;
+ rv = -1;
+ }
+ else
+@@ -2053,13 +2279,13 @@ ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
+ rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
+ if (rv != VPPCOM_OK)
+ {
+- (void) vls_close (accept_vlsh);
++ (void) vppcom_session_close (accept_vclsh);
+ errno = -rv;
+ rv = -1;
+ }
+ else
+ {
+- rv = ldp_vlsh_to_fd (accept_vlsh);
++ rv = ldp_vclsh_to_fd (accept_vclsh);
+ }
+ }
+ }
+@@ -2092,25 +2318,26 @@ accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
+ int
+ shutdown (int fd, int how)
+ {
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv = 0, flags;
+ u32 flags_len = sizeof (flags);
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vlsh = ldp_fd_to_vlsh (fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+- LDBG (0, "called shutdown: fd %u vlsh %u how %d", fd, vlsh, how);
++ LDBG (0, "called shutdown: fd %u vclsh %u how %d", fd, vclsh, how);
+
+- if (vls_attr (vlsh, VPPCOM_ATTR_SET_SHUT, &how, &flags_len))
++ if (vppcom_session_attr (vclsh, VPPCOM_ATTR_SET_SHUT, &how, &flags_len))
+ {
+ close (fd);
+ return -1;
+ }
+
+- if (vls_attr (vlsh, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len))
++ if (vppcom_session_attr
++ (vclsh, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len))
+ {
+ close (fd);
+ return -1;
+@@ -2132,7 +2359,7 @@ int
+ epoll_create1 (int flags)
+ {
+ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ int rv;
+
+ if ((errno = -ldp_init ()))
+@@ -2153,17 +2380,17 @@ epoll_create1 (int flags)
+ return rv;
+ }
+
+- vlsh = vls_epoll_create ();
+- if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
++ vclsh = vppcom_epoll_create ();
++ if (PREDICT_FALSE (vclsh == INVALID_SESSION_ID))
+ {
+- errno = -vlsh;
++ errno = -vclsh;
+ rv = -1;
+ }
+ else
+ {
+- rv = ldp_vlsh_to_fd (vlsh);
++ rv = ldp_vclsh_to_fd (vclsh);
+ }
+- LDBG (0, "epoll_create epfd %u vlsh %u", rv, vlsh);
++ LDBG (0, "epoll_create epfd %u vclsh %u", rv, vclsh);
+ return rv;
+ }
+
+@@ -2176,14 +2403,14 @@ epoll_create (int size)
+ int
+ epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
+ {
+- vls_handle_t vep_vlsh, vlsh;
++ vcl_session_handle_t vep_vclsh, vclsh;
+ int rv;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+
+- vep_vlsh = ldp_fd_to_vlsh (epfd);
+- if (PREDICT_FALSE (vep_vlsh == VLS_INVALID_HANDLE))
++ vep_vclsh = ldp_fd_to_vclsh (epfd);
++ if (PREDICT_FALSE (vep_vclsh == INVALID_SESSION_ID))
+ {
+ /* The LDP epoll_create1 always creates VCL epfd's.
+ * The app should never have a kernel base epoll fd unless it
+@@ -2197,17 +2424,18 @@ epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
+ goto done;
+ }
+
+- vlsh = ldp_fd_to_vlsh (fd);
++ vclsh = ldp_fd_to_vclsh (fd);
+
+- LDBG (0, "epfd %d ep_vlsh %d, fd %u vlsh %d, op %u", epfd, vep_vlsh, fd,
+- vlsh, op);
++ LDBG (0, "epfd %d ep_vclsh %d, fd %u vclsh %d, op %u", epfd, vep_vclsh, fd,
++ vclsh, op);
+
+- if (vlsh != VLS_INVALID_HANDLE)
++ if (vclsh != INVALID_SESSION_ID)
+ {
+- LDBG (1, "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
+- " event %p", epfd, vep_vlsh, vlsh, event);
++ LDBG (1,
++ "epfd %d: calling vppcom_epoll_ctl: ep_vclsh %d op %d, vclsh %u,"
++ " event %p", epfd, vep_vclsh, vclsh, event);
+
+- rv = vls_epoll_ctl (vep_vlsh, op, vlsh, event);
++ rv = vppcom_epoll_ctl (vep_vclsh, op, vclsh, event);
+ if (rv != VPPCOM_OK)
+ {
+ errno = -rv;
+@@ -2219,11 +2447,12 @@ epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
+ int libc_epfd;
+ u32 size = sizeof (epfd);
+
+- libc_epfd = vls_attr (vep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
++ libc_epfd =
++ vppcom_session_attr (vep_vclsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ if (!libc_epfd)
+ {
+- LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
+- "EPOLL_CLOEXEC", epfd, vep_vlsh);
++ LDBG (1, "epfd %d, vep_vclsh %d calling libc_epoll_create1: "
++ "EPOLL_CLOEXEC", epfd, vep_vclsh);
+
+ libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
+ if (libc_epfd < 0)
+@@ -2232,8 +2461,9 @@ epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
+ goto done;
+ }
+
+- rv = vls_attr (vep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd,
+- &size);
++ rv =
++ vppcom_session_attr (vep_vclsh, VPPCOM_ATTR_SET_LIBC_EPFD,
++ &libc_epfd, &size);
+ if (rv < 0)
+ {
+ errno = -rv;
+@@ -2265,7 +2495,7 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
+ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
+ double time_to_wait = (double) 0, max_time;
+ int libc_epfd, rv = 0;
+- vls_handle_t ep_vlsh;
++ vcl_session_handle_t ep_vclsh;
+
+ if ((errno = -ldp_init ()))
+ return -1;
+@@ -2279,10 +2509,10 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
+ if (epfd == ldpw->vcl_mq_epfd)
+ return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
+
+- ep_vlsh = ldp_fd_to_vlsh (epfd);
+- if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
++ ep_vclsh = ldp_fd_to_vclsh (epfd);
++ if (PREDICT_FALSE (ep_vclsh == INVALID_SESSION_ID))
+ {
+- LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
++ LDBG (0, "epfd %d: bad ep_vclsh %d!", epfd, ep_vclsh);
+ errno = EBADFD;
+ return -1;
+ }
+@@ -2292,7 +2522,7 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
+ time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
+ max_time = clib_time_now (&ldpw->clib_time) + time_to_wait;
+
+- libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
++ libc_epfd = vppcom_session_attr (ep_vclsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
+ if (PREDICT_FALSE (libc_epfd < 0))
+ {
+ errno = -libc_epfd;
+@@ -2301,13 +2531,13 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
+ }
+
+ LDBG (2, "epfd %d: vep_idx %d, libc_epfd %d, events %p, maxevents %d, "
+- "timeout %d, sigmask %p: time_to_wait %.02f", epfd, ep_vlsh,
++ "timeout %d, sigmask %p: time_to_wait %.02f", epfd, ep_vclsh,
+ libc_epfd, events, maxevents, timeout, sigmask, time_to_wait);
+ do
+ {
+ if (!ldpw->epoll_wait_vcl)
+ {
+- rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
++ rv = vppcom_epoll_wait (ep_vclsh, events, maxevents, 0);
+ if (rv > 0)
+ {
+ ldpw->epoll_wait_vcl = 1;
+@@ -2354,7 +2584,7 @@ poll (struct pollfd *fds, nfds_t nfds, int timeout)
+ {
+ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
+ int rv, i, n_revents = 0;
+- vls_handle_t vlsh;
++ vcl_session_handle_t vclsh;
+ vcl_poll_t *vp;
+ double max_time;
+
+@@ -2371,13 +2601,13 @@ poll (struct pollfd *fds, nfds_t nfds, int timeout)
+ if (fds[i].fd < 0)
+ continue;
+
+- vlsh = ldp_fd_to_vlsh (fds[i].fd);
+- if (vlsh != VLS_INVALID_HANDLE)
++ vclsh = ldp_fd_to_vclsh (fds[i].fd);
++ if (vclsh != INVALID_SESSION_ID)
+ {
+ fds[i].fd = -fds[i].fd;
+ vec_add2 (ldpw->vcl_poll, vp, 1);
+ vp->fds_ndx = i;
+- vp->sh = vlsh_to_sh (vlsh);
++ vp->sh = vclsh;
+ vp->events = fds[i].events;
+ #ifdef __USE_XOPEN2K
+ if (fds[i].events & POLLRDNORM)
+diff --git a/src/vcl/ldp.c.orig b/src/vcl/ldp.c.orig
+new file mode 100644
+index 000000000..c23f995d5
+--- /dev/null
++++ b/src/vcl/ldp.c.orig
+@@ -0,0 +1,2520 @@
++/*
++ * Copyright (c) 2016-2019 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.
++ */
++#include <unistd.h>
++#include <stdio.h>
++#include <signal.h>
++#include <dlfcn.h>
++#include <pthread.h>
++#include <time.h>
++#include <stdarg.h>
++#include <sys/resource.h>
++#include <netinet/tcp.h>
++
++#include <vcl/ldp_socket_wrapper.h>
++#include <vcl/ldp.h>
++#include <sys/time.h>
++
++#include <vcl/vcl_locked.h>
++#include <vppinfra/time.h>
++#include <vppinfra/bitmap.h>
++#include <vppinfra/lock.h>
++#include <vppinfra/pool.h>
++#include <vppinfra/hash.h>
++
++#define HAVE_CONSTRUCTOR_ATTRIBUTE
++#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
++#define CONSTRUCTOR_ATTRIBUTE \
++ __attribute__ ((constructor))
++#else
++#define CONSTRUCTOR_ATTRIBUTE
++#endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
++
++#define HAVE_DESTRUCTOR_ATTRIBUTE
++#ifdef HAVE_DESTRUCTOR_ATTRIBUTE
++#define DESTRUCTOR_ATTRIBUTE \
++ __attribute__ ((destructor))
++#else
++#define DESTRUCTOR_ATTRIBUTE
++#endif
++
++#define LDP_MAX_NWORKERS 32
++
++typedef struct ldp_worker_ctx_
++{
++ u8 *io_buffer;
++ clib_time_t clib_time;
++
++ /*
++ * Select state
++ */
++ clib_bitmap_t *rd_bitmap;
++ clib_bitmap_t *wr_bitmap;
++ clib_bitmap_t *ex_bitmap;
++ clib_bitmap_t *si_rd_bitmap;
++ clib_bitmap_t *si_wr_bitmap;
++ clib_bitmap_t *si_ex_bitmap;
++ clib_bitmap_t *libc_rd_bitmap;
++ clib_bitmap_t *libc_wr_bitmap;
++ clib_bitmap_t *libc_ex_bitmap;
++
++ /*
++ * Poll state
++ */
++ vcl_poll_t *vcl_poll;
++ struct pollfd *libc_poll;
++ u16 *libc_poll_idxs;
++
++ /*
++ * Epoll state
++ */
++ u8 epoll_wait_vcl;
++ int vcl_mq_epfd;
++
++} ldp_worker_ctx_t;
++
++/* clib_bitmap_t, fd_mask and vcl_si_set are used interchangeably. Make sure
++ * they are the same size */
++STATIC_ASSERT (sizeof (clib_bitmap_t) == sizeof (fd_mask),
++ "ldp bitmap size mismatch");
++STATIC_ASSERT (sizeof (vcl_si_set) == sizeof (fd_mask),
++ "ldp bitmap size mismatch");
++
++typedef struct
++{
++ ldp_worker_ctx_t *workers;
++ int init;
++ char app_name[LDP_APP_NAME_MAX];
++ u32 vlsh_bit_val;
++ u32 vlsh_bit_mask;
++ u32 debug;
++ u8 transparent_tls;
++
++ /** vcl needs next epoll_create to go to libc_epoll */
++ u8 vcl_needs_real_epoll;
++} ldp_main_t;
++
++#define LDP_DEBUG ldp->debug
++
++#define LDBG(_lvl, _fmt, _args...) \
++ if (ldp->debug > _lvl) \
++ { \
++ int errno_saved = errno; \
++ clib_warning ("ldp<%d>: " _fmt, getpid(), ##_args); \
++ errno = errno_saved; \
++ }
++
++static ldp_main_t ldp_main = {
++ .vlsh_bit_val = (1 << LDP_SID_BIT_MIN),
++ .vlsh_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
++ .debug = LDP_DEBUG_INIT,
++ .transparent_tls = 0,
++};
++
++static ldp_main_t *ldp = &ldp_main;
++
++static inline ldp_worker_ctx_t *
++ldp_worker_get_current (void)
++{
++ return (ldp->workers + vppcom_worker_index ());
++}
++
++/*
++ * RETURN: 0 on success or -1 on error.
++ * */
++static inline void
++ldp_set_app_name (char *app_name)
++{
++ snprintf (ldp->app_name, LDP_APP_NAME_MAX,
++ "ldp-%d-%s", getpid (), app_name);
++}
++
++static inline char *
++ldp_get_app_name ()
++{
++ if (ldp->app_name[0] == '\0')
++ ldp_set_app_name ("app");
++
++ return ldp->app_name;
++}
++
++static inline int
++ldp_vlsh_to_fd (vls_handle_t vlsh)
++{
++ return (vlsh + ldp->vlsh_bit_val);
++}
++
++static inline vls_handle_t
++ldp_fd_to_vlsh (int fd)
++{
++ if (fd < ldp->vlsh_bit_val)
++ return VLS_INVALID_HANDLE;
++
++ return (fd - ldp->vlsh_bit_val);
++}
++
++static void
++ldp_alloc_workers (void)
++{
++ if (ldp->workers)
++ return;
++ pool_alloc (ldp->workers, LDP_MAX_NWORKERS);
++}
++
++static inline int
++ldp_init (void)
++{
++ ldp_worker_ctx_t *ldpw;
++ int rv;
++
++ if (PREDICT_TRUE (ldp->init))
++ return 0;
++
++ ldp->init = 1;
++ ldp->vcl_needs_real_epoll = 1;
++ rv = vls_app_create (ldp_get_app_name ());
++ if (rv != VPPCOM_OK)
++ {
++ ldp->vcl_needs_real_epoll = 0;
++ if (rv == VPPCOM_EEXIST)
++ return 0;
++ LDBG (2, "\nERROR: ldp_init: vppcom_app_create()"
++ " failed! rv = %d (%s)\n", rv, vppcom_retval_str (rv));
++ ldp->init = 0;
++ return rv;
++ }
++ ldp->vcl_needs_real_epoll = 0;
++ ldp_alloc_workers ();
++ ldpw = ldp_worker_get_current ();
++
++ char *env_var_str = getenv (LDP_ENV_DEBUG);
++ if (env_var_str)
++ {
++ u32 tmp;
++ if (sscanf (env_var_str, "%u", &tmp) != 1)
++ clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
++ " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
++ env_var_str);
++ else
++ {
++ ldp->debug = tmp;
++ LDBG (0, "configured LDP debug level (%u) from env var "
++ LDP_ENV_DEBUG "!", ldp->debug);
++ }
++ }
++
++ env_var_str = getenv (LDP_ENV_APP_NAME);
++ if (env_var_str)
++ {
++ ldp_set_app_name (env_var_str);
++ LDBG (0, "configured LDP app name (%s) from the env var "
++ LDP_ENV_APP_NAME "!", ldp->app_name);
++ }
++
++ env_var_str = getenv (LDP_ENV_SID_BIT);
++ if (env_var_str)
++ {
++ u32 sb;
++ if (sscanf (env_var_str, "%u", &sb) != 1)
++ {
++ LDBG (0, "WARNING: Invalid LDP sid bit specified in the env var "
++ LDP_ENV_SID_BIT " (%s)! sid bit value %d (0x%x)", env_var_str,
++ ldp->vlsh_bit_val, ldp->vlsh_bit_val);
++ }
++ else if (sb < LDP_SID_BIT_MIN)
++ {
++ ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MIN);
++ ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
++
++ LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
++ LDP_ENV_SID_BIT " (%s) is too small. Using LDP_SID_BIT_MIN"
++ " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
++ LDP_SID_BIT_MIN, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
++ }
++ else if (sb > LDP_SID_BIT_MAX)
++ {
++ ldp->vlsh_bit_val = (1 << LDP_SID_BIT_MAX);
++ ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
++
++ LDBG (0, "WARNING: LDP sid bit (%u) specified in the env var "
++ LDP_ENV_SID_BIT " (%s) is too big. Using LDP_SID_BIT_MAX"
++ " (%d)! sid bit value %d (0x%x)", sb, env_var_str,
++ LDP_SID_BIT_MAX, ldp->vlsh_bit_val, ldp->vlsh_bit_val);
++ }
++ else
++ {
++ ldp->vlsh_bit_val = (1 << sb);
++ ldp->vlsh_bit_mask = ldp->vlsh_bit_val - 1;
++
++ LDBG (0, "configured LDP sid bit (%u) from "
++ LDP_ENV_SID_BIT "! sid bit value %d (0x%x)", sb,
++ ldp->vlsh_bit_val, ldp->vlsh_bit_val);
++ }
++
++ /* Make sure there are enough bits in the fd set for vcl sessions */
++ if (ldp->vlsh_bit_val > FD_SETSIZE / 2)
++ {
++ LDBG (0, "ERROR: LDP vlsh bit value %d > FD_SETSIZE/2 %d!",
++ ldp->vlsh_bit_val, FD_SETSIZE / 2);
++ ldp->init = 0;
++ return -1;
++ }
++ }
++ env_var_str = getenv (LDP_ENV_TLS_TRANS);
++ if (env_var_str)
++ {
++ ldp->transparent_tls = 1;
++ }
++
++ /* *INDENT-OFF* */
++ pool_foreach (ldpw, ldp->workers, ({
++ clib_memset (&ldpw->clib_time, 0, sizeof (ldpw->clib_time));
++ }));
++ /* *INDENT-ON* */
++
++ LDBG (0, "LDP initialization: done!");
++
++ return 0;
++}
++
++int
++close (int fd)
++{
++ vls_handle_t vlsh;
++ int rv, epfd;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ epfd = vls_attr (vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
++ if (epfd > 0)
++ {
++ LDBG (0, "fd %d: calling libc_close: epfd %u", fd, epfd);
++
++ rv = libc_close (epfd);
++ if (rv < 0)
++ {
++ u32 size = sizeof (epfd);
++ epfd = 0;
++
++ (void) vls_attr (vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &epfd, &size);
++ }
++ }
++ else if (PREDICT_FALSE (epfd < 0))
++ {
++ errno = -epfd;
++ rv = -1;
++ goto done;
++ }
++
++ LDBG (0, "fd %d: calling vls_close: vlsh %u", fd, vlsh);
++
++ rv = vls_close (vlsh);
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ else
++ {
++ LDBG (0, "fd %d: calling libc_close", fd);
++ rv = libc_close (fd);
++ }
++
++done:
++ return rv;
++}
++
++ssize_t
++read (int fd, void *buf, size_t nbytes)
++{
++ vls_handle_t vlsh;
++ ssize_t size;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ size = vls_read (vlsh, buf, nbytes);
++ if (size < 0)
++ {
++ errno = -size;
++ size = -1;
++ }
++ }
++ else
++ {
++ size = libc_read (fd, buf, nbytes);
++ }
++
++ return size;
++}
++
++ssize_t
++readv (int fd, const struct iovec * iov, int iovcnt)
++{
++ int rv = 0, i, total = 0;
++ vls_handle_t vlsh;
++ ssize_t size = 0;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ for (i = 0; i < iovcnt; ++i)
++ {
++ rv = vls_read (vlsh, iov[i].iov_base, iov[i].iov_len);
++ if (rv <= 0)
++ break;
++ else
++ {
++ total += rv;
++ if (rv < iov[i].iov_len)
++ break;
++ }
++ }
++ if (rv < 0 && total == 0)
++ {
++ errno = -rv;
++ size = -1;
++ }
++ else
++ size = total;
++ }
++ else
++ {
++ size = libc_readv (fd, iov, iovcnt);
++ }
++
++ return size;
++}
++
++ssize_t
++write (int fd, const void *buf, size_t nbytes)
++{
++ vls_handle_t vlsh;
++ ssize_t size = 0;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ size = vls_write_msg (vlsh, (void *) buf, nbytes);
++ if (size < 0)
++ {
++ errno = -size;
++ size = -1;
++ }
++ }
++ else
++ {
++ size = libc_write (fd, buf, nbytes);
++ }
++
++ return size;
++}
++
++ssize_t
++writev (int fd, const struct iovec * iov, int iovcnt)
++{
++ ssize_t size = 0, total = 0;
++ vls_handle_t vlsh;
++ int i, rv = 0;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ for (i = 0; i < iovcnt; ++i)
++ {
++ rv = vls_write_msg (vlsh, iov[i].iov_base, iov[i].iov_len);
++ if (rv < 0)
++ break;
++ else
++ {
++ total += rv;
++ if (rv < iov[i].iov_len)
++ break;
++ }
++ }
++
++ if (rv < 0 && total == 0)
++ {
++ errno = -rv;
++ size = -1;
++ }
++ else
++ size = total;
++ }
++ else
++ {
++ size = libc_writev (fd, iov, iovcnt);
++ }
++
++ return size;
++}
++
++#ifdef HAVE_FCNTL64
++int
++fcntl64 (int fd, int cmd, ...)
++#else
++int
++fcntl (int fd, int cmd, ...)
++#endif
++{
++ vls_handle_t vlsh;
++ int rv = 0;
++ va_list ap;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ va_start (ap, cmd);
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ LDBG (0, "fd %u vlsh %d, cmd %u", fd, vlsh, cmd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ int flags = va_arg (ap, int);
++ u32 size;
++
++ size = sizeof (flags);
++ rv = -EOPNOTSUPP;
++ switch (cmd)
++ {
++ case F_SETFL:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
++ break;
++
++ case F_GETFL:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &size);
++ if (rv == VPPCOM_OK)
++ rv = flags;
++ break;
++ case F_SETFD:
++ /* TODO handle this */
++ LDBG (0, "F_SETFD ignored flags %u", flags);
++ rv = 0;
++ break;
++ default:
++ rv = -EOPNOTSUPP;
++ break;
++ }
++ if (rv < 0)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ else
++ {
++#ifdef HAVE_FCNTL64
++ rv = libc_vfcntl64 (fd, cmd, ap);
++#else
++ rv = libc_vfcntl (fd, cmd, ap);
++#endif
++ }
++
++ va_end (ap);
++
++ return rv;
++}
++
++int
++ioctl (int fd, unsigned long int cmd, ...)
++{
++ vls_handle_t vlsh;
++ va_list ap;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ va_start (ap, cmd);
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ switch (cmd)
++ {
++ case FIONREAD:
++ rv = vls_attr (vlsh, 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 = vls_attr (vlsh, VPPCOM_ATTR_SET_FLAGS, &flags, &size);
++ }
++ break;
++
++ default:
++ rv = -EOPNOTSUPP;
++ break;
++ }
++ if (rv < 0)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ else
++ {
++ rv = libc_vioctl (fd, cmd, ap);
++ }
++
++ va_end (ap);
++ return rv;
++}
++
++always_inline void
++ldp_select_init_maps (fd_set * __restrict original,
++ clib_bitmap_t ** resultb, clib_bitmap_t ** libcb,
++ clib_bitmap_t ** vclb, int nfds, u32 minbits,
++ u32 n_bytes, uword * si_bits, uword * libc_bits)
++{
++ uword si_bits_set, libc_bits_set;
++ vls_handle_t vlsh;
++ int fd;
++
++ clib_bitmap_validate (*vclb, minbits);
++ clib_bitmap_validate (*libcb, minbits);
++ clib_bitmap_validate (*resultb, minbits);
++ clib_memcpy_fast (*resultb, original, n_bytes);
++ memset (original, 0, n_bytes);
++
++ /* *INDENT-OFF* */
++ clib_bitmap_foreach (fd, *resultb, ({
++ if (fd > nfds)
++ break;
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh == VLS_INVALID_HANDLE)
++ clib_bitmap_set_no_check (*libcb, fd, 1);
++ else
++ *vclb = clib_bitmap_set (*vclb, vlsh_to_session_index (vlsh), 1);
++ }));
++ /* *INDENT-ON* */
++
++ si_bits_set = clib_bitmap_last_set (*vclb) + 1;
++ *si_bits = (si_bits_set > *si_bits) ? si_bits_set : *si_bits;
++ clib_bitmap_validate (*resultb, *si_bits);
++
++ libc_bits_set = clib_bitmap_last_set (*libcb) + 1;
++ *libc_bits = (libc_bits_set > *libc_bits) ? libc_bits_set : *libc_bits;
++}
++
++always_inline int
++ldp_select_vcl_map_to_libc (clib_bitmap_t * vclb, fd_set * __restrict libcb)
++{
++ vls_handle_t vlsh;
++ uword si;
++ int fd;
++
++ if (!libcb)
++ return 0;
++
++ /* *INDENT-OFF* */
++ clib_bitmap_foreach (si, vclb, ({
++ vlsh = vls_session_index_to_vlsh (si);
++ ASSERT (vlsh != VLS_INVALID_HANDLE);
++ fd = ldp_vlsh_to_fd (vlsh);
++ if (PREDICT_FALSE (fd < 0))
++ {
++ errno = EBADFD;
++ return -1;
++ }
++ FD_SET (fd, libcb);
++ }));
++ /* *INDENT-ON* */
++
++ return 0;
++}
++
++always_inline void
++ldp_select_libc_map_merge (clib_bitmap_t * result, fd_set * __restrict libcb)
++{
++ uword fd;
++
++ if (!libcb)
++ return;
++
++ /* *INDENT-OFF* */
++ clib_bitmap_foreach (fd, result, ({
++ FD_SET ((int)fd, libcb);
++ }));
++ /* *INDENT-ON* */
++}
++
++int
++ldp_pselect (int nfds, fd_set * __restrict readfds,
++ fd_set * __restrict writefds,
++ fd_set * __restrict exceptfds,
++ const struct timespec *__restrict timeout,
++ const __sigset_t * __restrict sigmask)
++{
++ u32 minbits = clib_max (nfds, BITS (uword)), n_bytes;
++ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
++ struct timespec libc_tspec = { 0 };
++ f64 time_out, vcl_timeout = 0;
++ uword si_bits, libc_bits;
++ int rv, bits_set = 0;
++
++ if (nfds < 0)
++ {
++ errno = EINVAL;
++ return -1;
++ }
++
++ if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
++ clib_time_init (&ldpw->clib_time);
++
++ if (timeout)
++ {
++ time_out = (timeout->tv_sec == 0 && timeout->tv_nsec == 0) ?
++ (f64) 0 : (f64) timeout->tv_sec + (f64) timeout->tv_nsec / (f64) 1e9;
++
++ /* select as fine grained sleep */
++ if (!nfds)
++ {
++ time_out += clib_time_now (&ldpw->clib_time);
++ while (clib_time_now (&ldpw->clib_time) < time_out)
++ ;
++ return 0;
++ }
++ }
++ else if (!nfds)
++ {
++ errno = EINVAL;
++ return -1;
++ }
++ else
++ time_out = -1;
++
++ if (nfds <= ldp->vlsh_bit_val)
++ {
++ rv = libc_pselect (nfds, readfds, writefds, exceptfds,
++ timeout, sigmask);
++ goto done;
++ }
++
++ si_bits = libc_bits = 0;
++ n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0);
++
++ if (readfds)
++ ldp_select_init_maps (readfds, &ldpw->rd_bitmap, &ldpw->libc_rd_bitmap,
++ &ldpw->si_rd_bitmap, nfds, minbits, n_bytes,
++ &si_bits, &libc_bits);
++ if (writefds)
++ ldp_select_init_maps (writefds, &ldpw->wr_bitmap,
++ &ldpw->libc_wr_bitmap, &ldpw->si_wr_bitmap, nfds,
++ minbits, n_bytes, &si_bits, &libc_bits);
++ if (exceptfds)
++ ldp_select_init_maps (exceptfds, &ldpw->ex_bitmap,
++ &ldpw->libc_ex_bitmap, &ldpw->si_ex_bitmap, nfds,
++ minbits, n_bytes, &si_bits, &libc_bits);
++
++ if (PREDICT_FALSE (!si_bits && !libc_bits))
++ {
++ errno = EINVAL;
++ rv = -1;
++ goto done;
++ }
++
++ if (!si_bits)
++ libc_tspec = timeout ? *timeout : libc_tspec;
++
++ do
++ {
++ if (si_bits)
++ {
++ if (readfds)
++ clib_memcpy_fast (ldpw->rd_bitmap, ldpw->si_rd_bitmap,
++ vec_len (ldpw->si_rd_bitmap) *
++ sizeof (clib_bitmap_t));
++ if (writefds)
++ clib_memcpy_fast (ldpw->wr_bitmap, ldpw->si_wr_bitmap,
++ vec_len (ldpw->si_wr_bitmap) *
++ sizeof (clib_bitmap_t));
++ if (exceptfds)
++ clib_memcpy_fast (ldpw->ex_bitmap, ldpw->si_ex_bitmap,
++ vec_len (ldpw->si_ex_bitmap) *
++ sizeof (clib_bitmap_t));
++
++ rv = vls_select (si_bits, readfds ? ldpw->rd_bitmap : NULL,
++ writefds ? ldpw->wr_bitmap : NULL,
++ exceptfds ? ldpw->ex_bitmap : NULL, vcl_timeout);
++ if (rv < 0)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ else if (rv > 0)
++ {
++ if (ldp_select_vcl_map_to_libc (ldpw->rd_bitmap, readfds))
++ {
++ rv = -1;
++ goto done;
++ }
++
++ if (ldp_select_vcl_map_to_libc (ldpw->wr_bitmap, writefds))
++ {
++ rv = -1;
++ goto done;
++ }
++
++ if (ldp_select_vcl_map_to_libc (ldpw->ex_bitmap, exceptfds))
++ {
++ rv = -1;
++ goto done;
++ }
++ bits_set = rv;
++ }
++ }
++ if (libc_bits)
++ {
++ if (readfds)
++ clib_memcpy_fast (ldpw->rd_bitmap, ldpw->libc_rd_bitmap,
++ vec_len (ldpw->libc_rd_bitmap) *
++ sizeof (clib_bitmap_t));
++ if (writefds)
++ clib_memcpy_fast (ldpw->wr_bitmap, ldpw->libc_wr_bitmap,
++ vec_len (ldpw->libc_wr_bitmap) *
++ sizeof (clib_bitmap_t));
++ if (exceptfds)
++ clib_memcpy_fast (ldpw->ex_bitmap, ldpw->libc_ex_bitmap,
++ vec_len (ldpw->libc_ex_bitmap) *
++ sizeof (clib_bitmap_t));
++
++ rv = libc_pselect (libc_bits,
++ readfds ? (fd_set *) ldpw->rd_bitmap : NULL,
++ writefds ? (fd_set *) ldpw->wr_bitmap : NULL,
++ exceptfds ? (fd_set *) ldpw->ex_bitmap : NULL,
++ &libc_tspec, sigmask);
++ if (rv > 0)
++ {
++ ldp_select_libc_map_merge (ldpw->rd_bitmap, readfds);
++ ldp_select_libc_map_merge (ldpw->wr_bitmap, writefds);
++ ldp_select_libc_map_merge (ldpw->ex_bitmap, exceptfds);
++ bits_set += rv;
++ }
++ }
++
++ if (bits_set)
++ {
++ rv = bits_set;
++ goto done;
++ }
++ }
++ while ((time_out == -1) || (clib_time_now (&ldpw->clib_time) < time_out));
++ rv = 0;
++
++done:
++ /* TBD: set timeout to amount of time left */
++ clib_bitmap_zero (ldpw->rd_bitmap);
++ clib_bitmap_zero (ldpw->si_rd_bitmap);
++ clib_bitmap_zero (ldpw->libc_rd_bitmap);
++ clib_bitmap_zero (ldpw->wr_bitmap);
++ clib_bitmap_zero (ldpw->si_wr_bitmap);
++ clib_bitmap_zero (ldpw->libc_wr_bitmap);
++ clib_bitmap_zero (ldpw->ex_bitmap);
++ clib_bitmap_zero (ldpw->si_ex_bitmap);
++ clib_bitmap_zero (ldpw->libc_ex_bitmap);
++
++ return rv;
++}
++
++int
++select (int nfds, fd_set * __restrict readfds,
++ fd_set * __restrict writefds,
++ fd_set * __restrict exceptfds, struct timeval *__restrict timeout)
++{
++ struct timespec tspec;
++
++ if (timeout)
++ {
++ tspec.tv_sec = timeout->tv_sec;
++ tspec.tv_nsec = timeout->tv_usec * 1000;
++ }
++ return ldp_pselect (nfds, readfds, writefds, exceptfds,
++ timeout ? &tspec : NULL, NULL);
++}
++
++#ifdef __USE_XOPEN2K
++int
++pselect (int nfds, fd_set * __restrict readfds,
++ fd_set * __restrict writefds,
++ fd_set * __restrict exceptfds,
++ const struct timespec *__restrict timeout,
++ const __sigset_t * __restrict sigmask)
++{
++ return ldp_pselect (nfds, readfds, writefds, exceptfds, timeout, 0);
++}
++#endif
++
++/* If transparent TLS mode is turned on, then ldp will load key and cert.
++ */
++static int
++load_tls_cert (vls_handle_t vlsh)
++{
++ char *env_var_str = getenv (LDP_ENV_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)
++ {
++ LDBG (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 (vlsh_to_session_index (vlsh), tls_cert,
++ cert_size);
++ fclose (fp);
++ }
++ else
++ {
++ LDBG (0, "ERROR: failed to read LDP environment %s\n",
++ LDP_ENV_TLS_CERT);
++ return -1;
++ }
++ return 0;
++}
++
++static int
++load_tls_key (vls_handle_t vlsh)
++{
++ char *env_var_str = getenv (LDP_ENV_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)
++ {
++ LDBG (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 (vlsh_to_session_index (vlsh), tls_key,
++ key_size);
++ fclose (fp);
++ }
++ else
++ {
++ LDBG (0, "ERROR: failed to read LDP environment %s\n", LDP_ENV_TLS_KEY);
++ return -1;
++ }
++ return 0;
++}
++
++int
++socket (int domain, int type, int protocol)
++{
++ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
++ u8 is_nonblocking = type & SOCK_NONBLOCK ? 1 : 0;
++ vls_handle_t vlsh;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ if (((domain == AF_INET) || (domain == AF_INET6)) &&
++ ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
++ {
++ u8 proto;
++ if (ldp->transparent_tls)
++ {
++ proto = VPPCOM_PROTO_TLS;
++ }
++ else
++ proto = ((sock_type == SOCK_DGRAM) ?
++ VPPCOM_PROTO_UDP : VPPCOM_PROTO_TCP);
++
++ LDBG (0, "calling vls_create: proto %u (%s), is_nonblocking %u",
++ proto, vppcom_proto_str (proto), is_nonblocking);
++
++ vlsh = vls_create (proto, is_nonblocking);
++ if (vlsh < 0)
++ {
++ errno = -vlsh;
++ rv = -1;
++ }
++ else
++ {
++ if (ldp->transparent_tls)
++ {
++ if (load_tls_cert (vlsh) < 0 || load_tls_key (vlsh) < 0)
++ {
++ return -1;
++ }
++ }
++ rv = ldp_vlsh_to_fd (vlsh);
++ }
++ }
++ else
++ {
++ LDBG (0, "calling libc_socket");
++ rv = libc_socket (domain, type, protocol);
++ }
++
++ return rv;
++}
++
++/*
++ * Create two new sockets, of type TYPE in domain DOMAIN and using
++ * protocol PROTOCOL, which are connected to each other, and put file
++ * descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero,
++ * one will be chosen automatically.
++ * Returns 0 on success, -1 for errors.
++ * */
++int
++socketpair (int domain, int type, int protocol, int fds[2])
++{
++ int rv, sock_type = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ if (((domain == AF_INET) || (domain == AF_INET6)) &&
++ ((sock_type == SOCK_STREAM) || (sock_type == SOCK_DGRAM)))
++ {
++ LDBG (0, "LDP-TBD");
++ errno = ENOSYS;
++ rv = -1;
++ }
++ else
++ {
++ LDBG (1, "calling libc_socketpair");
++ rv = libc_socketpair (domain, type, protocol, fds);
++ }
++
++ return rv;
++}
++
++int
++bind (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
++{
++ vls_handle_t vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ vppcom_endpt_t ep;
++
++ switch (addr->sa_family)
++ {
++ case AF_INET:
++ if (len != sizeof (struct sockaddr_in))
++ {
++ LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET addr len %u!",
++ fd, vlsh, len);
++ 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 (len != sizeof (struct sockaddr_in6))
++ {
++ LDBG (0, "ERROR: fd %d: vlsh %u: Invalid AF_INET6 addr len %u!",
++ fd, vlsh, len);
++ 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:
++ LDBG (0, "ERROR: fd %d: vlsh %u: Unsupported address family %u!",
++ fd, vlsh, addr->sa_family);
++ errno = EAFNOSUPPORT;
++ rv = -1;
++ goto done;
++ }
++ LDBG (0, "fd %d: calling vls_bind: vlsh %u, addr %p, len %u", fd, vlsh,
++ addr, len);
++
++ rv = vls_bind (vlsh, &ep);
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ else
++ {
++ LDBG (0, "fd %d: calling libc_bind: addr %p, len %u", fd, addr, len);
++ rv = libc_bind (fd, addr, len);
++ }
++
++done:
++ LDBG (1, "fd %d: returning %d", fd, rv);
++
++ return rv;
++}
++
++static inline int
++ldp_copy_ep_to_sockaddr (__SOCKADDR_ARG addr, socklen_t * __restrict len,
++ vppcom_endpt_t * ep)
++{
++ int rv = 0;
++ int sa_len, copy_len;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ 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;
++}
++
++int
++getsockname (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
++{
++ vls_handle_t vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ vppcom_endpt_t ep;
++ u8 addr_buf[sizeof (struct in6_addr)];
++ u32 size = sizeof (ep);
++
++ ep.ip = addr_buf;
++
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LCL_ADDR, &ep, &size);
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ else
++ {
++ rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ }
++ else
++ {
++ rv = libc_getsockname (fd, addr, len);
++ }
++
++ return rv;
++}
++
++int
++connect (int fd, __CONST_SOCKADDR_ARG addr, socklen_t len)
++{
++ vls_handle_t vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ if (!addr)
++ {
++ LDBG (0, "ERROR: fd %d: NULL addr, len %u", fd, len);
++ errno = EINVAL;
++ rv = -1;
++ goto done;
++ }
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ vppcom_endpt_t ep;
++
++ switch (addr->sa_family)
++ {
++ case AF_INET:
++ if (len != sizeof (struct sockaddr_in))
++ {
++ LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET addr len %u!",
++ fd, vlsh, len);
++ 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 (len != sizeof (struct sockaddr_in6))
++ {
++ LDBG (0, "fd %d: ERROR vlsh %u: Invalid AF_INET6 addr len %u!",
++ fd, vlsh, len);
++ 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:
++ LDBG (0, "fd %d: ERROR vlsh %u: Unsupported address family %u!",
++ fd, vlsh, addr->sa_family);
++ errno = EAFNOSUPPORT;
++ rv = -1;
++ goto done;
++ }
++ LDBG (0, "fd %d: calling vls_connect(): vlsh %u addr %p len %u", fd,
++ vlsh, addr, len);
++
++ rv = vls_connect (vlsh, &ep);
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ else
++ {
++ LDBG (0, "fd %d: calling libc_connect(): addr %p, len %u",
++ fd, addr, len);
++
++ rv = libc_connect (fd, addr, len);
++ }
++
++done:
++ LDBG (1, "fd %d: returning %d (0x%x)", fd, rv, rv);
++ return rv;
++}
++
++int
++getpeername (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict len)
++{
++ vls_handle_t vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ vppcom_endpt_t ep;
++ u8 addr_buf[sizeof (struct in6_addr)];
++ u32 size = sizeof (ep);
++
++ ep.ip = addr_buf;
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PEER_ADDR, &ep, &size);
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ else
++ {
++ rv = ldp_copy_ep_to_sockaddr (addr, len, &ep);
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ }
++ else
++ {
++ rv = libc_getpeername (fd, addr, len);
++ }
++
++ return rv;
++}
++
++ssize_t
++send (int fd, const void *buf, size_t n, int flags)
++{
++ vls_handle_t vlsh = ldp_fd_to_vlsh (fd);
++ ssize_t size;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ size = vls_sendto (vlsh, (void *) buf, n, flags, NULL);
++ if (size < VPPCOM_OK)
++ {
++ errno = -size;
++ size = -1;
++ }
++ }
++ else
++ {
++ size = libc_send (fd, buf, n, flags);
++ }
++
++ return size;
++}
++
++ssize_t
++sendfile (int out_fd, int in_fd, off_t * offset, size_t len)
++{
++ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
++ vls_handle_t vlsh;
++ ssize_t size = 0;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (out_fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ int rv;
++ 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 = vls_attr (vlsh, VPPCOM_ATTR_GET_FLAGS, &flags, &flags_len);
++ if (PREDICT_FALSE (rv != VPPCOM_OK))
++ {
++ LDBG (0, "ERROR: out fd %d: vls_attr: vlsh %u, returned %d (%s)!",
++ out_fd, vlsh, rv, vppcom_retval_str (rv));
++
++ vec_reset_length (ldpw->io_buffer);
++ errno = -rv;
++ size = -1;
++ goto done;
++ }
++
++ if (offset)
++ {
++ off_t off = lseek (in_fd, *offset, SEEK_SET);
++ if (PREDICT_FALSE (off == -1))
++ {
++ size = -1;
++ goto done;
++ }
++
++ ASSERT (off == *offset);
++ }
++
++ do
++ {
++ size = vls_attr (vlsh, VPPCOM_ATTR_GET_NWRITE, 0, 0);
++ if (size < 0)
++ {
++ LDBG (0, "ERROR: fd %d: vls_attr: vlsh %u returned %d (%s)!",
++ out_fd, vlsh, size, vppcom_retval_str (size));
++ vec_reset_length (ldpw->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 (ldpw->io_buffer, bytes_to_read);
++ nbytes = libc_read (in_fd, ldpw->io_buffer, bytes_to_read);
++ if (nbytes < 0)
++ {
++ if (results == 0)
++ {
++ vec_reset_length (ldpw->io_buffer);
++ size = -1;
++ goto done;
++ }
++ goto update_offset;
++ }
++
++ size = vls_write (vlsh, ldpw->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 (ldpw->io_buffer);
++ errno = -size;
++ size = -1;
++ goto done;
++ }
++ goto update_offset;
++ }
++
++ results += nbytes;
++ ASSERT (n_bytes_left >= nbytes);
++ n_bytes_left = n_bytes_left - nbytes;
++ }
++ while (n_bytes_left > 0);
++
++ update_offset:
++ vec_reset_length (ldpw->io_buffer);
++ if (offset)
++ {
++ off_t off = lseek (in_fd, *offset, SEEK_SET);
++ if (PREDICT_FALSE (off == -1))
++ {
++ size = -1;
++ goto done;
++ }
++
++ ASSERT (off == *offset);
++ *offset += results + 1;
++ }
++ if (eagain)
++ {
++ errno = EAGAIN;
++ size = -1;
++ }
++ else
++ size = results;
++ }
++ else
++ {
++ size = libc_sendfile (out_fd, in_fd, offset, len);
++ }
++
++done:
++ return size;
++}
++
++ssize_t
++sendfile64 (int out_fd, int in_fd, off_t * offset, size_t len)
++{
++ return sendfile (out_fd, in_fd, offset, len);
++}
++
++ssize_t
++recv (int fd, void *buf, size_t n, int flags)
++{
++ vls_handle_t vlsh;
++ ssize_t size;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ size = vls_recvfrom (vlsh, buf, n, flags, NULL);
++ if (size < 0)
++ {
++ errno = -size;
++ size = -1;
++ }
++ }
++ else
++ {
++ size = libc_recv (fd, buf, n, flags);
++ }
++
++ return size;
++}
++
++ssize_t
++sendto (int fd, const void *buf, size_t n, int flags,
++ __CONST_SOCKADDR_ARG addr, socklen_t addr_len)
++{
++ vls_handle_t vlsh;
++ ssize_t size;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != INVALID_SESSION_ID)
++ {
++ 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 = vls_sendto (vlsh, (void *) buf, n, flags, ep);
++ if (size < 0)
++ {
++ errno = -size;
++ size = -1;
++ }
++ }
++ else
++ {
++ size = libc_sendto (fd, buf, n, flags, addr, addr_len);
++ }
++
++done:
++ return size;
++}
++
++ssize_t
++recvfrom (int fd, void *__restrict buf, size_t n, int flags,
++ __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
++{
++ vls_handle_t sid;
++ ssize_t size, rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ sid = ldp_fd_to_vlsh (fd);
++ if (sid != VLS_INVALID_HANDLE)
++ {
++ vppcom_endpt_t ep;
++ u8 src_addr[sizeof (struct sockaddr_in6)];
++
++ if (addr)
++ {
++ ep.ip = src_addr;
++ size = vls_recvfrom (sid, buf, n, flags, &ep);
++
++ if (size > 0)
++ {
++ rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
++ if (rv < 0)
++ size = rv;
++ }
++ }
++ else
++ size = vls_recvfrom (sid, buf, n, flags, NULL);
++
++ if (size < 0)
++ {
++ errno = -size;
++ size = -1;
++ }
++ }
++ else
++ {
++ size = libc_recvfrom (fd, buf, n, flags, addr, addr_len);
++ }
++
++ return size;
++}
++
++ssize_t
++sendmsg (int fd, const struct msghdr * message, int flags)
++{
++ vls_handle_t vlsh;
++ ssize_t size;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ LDBG (0, "LDP-TBD");
++ errno = ENOSYS;
++ size = -1;
++ }
++ else
++ {
++ size = libc_sendmsg (fd, message, flags);
++ }
++
++ return size;
++}
++
++#ifdef USE_GNU
++int
++sendmmsg (int fd, struct mmsghdr *vmessages, unsigned int vlen, int flags)
++{
++ ssize_t size;
++ const char *func_str;
++ u32 sh = ldp_fd_to_vlsh (fd);
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ if (sh != INVALID_SESSION_ID)
++ {
++ clib_warning ("LDP<%d>: LDP-TBD", getpid ());
++ errno = ENOSYS;
++ size = -1;
++ }
++ else
++ {
++ func_str = "libc_sendmmsg";
++
++ if (LDP_DEBUG > 2)
++ clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
++ "vmessages %p, vlen %u, flags 0x%x",
++ getpid (), fd, fd, func_str, vmessages, vlen, flags);
++
++ size = libc_sendmmsg (fd, vmessages, vlen, flags);
++ }
++
++ if (LDP_DEBUG > 2)
++ {
++ if (size < 0)
++ {
++ int errno_val = errno;
++ perror (func_str);
++ clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
++ "rv %d, errno = %d", getpid (), fd, fd,
++ func_str, size, errno_val);
++ errno = errno_val;
++ }
++ else
++ clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
++ getpid (), fd, fd, size, size);
++ }
++ return size;
++}
++#endif
++
++ssize_t
++recvmsg (int fd, struct msghdr * message, int flags)
++{
++ vls_handle_t vlsh;
++ ssize_t size;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ LDBG (0, "LDP-TBD");
++ errno = ENOSYS;
++ size = -1;
++ }
++ else
++ {
++ size = libc_recvmsg (fd, message, flags);
++ }
++
++ return size;
++}
++
++#ifdef USE_GNU
++int
++recvmmsg (int fd, struct mmsghdr *vmessages,
++ unsigned int vlen, int flags, struct timespec *tmo)
++{
++ ssize_t size;
++ const char *func_str;
++ u32 sh = ldp_fd_to_vlsh (fd);
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ if (sh != INVALID_SESSION_ID)
++ {
++ clib_warning ("LDP<%d>: LDP-TBD", getpid ());
++ errno = ENOSYS;
++ size = -1;
++ }
++ else
++ {
++ func_str = "libc_recvmmsg";
++
++ if (LDP_DEBUG > 2)
++ clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): "
++ "vmessages %p, vlen %u, flags 0x%x, tmo %p",
++ getpid (), fd, fd, func_str, vmessages, vlen,
++ flags, tmo);
++
++ size = libc_recvmmsg (fd, vmessages, vlen, flags, tmo);
++ }
++
++ if (LDP_DEBUG > 2)
++ {
++ if (size < 0)
++ {
++ int errno_val = errno;
++ perror (func_str);
++ clib_warning ("LDP<%d>: ERROR: fd %d (0x%x): %s() failed! "
++ "rv %d, errno = %d", getpid (), fd, fd,
++ func_str, size, errno_val);
++ errno = errno_val;
++ }
++ else
++ clib_warning ("LDP<%d>: fd %d (0x%x): returning %d (0x%x)",
++ getpid (), fd, fd, size, size);
++ }
++ return size;
++}
++#endif
++
++int
++getsockopt (int fd, int level, int optname,
++ void *__restrict optval, socklen_t * __restrict optlen)
++{
++ vls_handle_t vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ rv = -EOPNOTSUPP;
++
++ switch (level)
++ {
++ case SOL_TCP:
++ switch (optname)
++ {
++ case TCP_NODELAY:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_NODELAY,
++ optval, optlen);
++ break;
++ case TCP_MAXSEG:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_USER_MSS,
++ optval, optlen);
++ break;
++ case TCP_KEEPIDLE:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPIDLE,
++ optval, optlen);
++ break;
++ case TCP_KEEPINTVL:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TCP_KEEPINTVL,
++ optval, optlen);
++ break;
++ case TCP_INFO:
++ if (optval && optlen && (*optlen == sizeof (struct tcp_info)))
++ {
++ LDBG (1, "fd %d: vlsh %u SOL_TCP, TCP_INFO, optval %p, "
++ "optlen %d: #LDP-NOP#", fd, vlsh, optval, *optlen);
++ memset (optval, 0, *optlen);
++ rv = VPPCOM_OK;
++ }
++ else
++ rv = -EFAULT;
++ break;
++ case TCP_CONGESTION:
++ *optlen = strlen ("cubic");
++ strncpy (optval, "cubic", *optlen + 1);
++ rv = 0;
++ break;
++ default:
++ LDBG (0, "ERROR: fd %d: getsockopt SOL_TCP: sid %u, "
++ "optname %d unsupported!", fd, vlsh, optname);
++ break;
++ }
++ break;
++ case SOL_IPV6:
++ switch (optname)
++ {
++ case IPV6_V6ONLY:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_V6ONLY, optval, optlen);
++ break;
++ default:
++ LDBG (0, "ERROR: fd %d: getsockopt SOL_IPV6: vlsh %u "
++ "optname %d unsupported!", fd, vlsh, optname);
++ break;
++ }
++ break;
++ case SOL_SOCKET:
++ switch (optname)
++ {
++ case SO_ACCEPTCONN:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_LISTEN, optval, optlen);
++ break;
++ case SO_KEEPALIVE:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_KEEPALIVE, optval, optlen);
++ break;
++ case SO_PROTOCOL:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_PROTOCOL, optval, optlen);
++ *(int *) optval = *(int *) optval ? SOCK_DGRAM : SOCK_STREAM;
++ break;
++ case SO_SNDBUF:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_TX_FIFO_LEN,
++ optval, optlen);
++ break;
++ case SO_RCVBUF:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_RX_FIFO_LEN,
++ optval, optlen);
++ break;
++ case SO_REUSEADDR:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_REUSEADDR, optval, optlen);
++ break;
++ case SO_BROADCAST:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_BROADCAST, optval, optlen);
++ break;
++ case SO_ERROR:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_GET_ERROR, optval, optlen);
++ break;
++ default:
++ LDBG (0, "ERROR: fd %d: getsockopt SOL_SOCKET: vlsh %u "
++ "optname %d unsupported!", fd, vlsh, optname);
++ break;
++ }
++ break;
++ default:
++ break;
++ }
++
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ else
++ {
++ rv = libc_getsockopt (fd, level, optname, optval, optlen);
++ }
++
++ return rv;
++}
++
++int
++setsockopt (int fd, int level, int optname,
++ const void *optval, socklen_t optlen)
++{
++ vls_handle_t vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ rv = -EOPNOTSUPP;
++
++ switch (level)
++ {
++ case SOL_TCP:
++ switch (optname)
++ {
++ case TCP_NODELAY:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_NODELAY,
++ (void *) optval, &optlen);
++ break;
++ case TCP_MAXSEG:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_USER_MSS,
++ (void *) optval, &optlen);
++ break;
++ case TCP_KEEPIDLE:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPIDLE,
++ (void *) optval, &optlen);
++ break;
++ case TCP_KEEPINTVL:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_TCP_KEEPINTVL,
++ (void *) optval, &optlen);
++ break;
++ case TCP_CONGESTION:
++ case TCP_CORK:
++ /* Ignore */
++ rv = 0;
++ break;
++ default:
++ LDBG (0, "ERROR: fd %d: setsockopt() SOL_TCP: vlsh %u"
++ "optname %d unsupported!", fd, vlsh, optname);
++ break;
++ }
++ break;
++ case SOL_IPV6:
++ switch (optname)
++ {
++ case IPV6_V6ONLY:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_V6ONLY,
++ (void *) optval, &optlen);
++ break;
++ default:
++ LDBG (0, "ERROR: fd %d: setsockopt SOL_IPV6: vlsh %u"
++ "optname %d unsupported!", fd, vlsh, optname);
++ break;
++ }
++ break;
++ case SOL_SOCKET:
++ switch (optname)
++ {
++ case SO_KEEPALIVE:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_KEEPALIVE,
++ (void *) optval, &optlen);
++ break;
++ case SO_REUSEADDR:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_REUSEADDR,
++ (void *) optval, &optlen);
++ break;
++ case SO_BROADCAST:
++ rv = vls_attr (vlsh, VPPCOM_ATTR_SET_BROADCAST,
++ (void *) optval, &optlen);
++ break;
++ default:
++ LDBG (0, "ERROR: fd %d: setsockopt SOL_SOCKET: vlsh %u "
++ "optname %d unsupported!", fd, vlsh, optname);
++ break;
++ }
++ break;
++ default:
++ break;
++ }
++
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ else
++ {
++ rv = libc_setsockopt (fd, level, optname, optval, optlen);
++ }
++
++ return rv;
++}
++
++int
++listen (int fd, int n)
++{
++ vls_handle_t vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ LDBG (0, "fd %d: calling vls_listen: vlsh %u, n %d", fd, vlsh, n);
++
++ rv = vls_listen (vlsh, n);
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ else
++ {
++ LDBG (0, "fd %d: calling libc_listen(): n %d", fd, n);
++ rv = libc_listen (fd, n);
++ }
++
++ LDBG (1, "fd %d: returning %d", fd, rv);
++ return rv;
++}
++
++static inline int
++ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr,
++ socklen_t * __restrict addr_len, int flags)
++{
++ vls_handle_t listen_vlsh, accept_vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ listen_vlsh = ldp_fd_to_vlsh (listen_fd);
++ if (listen_vlsh != VLS_INVALID_HANDLE)
++ {
++ vppcom_endpt_t ep;
++ u8 src_addr[sizeof (struct sockaddr_in6)];
++ memset (&ep, 0, sizeof (ep));
++ ep.ip = src_addr;
++
++ LDBG (0, "listen fd %d: calling vppcom_session_accept: listen sid %u,"
++ " ep %p, flags 0x%x", listen_fd, listen_vlsh, ep, flags);
++
++ accept_vlsh = vls_accept (listen_vlsh, &ep, flags);
++ if (accept_vlsh < 0)
++ {
++ errno = -accept_vlsh;
++ rv = -1;
++ }
++ else
++ {
++ rv = ldp_copy_ep_to_sockaddr (addr, addr_len, &ep);
++ if (rv != VPPCOM_OK)
++ {
++ (void) vls_close (accept_vlsh);
++ errno = -rv;
++ rv = -1;
++ }
++ else
++ {
++ rv = ldp_vlsh_to_fd (accept_vlsh);
++ }
++ }
++ }
++ else
++ {
++ LDBG (0, "listen fd %d: calling libc_accept4(): addr %p, addr_len %p,"
++ " flags 0x%x", listen_fd, addr, addr_len, flags);
++
++ rv = libc_accept4 (listen_fd, addr, addr_len, flags);
++ }
++
++ LDBG (1, "listen fd %d: accept returning %d", listen_fd, rv);
++
++ return rv;
++}
++
++int
++accept4 (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len,
++ int flags)
++{
++ return ldp_accept4 (fd, addr, addr_len, flags);
++}
++
++int
++accept (int fd, __SOCKADDR_ARG addr, socklen_t * __restrict addr_len)
++{
++ return ldp_accept4 (fd, addr, addr_len, 0);
++}
++
++int
++shutdown (int fd, int how)
++{
++ vls_handle_t vlsh;
++ int rv = 0, flags;
++ u32 flags_len = sizeof (flags);
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vlsh = ldp_fd_to_vlsh (fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ LDBG (0, "called shutdown: fd %u vlsh %u how %d", fd, vlsh, how);
++
++ if (vls_attr (vlsh, VPPCOM_ATTR_SET_SHUT, &how, &flags_len))
++ {
++ close (fd);
++ return -1;
++ }
++
++ if (vls_attr (vlsh, VPPCOM_ATTR_GET_SHUT, &flags, &flags_len))
++ {
++ close (fd);
++ return -1;
++ }
++
++ if (flags == SHUT_RDWR)
++ rv = close (fd);
++ }
++ else
++ {
++ LDBG (0, "fd %d: calling libc_shutdown: how %d", fd, how);
++ rv = libc_shutdown (fd, how);
++ }
++
++ return rv;
++}
++
++int
++epoll_create1 (int flags)
++{
++ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
++ vls_handle_t vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ if (ldp->vcl_needs_real_epoll)
++ {
++ /* Make sure workers have been allocated */
++ if (!ldp->workers)
++ {
++ ldp_alloc_workers ();
++ ldpw = ldp_worker_get_current ();
++ }
++ rv = libc_epoll_create1 (flags);
++ ldp->vcl_needs_real_epoll = 0;
++ ldpw->vcl_mq_epfd = rv;
++ LDBG (0, "created vcl epfd %u", rv);
++ return rv;
++ }
++
++ vlsh = vls_epoll_create ();
++ if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE))
++ {
++ errno = -vlsh;
++ rv = -1;
++ }
++ else
++ {
++ rv = ldp_vlsh_to_fd (vlsh);
++ }
++ LDBG (0, "epoll_create epfd %u vlsh %u", rv, vlsh);
++ return rv;
++}
++
++int
++epoll_create (int size)
++{
++ return epoll_create1 (0);
++}
++
++int
++epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
++{
++ vls_handle_t vep_vlsh, vlsh;
++ int rv;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ vep_vlsh = ldp_fd_to_vlsh (epfd);
++ if (PREDICT_FALSE (vep_vlsh == VLS_INVALID_HANDLE))
++ {
++ /* The LDP epoll_create1 always creates VCL epfd's.
++ * The app should never have a kernel base epoll fd unless it
++ * was acquired outside of the LD_PRELOAD process context.
++ * In any case, if we get one, punt it to libc_epoll_ctl.
++ */
++ LDBG (1, "epfd %d: calling libc_epoll_ctl: op %d, fd %d"
++ " event %p", epfd, op, fd, event);
++
++ rv = libc_epoll_ctl (epfd, op, fd, event);
++ goto done;
++ }
++
++ vlsh = ldp_fd_to_vlsh (fd);
++
++ LDBG (0, "epfd %d ep_vlsh %d, fd %u vlsh %d, op %u", epfd, vep_vlsh, fd,
++ vlsh, op);
++
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ LDBG (1, "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
++ " event %p", epfd, vep_vlsh, vlsh, event);
++
++ rv = vls_epoll_ctl (vep_vlsh, op, vlsh, event);
++ if (rv != VPPCOM_OK)
++ {
++ errno = -rv;
++ rv = -1;
++ }
++ }
++ else
++ {
++ int libc_epfd;
++ u32 size = sizeof (epfd);
++
++ libc_epfd = vls_attr (vep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
++ if (!libc_epfd)
++ {
++ LDBG (1, "epfd %d, vep_vlsh %d calling libc_epoll_create1: "
++ "EPOLL_CLOEXEC", epfd, vep_vlsh);
++
++ libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
++ if (libc_epfd < 0)
++ {
++ rv = libc_epfd;
++ goto done;
++ }
++
++ rv = vls_attr (vep_vlsh, VPPCOM_ATTR_SET_LIBC_EPFD, &libc_epfd,
++ &size);
++ if (rv < 0)
++ {
++ errno = -rv;
++ rv = -1;
++ goto done;
++ }
++ }
++ else if (PREDICT_FALSE (libc_epfd < 0))
++ {
++ errno = -epfd;
++ rv = -1;
++ goto done;
++ }
++
++ LDBG (1, "epfd %d: calling libc_epoll_ctl: libc_epfd %d, op %d, fd %d,"
++ " event %p", epfd, libc_epfd, op, fd, event);
++
++ rv = libc_epoll_ctl (libc_epfd, op, fd, event);
++ }
++
++done:
++ return rv;
++}
++
++static inline int
++ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
++ int timeout, const sigset_t * sigmask)
++{
++ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
++ double time_to_wait = (double) 0, max_time;
++ int libc_epfd, rv = 0;
++ vls_handle_t ep_vlsh;
++
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ if (PREDICT_FALSE (!events || (timeout < -1)))
++ {
++ errno = EFAULT;
++ return -1;
++ }
++
++ if (epfd == ldpw->vcl_mq_epfd)
++ return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
++
++ ep_vlsh = ldp_fd_to_vlsh (epfd);
++ if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE))
++ {
++ LDBG (0, "epfd %d: bad ep_vlsh %d!", epfd, ep_vlsh);
++ errno = EBADFD;
++ return -1;
++ }
++
++ if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
++ clib_time_init (&ldpw->clib_time);
++ time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0);
++ max_time = clib_time_now (&ldpw->clib_time) + time_to_wait;
++
++ libc_epfd = vls_attr (ep_vlsh, VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
++ if (PREDICT_FALSE (libc_epfd < 0))
++ {
++ errno = -libc_epfd;
++ rv = -1;
++ goto done;
++ }
++
++ LDBG (2, "epfd %d: vep_idx %d, libc_epfd %d, events %p, maxevents %d, "
++ "timeout %d, sigmask %p: time_to_wait %.02f", epfd, ep_vlsh,
++ libc_epfd, events, maxevents, timeout, sigmask, time_to_wait);
++ do
++ {
++ if (!ldpw->epoll_wait_vcl)
++ {
++ rv = vls_epoll_wait (ep_vlsh, events, maxevents, 0);
++ if (rv > 0)
++ {
++ ldpw->epoll_wait_vcl = 1;
++ goto done;
++ }
++ else if (rv < 0)
++ {
++ errno = -rv;
++ rv = -1;
++ goto done;
++ }
++ }
++ else
++ ldpw->epoll_wait_vcl = 0;
++
++ if (libc_epfd > 0)
++ {
++ rv = libc_epoll_pwait (libc_epfd, events, maxevents, 0, sigmask);
++ if (rv != 0)
++ goto done;
++ }
++ }
++ while ((timeout == -1) || (clib_time_now (&ldpw->clib_time) < max_time));
++
++done:
++ return rv;
++}
++
++int
++epoll_pwait (int epfd, struct epoll_event *events,
++ int maxevents, int timeout, const sigset_t * sigmask)
++{
++ return ldp_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
++}
++
++int
++epoll_wait (int epfd, struct epoll_event *events, int maxevents, int timeout)
++{
++ return ldp_epoll_pwait (epfd, events, maxevents, timeout, NULL);
++}
++
++int
++poll (struct pollfd *fds, nfds_t nfds, int timeout)
++{
++ ldp_worker_ctx_t *ldpw = ldp_worker_get_current ();
++ int rv, i, n_revents = 0;
++ vls_handle_t vlsh;
++ vcl_poll_t *vp;
++ double max_time;
++
++ LDBG (3, "fds %p, nfds %d, timeout %d", fds, nfds, timeout);
++
++ if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0))
++ clib_time_init (&ldpw->clib_time);
++
++ max_time = (timeout >= 0) ? (f64) timeout / 1000 : 0;
++ max_time += clib_time_now (&ldpw->clib_time);
++
++ for (i = 0; i < nfds; i++)
++ {
++ if (fds[i].fd < 0)
++ continue;
++
++ vlsh = ldp_fd_to_vlsh (fds[i].fd);
++ if (vlsh != VLS_INVALID_HANDLE)
++ {
++ fds[i].fd = -fds[i].fd;
++ vec_add2 (ldpw->vcl_poll, vp, 1);
++ vp->fds_ndx = i;
++ vp->sh = vlsh_to_sh (vlsh);
++ vp->events = fds[i].events;
++#ifdef __USE_XOPEN2K
++ if (fds[i].events & POLLRDNORM)
++ vp->events |= POLLIN;
++ if (fds[i].events & POLLWRNORM)
++ vp->events |= POLLOUT;
++#endif
++ vp->revents = fds[i].revents;
++ }
++ else
++ {
++ vec_add1 (ldpw->libc_poll, fds[i]);
++ vec_add1 (ldpw->libc_poll_idxs, i);
++ }
++ }
++
++ do
++ {
++ if (vec_len (ldpw->vcl_poll))
++ {
++ rv = vppcom_poll (ldpw->vcl_poll, vec_len (ldpw->vcl_poll), 0);
++ if (rv < 0)
++ {
++ errno = -rv;
++ rv = -1;
++ goto done;
++ }
++ else
++ n_revents += rv;
++ }
++
++ if (vec_len (ldpw->libc_poll))
++ {
++ rv = libc_poll (ldpw->libc_poll, vec_len (ldpw->libc_poll), 0);
++ if (rv < 0)
++ goto done;
++ else
++ n_revents += rv;
++ }
++
++ if (n_revents)
++ {
++ rv = n_revents;
++ goto done;
++ }
++ }
++ while ((timeout < 0) || (clib_time_now (&ldpw->clib_time) < max_time));
++ rv = 0;
++
++done:
++ vec_foreach (vp, ldpw->vcl_poll)
++ {
++ fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
++ fds[vp->fds_ndx].revents = vp->revents;
++#ifdef __USE_XOPEN2K
++ if ((fds[vp->fds_ndx].revents & POLLIN) &&
++ (fds[vp->fds_ndx].events & POLLRDNORM))
++ fds[vp->fds_ndx].revents |= POLLRDNORM;
++ if ((fds[vp->fds_ndx].revents & POLLOUT) &&
++ (fds[vp->fds_ndx].events & POLLWRNORM))
++ fds[vp->fds_ndx].revents |= POLLWRNORM;
++#endif
++ }
++ vec_reset_length (ldpw->vcl_poll);
++
++ for (i = 0; i < vec_len (ldpw->libc_poll); i++)
++ {
++ fds[ldpw->libc_poll_idxs[i]].revents = ldpw->libc_poll[i].revents;
++ }
++ vec_reset_length (ldpw->libc_poll_idxs);
++ vec_reset_length (ldpw->libc_poll);
++
++ return rv;
++}
++
++#ifdef USE_GNU
++int
++ppoll (struct pollfd *fds, nfds_t nfds,
++ const struct timespec *timeout, const sigset_t * sigmask)
++{
++ if ((errno = -ldp_init ()))
++ return -1;
++
++ clib_warning ("LDP<%d>: LDP-TBD", getpid ());
++ errno = ENOSYS;
++
++
++ return -1;
++}
++#endif
++
++void CONSTRUCTOR_ATTRIBUTE ldp_constructor (void);
++
++void DESTRUCTOR_ATTRIBUTE ldp_destructor (void);
++
++/*
++ * This function is called when the library is loaded
++ */
++void
++ldp_constructor (void)
++{
++ swrap_constructor ();
++ if (ldp_init () != 0)
++ {
++ fprintf (stderr, "\nLDP<%d>: ERROR: ldp_constructor: failed!\n",
++ getpid ());
++ _exit (1);
++ }
++ else if (LDP_DEBUG > 0)
++ clib_warning ("LDP<%d>: LDP constructor: done!\n", getpid ());
++}
++
++/*
++ * This function is called when the library is unloaded
++ */
++void
++ldp_destructor (void)
++{
++ /*
++ swrap_destructor ();
++ if (ldp->init)
++ ldp->init = 0;
++ */
++
++ /* Don't use clib_warning() here because that calls writev()
++ * which will call ldp_init().
++ */
++ if (LDP_DEBUG > 0)
++ fprintf (stderr, "%s:%d: LDP<%d>: LDP destructor: done!\n",
++ __func__, __LINE__, getpid ());
++}
++
++
++/*
++ * fd.io coding-style-patch-verification: ON
++ *
++ * Local Variables:
++ * eval: (c-set-style "gnu")
++ * End:
++ */
+diff --git a/src/vcl/ldp.h b/src/vcl/ldp.h
+index 8d78ead08..0a03f442d 100644
+--- a/src/vcl/ldp.h
++++ b/src/vcl/ldp.h
+@@ -34,7 +34,7 @@
+ #define LDP_ENV_TLS_KEY "LDP_TLS_KEY_FILE"
+ #define LDP_ENV_TLS_TRANS "LDP_TRANSPARENT_TLS"
+
+-#define LDP_SID_BIT_MIN 5
++#define LDP_SID_BIT_MIN 16
+ #define LDP_SID_BIT_MAX 30
+
+ #define LDP_APP_NAME_MAX 256
+diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
+index c4ec02e83..c90b982bb 100644
+--- a/src/vcl/vcl_private.h
++++ b/src/vcl/vcl_private.h
+@@ -244,7 +244,12 @@ typedef struct vcl_worker_
+ /* Session pool */
+ vcl_session_t *sessions;
+
+- /** Worker/thread index in current process */
++ u32 listen_session_index;
++
++ u32 listen_fd;
++
++ u32 listen_queue_size;
++/** Worker/thread index in current process */
+ u32 wrk_index;
+
+ /** Worker index in vpp*/
+diff --git a/src/vcl/vcl_private.h.orig b/src/vcl/vcl_private.h.orig
+new file mode 100644
+index 000000000..12af09fbf
+--- /dev/null
++++ b/src/vcl/vcl_private.h.orig
+@@ -0,0 +1,679 @@
++/*
++ * Copyright (c) 2018-2019 Cisco and/or its affiliates.
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ * you may not use this
++ * You may obtain a copy of the License at:
++ *
++ * http://www.apache.org/licenses/LICENSE-2.0
++ *
++ * Unless required by applicable law or agreed to in writing, software
++ * distributed under the License is distributed on an "AS IS" BASIS,
++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ * See the License for the specific language governing permissions and
++ * limitations under the License.
++ */
++
++#ifndef SRC_VCL_VCL_PRIVATE_H_
++#define SRC_VCL_VCL_PRIVATE_H_
++
++#include <vnet/session/application_interface.h>
++#include <vcl/vppcom.h>
++#include <vcl/vcl_debug.h>
++
++#if (CLIB_DEBUG > 0)
++/* Set VPPCOM_DEBUG_INIT 2 for connection debug,
++ * 3 for read/write debug output
++ * or
++ * export VCL_DEBUG=<#> to set dynamically.
++ */
++#define VPPCOM_DEBUG_INIT 1
++#else
++#define VPPCOM_DEBUG_INIT 0
++#endif
++
++#define VPPCOM_DEBUG vcm->debug
++
++extern __thread uword __vcl_worker_index;
++
++static inline void
++vcl_set_worker_index (uword wrk_index)
++{
++ __vcl_worker_index = wrk_index;
++}
++
++static inline uword
++vcl_get_worker_index (void)
++{
++ return __vcl_worker_index;
++}
++
++/*
++ * VPPCOM Private definitions and functions.
++ */
++typedef enum
++{
++ STATE_APP_START,
++ STATE_APP_CONN_VPP,
++ STATE_APP_ENABLED,
++ STATE_APP_ATTACHED,
++ STATE_APP_ADDING_WORKER,
++ STATE_APP_ADDING_TLS_DATA,
++ STATE_APP_FAILED,
++ STATE_APP_READY
++} app_state_t;
++
++typedef enum
++{
++ STATE_CLOSED = 0,
++ STATE_CONNECT = 0x01,
++ STATE_LISTEN = 0x02,
++ STATE_ACCEPT = 0x04,
++ STATE_VPP_CLOSING = 0x08,
++ STATE_DISCONNECT = 0x10,
++ STATE_DETACHED = 0x20,
++ STATE_UPDATED = 0x40,
++ STATE_LISTEN_NO_MQ = 0x80,
++} vcl_session_state_t;
++
++#define SERVER_STATE_OPEN (STATE_ACCEPT|STATE_VPP_CLOSING)
++#define CLIENT_STATE_OPEN (STATE_CONNECT|STATE_VPP_CLOSING)
++#define STATE_OPEN (SERVER_STATE_OPEN | CLIENT_STATE_OPEN)
++
++typedef struct epoll_event vppcom_epoll_event_t;
++
++typedef struct
++{
++ u32 next_sh;
++ u32 prev_sh;
++ u32 vep_sh;
++ vppcom_epoll_event_t ev;
++#define VEP_DEFAULT_ET_MASK (EPOLLIN|EPOLLOUT)
++#define VEP_UNSUPPORTED_EVENTS (EPOLLONESHOT|EPOLLEXCLUSIVE)
++ u32 et_mask;
++} vppcom_epoll_t;
++
++/* Select uses the vcl_si_set as if a clib_bitmap. Make sure they are the
++ * same size */
++STATIC_ASSERT (sizeof (clib_bitmap_t) == sizeof (vcl_si_set),
++ "vppcom bitmap size mismatch");
++
++typedef struct
++{
++ u8 is_ip4;
++ ip46_address_t ip46;
++} vppcom_ip46_t;
++
++#define VCL_ACCEPTED_F_CLOSED (1 << 0)
++#define VCL_ACCEPTED_F_RESET (1 << 1)
++
++typedef struct vcl_session_msg
++{
++ union
++ {
++ session_accepted_msg_t accepted_msg;
++ };
++ u32 flags;
++} vcl_session_msg_t;
++
++typedef enum
++{
++ VCL_SESS_ATTR_SERVER,
++ VCL_SESS_ATTR_CUT_THRU,
++ VCL_SESS_ATTR_VEP,
++ VCL_SESS_ATTR_VEP_SESSION,
++ VCL_SESS_ATTR_LISTEN, // SOL_SOCKET,SO_ACCEPTCONN
++ VCL_SESS_ATTR_NONBLOCK, // fcntl,O_NONBLOCK
++ VCL_SESS_ATTR_REUSEADDR, // SOL_SOCKET,SO_REUSEADDR
++ VCL_SESS_ATTR_REUSEPORT, // SOL_SOCKET,SO_REUSEPORT
++ VCL_SESS_ATTR_BROADCAST, // SOL_SOCKET,SO_BROADCAST
++ VCL_SESS_ATTR_V6ONLY, // SOL_TCP,IPV6_V6ONLY
++ VCL_SESS_ATTR_KEEPALIVE, // SOL_SOCKET,SO_KEEPALIVE
++ VCL_SESS_ATTR_TCP_NODELAY, // SOL_TCP,TCP_NODELAY
++ VCL_SESS_ATTR_TCP_KEEPIDLE, // SOL_TCP,TCP_KEEPIDLE
++ VCL_SESS_ATTR_TCP_KEEPINTVL, // SOL_TCP,TCP_KEEPINTVL
++ VCL_SESS_ATTR_SHUT_RD,
++ VCL_SESS_ATTR_SHUT_WR,
++ VCL_SESS_ATTR_MAX
++} vppcom_session_attr_t;
++
++#define VCL_SESS_ATTR_SET(ATTR, VAL) \
++do { \
++ (ATTR) |= 1 << (VAL); \
++ } while (0)
++
++#define VCL_SESS_ATTR_CLR(ATTR, VAL) \
++do { \
++ (ATTR) &= ~(1 << (VAL)); \
++ } while (0)
++
++#define VCL_SESS_ATTR_TEST(ATTR, VAL) \
++ ((ATTR) & (1 << (VAL)) ? 1 : 0)
++
++typedef enum vcl_session_flags_
++{
++ VCL_SESSION_F_CONNECTED = 1 << 0,
++} __clib_packed vcl_session_flags_t;
++
++typedef struct
++{
++ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
++#define _(type, name) type name;
++ foreach_app_session_field
++#undef _
++ u32 sndbuf_size; // VPP-TBD: Hack until support setsockopt(SO_SNDBUF)
++ u32 rcvbuf_size; // VPP-TBD: Hack until support setsockopt(SO_RCVBUF)
++ u32 user_mss; // VPP-TBD: Hack until support setsockopt(TCP_MAXSEG)
++ u64 vpp_handle;
++ u32 vpp_thread_index;
++
++ svm_fifo_t *ct_rx_fifo;
++ svm_fifo_t *ct_tx_fifo;
++
++ /* Socket configuration state */
++ u8 is_vep;
++ u8 is_vep_session;
++ vcl_session_flags_t flags;
++ /* VCL session index of the listening session (if any) */
++ u32 listener_index;
++ /* Accepted sessions on this listener */
++ int n_accepted_sessions;
++ u8 has_rx_evt;
++ u32 attr;
++ u64 parent_handle;
++ vppcom_epoll_t vep;
++ int libc_epfd;
++ svm_msg_q_t *our_evt_q;
++ vcl_session_msg_t *accept_evts_fifo;
++#if VCL_ELOG
++ elog_track_t elog_track;
++#endif
++} vcl_session_t;
++
++typedef struct vppcom_cfg_t_
++{
++ uword heapsize;
++ u32 max_workers;
++ u32 vpp_api_q_length;
++ uword segment_baseva;
++ uword segment_size;
++ uword add_segment_size;
++ u32 preallocated_fifo_pairs;
++ u32 rx_fifo_size;
++ u32 tx_fifo_size;
++ u32 event_queue_size;
++ u32 listen_queue_size;
++ u8 app_proxy_transport_tcp;
++ u8 app_proxy_transport_udp;
++ u8 app_scope_local;
++ u8 app_scope_global;
++ u8 *namespace_id;
++ u64 namespace_secret;
++ u8 use_mq_eventfd;
++ f64 app_timeout;
++ f64 session_timeout;
++ f64 accept_timeout;
++ u32 event_ring_size;
++ char *event_log_path;
++ u8 *vpp_api_filename;
++ u8 *vpp_api_socket_name;
++ u8 *vpp_api_chroot;
++ u32 tls_engine;
++} vppcom_cfg_t;
++
++void vppcom_cfg (vppcom_cfg_t * vcl_cfg);
++
++typedef struct vcl_cut_through_registration_
++{
++ svm_msg_q_t *mq;
++ svm_msg_q_t *peer_mq;
++ u32 sid;
++ u32 epoll_evt_conn_index; /*< mq evt connection index part of
++ the mqs evtfd epoll (if used) */
++} vcl_cut_through_registration_t;
++
++typedef struct vcl_mq_evt_conn_
++{
++ svm_msg_q_t *mq;
++ int mq_fd;
++} vcl_mq_evt_conn_t;
++
++typedef struct vcl_worker_
++{
++ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
++
++ /* Session pool */
++ vcl_session_t *sessions;
++
++ /** Worker/thread index in current process */
++ u32 wrk_index;
++
++ /** Worker index in vpp*/
++ u32 vpp_wrk_index;
++
++ /** API client handle */
++ u32 my_client_index;
++
++ /** State of the connection, shared between msg RX thread and main thread */
++ volatile app_state_t wrk_state;
++
++ /** VPP binary api input queue */
++ svm_queue_t *vl_input_queue;
++
++ /** VPP mq to be used for exchanging control messages */
++ svm_msg_q_t *ctrl_mq;
++
++ /** Message queues epoll fd. Initialized only if using mqs with eventfds */
++ int mqs_epfd;
++
++ /** Pool of event message queue event connections */
++ vcl_mq_evt_conn_t *mq_evt_conns;
++
++ /** Per worker buffer for receiving mq epoll events */
++ struct epoll_event *mq_events;
++
++ /** Hash table for disconnect processing */
++ uword *session_index_by_vpp_handles;
++
++ /** Select bitmaps */
++ clib_bitmap_t *rd_bitmap;
++ clib_bitmap_t *wr_bitmap;
++ clib_bitmap_t *ex_bitmap;
++
++ /** Our event message queue */
++ svm_msg_q_t *app_event_queue;
++
++ /** VPP workers event message queues */
++ svm_msg_q_t **vpp_event_queues;
++
++ /** For deadman timers */
++ clib_time_t clib_time;
++
++ /** Vector acting as buffer for mq messages */
++ svm_msg_q_msg_t *mq_msg_vector;
++
++ /** Vector of unhandled events */
++ session_event_t *unhandled_evts_vector;
++
++ u32 *pending_session_wrk_updates;
++
++ /** Used also as a thread stop key buffer */
++ pthread_t thread_id;
++
++ /** Current pid, may be different from main_pid if forked child */
++ pid_t current_pid;
++
++ u32 forked_child;
++
++ socket_client_main_t bapi_sock_ctx;
++ memory_client_main_t bapi_shm_ctx;
++ api_main_t bapi_api_ctx;
++} vcl_worker_t;
++
++typedef struct vppcom_main_t_
++{
++ u8 is_init;
++ u32 debug;
++ pthread_t main_cpu;
++
++ /** Main process pid */
++ pid_t main_pid;
++
++ /** App's index in vpp. It's used by vpp to identify the app */
++ u32 app_index;
++
++ /** State of the connection, shared between msg RX thread and main thread */
++ volatile app_state_t app_state;
++
++ u8 *app_name;
++
++ /** VCL configuration */
++ vppcom_cfg_t cfg;
++
++ volatile u32 forking;
++
++ /** Workers */
++ vcl_worker_t *workers;
++
++ /** Lock to protect worker registrations */
++ clib_spinlock_t workers_lock;
++
++ /** Lock to protect segment hash table */
++ clib_rwlock_t segment_table_lock;
++
++ /** Mapped segments table */
++ uword *segment_table;
++
++ /** Control mq obtained from attach */
++ svm_msg_q_t *ctrl_mq;
++
++ fifo_segment_main_t segment_main;
++
++#ifdef VCL_ELOG
++ /* VPP Event-logger */
++ elog_main_t elog_main;
++ elog_track_t elog_track;
++#endif
++
++ /* VNET_API_ERROR_FOO -> "Foo" hash table */
++ uword *error_string_by_error_number;
++
++} vppcom_main_t;
++
++extern vppcom_main_t *vcm;
++
++#define VCL_INVALID_SESSION_INDEX ((u32)~0)
++#define VCL_INVALID_SESSION_HANDLE ((u64)~0)
++#define VCL_INVALID_SEGMENT_INDEX ((u32)~0)
++#define VCL_INVALID_SEGMENT_HANDLE ((u64)~0)
++
++static inline vcl_session_t *
++vcl_session_alloc (vcl_worker_t * wrk)
++{
++ vcl_session_t *s;
++ pool_get (wrk->sessions, s);
++ memset (s, 0, sizeof (*s));
++ s->session_index = s - wrk->sessions;
++ s->listener_index = VCL_INVALID_SESSION_INDEX;
++ return s;
++}
++
++static inline void
++vcl_session_free (vcl_worker_t * wrk, vcl_session_t * s)
++{
++ /* Debug level set to 1 to avoid debug messages while ldp is cleaning up */
++ VDBG (1, "session %u [0x%llx] removed", s->session_index, s->vpp_handle);
++ pool_put (wrk->sessions, s);
++}
++
++static inline vcl_session_t *
++vcl_session_get (vcl_worker_t * wrk, u32 session_index)
++{
++ if (pool_is_free_index (wrk->sessions, session_index))
++ return 0;
++ return pool_elt_at_index (wrk->sessions, session_index);
++}
++
++static inline vcl_session_handle_t
++vcl_session_handle_from_index (u32 session_index)
++{
++ ASSERT (session_index < 2 << 24);
++ return (vcl_get_worker_index () << 24 | session_index);
++}
++
++static inline vcl_session_handle_t
++vcl_session_handle (vcl_session_t * s)
++{
++ return vcl_session_handle_from_index (s->session_index);
++}
++
++static inline void
++vcl_session_handle_parse (u32 handle, u32 * wrk_index, u32 * session_index)
++{
++ *wrk_index = handle >> 24;
++ *session_index = handle & 0xFFFFFF;
++}
++
++static inline vcl_session_t *
++vcl_session_get_w_handle (vcl_worker_t * wrk, u32 session_handle)
++{
++ u32 session_index, wrk_index;
++ vcl_session_handle_parse (session_handle, &wrk_index, &session_index);
++ ASSERT (wrk_index == wrk->wrk_index);
++ return vcl_session_get (wrk, session_index);
++}
++
++static inline vcl_session_t *
++vcl_session_get_w_vpp_handle (vcl_worker_t * wrk, u64 vpp_handle)
++{
++ uword *p;
++ if ((p = hash_get (wrk->session_index_by_vpp_handles, vpp_handle)))
++ return vcl_session_get (wrk, (u32) p[0]);
++ return 0;
++}
++
++static inline u32
++vcl_session_index_from_vpp_handle (vcl_worker_t * wrk, u64 vpp_handle)
++{
++ uword *p;
++ if ((p = hash_get (wrk->session_index_by_vpp_handles, vpp_handle)))
++ return p[0];
++ return VCL_INVALID_SESSION_INDEX;
++}
++
++static inline void
++vcl_session_table_add_vpp_handle (vcl_worker_t * wrk, u64 handle, u32 value)
++{
++ hash_set (wrk->session_index_by_vpp_handles, handle, value);
++}
++
++static inline void
++vcl_session_table_del_vpp_handle (vcl_worker_t * wrk, u64 vpp_handle)
++{
++ hash_unset (wrk->session_index_by_vpp_handles, vpp_handle);
++}
++
++static inline uword *
++vcl_session_table_lookup_vpp_handle (vcl_worker_t * wrk, u64 handle)
++{
++ return hash_get (wrk->session_index_by_vpp_handles, handle);
++}
++
++static inline void
++vcl_session_table_add_listener (vcl_worker_t * wrk, u64 listener_handle,
++ u32 value)
++{
++ hash_set (wrk->session_index_by_vpp_handles, listener_handle, value);
++}
++
++static inline void
++vcl_session_table_del_listener (vcl_worker_t * wrk, u64 listener_handle)
++{
++ hash_unset (wrk->session_index_by_vpp_handles, listener_handle);
++}
++
++static inline int
++vcl_session_is_connectable_listener (vcl_worker_t * wrk,
++ vcl_session_t * session)
++{
++ /* Tell if we session_handle is a QUIC session.
++ * We can be in the following cases :
++ * Listen session <- QUIC session <- Stream session
++ * QUIC session <- Stream session
++ */
++ vcl_session_t *ls;
++ if (session->session_type != VPPCOM_PROTO_QUIC)
++ return 0;
++ if (session->listener_index == VCL_INVALID_SESSION_INDEX)
++ return !(session->session_state & STATE_LISTEN);
++ ls = vcl_session_get_w_handle (wrk, session->listener_index);
++ if (!ls)
++ return VPPCOM_EBADFD;
++ return ls->session_state & STATE_LISTEN;
++}
++
++static inline vcl_session_t *
++vcl_session_table_lookup_listener (vcl_worker_t * wrk, u64 handle)
++{
++ uword *p;
++ vcl_session_t *session;
++
++ p = hash_get (wrk->session_index_by_vpp_handles, handle);
++ if (!p)
++ {
++ VDBG (0, "could not find listen session: unknown vpp listener handle"
++ " %llx", handle);
++ return 0;
++ }
++ session = vcl_session_get (wrk, p[0]);
++ if (!session)
++ {
++ VDBG (1, "invalid listen session index (%u)", p[0]);
++ return 0;
++ }
++
++ ASSERT ((session->session_state & (STATE_LISTEN | STATE_LISTEN_NO_MQ)) ||
++ vcl_session_is_connectable_listener (wrk, session));
++ return session;
++}
++
++const char *vppcom_session_state_str (vcl_session_state_t state);
++
++static inline u8
++vcl_session_is_ct (vcl_session_t * s)
++{
++ return (s->ct_tx_fifo != 0);
++}
++
++static inline u8
++vcl_session_is_cl (vcl_session_t * s)
++{
++ if (s->session_type == VPPCOM_PROTO_UDP)
++ return 1;
++ return 0;
++}
++
++static inline u8
++vcl_session_is_open (vcl_session_t * s)
++{
++ return ((s->session_state & STATE_OPEN)
++ || (s->session_state == STATE_LISTEN
++ && s->session_type == VPPCOM_PROTO_UDP));
++}
++
++static inline u8
++vcl_session_is_closing (vcl_session_t * s)
++{
++ return (s->session_state == STATE_VPP_CLOSING
++ || s->session_state == STATE_DISCONNECT);
++}
++
++static inline int
++vcl_session_closing_error (vcl_session_t * s)
++{
++ /* Return 0 on closing sockets */
++ return s->session_state == STATE_DISCONNECT ? VPPCOM_ECONNRESET : 0;
++}
++
++static inline int
++vcl_session_closed_error (vcl_session_t * s)
++{
++ return s->session_state == STATE_DISCONNECT
++ ? VPPCOM_ECONNRESET : VPPCOM_ENOTCONN;
++}
++
++static inline void
++vcl_ip_copy_from_ep (ip46_address_t * ip, vppcom_endpt_t * ep)
++{
++ if (ep->is_ip4)
++ clib_memcpy_fast (&ip->ip4, ep->ip, sizeof (ip4_address_t));
++ else
++ clib_memcpy_fast (&ip->ip6, ep->ip, sizeof (ip6_address_t));
++}
++
++static inline void
++vcl_ip_copy_to_ep (ip46_address_t * ip, vppcom_endpt_t * ep, u8 is_ip4)
++{
++ ep->is_ip4 = is_ip4;
++ if (is_ip4)
++ clib_memcpy_fast (ep->ip, &ip->ip4, sizeof (ip4_address_t));
++ else
++ clib_memcpy_fast (ep->ip, &ip->ip6, sizeof (ip6_address_t));
++}
++
++/*
++ * Helpers
++ */
++int vcl_wait_for_app_state_change (app_state_t app_state);
++vcl_mq_evt_conn_t *vcl_mq_evt_conn_alloc (vcl_worker_t * wrk);
++u32 vcl_mq_evt_conn_index (vcl_worker_t * wrk, vcl_mq_evt_conn_t * mqc);
++vcl_mq_evt_conn_t *vcl_mq_evt_conn_get (vcl_worker_t * wrk, u32 mq_conn_idx);
++int vcl_mq_epoll_add_evfd (vcl_worker_t * wrk, svm_msg_q_t * mq);
++int vcl_mq_epoll_del_evfd (vcl_worker_t * wrk, u32 mqc_index);
++
++vcl_worker_t *vcl_worker_alloc_and_init (void);
++void vcl_worker_cleanup (vcl_worker_t * wrk, u8 notify_vpp);
++int vcl_worker_register_with_vpp (void);
++int vcl_worker_set_bapi (void);
++svm_msg_q_t *vcl_worker_ctrl_mq (vcl_worker_t * wrk);
++
++void vcl_flush_mq_events (void);
++void vcl_cleanup_bapi (void);
++int vcl_session_cleanup (vcl_worker_t * wrk, vcl_session_t * session,
++ vcl_session_handle_t sh, u8 do_disconnect);
++
++void vcl_segment_table_add (u64 segment_handle, u32 svm_segment_index);
++u32 vcl_segment_table_lookup (u64 segment_handle);
++void vcl_segment_table_del (u64 segment_handle);
++
++int vcl_session_read_ready (vcl_session_t * session);
++int vcl_session_write_ready (vcl_session_t * session);
++
++static inline vcl_worker_t *
++vcl_worker_get (u32 wrk_index)
++{
++ return pool_elt_at_index (vcm->workers, wrk_index);
++}
++
++static inline vcl_worker_t *
++vcl_worker_get_if_valid (u32 wrk_index)
++{
++ if (pool_is_free_index (vcm->workers, wrk_index))
++ return 0;
++ return pool_elt_at_index (vcm->workers, wrk_index);
++}
++
++static inline vcl_worker_t *
++vcl_worker_get_current (void)
++{
++ return vcl_worker_get (vcl_get_worker_index ());
++}
++
++static inline u8
++vcl_n_workers (void)
++{
++ return pool_elts (vcm->workers);
++}
++
++static inline svm_msg_q_t *
++vcl_session_vpp_evt_q (vcl_worker_t * wrk, vcl_session_t * s)
++{
++ return wrk->vpp_event_queues[s->vpp_thread_index];
++}
++
++void vcl_send_session_worker_update (vcl_worker_t * wrk, vcl_session_t * s,
++ u32 wrk_index);
++/*
++ * VCL Binary API
++ */
++int vppcom_connect_to_vpp (char *app_name);
++void vppcom_disconnect_from_vpp (void);
++void vppcom_init_error_string_table (void);
++void vppcom_send_session_enable_disable (u8 is_enable);
++void vppcom_app_send_attach (void);
++void vppcom_app_send_detach (void);
++void vcl_send_session_unlisten (vcl_worker_t * wrk, vcl_session_t * s);
++void vppcom_send_disconnect_session (u64 vpp_handle);
++void vppcom_api_hookup (void);
++void vppcom_send_application_tls_cert_add (vcl_session_t * session,
++ char *cert, u32 cert_len);
++void vppcom_send_application_tls_key_add (vcl_session_t * session, char *key,
++ u32 key_len);
++void vcl_send_app_worker_add_del (u8 is_add);
++void vcl_send_child_worker_del (vcl_worker_t * wrk);
++
++int vcl_segment_attach (u64 segment_handle, char *name,
++ ssvm_segment_type_t type, int fd);
++void vcl_segment_detach (u64 segment_handle);
++
++u32 vcl_max_nsid_len (void);
++
++void vls_init ();
++#endif /* SRC_VCL_VCL_PRIVATE_H_ */
++
++/*
++ * fd.io coding-style-patch-verification: ON
++ *
++ * Local Variables:
++ * eval: (c-set-style "gnu")
++ * End:
++ */
+--
+2.17.1
+