add makefile 05/27005/12
authorxiaolongx.jiang <[email protected]>
Tue, 12 May 2020 05:07:26 +0000 (05:07 +0000)
committerxiaolongx.jiang <[email protected]>
Fri, 15 May 2020 16:42:40 +0000 (16:42 +0000)
Signed-off-by: xiaolongx.jiang <[email protected]>
Change-Id: Iaf6ec4d79538f8810d0c0ebc69b458d40ffb9c53

25 files changed:
.gitmodules [new file with mode: 0644]
Makefile [new file with mode: 0644]
README.md
configs/mime.types [new file with mode: 0644]
configs/nginx.conf
configs/tls-test-cert [new file with mode: 0644]
configs/tls-test-key [new file with mode: 0644]
openssl_patches/0001-openssl3.0.0-alpha1.patch [new file with mode: 0644]
packages/nginx-dl.mk [new file with mode: 0644]
packages/nginx_ldp.mk [new file with mode: 0644]
packages/nginx_vcl.mk [new file with mode: 0644]
packages/openssl-dl.mk [new file with mode: 0644]
packages/openssl.mk [new file with mode: 0644]
packages/package.mk [new file with mode: 0644]
packages/packages.mk [new file with mode: 0644]
packages/pre-install [new file with mode: 0644]
packages/vpp_ldp.mk [new file with mode: 0644]
packages/vpp_vcl.mk [new file with mode: 0644]
vpp [new submodule]
vpp_patches/common/0001-3.0.0.patch [new file with mode: 0644]
vpp_patches/common/0002-src-pkg-debian-rules.in.patch [new file with mode: 0644]
vpp_patches/common/2001/0001-quick-0.0.9.patch [new file with mode: 0644]
vpp_patches/common/master/0001-picotls-patch.patch [new file with mode: 0644]
vpp_patches/ldp/2001/0001-LDP-remove-lock.patch [moved from vpp_patches/ldp/0001-LDP-remove-lock.patch with 100% similarity]
vpp_patches/ldp/master/0001-LDP-remove-lock.patch [new file with mode: 0644]

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..69878e6
--- /dev/null
@@ -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 (file)
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
index 5ed9ad4..880a115 100644 (file)
--- 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 (file)
index 0000000..8a2348a
--- /dev/null
@@ -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;
+}
index 0466aeb..d184b89 100644 (file)
@@ -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 (file)
index 0000000..53ae6da
--- /dev/null
@@ -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 (file)
index 0000000..59d441b
--- /dev/null
@@ -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 (file)
index 0000000..f639104
--- /dev/null
@@ -0,0 +1,24 @@
+From 47904f922ac042c24d3c8d4ecfda15d902c48c2e Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <[email protected]>
+Date: Fri, 8 May 2020 07:06:30 +0000
+Subject: [PATCH] openssl3.0.0-alpha1
+
+Signed-off-by: xiaolongx.jiang <[email protected]>
+---
+ 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 (file)
index 0000000..7fc7bd3
--- /dev/null
@@ -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 (file)
index 0000000..cde52a2
--- /dev/null
@@ -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 (file)
index 0000000..031ada9
--- /dev/null
@@ -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 (file)
index 0000000..e7b8d5b
--- /dev/null
@@ -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 (file)
index 0000000..37f2c84
--- /dev/null
@@ -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 (file)
index 0000000..95f5f34
--- /dev/null
@@ -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 (file)
index 0000000..79aed56
--- /dev/null
@@ -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 (file)
index 0000000..a7f6471
--- /dev/null
@@ -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 (file)
index 0000000..cdf6307
--- /dev/null
@@ -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 (file)
index 0000000..9b83678
--- /dev/null
@@ -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 (submodule)
index 0000000..73a60b2
--- /dev/null
+++ b/vpp
@@ -0,0 +1 @@
+Subproject commit 73a60b2da44847f3725d362a49207330d4d22aa5
diff --git a/vpp_patches/common/0001-3.0.0.patch b/vpp_patches/common/0001-3.0.0.patch
new file mode 100644 (file)
index 0000000..69fd197
--- /dev/null
@@ -0,0 +1,113 @@
+From ff2148e2aec6c8fb9717f655aee424d9ec59f802 Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <[email protected]>
+Date: Wed, 13 May 2020 09:42:07 +0000
+Subject: [PATCH] 3.0.0
+
+Signed-off-by: xiaolongx.jiang <[email protected]>
+---
+ 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 (file)
index 0000000..7010b5d
--- /dev/null
@@ -0,0 +1,27 @@
+From 8b808809f3608470f0df77f73aed784d2b160a9e Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <[email protected]>
+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 (file)
index 0000000..4f8a082
--- /dev/null
@@ -0,0 +1,45 @@
+From b20dfd9f921be04b03899959bdf3feba5376c4c3 Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <[email protected]>
+Date: Wed, 13 May 2020 06:22:06 +0000
+Subject: [PATCH] quick 0.0.9
+
+Signed-off-by: xiaolongx.jiang <[email protected]>
+---
+ .../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" <[email protected]>
++Date: Fri, 8 May 2020 08:25:12 +0000
++Subject: [PATCH] picotls: openssl-3.0.0
++
++Signed-off-by: xiaolongx.jiang <[email protected]>
++---
++ .../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 (file)
index 0000000..9811fbc
--- /dev/null
@@ -0,0 +1,45 @@
+From 9f3edc2ca7eb417b46ab40beac45838ee58cc223 Mon Sep 17 00:00:00 2001
+From: "xiaolongx.jiang" <[email protected]>
+Date: Fri, 8 May 2020 10:01:36 +0000
+Subject: [PATCH] picotls: patch
+
+Signed-off-by: xiaolongx.jiang <[email protected]>
+---
+ .../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" <[email protected]>
++Date: Fri, 8 May 2020 08:25:12 +0000
++Subject: [PATCH] picotls: openssl-3.0.0
++
++Signed-off-by: xiaolongx.jiang <[email protected]>
++---
++ .../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/master/0001-LDP-remove-lock.patch b/vpp_patches/ldp/master/0001-LDP-remove-lock.patch
new file mode 100644 (file)
index 0000000..feb3502
--- /dev/null
@@ -0,0 +1,4909 @@
+From d9fffb4761489abc5976df0eac82fa6280a187cc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=E2=80=9Czsj=E2=80=9D?= <“[email protected]”>
+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
+