summaryrefslogtreecommitdiffstats
path: root/demo/nginx_proxy
diff options
context:
space:
mode:
Diffstat (limited to 'demo/nginx_proxy')
-rw-r--r--demo/nginx_proxy/README.md24
-rw-r--r--demo/nginx_proxy/demo-1/Vagrantfile98
-rw-r--r--demo/nginx_proxy/demo-1/adjust_hugepage.sh14
-rwxr-xr-xdemo/nginx_proxy/demo-1/apply_patch.sh9
-rw-r--r--demo/nginx_proxy/demo-1/demo_2stack.patch15
-rw-r--r--demo/nginx_proxy/demo-1/module_config.json26
-rw-r--r--demo/nginx_proxy/demo-1/proxy_nginx.conf81
-rw-r--r--demo/nginx_proxy/demo-1/rd_config.json42
-rw-r--r--demo/nginx_proxy/demo-1/setup_proxy.sh54
-rw-r--r--demo/nginx_proxy/demo-1/setup_upstream.sh45
-rw-r--r--demo/nginx_proxy/demo-1/startup.conf20
-rw-r--r--demo/nginx_proxy/demo-1/upstream_nginx.conf80
-rw-r--r--demo/nginx_proxy/demo-1/vpp_config6
-rw-r--r--demo/nginx_proxy/demo-2/README.md69
-rw-r--r--demo/nginx_proxy/demo-2/Vagrantfile116
-rw-r--r--demo/nginx_proxy/demo-2/adjust_hugepage.sh14
-rwxr-xr-xdemo/nginx_proxy/demo-2/apply_patch.sh9
-rw-r--r--demo/nginx_proxy/demo-2/dem-2-topo.pngbin0 -> 32437 bytes
-rw-r--r--demo/nginx_proxy/demo-2/demo-2.pngbin0 -> 125156 bytes
-rw-r--r--demo/nginx_proxy/demo-2/demo_2stack.patch15
-rw-r--r--demo/nginx_proxy/demo-2/module_config.json26
-rw-r--r--demo/nginx_proxy/demo-2/proxy_nginx.conf33
-rw-r--r--demo/nginx_proxy/demo-2/rd_config.json43
-rw-r--r--demo/nginx_proxy/demo-2/setup_client.sh25
-rw-r--r--demo/nginx_proxy/demo-2/setup_proxy.sh54
-rw-r--r--demo/nginx_proxy/demo-2/setup_udpserver.sh25
-rw-r--r--demo/nginx_proxy/demo-2/setup_upstream.sh44
-rw-r--r--demo/nginx_proxy/demo-2/startup.conf20
-rw-r--r--demo/nginx_proxy/demo-2/udpclient.c49
-rw-r--r--demo/nginx_proxy/demo-2/udpserver.c54
-rw-r--r--demo/nginx_proxy/demo-2/upstream_nginx.conf80
-rw-r--r--demo/nginx_proxy/demo-2/vpp_config6
-rw-r--r--demo/nginx_proxy/demo-3/NGINX_with_DMM_Demo.md26
-rw-r--r--demo/nginx_proxy/demo-3/proxy_nginx.conf81
-rw-r--r--demo/nginx_proxy/demo-3/rd_config.json23
-rw-r--r--demo/nginx_proxy/demo-3/rsocket.pngbin0 -> 10614 bytes
-rw-r--r--demo/nginx_proxy/demo-3/server/index.html31
-rw-r--r--demo/nginx_proxy/demo-3/server/test.c315
38 files changed, 1672 insertions, 0 deletions
diff --git a/demo/nginx_proxy/README.md b/demo/nginx_proxy/README.md
new file mode 100644
index 0000000..4085cc9
--- /dev/null
+++ b/demo/nginx_proxy/README.md
@@ -0,0 +1,24 @@
+# Introduction
+DMM (Dual Mode, Multi-protocol, Multi-instance) is to implement a transport agnostic framework for network
+applications that can
+1. Work with both user space and kernel space network stacks
+2. Use different network protocol stacks based on their functional and performance requirements (QOS)
+3. Work with multiple instances of a transport protocol stack.
+
+Following demo directory demonstrates some of these features of DMM.
+Procedures and details of how to run this demo is inside each demo directory.
+
+##demo-1
+
+This demo use NGINX as a reverse proxy server. The server uses lwip as client facing stack and kernel tcp/ip
+stack as upstream server facing stack.
+
+##demo-2
+
+This demo NGINX as a reverse proxy server. The server uses lwip as client facing stack and kernel tcp/ip stack
+as upstream server facing stack for UDP, vpp-hoststack for another updtream server facing stack for TCP.
+
+##demo-3
+
+This demo NGINX as a reverse proxy server. The server uses kernel tcp/ip as client facing stack and rsocket
+stack as upstream server facing stack.
diff --git a/demo/nginx_proxy/demo-1/Vagrantfile b/demo/nginx_proxy/demo-1/Vagrantfile
new file mode 100644
index 0000000..d3db5e5
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/Vagrantfile
@@ -0,0 +1,98 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+boxes = [
+ {
+ :name => "rproxy-client",
+ :hostname => "rproxy-client",
+ :mem => "1024",
+ :cpu => "1"
+ },
+ {
+ :name => "rproxy-server",
+ :hostname => "rproxy-server",
+ :mem => "1024",
+ :cpu => "1"
+ },
+ {
+ :name => "rproxy-proxy",
+ :hostname => "rproxy-proxy",
+ :mem => "10144",
+ :cpu => "4"
+ }
+]
+
+Vagrant.configure(2) do |config|
+
+ # Pick the right distro and bootstrap, default is ubuntu1604
+ distro = ( ENV['DMM_VAGRANT_DISTRO'] || "ubuntu")
+ if distro == 'centos7'
+ config.vm.box = "puppetlabs/centos-7.2-64-nocm"
+ else
+ config.vm.box = "puppetlabs/ubuntu-16.04-64-nocm"
+ end
+
+ config.vm.box_check_update = false
+ #ddconfig.ssh.password = vagrant
+ if Vagrant.has_plugin?("vagrant-cachier")
+ config.cache.scope = :box
+ end
+
+ # Define some physical ports for your VMs to be used by DPDK
+ #nics = (ENV['DMM_VAGRANT_NICS'] || "2").to_i(10)
+ #for i in 1..nics
+ # config.vm.network "private_network", type: "dhcp"
+ #end
+
+ if ENV['http_proxy'] && Vagrant.has_plugin?("vagrant-proxyconf")
+ config.proxy.http = ENV['http_proxy']
+ config.proxy.https = ENV['https_proxy']
+ config.proxy.no_proxy = "localhost,127.0.0.1"
+ end
+
+ config.ssh.forward_agent = true
+ config.ssh.forward_x11 = true
+
+ boxes.each do |opts|
+ config.vm.define opts[:name] do |srv|
+ srv.vm.hostname = opts[:hostname]
+ srv.vm.provider "virtualbox" do |vb|
+ vb.customize ["modifyvm", :id, "--ioapic", "on"]
+ vb.customize ["modifyvm", :id, "--memory", opts[:mem]]
+ vb.customize ["modifyvm", :id, "--cpus", opts[:cpu]]
+ end
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"../../../scripts/install_prereq.sh")
+ puts ' '..srv.vm.hostname
+
+ if opts[:name] == "rproxy-proxy"
+ puts 'NGINX Proxy Server, Run nginx in below way '
+ puts 'export LD_LIBRARY_PATH=/DMM/stacks/lwip_stack/release/lib64'
+ puts './DMM/thirdparty/apps/nginx/release/nginx'
+ srv.vm.synced_folder "../../../", "/DMM", type: "rsync"
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"adjust_hugepage.sh"), run: 'always'
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"apply_patch.sh"), run: 'always'
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"../../../stacks/lwip_stack/vagrant/build.sh"), :args => "/DMM vagrant"
+ srv.vm.network "private_network", ip: "192.168.50.20"
+ srv.vm.network "private_network", ip: "172.167.50.20"
+ srv.vm.network "private_network", type: "dhcp"
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"../../../stacks/lwip_stack/vagrant/start_nstackMain.sh"), :args => "/DMM vagrant"
+ #possibly overwrite by previous script so adjust again
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"adjust_hugepage.sh"), run: 'always'
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"setup_proxy.sh"), run: 'always'
+ end
+ if opts[:name] == "rproxy-client"
+ puts 'Client use command: curl http://192.168.50.20'
+ srv.vm.network "private_network", type: "dhcp"
+ srv.vm.network "private_network", ip: "192.168.50.10"
+ end
+ if opts[:name] == "rproxy-server"
+ puts 'Upstream server '
+
+ srv.vm.synced_folder "./", "/NGINX", type: "rsync"
+ srv.vm.network "private_network", type: "dhcp"
+ srv.vm.provision "up", type: "shell", :path => File.join(File.dirname(__FILE__),"setup_upstream.sh"), run: 'always'
+ srv.vm.network "private_network", ip: "172.167.50.30"
+ end
+ end
+ end
+end
diff --git a/demo/nginx_proxy/demo-1/adjust_hugepage.sh b/demo/nginx_proxy/demo-1/adjust_hugepage.sh
new file mode 100644
index 0000000..282e3bd
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/adjust_hugepage.sh
@@ -0,0 +1,14 @@
+#!/bin/bash -x
+hugepagesize=$(cat /proc/meminfo | grep Hugepagesize | awk -F " " {'print$2'})
+if [ "$hugepagesize" == "2048" ]; then
+ pages=3000
+elif [ "$hugepagesize" == "1048576" ]; then
+ pages=5
+fi
+sudo sysctl -w vm.nr_hugepages=$pages
+HUGEPAGES=`sysctl -n vm.nr_hugepages`
+echo "Configured hugepages: $HUGEPAGE"
+if [ $HUGEPAGES != $pages ]; then
+ echo "Warning: Unable to get $pages hugepages, only got $HUGEPAGES. Cannot finish."
+fi
+
diff --git a/demo/nginx_proxy/demo-1/apply_patch.sh b/demo/nginx_proxy/demo-1/apply_patch.sh
new file mode 100755
index 0000000..84ecc59
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/apply_patch.sh
@@ -0,0 +1,9 @@
+#!/bin/bash -x
+sudo apt-get install patch -y
+cd /DMM/src/
+sudo patch -p2 -i /DMM/demo/nginx_proxy/demo-1/demo_2stack.patch
+if [ $? -ne 0 ]; then
+ echo "Patch Apply failed. Downlaod correct commit. Check README for details."
+ exit -1
+fi
+cd -
diff --git a/demo/nginx_proxy/demo-1/demo_2stack.patch b/demo/nginx_proxy/demo-1/demo_2stack.patch
new file mode 100644
index 0000000..100f825
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/demo_2stack.patch
@@ -0,0 +1,15 @@
+diff --git a/src/nSocket/nstack/nstack_module.c b/src/nSocket/nstack/nstack_module.c
+index fdfea06..27e96d6 100644
+--- a/src/nSocket/nstack/nstack_module.c
++++ b/src/nSocket/nstack/nstack_module.c
+@@ -61,6 +61,10 @@ int nstack_get_deploy_type()
+ if (g_nstack_module_desc[icnt].deploytype > type)
+ {
+ type = g_nstack_module_desc[icnt].deploytype;
++ if (NSTACK_MODEL_TYPE3 == type)
++ {
++ break;
++ }
+ }
+ }
+ return type;
diff --git a/demo/nginx_proxy/demo-1/module_config.json b/demo/nginx_proxy/demo-1/module_config.json
new file mode 100644
index 0000000..2ed8f19
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/module_config.json
@@ -0,0 +1,26 @@
+{
+ "default_stack_name": "kernel",
+ "module_list": [
+ {
+ "stack_name": "kernel",
+ "function_name": "kernel_stack_register",
+ "libname": "./",
+ "deploytype": "1",
+ "stackid": "0"
+ },
+ {
+ "stack_name": "lwip",
+ "function_name": "lwip_stack_register",
+ "libname": "liblwip_dpdk.so",
+ "deploytype": "3",
+ "stackid": "1"
+ },
+ {
+ "stack_name": "vpp_hoststack",
+ "function_name": "vpp_hoststack_stack_register",
+ "libname": "./libdmm_vcl.so",
+ "deploytype": "4",
+ "stackid": "2"
+ }
+ ]
+}
diff --git a/demo/nginx_proxy/demo-1/proxy_nginx.conf b/demo/nginx_proxy/demo-1/proxy_nginx.conf
new file mode 100644
index 0000000..05d8d2a
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/proxy_nginx.conf
@@ -0,0 +1,81 @@
+user root;
+worker_processes 1;
+daemon off;
+#error_log logs/error.log;
+#error_log logs/error.log notice;
+#error_log logs/error.log info;
+
+#pid logs/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+
+ #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ # '$status $body_bytes_sent "$http_referer" '
+ # '"$http_user_agent" "$http_x_forwarded_for"';
+
+ #access_log logs/access.log main;
+
+ sendfile on;
+ #tcp_nopush on;
+
+ #keepalive_timeout 0;
+ keepalive_timeout 65;
+
+ #gzip on;
+
+ server {
+ listen 192.168.50.20:80 default_server;
+ server_name 192.168.50.20;
+
+ location / {
+ proxy_bind 172.167.50.20:2020;
+ proxy_pass http://172.167.50.30:80;
+ proxy_set_header X-Real-IP $remote_addr;
+ sendfile off;
+ proxy_buffering off;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ }
+
+ #error_page 404 /404.html;
+
+ # redirect server error pages to the static page /50x.html
+ #
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root html;
+ }
+
+ # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+ #
+ #location ~ \.php$ {
+ # proxy_pass http://127.0.0.1;
+ #}
+
+ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+ #
+ #location ~ \.php$ {
+ # root html;
+ # fastcgi_pass 127.0.0.1:9000;
+ # fastcgi_index index.php;
+ # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
+ # include fastcgi_params;
+ #}
+
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
+ #
+ #location ~ /\.ht {
+ # deny all;
+ #}
+ }
+
+
+}
diff --git a/demo/nginx_proxy/demo-1/rd_config.json b/demo/nginx_proxy/demo-1/rd_config.json
new file mode 100644
index 0000000..0ba79fd
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/rd_config.json
@@ -0,0 +1,42 @@
+{
+ "modules": [
+ {
+ "name": "kernel",
+ "ip_route": [
+ "192.168.50.10/32"
+ ],
+ "type_route": [
+ ],
+ "protocol_route": [
+ {
+ "value": "2",
+ "attr": "0"
+ }
+ ]
+ },
+ {
+ "name": "lwip",
+ "ip_route": [
+ "192.168.50.20/32"
+ ],
+ "type_route": [
+ ],
+ "protocol_route": [
+ {
+ "value": "1",
+ "attr": "0"
+ }
+ ]
+ },
+ {
+ "name": "vpp_hoststack",
+ "ip_route": [
+ "172.167.50.20/24"
+ ],
+ "type_route": [
+ ],
+ "protocol_route": [
+ ]
+ }
+ ]
+}
diff --git a/demo/nginx_proxy/demo-1/setup_proxy.sh b/demo/nginx_proxy/demo-1/setup_proxy.sh
new file mode 100644
index 0000000..d7bce92
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/setup_proxy.sh
@@ -0,0 +1,54 @@
+#########################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+#!/bin/bash -x
+
+set -x
+sudo su
+# Clean up build NGINX
+cd /DMM/build/
+
+#Download and compile NGINX
+make NGINX
+#Download and compile vpp-stack
+make vpp-stack
+
+#cp vpp libs
+cp -r /DMM/stacks/vpp/vpp/build-root/install-vpp_debug-native/vpp/lib/vpp_plugins /usr/lib/
+mkdir -p /etc/vpp/
+cp /DMM/demo/nginx_proxy/demo-1/startup.conf /etc/vpp/
+cp /DMM/demo/nginx_proxy/demo-1/vpp_config /etc/vpp/
+cd /DMM/stacks/vpp/vpp/build-root/install-vpp_debug-native/vpp/bin
+#run vpp
+sudo ifconfig enp0s9 down
+./vpp -c /etc/vpp/startup.conf
+
+#cp nginx libs
+cd /DMM/thirdparty/apps/nginx/release
+
+# Move the conf file.
+cp /DMM/demo/nginx_proxy/demo-1/module_config.json /DMM/thirdparty/apps/nginx/release/
+cp /DMM/stacks/lwip_stack/configure/nStackConfig.json /DMM/thirdparty/apps/nginx/release/
+cp /DMM/demo/nginx_proxy/demo-1/proxy_nginx.conf /DMM/thirdparty/apps/nginx/release/
+cp /DMM/demo/nginx_proxy/demo-1/rd_config.json /DMM/thirdparty/apps/nginx/release/
+mv /DMM/thirdparty/apps/nginx/release/proxy_nginx.conf /DMM/thirdparty/apps/nginx/release/nginx.conf
+
+sleep 5
+
+# Run nginx
+cp /DMM/stacks/vpp/vpp/build-root/install-vpp_debug-native/vpp/lib/libdmm_vcl.so /DMM/thirdparty/apps/nginx/release/
+echo "export LD_LIBRARY_PATH=/DMM/stacks/lwip_stack/release/lib64"
+echo "./nginx"
+
+exit 0
diff --git a/demo/nginx_proxy/demo-1/setup_upstream.sh b/demo/nginx_proxy/demo-1/setup_upstream.sh
new file mode 100644
index 0000000..0c2c774
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/setup_upstream.sh
@@ -0,0 +1,45 @@
+#########################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+#!/bin/bash -x
+
+set -x
+
+# Download nginx
+cd /NGINX
+wget http://nginx.org/download/nginx-1.14.0.tar.gz
+tar -zxf nginx-1.14.0.tar.gz
+
+#install supportive softwares
+apt-get install -yq libpcre3 libpcre3-dev zlibc zlib1g zlib1g-dev
+
+# Compile nginx
+cd nginx-1.14.0
+./configure
+make
+make install
+
+# Move the conf file.
+cd /usr/local/nginx/sbin
+cp -r * /usr/local/sbin
+cp /NGINX/upstream_nginx.conf /usr/local/nginx/conf/
+mv /usr/local/nginx/conf/upstream_nginx.conf /usr/local/nginx/conf/nginx.conf
+
+# Run nginx
+
+cd /usr/local/sbin
+./nginx
+echo "hi"
+exit 0
+
diff --git a/demo/nginx_proxy/demo-1/startup.conf b/demo/nginx_proxy/demo-1/startup.conf
new file mode 100644
index 0000000..616cd88
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/startup.conf
@@ -0,0 +1,20 @@
+unix {
+ log /var/log/vpp/vpp.log
+ cli-listen localhost:5002
+ exec /etc/vpp/vpp_config
+}
+
+api-trace {
+ on
+}
+
+cpu {
+ main-core 2
+}
+
+dpdk {
+ socket-mem 1024
+ uio-driver igb_uio
+ dev 0000:00:09.0
+}
+
diff --git a/demo/nginx_proxy/demo-1/upstream_nginx.conf b/demo/nginx_proxy/demo-1/upstream_nginx.conf
new file mode 100644
index 0000000..3904197
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/upstream_nginx.conf
@@ -0,0 +1,80 @@
+#user nobody;
+worker_processes 1;
+#daemon off;
+
+#error_log logs/error.log;
+#error_log logs/error.log notice;
+#error_log logs/error.log info;
+
+#pid logs/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+
+ #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ # '$status $body_bytes_sent "$http_referer" '
+ # '"$http_user_agent" "$http_x_forwarded_for"';
+
+ #access_log logs/access.log main;
+
+ sendfile on;
+ #tcp_nopush on;
+
+ #keepalive_timeout 0;
+ keepalive_timeout 65;
+
+ #gzip on;
+
+ server {
+ listen 80;
+ #server_name localhost;
+
+ #charset koi8-r;
+
+ #access_log logs/host.access.log main;
+
+ location / {
+ return 200 "Hello from upstream $hostname $server_addr:$server_port. Connect from $http_x_real_ip - $remote_user via $remote_addr:$remote_port at [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent\n";
+ }
+
+ #error_page 404 /404.html;
+
+ # redirect server error pages to the static page /50x.html
+ #
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root html;
+ }
+
+ # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+ #
+ #location ~ \.php$ {
+ # proxy_pass http://127.0.0.1;
+ #}
+
+ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+ #
+ #location ~ \.php$ {
+ # root html;
+ # fastcgi_pass 127.0.0.1:9000;
+ # fastcgi_index index.php;
+ # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
+ # include fastcgi_params;
+ #}
+
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
+ #
+ #location ~ /\.ht {
+ # deny all;
+ #}
+ }
+
+}
diff --git a/demo/nginx_proxy/demo-1/vpp_config b/demo/nginx_proxy/demo-1/vpp_config
new file mode 100644
index 0000000..aaeadfb
--- /dev/null
+++ b/demo/nginx_proxy/demo-1/vpp_config
@@ -0,0 +1,6 @@
+set int state GigabitEthernet0/9/0 up
+set int ip addr GigabitEthernet0/9/0 172.167.50.20/24
+show version
+show version verbose
+show cpu
+show int
diff --git a/demo/nginx_proxy/demo-2/README.md b/demo/nginx_proxy/demo-2/README.md
new file mode 100644
index 0000000..7d6feb1
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/README.md
@@ -0,0 +1,69 @@
+#demo-2
+## Introduction
+This demo NGINX as a reverse proxy server. The server uses "lwip" for client facing socket and "kernel tcp/ip stack "
+as upstream server facing socket for UDP, "vpp-hoststack" for another updtream server facing stack for TCP.
+
+## Topology
+![demo-2.png](demo-2.png)
+![dem-2-topo.png](dem-2-topo.png)
+## Steps
+####1. Create VMs using vagrant.
+Start demo VMs. Go to dmm/demo/nginx_proxy/demo-2 .
+```
+$ vagrant up
+```
+This command will create 4 VMs namely rproxy-client, rproxy-server1, rproxy-server2 and rproxy-proxy. The memory
+requirement for this demo is 13GB (approx).
+
+####2. Log in to VMs
+Open four terminal and login to VMs.
+```
+$ vagrant ssh <vm-name>
+```
+
+####3. Run Udp server Application at rproxy-server2
+```
+$ vagrant ssh rproxy-server2
+Inside VM
+vagrant@rproxy-server2:~$ sudo su
+root@rproxy-server2:/home/vagrant# cd /UDPSERVER/
+root@rproxy-server2:/UDPSERVER# ./udpserver
+```
+
+####4. Run NGINX proxy server at rproxy-proxy
+```
+$ vagrant ssh rproxy-proxy
+Inside VM
+vagrant@rproxy-proxy:~$ sudo su
+root@rproxy-proxy:/home/vagrant# cd /DMM/thirdparty/apps/nginx/release
+root@rproxy-proxy:/DMM/thirdparty/apps/nginx/release# export LD_LIBRARY_PATH=/DMM/stacks/lwip_stack/release/lib64
+root@rproxy-proxy:/DMM/thirdparty/apps/nginx/release# ./nginx
+```
+####5. Test TCP traffic
+```
+$ vagrant ssh rproxy-client
+vagrant@rproxy-client:~$ cd /CLIENT/
+vagrant@rproxy-client:/CLIENT$ curl http://192.168.50.20
+Hello from upstream rproxy-server1 172.167.50.30:80. Connect from - via 172.167.50.20:15140 at [12/Nov/2018:06:17:25 -0800] GET / HTTP/1.1 200 0 curl/7.47.0
+
+```
+
+####6. Test UDP traffic
+```
+$ vagrant ssh rproxy-client
+vagrant@rproxy-client:~$ cd /CLIENT/
+vagrant@rproxy-client:/CLIENT$ ./udpclient
+Hello message sent.
+Server : Hello from server
+```
+#### Notes:
+a. If enable debugs i.e. export NSTACK_LOG_ON=DBG before we run nginx in rroxy-proxy we can find below logs which suggest we use diffrent stack for diffrent ip/protoccol.
+```
+...
+nstack_bind<NSSOC>fd addr Select module]fd=18,addr=192.168.50.20,module=lwip
+...
+nstack_bind<NSSOC>fd addr Select module]fd=22,addr=172.167.50.20,module=vpp_hoststack
+...
+nstack_bind<NSSOC>fd addr Select module]fd=22,addr=182.167.50.20,module=kernel
+```
+b. This demo depends on commit of dmm. Please check commit version of your code.
diff --git a/demo/nginx_proxy/demo-2/Vagrantfile b/demo/nginx_proxy/demo-2/Vagrantfile
new file mode 100644
index 0000000..dbd703a
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/Vagrantfile
@@ -0,0 +1,116 @@
+# -*- mode: ruby -*-
+# vi: set ft=ruby :
+
+boxes = [
+ {
+ :name => "rproxy-client",
+ :hostname => "rproxy-client",
+ :mem => "1024",
+ :cpu => "1"
+ },
+ {
+ :name => "rproxy-server1",
+ :hostname => "rproxy-server1",
+ :mem => "1024",
+ :cpu => "1"
+ },
+ {
+ :name => "rproxy-server2",
+ :hostname => "rproxy-server2",
+ :mem => "1024",
+ :cpu => "1"
+ },
+ {
+ :name => "rproxy-proxy",
+ :hostname => "rproxy-proxy",
+ :mem => "10144",
+ :cpu => "4"
+ }
+]
+
+Vagrant.configure(2) do |config|
+
+ # Pick the right distro and bootstrap, default is ubuntu1604
+ distro = ( ENV['DMM_VAGRANT_DISTRO'] || "ubuntu")
+ if distro == 'centos7'
+ config.vm.box = "puppetlabs/centos-7.2-64-nocm"
+ else
+ config.vm.box = "puppetlabs/ubuntu-16.04-64-nocm"
+ end
+
+ config.vm.box_check_update = false
+ #ddconfig.ssh.password = vagrant
+ if Vagrant.has_plugin?("vagrant-cachier")
+ config.cache.scope = :box
+ end
+
+ # Define some physical ports for your VMs to be used by DPDK
+ #nics = (ENV['DMM_VAGRANT_NICS'] || "2").to_i(10)
+ #for i in 1..nics
+ # config.vm.network "private_network", type: "dhcp"
+ #end
+
+ if ENV['http_proxy'] && Vagrant.has_plugin?("vagrant-proxyconf")
+ config.proxy.http = ENV['http_proxy']
+ config.proxy.https = ENV['https_proxy']
+ config.proxy.no_proxy = "localhost,127.0.0.1"
+ end
+
+ config.ssh.forward_agent = true
+ config.ssh.forward_x11 = true
+
+ boxes.each do |opts|
+ config.vm.define opts[:name] do |srv|
+ srv.vm.hostname = opts[:hostname]
+ srv.vm.provider "virtualbox" do |vb|
+ vb.customize ["modifyvm", :id, "--ioapic", "on"]
+ vb.customize ["modifyvm", :id, "--memory", opts[:mem]]
+ vb.customize ["modifyvm", :id, "--cpus", opts[:cpu]]
+ end
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"../../../scripts/install_prereq.sh")
+ puts ' '..srv.vm.hostname
+
+ if opts[:name] == "rproxy-proxy"
+ puts 'NGINX Proxy Server, Run nginx in below way '
+ puts 'export LD_LIBRARY_PATH=/DMM/stacks/lwip_stack/release/lib64'
+ puts './DMM/thirdparty/apps/nginx/release/nginx'
+ srv.vm.synced_folder "../../../", "/DMM", type: "rsync"
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"adjust_hugepage.sh"), run: 'always'
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"apply_patch.sh"), run: 'always'
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"../../../stacks/lwip_stack/vagrant/build.sh"), :args => "/DMM vagrant"
+ srv.vm.network "private_network", ip: "192.168.50.20"
+ srv.vm.network "private_network", ip: "172.167.50.20"
+ srv.vm.network "private_network", ip: "182.167.50.20"
+ srv.vm.network "private_network", type: "dhcp"
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"../../../stacks/lwip_stack/vagrant/start_nstackMain.sh"), :args => "/DMM vagrant"
+ #possibly overwrite by previous script so adjust again
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"adjust_hugepage.sh"), run: 'always'
+ srv.vm.provision :shell, :path => File.join(File.dirname(__FILE__),"setup_proxy.sh"), run: 'always'
+ end
+ if opts[:name] == "rproxy-client"
+ puts 'Client use command for TCP: curl http://192.168.50.20'
+ puts 'Client use command for UDP: ./udpclient'
+ srv.vm.synced_folder "./", "/CLIENT", type: "rsync"
+ srv.vm.network "private_network", type: "dhcp"
+ srv.vm.network "private_network", ip: "192.168.50.10"
+ srv.vm.provision "up", type: "shell", :path => File.join(File.dirname(__FILE__),"setup_client.sh"), run: 'always'
+ end
+ if opts[:name] == "rproxy-server1"
+ puts 'Upstream server 1'
+
+ srv.vm.synced_folder "./", "/NGINX", type: "rsync"
+ srv.vm.network "private_network", type: "dhcp"
+ srv.vm.provision "up", type: "shell", :path => File.join(File.dirname(__FILE__),"setup_upstream.sh"), run: 'always'
+ srv.vm.network "private_network", ip: "172.167.50.30"
+ end
+ if opts[:name] == "rproxy-server2"
+ puts 'Upstream server 2 '
+
+ srv.vm.synced_folder "./", "/UDPSERVER", type: "rsync"
+ srv.vm.network "private_network", type: "dhcp"
+ srv.vm.provision "up", type: "shell", :path => File.join(File.dirname(__FILE__),"setup_udpserver.sh"), run: 'always'
+ srv.vm.network "private_network", ip: "182.167.50.30"
+ end
+ end
+ end
+end
diff --git a/demo/nginx_proxy/demo-2/adjust_hugepage.sh b/demo/nginx_proxy/demo-2/adjust_hugepage.sh
new file mode 100644
index 0000000..282e3bd
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/adjust_hugepage.sh
@@ -0,0 +1,14 @@
+#!/bin/bash -x
+hugepagesize=$(cat /proc/meminfo | grep Hugepagesize | awk -F " " {'print$2'})
+if [ "$hugepagesize" == "2048" ]; then
+ pages=3000
+elif [ "$hugepagesize" == "1048576" ]; then
+ pages=5
+fi
+sudo sysctl -w vm.nr_hugepages=$pages
+HUGEPAGES=`sysctl -n vm.nr_hugepages`
+echo "Configured hugepages: $HUGEPAGE"
+if [ $HUGEPAGES != $pages ]; then
+ echo "Warning: Unable to get $pages hugepages, only got $HUGEPAGES. Cannot finish."
+fi
+
diff --git a/demo/nginx_proxy/demo-2/apply_patch.sh b/demo/nginx_proxy/demo-2/apply_patch.sh
new file mode 100755
index 0000000..05e8c66
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/apply_patch.sh
@@ -0,0 +1,9 @@
+#!/bin/bash -x
+sudo apt-get install patch -y
+cd /DMM/src/
+sudo patch -p2 -i /DMM/demo/nginx_proxy/demo-2/demo_2stack.patch
+if [ $? -ne 0 ]; then
+ echo "Patch Apply failed. Downlaod correct commit. Check README for details."
+ exit -1
+fi
+cd -
diff --git a/demo/nginx_proxy/demo-2/dem-2-topo.png b/demo/nginx_proxy/demo-2/dem-2-topo.png
new file mode 100644
index 0000000..ad81372
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/dem-2-topo.png
Binary files differ
diff --git a/demo/nginx_proxy/demo-2/demo-2.png b/demo/nginx_proxy/demo-2/demo-2.png
new file mode 100644
index 0000000..604c301
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/demo-2.png
Binary files differ
diff --git a/demo/nginx_proxy/demo-2/demo_2stack.patch b/demo/nginx_proxy/demo-2/demo_2stack.patch
new file mode 100644
index 0000000..100f825
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/demo_2stack.patch
@@ -0,0 +1,15 @@
+diff --git a/src/nSocket/nstack/nstack_module.c b/src/nSocket/nstack/nstack_module.c
+index fdfea06..27e96d6 100644
+--- a/src/nSocket/nstack/nstack_module.c
++++ b/src/nSocket/nstack/nstack_module.c
+@@ -61,6 +61,10 @@ int nstack_get_deploy_type()
+ if (g_nstack_module_desc[icnt].deploytype > type)
+ {
+ type = g_nstack_module_desc[icnt].deploytype;
++ if (NSTACK_MODEL_TYPE3 == type)
++ {
++ break;
++ }
+ }
+ }
+ return type;
diff --git a/demo/nginx_proxy/demo-2/module_config.json b/demo/nginx_proxy/demo-2/module_config.json
new file mode 100644
index 0000000..2ed8f19
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/module_config.json
@@ -0,0 +1,26 @@
+{
+ "default_stack_name": "kernel",
+ "module_list": [
+ {
+ "stack_name": "kernel",
+ "function_name": "kernel_stack_register",
+ "libname": "./",
+ "deploytype": "1",
+ "stackid": "0"
+ },
+ {
+ "stack_name": "lwip",
+ "function_name": "lwip_stack_register",
+ "libname": "liblwip_dpdk.so",
+ "deploytype": "3",
+ "stackid": "1"
+ },
+ {
+ "stack_name": "vpp_hoststack",
+ "function_name": "vpp_hoststack_stack_register",
+ "libname": "./libdmm_vcl.so",
+ "deploytype": "4",
+ "stackid": "2"
+ }
+ ]
+}
diff --git a/demo/nginx_proxy/demo-2/proxy_nginx.conf b/demo/nginx_proxy/demo-2/proxy_nginx.conf
new file mode 100644
index 0000000..925e1a9
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/proxy_nginx.conf
@@ -0,0 +1,33 @@
+user root;
+worker_processes 1;
+daemon off;
+#error_log logs/error.log;
+#error_log logs/error.log notice;
+#error_log logs/error.log info;
+
+#pid logs/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+stream {
+ upstream stream_tcp {
+ server 172.167.50.30:80;
+ }
+ upstream stream_udp {
+ server 182.167.50.30:53;
+ }
+ server {
+ listen 192.168.50.20:80;
+ proxy_bind 172.167.50.20:2020;
+ proxy_pass stream_tcp;
+ }
+ server {
+ listen 192.168.50.20:53 udp;
+ proxy_bind 182.167.50.20:53;
+ proxy_pass stream_udp;
+ }
+}
+
diff --git a/demo/nginx_proxy/demo-2/rd_config.json b/demo/nginx_proxy/demo-2/rd_config.json
new file mode 100644
index 0000000..e312af4
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/rd_config.json
@@ -0,0 +1,43 @@
+{
+ "modules": [
+ {
+ "name": "kernel",
+ "ip_route": [
+ "192.168.50.10/32",
+ "182.167.50.20/32"
+ ],
+ "type_route": [
+ ],
+ "protocol_route": [
+ {
+ "value": "2",
+ "attr": "0"
+ }
+ ]
+ },
+ {
+ "name": "lwip",
+ "ip_route": [
+ "192.168.50.20/32"
+ ],
+ "type_route": [
+ ],
+ "protocol_route": [
+ {
+ "value": "1",
+ "attr": "0"
+ }
+ ]
+ },
+ {
+ "name": "vpp_hoststack",
+ "ip_route": [
+ "172.167.50.20/24"
+ ],
+ "type_route": [
+ ],
+ "protocol_route": [
+ ]
+ }
+ ]
+}
diff --git a/demo/nginx_proxy/demo-2/setup_client.sh b/demo/nginx_proxy/demo-2/setup_client.sh
new file mode 100644
index 0000000..a0f4363
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/setup_client.sh
@@ -0,0 +1,25 @@
+#########################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+#!/bin/bash -x
+
+set -x
+
+# Download nginx
+cd /CLIENT
+
+gcc udpclient.c -o udpclient
+
+exit 0
+
diff --git a/demo/nginx_proxy/demo-2/setup_proxy.sh b/demo/nginx_proxy/demo-2/setup_proxy.sh
new file mode 100644
index 0000000..b46fe6a
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/setup_proxy.sh
@@ -0,0 +1,54 @@
+#########################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+#!/bin/bash -x
+
+set -x
+sudo su
+# Clean up build NGINX
+cd /DMM/build/
+
+#Download and compile NGINX
+make NGINX
+#Download and compile vpp-stack
+make vpp-stack
+
+#cp vpp libs
+cp -r /DMM/stacks/vpp/vpp/build-root/install-vpp_debug-native/vpp/lib/vpp_plugins /usr/lib/
+mkdir -p /etc/vpp/
+cp /DMM/demo/nginx_proxy/demo-2/startup.conf /etc/vpp/
+cp /DMM/demo/nginx_proxy/demo-2/vpp_config /etc/vpp/
+cd /DMM/stacks/vpp/vpp/build-root/install-vpp_debug-native/vpp/bin
+#run vpp
+sudo ifconfig enp0s9 down
+./vpp -c /etc/vpp/startup.conf
+
+#cp nginx libs
+cd /DMM/thirdparty/apps/nginx/release
+
+# Move the conf file.
+cp /DMM/demo/nginx_proxy/demo-2/module_config.json /DMM/thirdparty/apps/nginx/release/
+cp /DMM/stacks/lwip_stack/configure/nStackConfig.json /DMM/thirdparty/apps/nginx/release/
+cp /DMM/demo/nginx_proxy/demo-2/proxy_nginx.conf /DMM/thirdparty/apps/nginx/release/
+cp /DMM/demo/nginx_proxy/demo-2/rd_config.json /DMM/thirdparty/apps/nginx/release/
+mv /DMM/thirdparty/apps/nginx/release/proxy_nginx.conf /DMM/thirdparty/apps/nginx/release/nginx.conf
+
+sleep 5
+
+# Run nginx
+cp /DMM/stacks/vpp/vpp/build-root/install-vpp_debug-native/vpp/lib/libdmm_vcl.so /DMM/thirdparty/apps/nginx/release/
+echo "export LD_LIBRARY_PATH=/DMM/stacks/lwip_stack/release/lib64"
+echo "./nginx"
+
+exit 0
diff --git a/demo/nginx_proxy/demo-2/setup_udpserver.sh b/demo/nginx_proxy/demo-2/setup_udpserver.sh
new file mode 100644
index 0000000..d684286
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/setup_udpserver.sh
@@ -0,0 +1,25 @@
+#########################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+#!/bin/bash -x
+
+set -x
+
+# Download nginx
+cd /UDPSERVER
+
+gcc udpserver.c -o udpserver
+
+exit 0
+
diff --git a/demo/nginx_proxy/demo-2/setup_upstream.sh b/demo/nginx_proxy/demo-2/setup_upstream.sh
new file mode 100644
index 0000000..ee7dbd4
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/setup_upstream.sh
@@ -0,0 +1,44 @@
+#########################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#########################################################################
+#!/bin/bash -x
+
+set -x
+
+# Download nginx
+cd /NGINX
+wget http://nginx.org/download/nginx-1.14.0.tar.gz
+tar -zxf nginx-1.14.0.tar.gz
+
+#install supportive softwares
+apt-get install -yq libpcre3 libpcre3-dev zlibc zlib1g zlib1g-dev
+
+# Compile nginx
+cd nginx-1.14.0
+./configure
+make
+make install
+
+# Move the conf file.
+cd /usr/local/nginx/sbin
+cp -r * /usr/local/sbin
+cp /NGINX/upstream_nginx.conf /usr/local/nginx/conf/
+mv /usr/local/nginx/conf/upstream_nginx.conf /usr/local/nginx/conf/nginx.conf
+
+# Run nginx
+
+cd /usr/local/sbin
+./nginx
+exit 0
+
diff --git a/demo/nginx_proxy/demo-2/startup.conf b/demo/nginx_proxy/demo-2/startup.conf
new file mode 100644
index 0000000..616cd88
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/startup.conf
@@ -0,0 +1,20 @@
+unix {
+ log /var/log/vpp/vpp.log
+ cli-listen localhost:5002
+ exec /etc/vpp/vpp_config
+}
+
+api-trace {
+ on
+}
+
+cpu {
+ main-core 2
+}
+
+dpdk {
+ socket-mem 1024
+ uio-driver igb_uio
+ dev 0000:00:09.0
+}
+
diff --git a/demo/nginx_proxy/demo-2/udpclient.c b/demo/nginx_proxy/demo-2/udpclient.c
new file mode 100644
index 0000000..3aca2df
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/udpclient.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define PORT 53
+#define MAXLINE 1024
+
+// Driver code
+int main()
+{
+ int sockfd;
+ char buffer[MAXLINE];
+ char *hello = "Hello from client";
+ struct sockaddr_in servaddr;
+
+ // Creating socket file descriptor
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ perror("socket creation failed");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&servaddr, 0, sizeof(servaddr));
+
+ // Filling server information
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = htons(PORT);
+ servaddr.sin_addr.s_addr = inet_addr("192.168.50.20");
+
+ int n, len;
+
+ sendto(sockfd, (const char *) hello, strlen(hello),
+ MSG_CONFIRM, (const struct sockaddr *) &servaddr,
+ sizeof(servaddr));
+ printf("Hello message sent.\n");
+
+ n = recvfrom(sockfd, (char *) buffer, MAXLINE,
+ MSG_WAITALL, (struct sockaddr *) &servaddr, &len);
+ buffer[n] = '\0';
+ printf("Server : %s\n", buffer);
+
+ close(sockfd);
+ return 0;
+}
diff --git a/demo/nginx_proxy/demo-2/udpserver.c b/demo/nginx_proxy/demo-2/udpserver.c
new file mode 100644
index 0000000..dfea2f2
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/udpserver.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#define PORT 53
+#define MAXLINE 1024
+
+int main()
+{
+ int sockfd;
+ char buffer[MAXLINE];
+ char *hello = "Hello from server";
+
+ struct sockaddr_in servaddr, cliaddr;
+ char name[128] = { 0 };
+
+ // Creating socket file descriptor
+ if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ perror("socket creation failed");
+ exit(EXIT_FAILURE);
+ }
+
+ memset(&servaddr, 0, sizeof(servaddr));
+ memset(&cliaddr, 0, sizeof(cliaddr));
+
+ // Filling server information
+ servaddr.sin_family = AF_INET; // IPv4
+ servaddr.sin_addr.s_addr = inet_addr("182.167.50.30");
+ servaddr.sin_port = htons(PORT);
+
+ if (bind(sockfd, (const struct sockaddr *) &servaddr,
+ sizeof(servaddr)) < 0)
+ {
+ perror("bind failed");
+ exit(EXIT_FAILURE);
+ }
+
+ int len, n;
+ n = recvfrom(sockfd, (char *) buffer, MAXLINE,
+ MSG_WAITALL, (struct sockaddr *) &cliaddr, &len);
+ buffer[n] = '\0';
+ (void) gethostname(name, 127);
+ printf("Client : %s \n", buffer);
+ sendto(sockfd, (const char *) hello, strlen(hello),
+ MSG_CONFIRM, (const struct sockaddr *) &cliaddr, len);
+ printf("%s\n", hello);
+ return 0;
+}
diff --git a/demo/nginx_proxy/demo-2/upstream_nginx.conf b/demo/nginx_proxy/demo-2/upstream_nginx.conf
new file mode 100644
index 0000000..3904197
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/upstream_nginx.conf
@@ -0,0 +1,80 @@
+#user nobody;
+worker_processes 1;
+#daemon off;
+
+#error_log logs/error.log;
+#error_log logs/error.log notice;
+#error_log logs/error.log info;
+
+#pid logs/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+
+ #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ # '$status $body_bytes_sent "$http_referer" '
+ # '"$http_user_agent" "$http_x_forwarded_for"';
+
+ #access_log logs/access.log main;
+
+ sendfile on;
+ #tcp_nopush on;
+
+ #keepalive_timeout 0;
+ keepalive_timeout 65;
+
+ #gzip on;
+
+ server {
+ listen 80;
+ #server_name localhost;
+
+ #charset koi8-r;
+
+ #access_log logs/host.access.log main;
+
+ location / {
+ return 200 "Hello from upstream $hostname $server_addr:$server_port. Connect from $http_x_real_ip - $remote_user via $remote_addr:$remote_port at [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent\n";
+ }
+
+ #error_page 404 /404.html;
+
+ # redirect server error pages to the static page /50x.html
+ #
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root html;
+ }
+
+ # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+ #
+ #location ~ \.php$ {
+ # proxy_pass http://127.0.0.1;
+ #}
+
+ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+ #
+ #location ~ \.php$ {
+ # root html;
+ # fastcgi_pass 127.0.0.1:9000;
+ # fastcgi_index index.php;
+ # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
+ # include fastcgi_params;
+ #}
+
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
+ #
+ #location ~ /\.ht {
+ # deny all;
+ #}
+ }
+
+}
diff --git a/demo/nginx_proxy/demo-2/vpp_config b/demo/nginx_proxy/demo-2/vpp_config
new file mode 100644
index 0000000..aaeadfb
--- /dev/null
+++ b/demo/nginx_proxy/demo-2/vpp_config
@@ -0,0 +1,6 @@
+set int state GigabitEthernet0/9/0 up
+set int ip addr GigabitEthernet0/9/0 172.167.50.20/24
+show version
+show version verbose
+show cpu
+show int
diff --git a/demo/nginx_proxy/demo-3/NGINX_with_DMM_Demo.md b/demo/nginx_proxy/demo-3/NGINX_with_DMM_Demo.md
new file mode 100644
index 0000000..6deb348
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/NGINX_with_DMM_Demo.md
@@ -0,0 +1,26 @@
+# Demo: NGINX working with multi-stack using DMM
+
+![image](rsocket.png)
+
+
+
+In above diagram NGINX box in the middle is working as reverse proxy.
+One of the NIC ( client facing) is using kernel tcp/ip stack whereas the
+other NIC is connected to upstream server using rsocket tcp/ip stack.
+
+you can use test.c to compile a server depend on libnStackAPI.so. It bind the
+port 8888 by default and you can change it to other port. Then copy the
+module_config.json rd_config.json to the folder of server. Then you can start the
+server as follow:
+./server 162.128.1.16
+
+####More Information:
+https://wiki.fd.io/view/DMM
+https://www.nginx.com/blog/ip-transparency-direct-server-return-nginx-plus-transparent-proxy/
+
+
+
+
+
+
+
diff --git a/demo/nginx_proxy/demo-3/proxy_nginx.conf b/demo/nginx_proxy/demo-3/proxy_nginx.conf
new file mode 100644
index 0000000..fb085ac
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/proxy_nginx.conf
@@ -0,0 +1,81 @@
+user root;
+worker_processes 1;
+daemon off;
+#error_log logs/error.log;
+#error_log logs/error.log notice;
+#error_log logs/error.log info;
+
+#pid logs/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+
+ #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ # '$status $body_bytes_sent "$http_referer" '
+ # '"$http_user_agent" "$http_x_forwarded_for"';
+
+ #access_log logs/access.log main;
+
+ sendfile on;
+ #tcp_nopush on;
+
+ #keepalive_timeout 0;
+ keepalive_timeout 65;
+
+ #gzip on;
+
+ server {
+ listen 192.168.131.181:80 default_server;
+ server_name 192.168.131.181;
+
+ location / {
+ proxy_bind 192.168.21.181;
+ proxy_pass http://192.168.21.180:8888;
+ proxy_set_header X-Real-IP $remote_addr;
+ sendfile off;
+ proxy_buffering off;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ }
+
+ #error_page 404 /404.html;
+
+ # redirect server error pages to the static page /50x.html
+ #
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root html;
+ }
+
+ # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+ #
+ #location ~ \.php$ {
+ # proxy_pass http://127.0.0.1;
+ #}
+
+ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+ #
+ #location ~ \.php$ {
+ # root html;
+ # fastcgi_pass 127.0.0.1:9000;
+ # fastcgi_index index.php;
+ # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
+ # include fastcgi_params;
+ #}
+
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
+ #
+ #location ~ /\.ht {
+ # deny all;
+ #}
+ }
+
+
+}
diff --git a/demo/nginx_proxy/demo-3/rd_config.json b/demo/nginx_proxy/demo-3/rd_config.json
new file mode 100644
index 0000000..51fa4a5
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/rd_config.json
@@ -0,0 +1,23 @@
+{
+ "ip_route": [
+ {
+ "subnet": "192.168.131.1/24",
+ "stack_name": "kernel",
+ },
+ {
+ "subnet": "192.168.21.1/24",
+ "stack_name": "rsocket",
+ },
+ ],
+ "prot_route": [
+ {
+ "proto_type": "1",
+ "stack_name": "rsocket",
+ },
+ {
+ "proto_type": "2",
+ "stack_name": "kernel",
+ }
+ ],
+}
+
diff --git a/demo/nginx_proxy/demo-3/rsocket.png b/demo/nginx_proxy/demo-3/rsocket.png
new file mode 100644
index 0000000..389ae19
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/rsocket.png
Binary files differ
diff --git a/demo/nginx_proxy/demo-3/server/index.html b/demo/nginx_proxy/demo-3/server/index.html
new file mode 100644
index 0000000..9ab30e1
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/server/index.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+
+<!--
+Copyright 2015 Google Inc.
+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.
+-->
+
+<html>
+
+<head>
+ <title>Hello, world</title>
+ <link rel="stylesheet" href="/style.css">
+ <script src="/script.js"></script>
+</head>
+
+<body>
+ <h1>Hello, world</h1>
+
+ <button onclick="fetchMessage()">Fetch Message</button>
+ <p id="message">Click on the button to fetch the message.</p>
+</body>
+
+</html>
diff --git a/demo/nginx_proxy/demo-3/server/test.c b/demo/nginx_proxy/demo-3/server/test.c
new file mode 100644
index 0000000..d0e9ecb
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/server/test.c
@@ -0,0 +1,315 @@
+/*
+ * httpd.c
+ *
+ * Copyright Adin Scannell 2011
+ *
+ * This code is intended for demo purposes only,
+ * please don't actually use it to do anything.
+ *
+ * To compile, use:
+ * gcc -o httpd httpd.c
+ * Then, create a file 'index.html' in the directory
+ * that you are running the server from. Put stuff in
+ * it.
+ * Then go to http://localhost:8888 and see the file.
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/sendfile.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/mman.h>
+
+#define HTTP_BAD_REQUEST "HTTP/1.0 404 Not Found\r\n"
+#define HTTP_GOOD_REQUEST "HTTP/1.0 200\r\n"
+#define HTTP_CONTENT_TYPE "Content-Type: text/html\r\n"
+#define HTTP_CONTENT_LENGTH "Content-Length: %ld\r\n\r\n"
+#define MAX_REQUEST_SIZE 4096
+#define DEFAULT_PATH "index.html"
+
+#define DEBUG
+#ifdef DEBUG
+#define log(fmt, args...) fprintf(stderr, fmt "\n", ## args)
+#else
+#define log(fmt, args...)
+#endif
+
+int send_error(int fd)
+{
+ write(fd, HTTP_BAD_REQUEST, strlen(HTTP_BAD_REQUEST));
+ write(fd, HTTP_CONTENT_TYPE, strlen(HTTP_CONTENT_TYPE));
+ return 0;
+}
+
+int send_file(int fd, char *path)
+{
+ int iofd = open(path, O_RDONLY);
+
+ int ret = 0;
+ if (iofd < 0)
+ {
+ write(fd, HTTP_BAD_REQUEST, strlen(HTTP_BAD_REQUEST));
+ write(fd, HTTP_CONTENT_TYPE, strlen(HTTP_CONTENT_TYPE));
+ log("error opening file");
+ }
+ else
+ {
+ char length[MAX_REQUEST_SIZE];
+ struct stat statinfo;
+ if (fstat(iofd, &statinfo) < 0)
+ {
+ /* Can't get the length. */
+ write(fd, HTTP_BAD_REQUEST, strlen(HTTP_BAD_REQUEST));
+ write(fd, HTTP_CONTENT_TYPE, strlen(HTTP_CONTENT_TYPE));
+ log("error fetching size");
+ }
+ else
+ {
+ ret = write(fd, HTTP_GOOD_REQUEST, strlen(HTTP_GOOD_REQUEST));
+
+ log("write HTTP_GOOD_REQUEST %s ret %d", HTTP_GOOD_REQUEST, ret);
+ ret = write(fd, HTTP_CONTENT_TYPE, strlen(HTTP_CONTENT_TYPE));
+ log("write HTTP_CONTENT_TYPE %s ret %d", HTTP_CONTENT_TYPE, ret);
+ snprintf(length, MAX_REQUEST_SIZE,
+ HTTP_CONTENT_LENGTH, statinfo.st_size);
+
+ ret = write(fd, length, strlen(length));
+ log("write %s ret %d", length, ret);
+
+#if 1
+#if 1
+ //char *source = NULL;
+ //source = malloc(sizeof(char) * (statinfo.st_size + 1));
+ void *file_addr = NULL;
+ file_addr =
+ mmap(NULL, statinfo.st_size, PROT_READ, MAP_PRIVATE, iofd, 0);
+
+ if (write(fd, file_addr, statinfo.st_size) < 0)
+ {
+ perror("wyl new");
+ }
+
+#else
+// if( write(fd, length, strlen(length)) < 0 ||
+ if (sendfile(fd, iofd, NULL, statinfo.st_size) < 0)
+ {
+ /* Error sending the file. Nothing can be done. */
+ perror("error writing file");
+ }
+#endif
+
+#endif
+ close(fd);
+ }
+
+ close(iofd);
+ }
+
+ return 0;
+}
+
+int process(int fd, char *header)
+{
+ char npath[MAX_REQUEST_SIZE];
+
+ char *eol = strchr(header, '\r');
+
+ /* Nuts to thread-safe, this demo uses it's own process :P */
+ char *method = strtok(header, " ");
+ char *path = strtok(NULL, " ");
+ char *http = strtok(NULL, " ");
+
+ if (eol != NULL)
+ {
+ *eol = '\0';
+ }
+
+ /* Debug output here, just in case anyone is watching. */
+ log(" * method = %s", method);
+ log(" * path = %s", path);
+ log(" * http = %s", http);
+
+ /* Ensure that we can process it. */
+ if (strcmp(method, "GET") ||
+ (strcmp(http, "HTTP/1.0") && strcmp(http, "HTTP/1.1")))
+ {
+ log("bad request");
+ return send_error(fd);
+ }
+ else
+ {
+ if (path[0] == '/' && path[1] == '\0')
+ {
+ path = DEFAULT_PATH;
+ }
+ else if (path[0] == '/')
+ {
+ snprintf(npath, MAX_REQUEST_SIZE, ".%s", path);
+ path = npath;
+ }
+ log("sending %s to %d", path, fd);
+ return send_file(fd, path);
+ }
+}
+
+int service(int fd)
+{
+ char buffer[MAX_REQUEST_SIZE];
+ int readbytes = 0, scanned = 0;
+
+ /* Attempt to read a chunk of bytes, but not process forever. */
+ while (readbytes < (MAX_REQUEST_SIZE - 1))
+ {
+ log("read from %d", fd);
+ int cur = read(fd, &(buffer[readbytes]),
+ (MAX_REQUEST_SIZE - 1) - readbytes);
+ if (cur < 0)
+ {
+ perror("read failed");
+ return -1;
+ }
+ else
+ {
+ buffer[readbytes + cur + 1] = '\0';
+ readbytes += cur;
+ }
+
+ /* Check for the \n\n found at the end of the header. */
+ for (; scanned < readbytes - 3; scanned++)
+ {
+ if (buffer[scanned] == '\r' && buffer[scanned + 1] == '\n' &&
+ buffer[scanned + 2] == '\r' && buffer[scanned + 3] == '\n')
+ {
+ buffer[scanned] = '\0';
+ return process(fd, buffer);
+ }
+ }
+ }
+
+ /* Failed to find the end of the header. */
+ log("header too long");
+ return -1;
+}
+
+int main(int argc, char *argv[])
+{
+
+ struct sockaddr_in servaddr;
+ int serversock = socket(AF_INET, SOCK_STREAM, 0);
+ int on = 1;
+
+ if (NULL == argv[1])
+ {
+ log("please set the ip argument");
+ return 1;
+ }
+
+ /* Create socket. */
+ if (serversock < 0)
+ {
+ perror("error creating socket");
+ return 1;
+ }
+
+ /* Tweak it for reuse. Not necessary for fork, just useful *
+ * when one is killing and running this server a few times. */
+ if (setsockopt(serversock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
+ {
+ perror("unable to tweak socket options");
+ }
+
+ /* Bind to port 8888. */
+ memset(&servaddr, 0, sizeof(servaddr));
+ servaddr.sin_family = AF_INET;
+ //servaddr.sin_addr.s_addr = inet_addr("192.168.21.180");
+ servaddr.sin_addr.s_addr = inet_addr(argv[1]);
+ servaddr.sin_port = htons(8888);
+ if (bind(serversock, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
+ {
+ perror("couldn't bind to given address");
+ return 1;
+ }
+ log("bound to %s:8888", argv[1]);
+
+ /* Start listening, queue size 10. */
+ if (listen(serversock, 10) < 0)
+ {
+ perror("listen failed");
+ return 1;
+ }
+ log("listening");
+
+ /* Enter the service loop. */
+ while (1)
+ {
+ int clientsock, pid, childstatus;
+ log("waiting for next request");
+
+ /* Grab the next request. */
+ clientsock = accept(serversock, NULL, NULL);
+ if (clientsock < 0)
+ {
+ perror("accept failed");
+ break;
+ }
+ log("accepted connection %d from %d, forking ", clientsock,
+ serversock);
+
+ /* Fork off a handler. */
+ //pid = fork();
+ pid = 0;
+ if (pid < 0)
+ {
+ perror("fork failed");
+ close(clientsock);
+ continue;
+ }
+ else if (pid > 0)
+ {
+ close(clientsock);
+ }
+ else
+ {
+ //close(serversock);
+ log("servicing connection (as child) sfd %d cfd %d", serversock,
+ clientsock);
+ service(clientsock);
+ //return 0;
+ }
+
+ /* Collect any exit statuses (lazy). */
+
+#if 0
+ while (1)
+ {
+ pid = waitpid(-1, &childstatus, WNOHANG);
+ if (pid < 0)
+ {
+ perror("waitpid error?");
+ break;
+ }
+ else if (pid == 0)
+ {
+ break;
+ }
+ else if (WIFEXITED(childstatus))
+ {
+ log("child %d exited with status %d", pid,
+ WEXITSTATUS(childstatus));
+ }
+ }
+#endif
+
+ }
+
+ /* Should never arrive here. */
+ return 254;
+}