summaryrefslogtreecommitdiffstats
path: root/docs/usecases
diff options
context:
space:
mode:
authorJohn DeNisco <jdenisco@cisco.com>2018-07-26 12:45:10 -0400
committerDave Barach <openvpp@barachs.net>2018-07-26 18:34:47 +0000
commit06dcd45ff81e06bc8cf40ed487c0b2652d346a5a (patch)
tree71403f9d422c4e532b2871a66ab909bd6066b10b /docs/usecases
parent1d65279ffecd0f540288187b94cb1a6b84a7a0c6 (diff)
Initial commit of Sphinx docs
Change-Id: I9fca8fb98502dffc2555f9de7f507b6f006e0e77 Signed-off-by: John DeNisco <jdenisco@cisco.com>
Diffstat (limited to 'docs/usecases')
-rw-r--r--docs/usecases/Routing.rst266
-rw-r--r--docs/usecases/containerCreation.rst123
-rw-r--r--docs/usecases/containerSetup.rst49
-rw-r--r--docs/usecases/containers.rst13
-rw-r--r--docs/usecases/homegateway.rst207
-rw-r--r--docs/usecases/index.rst15
-rw-r--r--docs/usecases/uc_vSwitchvRouter.rst47
-rw-r--r--docs/usecases/vhost/index.rst17
-rw-r--r--docs/usecases/vhost/iperf-vm.xml106
-rw-r--r--docs/usecases/vhost/vhost.rst115
-rw-r--r--docs/usecases/vhost/vhost02.rst109
-rw-r--r--docs/usecases/vhost/vhost03.rst88
-rw-r--r--docs/usecases/vhost/vhost04.rst43
-rw-r--r--docs/usecases/vhost/vhost05.rst25
-rw-r--r--docs/usecases/vhost/xmlexample.rst11
15 files changed, 1234 insertions, 0 deletions
diff --git a/docs/usecases/Routing.rst b/docs/usecases/Routing.rst
new file mode 100644
index 00000000000..0c5908fd57e
--- /dev/null
+++ b/docs/usecases/Routing.rst
@@ -0,0 +1,266 @@
+.. _Routing:
+
+.. toctree::
+
+Connecting the two Containers
+_____________________________
+
+Now for connecting these two linux containers to VPP and pinging between them.
+
+Enter container *cone*, and check the current network configuration:
+
+.. code-block:: console
+
+ root@cone:/# ip -o a
+ 1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever
+ 1: lo inet6 ::1/128 scope host \ valid_lft forever preferred_lft forever
+ 30: veth0 inet 10.0.3.157/24 brd 10.0.3.255 scope global veth0\ valid_lft forever preferred_lft forever
+ 30: veth0 inet6 fe80::216:3eff:fee2:d0ba/64 scope link \ valid_lft forever preferred_lft forever
+ 32: veth_link1 inet6 fe80::2c9d:83ff:fe33:37e/64 scope link \ valid_lft forever preferred_lft forever
+
+You can see that there are three network interfaces, *lo, veth0*, and *veth_link1*.
+
+Notice that *veth_link1* has no assigned IP.
+
+Check if the interfaces are down or up:
+
+.. code-block:: console
+
+ root@cone:/# ip link
+ 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ 30: veth0@if31: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
+ link/ether 00:16:3e:e2:d0:ba brd ff:ff:ff:ff:ff:ff link-netnsid 0
+ 32: veth_link1@if33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
+ link/ether 2e:9d:83:33:03:7e brd ff:ff:ff:ff:ff:ff link-netnsid 0
+
+.. _networkNote:
+
+.. note::
+
+ Take note of the network index for **veth_link1**. In our case, it 32, and its parent index (the host machine, not the containers) is 33, shown by **veth_link1@if33**. Yours will most likely be different, but **please take note of these index's**.
+
+Make sure your loopback interface is up, and assign an IP and gateway to veth_link1.
+
+.. code-block:: console
+
+ root@cone:/# ip link set dev lo up
+ root@cone:/# ip addr add 172.16.1.2/24 dev veth_link1
+ root@cone:/# ip link set dev veth_link1 up
+ root@cone:/# dhclient -r
+ root@cone:/# ip route add default via 172.16.1.1 dev veth_link1
+
+Here, the IP is 172.16.1.2/24 and the gateway is 172.16.1.1.
+
+Run some commands to verify the changes:
+
+.. code-block:: console
+
+ root@cone:/# ip -o a
+ 1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever
+ 1: lo inet6 ::1/128 scope host \ valid_lft forever preferred_lft forever
+ 30: veth0 inet6 fe80::216:3eff:fee2:d0ba/64 scope link \ valid_lft forever preferred_lft forever
+ 32: veth_link1 inet 172.16.1.2/24 scope global veth_link1\ valid_lft forever preferred_lft forever
+ 32: veth_link1 inet6 fe80::2c9d:83ff:fe33:37e/64 scope link \ valid_lft forever preferred_lft forever
+
+ root@cone:/# route
+ Kernel IP routing table
+ Destination Gateway Genmask Flags Metric Ref Use Iface
+ default 172.16.1.1 0.0.0.0 UG 0 0 0 veth_link1
+ 172.16.1.0 * 255.255.255.0 U 0 0 0 veth_link1
+
+
+We see that the IP has been assigned, as well as our default gateway.
+
+Now exit this container and repeat this process with container *ctwo*, except with IP 172.16.2.2/24 and gateway 172.16.2.1.
+
+
+After thats done for *both* containers, exit from the container if you're in one:
+
+.. code-block:: console
+
+ root@ctwo:/# exit
+ exit
+ root@localhost:~#
+
+In the machine running the containers, run **ip link** to see the host *veth* network interfaces, and their link with their respective *container veth's*.
+
+.. code-block:: console
+
+ root@localhost:~# ip link
+ 1: lo: <LOOPBACK> mtu 65536 qdisc noqueue state DOWN mode DEFAULT group default qlen 1
+ link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
+ 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
+ link/ether 08:00:27:33:82:8a brd ff:ff:ff:ff:ff:ff
+ 3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
+ link/ether 08:00:27:d9:9f:ac brd ff:ff:ff:ff:ff:ff
+ 4: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
+ link/ether 08:00:27:78:84:9d brd ff:ff:ff:ff:ff:ff
+ 5: lxcbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
+ link/ether 00:16:3e:00:00:00 brd ff:ff:ff:ff:ff:ff
+ 19: veth0C2FL7@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master lxcbr0 state UP mode DEFAULT group default qlen 1000
+ link/ether fe:0d:da:90:c1:65 brd ff:ff:ff:ff:ff:ff link-netnsid 1
+ 21: veth8NA72P@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
+ link/ether fe:1c:9e:01:9f:82 brd ff:ff:ff:ff:ff:ff link-netnsid 1
+ 31: vethXQMY4C@if30: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master lxcbr0 state UP mode DEFAULT group default qlen 1000
+ link/ether fe:9a:d9:29:40:bb brd ff:ff:ff:ff:ff:ff link-netnsid 0
+ 33: vethQL7KOC@if32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
+ link/ether fe:ed:89:54:47:a2 brd ff:ff:ff:ff:ff:ff link-netnsid 0
+
+
+Remember our network interface index 32 in *cone* from this :ref:`note <networkNote>`? We can see at the bottom the name of the 33rd index **vethQL7KOC@if32**. Keep note of this network interface name for the veth connected to *cone* (ex. vethQL7KOC), and the other network interface name for *ctwo*.
+
+With VPP in the host machine, show current VPP interfaces:
+
+.. code-block:: console
+
+ root@localhost:~# vppctl show inter
+ Name Idx State MTU (L3/IP4/IP6/MPLS) Counter Count
+ local0 0 down 0/0/0/0
+
+Which should only output local0.
+
+Based on the names of the network interfaces discussed previously, which are specific to my systems, we can create VPP host-interfaces:
+
+.. code-block:: console
+
+ root@localhost:~# vppctl create host-interface name vethQL7K0C
+ root@localhost:~# vppctl create host-interface name veth8NA72P
+
+Verify they have been set up properly:
+
+.. code-block:: console
+
+ root@localhost:~# vppctl show inter
+ Name Idx State MTU (L3/IP4/IP6/MPLS) Counter Count
+ host-vethQL7K0C 1 down 9000/0/0/0
+ host-veth8NA72P 2 down 9000/0/0/0
+ local0 0 down 0/0/0/0
+
+Which should output *three network interfaces*, local0, and the other two host network interfaces linked to the container veth's.
+
+
+Set their state to up:
+
+.. code-block:: console
+
+ root@localhost:~# vppctl set interface state host-vethQL7K0C up
+ root@localhost:~# vppctl set interface state host-veth8NA72P up
+
+Verify they are now up:
+
+.. code-block:: console
+
+ root@localhost:~# vppctl show inter
+ Name Idx State MTU (L3/IP4/IP6/MPLS) Counter Count
+ host-vethQL7K0C 1 up 9000/0/0/0
+ host-veth8NA72P 2 up 9000/0/0/0
+ local0 0 down 0/0/0/0
+
+
+Add IP addresses for the other end of each veth link:
+
+.. code-block:: console
+
+ root@localhost:~# vppctl set interface ip address host-vethQL7K0C 172.16.1.1/24
+ root@localhost:~# vppctl set interface ip address host-veth8NA72P 172.16.2.1/24
+
+
+Verify the addresses are set properly by looking at the L3 table:
+
+.. code-block:: console
+
+ root@localhost:~# vppctl show inter addr
+ host-vethQL7K0C (up):
+ L3 172.16.1.1/24
+ host-veth8NA72P (up):
+ L3 172.16.2.1/24
+ local0 (dn):
+
+Or looking at the FIB by doing:
+
+.. code-block:: console
+
+ root@localhost:~# vppctl show ip fib
+ ipv4-VRF:0, fib_index:0, flow hash:[src dst sport dport proto ] locks:[src:plugin-hi:2, src:default-route:1, ]
+ 0.0.0.0/0
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:1 buckets:1 uRPF:0 to:[0:0]]
+ [0] [@0]: dpo-drop ip4
+ 0.0.0.0/32
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:2 buckets:1 uRPF:1 to:[0:0]]
+ [0] [@0]: dpo-drop ip4
+ 172.16.1.0/32
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:10 buckets:1 uRPF:9 to:[0:0]]
+ [0] [@0]: dpo-drop ip4
+ 172.16.1.0/24
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:9 buckets:1 uRPF:8 to:[0:0]]
+ [0] [@4]: ipv4-glean: host-vethQL7K0C: mtu:9000 ffffffffffff02fec953f98c0806
+ 172.16.1.1/32
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:12 buckets:1 uRPF:13 to:[0:0]]
+ [0] [@2]: dpo-receive: 172.16.1.1 on host-vethQL7K0C
+ 172.16.1.255/32
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:11 buckets:1 uRPF:11 to:[0:0]]
+ [0] [@0]: dpo-drop ip4
+ 172.16.2.0/32
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:14 buckets:1 uRPF:15 to:[0:0]]
+ [0] [@0]: dpo-drop ip4
+ 172.16.2.0/24
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:13 buckets:1 uRPF:14 to:[0:0]]
+ [0] [@4]: ipv4-glean: host-veth8NA72P: mtu:9000 ffffffffffff02fe305400e80806
+ 172.16.2.1/32
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:16 buckets:1 uRPF:19 to:[0:0]]
+ [0] [@2]: dpo-receive: 172.16.2.1 on host-veth8NA72P
+ 172.16.2.255/32
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:15 buckets:1 uRPF:17 to:[0:0]]
+ [0] [@0]: dpo-drop ip4
+ 224.0.0.0/4
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:4 buckets:1 uRPF:3 to:[0:0]]
+ [0] [@0]: dpo-drop ip4
+ 240.0.0.0/4
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:3 buckets:1 uRPF:2 to:[0:0]]
+ [0] [@0]: dpo-drop ip4
+ 255.255.255.255/32
+ unicast-ip4-chain
+ [@0]: dpo-load-balance: [proto:ip4 index:5 buckets:1 uRPF:4 to:[0:0]]
+ [0] [@0]: dpo-drop ip4
+
+At long last you probably want to see some pings:
+
+.. code-block:: console
+
+ root@localhost:~# lxc-attach -n cone -- ping -c3 172.16.2.2
+ PING 172.16.2.2 (172.16.2.2) 56(84) bytes of data.
+ 64 bytes from 172.16.2.2: icmp_seq=1 ttl=63 time=0.102 ms
+ 64 bytes from 172.16.2.2: icmp_seq=2 ttl=63 time=0.189 ms
+ 64 bytes from 172.16.2.2: icmp_seq=3 ttl=63 time=0.150 ms
+
+ --- 172.16.2.2 ping statistics ---
+ 3 packets transmitted, 3 received, 0% packet loss, time 1999ms
+ rtt min/avg/max/mdev = 0.102/0.147/0.189/0.035 ms
+
+ root@localhost:~# lxc-attach -n ctwo -- ping -c3 172.16.1.2
+ PING 172.16.1.2 (172.16.1.2) 56(84) bytes of data.
+ 64 bytes from 172.16.1.2: icmp_seq=1 ttl=63 time=0.111 ms
+ 64 bytes from 172.16.1.2: icmp_seq=2 ttl=63 time=0.089 ms
+ 64 bytes from 172.16.1.2: icmp_seq=3 ttl=63 time=0.096 ms
+
+ --- 172.16.1.2 ping statistics ---
+ 3 packets transmitted, 3 received, 0% packet loss, time 1998ms
+ rtt min/avg/max/mdev = 0.089/0.098/0.111/0.014 ms
+
+
+Which should send/recieve three packets for each command.
+
+This is the end of this guide. Great work! \ No newline at end of file
diff --git a/docs/usecases/containerCreation.rst b/docs/usecases/containerCreation.rst
new file mode 100644
index 00000000000..b9344f35ce5
--- /dev/null
+++ b/docs/usecases/containerCreation.rst
@@ -0,0 +1,123 @@
+.. _containerCreation:
+
+.. toctree::
+
+Creating Containers
+___________________
+
+First you should have root privileges:
+
+.. code-block:: console
+
+ $ sudo bash
+
+Then install packages for containers such as lxc:
+
+.. code-block:: console
+
+ # apt-get install bridge-utils lxc
+
+As quoted from the `lxc.conf manpage <https://linuxcontainers.org/it/lxc/manpages/man5/lxc.conf.5.html>`_, "container configuration is held in the config stored in the container's directory.
+A basic configuration is generated at container creation time with the default's recommended for the chosen template as well as extra default keys coming from the default.conf file."
+
+"That *default.conf* file is either located at /etc/lxc/default.conf or for unprivileged containers at ~/.config/lxc/default.conf."
+
+Since we want to ping between two containers, we'll need to **add to this file**.
+
+Look at the contents of *default.conf*, which should initially look like this:
+
+.. code-block:: console
+
+ # cat /etc/lxc/default.conf
+ lxc.network.type = veth
+ lxc.network.link = lxcbr0
+ lxc.network.flags = up
+ lxc.network.hwaddr = 00:16:3e:xx:xx:xx
+
+As you can see, by default there is one veth interface.
+
+Now you will *append to this file* so that each container you create will have an interface for a Linux bridge and an unconsumed second interface.
+
+You can do this by piping *echo* output into *tee*, where each line is separated with a newline character *\\n* as shown below. Alternatively, you can manually add to this file with a text editor such as **vi**, but make sure you have root privileges.
+
+.. code-block:: console
+
+ # echo -e "lxc.network.name = veth0\nlxc.network.type = veth\nlxc.network.name = veth_link1" | sudo tee -a /etc/lxc/default.conf
+
+Inspect the contents again to verify the file was indeed modified:
+
+.. code-block:: console
+
+ # cat /etc/lxc/default.conf
+ lxc.network.type = veth
+ lxc.network.link = lxcbr0
+ lxc.network.flags = up
+ lxc.network.hwaddr = 00:16:3e:xx:xx:xx
+ lxc.network.name = veth0
+ lxc.network.type = veth
+ lxc.network.name = veth_link1
+
+
+After this, we're ready to create the containers.
+
+Creates an Ubuntu Xenial container named "cone".
+
+.. code-block:: console
+
+ # lxc-create -t download -n cone -- --dist ubuntu --release xenial --arch amd64 --keyserver hkp://p80.pool.sks-keyservers.net:80
+
+
+If successful, you'll get an output similar to this:
+
+.. code-block:: console
+
+ You just created an Ubuntu xenial amd64 (20180625_07:42) container.
+
+ To enable SSH, run: apt install openssh-server
+ No default root or user password are set by LXC.
+
+
+Make another container "ctwo".
+
+.. code-block:: console
+
+ # lxc-create -t download -n ctwo -- --dist ubuntu --release xenial --arch amd64 --keyserver hkp://p80.pool.sks-keyservers.net:80
+
+
+List your containers to verify they exist:
+
+
+.. code-block:: console
+
+ # lxc-ls
+ cone ctwo
+
+
+Start the first container:
+
+.. code-block:: console
+
+ # lxc-start --name cone
+
+And verify its running:
+
+.. code-block:: console
+
+ # lxc-ls --fancy
+ NAME STATE AUTOSTART GROUPS IPV4 IPV6
+ cone RUNNING 0 - - -
+ ctwo STOPPED 0 - - -
+
+
+.. note::
+
+ Here are some `lxc container commands <https://help.ubuntu.com/lts/serverguide/lxc.html.en-GB#lxc-basic-usage>`_ you may find useful:
+
+
+ .. code-block:: console
+
+ sudo lxc-ls --fancy
+ sudo lxc-start --name u1 --daemon
+ sudo lxc-info --name u1
+ sudo lxc-stop --name u1
+ sudo lxc-destroy --name u1
diff --git a/docs/usecases/containerSetup.rst b/docs/usecases/containerSetup.rst
new file mode 100644
index 00000000000..e0fd81eebc3
--- /dev/null
+++ b/docs/usecases/containerSetup.rst
@@ -0,0 +1,49 @@
+.. _containerSetup:
+
+.. toctree::
+
+Container packages
+__________________
+
+Now we can go into container *cone* and install prerequisites such as VPP, and perform some additional commands:
+
+To enter our container via the shell, type:
+
+.. code-block:: console
+
+ # lxc-attach -n cone
+ root@cone:/#
+
+Run the linux DHCP setup and install VPP:
+
+.. code-block:: console
+
+ root@cone:/# resolvconf -d eth0
+ root@cone:/# dhclient
+ root@cone:/# apt-get install -y wget
+ root@cone:/# echo "deb [trusted=yes] https://nexus.fd.io/content/repositories/fd.io.ubuntu.xenial.main/ ./" | sudo tee -a /etc/apt/sources.list.d/99fd.io.list
+ root@cone:/# apt-get update
+ root@cone:/# apt-get install -y --force-yes vpp
+ root@cone:/# sh -c 'echo \"\\ndpdk {\\n no-pci\\n}\" >> /etc/vpp/startup.conf'
+
+After this is done, start VPP in this container:
+
+.. code-block:: console
+
+ root@cone:/# service vpp start
+
+Exit this container with the **exit** command (you *may* need to run **exit** twice):
+
+.. code-block:: console
+
+ root@cone:/# exit
+ exit
+ root@cone:/# exit
+ exit
+ root@localhost:~#
+
+Repeat the container setup on this page for the second container **ctwo**. Go to the end of the previous page if you forgot how to start a container.
+
+
+
+
diff --git a/docs/usecases/containers.rst b/docs/usecases/containers.rst
new file mode 100644
index 00000000000..90e41db6cb8
--- /dev/null
+++ b/docs/usecases/containers.rst
@@ -0,0 +1,13 @@
+.. _containers:
+
+FD.io VPP with Containers
+=========================
+
+This section will cover connecting two Linux containers with VPP. A container is essentially a more efficient and faster VM, due to the fact that a container does not simulate a separate kernel and hardware. You can read more about `Linux containers here <https://linuxcontainers.org/>`_.
+
+
+.. toctree::
+
+ containerCreation
+ containerSetup
+ Routing
diff --git a/docs/usecases/homegateway.rst b/docs/usecases/homegateway.rst
new file mode 100644
index 00000000000..f6d7ec9a329
--- /dev/null
+++ b/docs/usecases/homegateway.rst
@@ -0,0 +1,207 @@
+.. _homegateway:
+
+.. toctree::
+
+Using VPP as a Home Gateway
+===========================
+
+Vpp running on a small system (with appropriate NICs) makes a fine
+home gateway. The resulting system performs far in excess of
+requirements: a TAG=vpp_debug image runs at a vector size of ~1.1
+terminating a 90-mbit down / 10-mbit up cable modem connection.
+
+At a minimum, install sshd and the isc-dhcp-server. If you prefer, you
+can use dnsmasq.
+
+Configuration files
+-------------------
+
+/etc/vpp/startup.conf::
+
+ unix {
+ nodaemon
+ log /var/log/vpp/vpp.log
+ full-coredump
+ cli-listen /run/vpp/cli.sock
+ startup-config /setup.gate
+ gid vpp
+ }
+ api-segment {
+ gid vpp
+ }
+ dpdk {
+ dev 0000:03:00.0
+ dev 0000:14:00.0
+ etc.
+ poll-sleep 10
+ }
+
+isc-dhcp-server configuration::
+
+ subnet 192.168.1.0 netmask 255.255.255.0 {
+ range 192.168.1.10 192.168.1.99;
+ option routers 192.168.1.1;
+ option domain-name-servers 8.8.8.8;
+ }
+
+If you decide to enable the vpp dns name resolver, substitute
+192.168.1.2 for 8.8.8.8 in the dhcp server configuration.
+
+/etc/ssh/sshd_config::
+
+ # What ports, IPs and protocols we listen for
+ Port <REDACTED-high-number-port>
+ # Change to no to disable tunnelled clear text passwords
+ PasswordAuthentication no
+
+For your own comfort and safety, do NOT allow password authentication
+and do not answer ssh requests on port 22. Experience shows several
+hack attempts per hour on port 22, but none (ever) on random
+high-number ports.
+
+vpp configuration::
+
+ comment { This is the WAN interface }
+ set int state GigabitEthernet3/0/0 up
+ comment { set int mac address GigabitEthernet3/0/0 mac-to-clone-if-needed }
+ set dhcp client intfc GigabitEthernet3/0/0 hostname vppgate
+
+ comment { Create a BVI loopback interface}
+ loop create
+ set int l2 bridge loop0 1 bvi
+ set int ip address loop0 192.168.1.1/24
+ set int state loop0 up
+
+ comment { Add more inside interfaces as needed ... }
+ set int l2 bridge GigabitEthernet0/14/0 1
+ set int state GigabitEthernet0/14/0 up
+
+ comment { dhcp server and host-stack access }
+ tap connect lstack address 192.168.1.2/24
+ set int l2 bridge tapcli-0 1
+ set int state tapcli-0 up
+
+ comment { Configure NAT}
+ nat44 add interface address GigabitEthernet3/0/0
+ set interface nat44 in loop0 out GigabitEthernet3/0/0
+
+ comment { allow inbound ssh to the <REDACTED-high-number-port>
+ nat44 add static mapping local 192.168.1.2 <REDACTED> external GigabitEthernet3/0/0 <REDACTED> tcp
+
+ comment { if you want to use the vpp DNS server, add the following }
+ comment { Remember to adjust the isc-dhcp-server configuration appropriately }
+ comment { nat44 add identity mapping external GigabitEthernet3/0/0 udp 53053 }
+ comment { bin dns_name_server_add_del 8.8.8.8 }
+ comment { bin dns_name_server_add_del 68.87.74.166 }
+ comment { bin dns_enable_disable }
+ comment { see patch below, which adds these commands }
+ service restart isc-dhcp-server
+ add default linux route via 192.168.1.1
+
+Patches
+-------
+
+You'll need this patch to add the "service restart" and "add default
+linux route" commands::
+
+ diff --git a/src/vpp/vnet/main.c b/src/vpp/vnet/main.c
+ index 6e136e19..69189c93 100644
+ --- a/src/vpp/vnet/main.c
+ +++ b/src/vpp/vnet/main.c
+ @@ -18,6 +18,8 @@
+ #include <vlib/unix/unix.h>
+ #include <vnet/plugin/plugin.h>
+ #include <vnet/ethernet/ethernet.h>
+ +#include <vnet/ip/ip4_packet.h>
+ +#include <vnet/ip/format.h>
+ #include <vpp/app/version.h>
+ #include <vpp/api/vpe_msg_enum.h>
+ #include <limits.h>
+ @@ -400,6 +402,63 @@ VLIB_CLI_COMMAND (test_crash_command, static) = {
+
+ #endif
+
+ +static clib_error_t *
+ +restart_isc_dhcp_server_command_fn (vlib_main_t * vm,
+ + unformat_input_t * input,
+ + vlib_cli_command_t * cmd)
+ +{
+ + int rv __attribute__((unused));
+ + /* Wait three seconds... */
+ + vlib_process_suspend (vm, 3.0);
+ +
+ + rv = system ("/usr/sbin/service isc-dhcp-server restart");
+ +
+ + vlib_cli_output (vm, "Restarted the isc-dhcp-server...");
+ + return 0;
+ +}
+ +
+ +/* *INDENT-OFF* */
+ +VLIB_CLI_COMMAND (restart_isc_dhcp_server_command, static) = {
+ + .path = "service restart isc-dhcp-server",
+ + .short_help = "restarts the isc-dhcp-server",
+ + .function = restart_isc_dhcp_server_command_fn,
+ +};
+ +/* *INDENT-ON* */
+ +
+ +static clib_error_t *
+ +add_default_linux_route_command_fn (vlib_main_t * vm,
+ + unformat_input_t * input,
+ + vlib_cli_command_t * c)
+ +{
+ + int rv __attribute__((unused));
+ + ip4_address_t ip4_addr;
+ + u8 *cmd;
+ +
+ + if (!unformat (input, "%U", unformat_ip4_address, &ip4_addr))
+ + return clib_error_return (0, "default gateway address required...");
+ +
+ + cmd = format (0, "/sbin/route add -net 0.0.0.0/0 gw %U",
+ + format_ip4_address, &ip4_addr);
+ + vec_add1 (cmd, 0);
+ +
+ + rv = system (cmd);
+ +
+ + vlib_cli_output (vm, "%s", cmd);
+ +
+ + vec_free(cmd);
+ +
+ + return 0;
+ +}
+ +
+ +/* *INDENT-OFF* */
+ +VLIB_CLI_COMMAND (add_default_linux_route_command, static) = {
+ + .path = "add default linux route via",
+ + .short_help = "Adds default linux route: 0.0.0.0/0 via <addr>",
+ + .function = add_default_linux_route_command_fn,
+ +};
+ +/* *INDENT-ON* */
+ +
+ +
+
+Using the temporal mac filter plugin
+------------------------------------
+
+If you need to restrict network access for certain devices to specific
+daily time ranges, configure the "mactime" plugin. Enable the feature
+on the NAT "inside" interfaces::
+
+ bin mactime_enable_disable GigabitEthernet0/14/0
+ bin mactime_enable_disable GigabitEthernet0/14/1
+ ...
+
+Create the required src-mac-address rule database. There are 4 rule
+entry types:
+
+* allow-static - pass traffic from this mac address
+* drop-static - drop traffic from this mac address
+* allow-range - pass traffic from this mac address at specific times
+* drop-range - drop traffic from this mac address at specific times
+
+Here are some examples::
+
+ bin mactime_add_del_range name alarm-system mac 00:de:ad:be:ef:00 allow-static
+ bin mactime_add_del_range name unwelcome mac 00:de:ad:be:ef:01 drop-static
+ bin mactime_add_del_range name not-during-business-hours mac <mac> drop-range Mon - Fri 7:59 - 18:01
+ bin mactime_add_del_range name monday-busines-hours mac <mac> allow-range Mon 7:59 - 18:01
+
diff --git a/docs/usecases/index.rst b/docs/usecases/index.rst
new file mode 100644
index 00000000000..523dffa69d3
--- /dev/null
+++ b/docs/usecases/index.rst
@@ -0,0 +1,15 @@
+.. _usecases:
+
+
+Use Cases
+==========
+
+This chapter contains a sample of the many ways FD.io VPP can be used. It is by no means an
+extensive list, but should give a sampling of the many features contained in FD.io VPP.
+
+.. toctree::
+
+ containers
+ vhost/index.rst
+ homegateway
+ uc_vSwitchvRouter
diff --git a/docs/usecases/uc_vSwitchvRouter.rst b/docs/usecases/uc_vSwitchvRouter.rst
new file mode 100644
index 00000000000..ace67ec7608
--- /dev/null
+++ b/docs/usecases/uc_vSwitchvRouter.rst
@@ -0,0 +1,47 @@
+.. _vswitch:
+
+.. toctree::
+
+.. _vswitchrtr:
+
+vSwitch/vRouter
+===============
+
+
+FD.io VPP as a vSwitch/vRouter
+------------------------------
+
+.. note::
+
+ We need to provide commands and and show how to use VPP as a vSwitch/vRouter
+
+One of the use cases for the FD.io VPP platform is to implement it as a
+virtual switch or router. The following section describes examples of
+possible implementations that can be created with the FD.io VPP platform. For
+more in depth descriptions about other possible use cases, see the list
+of
+
+.. figure:: /_images/VPP_App_as_a_vSwitch_x201.jpg
+ :alt: Figure: Linux host as a vSwitch
+ :align: right
+
+ Figure: Linux host as a vSwitch
+
+You can use the FD.io VPP platform to create out-of-the-box virtual switches
+(vSwitch) and virtual routers (vRouter). The FD.io VPP platform allows you to
+manage certain functions and configurations of these application through
+a command-line interface (CLI).
+
+Some of the functionality that a switching application can create
+includes:
+
+* Bridge Domains
+* Ports (including tunnel ports)
+* Connect ports to bridge domains
+* Program ARP termination
+
+Some of the functionality that a routing application can create
+includes:
+
+* Virtual Routing and Forwarding (VRF) tables (in the thousands)
+* Routes (in the millions)
diff --git a/docs/usecases/vhost/index.rst b/docs/usecases/vhost/index.rst
new file mode 100644
index 00000000000..002ebc17639
--- /dev/null
+++ b/docs/usecases/vhost/index.rst
@@ -0,0 +1,17 @@
+.. _vhost:
+
+FD.io VPP with Virtual Machines
+===============================
+This chapter will describe how to use FD.io VPP with virtual machines. We describe
+how to create Vhost port with VPP and how to connect them to VPP. We will also discuss
+some limitations of Vhost.
+
+.. toctree::
+
+ vhost
+ vhost02
+ vhost03
+ vhost04
+ vhost05
+ xmlexample
+
diff --git a/docs/usecases/vhost/iperf-vm.xml b/docs/usecases/vhost/iperf-vm.xml
new file mode 100644
index 00000000000..be354c5f977
--- /dev/null
+++ b/docs/usecases/vhost/iperf-vm.xml
@@ -0,0 +1,106 @@
+<domain type='kvm' id='54'>
+ <name>iperf-server</name>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <memoryBacking>
+ <hugepages>
+ <page size='2048' unit='KiB'/>
+ </hugepages>
+ </memoryBacking>
+ <vcpu placement='static'>1</vcpu>
+ <resource>
+ <partition>/machine</partition>
+ </resource>
+ <os>
+ <type arch='x86_64' machine='pc-i440fx-xenial'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ </features>
+ <cpu mode='host-model'>
+ <model fallback='allow'></model>
+ <numa>
+ <cell id='0' cpus='0' memory='262144' unit='KiB' memAccess='shared'/>
+ </numa>
+ </cpu>
+ <clock offset='utc'>
+ <timer name='rtc' tickpolicy='catchup'/>
+ <timer name='pit' tickpolicy='delay'/>
+ <timer name='hpet' present='no'/>
+ </clock>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <pm>
+ <suspend-to-mem enabled='no'/>
+ <suspend-to-disk enabled='no'/>
+ </pm>
+ <devices>
+ <emulator>/usr/bin/kvm</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source file='/tmp/xenial-mod.img'/>
+ <backingStore/>
+ <target dev='vda' bus='virtio'/>
+ <alias name='virtio-disk0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source file='/scratch/jdenisco/sae/configs/cloud-config.iso'/>
+ <backingStore/>
+ <target dev='hda' bus='ide'/>
+ <readonly/>
+ <alias name='ide0-0-0'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0' model='ich9-ehci1'>
+ <alias name='usb'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'>
+ <alias name='pci.0'/>
+ </controller>
+ <controller type='ide' index='0'>
+ <alias name='ide'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='virtio-serial' index='0'>
+ <alias name='virtio-serial0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+ </controller>
+ <interface type='vhostuser'>
+ <mac address='52:54:00:4c:47:f2'/>
+ <source type='unix' path='/tmp//vm00.sock' mode='server'/>
+ <model type='virtio'/>
+ <alias name='net1'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </interface>
+ <serial type='pty'>
+ <source path='/dev/pts/2'/>
+ <target port='0'/>
+ <alias name='serial0'/>
+ </serial>
+ <console type='pty' tty='/dev/pts/2'>
+ <source path='/dev/pts/2'/>
+ <target type='serial' port='0'/>
+ <alias name='serial0'/>
+ </console>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1'>
+ <listen type='address' address='127.0.0.1'/>
+ </graphics>
+ <memballoon model='virtio'>
+ <alias name='balloon0'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
+ </memballoon>
+ </devices>
+ <seclabel type='dynamic' model='apparmor' relabel='yes'>
+ <label>libvirt-2c4c9317-c7a5-4b37-b789-386ccda7348a</label>
+ <imagelabel>libvirt-2c4c9317-c7a5-4b37-b789-386ccda7348a</imagelabel>
+ </seclabel>
+</domain>
+
diff --git a/docs/usecases/vhost/vhost.rst b/docs/usecases/vhost/vhost.rst
new file mode 100644
index 00000000000..f62faade306
--- /dev/null
+++ b/docs/usecases/vhost/vhost.rst
@@ -0,0 +1,115 @@
+.. toctree::
+
+.. _vhost01:
+
+Prerequisites
+-------------
+
+For this use case we will assume FD.io VPP is installed. We will also assume the user can create and start
+basic virtual machines. This use case will use the linux virsh commands. For more information on virsh
+refer to `virsh man page <https://linux.die.net/man/1/virsh>`_.
+
+The image that we use is based on an Ubuntu cloud image downloaded from:
+`Ubuntu Cloud Images <https://cloud-images.ubuntu.com/xenial/current>`_.
+
+All FD.io VPP commands are being run from a su shell.
+
+.. _vhosttopo:
+
+Topology
+---------
+
+In this case we will use 2 systems. One system we will be running standard linux, the other will
+be running FD.io VPP.
+
+.. figure:: /_images/vhost-topo.png
+ :alt:
+
+ Vhost Use Case Topology
+
+Creating The Virtual Interface
+------------------------------
+
+We will start on the system running FD.io VPP and show that no Virtual interfaces have been created.
+We do this using the :ref:`showintcommand` command.
+
+Notice we do not have any virtual interfaces. We do have an interface (TenGigabitEthernet86/0/0) that
+is up. This interface is connected to a system running, in our example standard linux. We will use
+this system to verify our connectivity to our VM with ping.
+
+.. code-block:: console
+
+ $ sudo bash
+ # vppctl
+ _______ _ _ _____ ___
+ __/ __/ _ \ (_)__ | | / / _ \/ _ \
+ _/ _// // / / / _ \ | |/ / ___/ ___/
+ /_/ /____(_)_/\___/ |___/_/ /_/
+
+ vpp# clear interfaces
+ vpp# show int
+ Name Idx State Counter Count
+ TenGigabitEthernet86/0/0 1 up
+ TenGigabitEthernet86/0/1 2 down
+ local0 0 down
+ vpp#
+
+For more information on the interface commands refer to: :ref:`intcommands`
+
+The next step will be to create the virtual port using the :ref:`createvhostuser` command.
+This command will create the virtual port in VPP and create a linux socket that the VM will
+use to connect to VPP.
+
+The port can be created using VPP as the socket server or client.
+
+Creating the VPP port:
+
+.. code-block:: console
+
+ vpp# create vhost socket /tmp/vm00.sock
+ VirtualEthernet0/0/0
+ vpp# show int
+ Name Idx State Counter Count
+ TenGigabitEthernet86/0/0 1 up
+ TenGigabitEthernet86/0/1 2 down
+ VirtualEthernet0/0/0 3 down
+ local0 0 down
+ vpp#
+
+Notice the interface **VirtualEthernet0/0/0**. In this example we created the virtual interface as
+a client.
+
+We can get more detail on the vhost connection with the :ref:`showvhost` command.
+
+.. code-block:: console
+
+ vpp# show vhost
+ Virtio vhost-user interfaces
+ Global:
+ coalesce frames 32 time 1e-3
+ number of rx virtqueues in interrupt mode: 0
+ Interface: VirtualEthernet0/0/0 (ifindex 3)
+ virtio_net_hdr_sz 12
+ features mask (0xffffffffffffffff):
+ features (0x58208000):
+ VIRTIO_NET_F_MRG_RXBUF (15)
+ VIRTIO_NET_F_GUEST_ANNOUNCE (21)
+ VIRTIO_F_ANY_LAYOUT (27)
+ VIRTIO_F_INDIRECT_DESC (28)
+ VHOST_USER_F_PROTOCOL_FEATURES (30)
+ protocol features (0x3)
+ VHOST_USER_PROTOCOL_F_MQ (0)
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD (1)
+
+ socket filename /tmp/vm00.sock type client errno "No such file or directory"
+
+ rx placement:
+ tx placement: spin-lock
+ thread 0 on vring 0
+ thread 1 on vring 0
+
+ Memory regions (total 0)
+
+Notice **No such file or directory** and **Memory regions (total 0)**. This is because the
+VM has not been created yet.
+
diff --git a/docs/usecases/vhost/vhost02.rst b/docs/usecases/vhost/vhost02.rst
new file mode 100644
index 00000000000..b9d1f5696c9
--- /dev/null
+++ b/docs/usecases/vhost/vhost02.rst
@@ -0,0 +1,109 @@
+.. _vhost02:
+
+Creating the Virtual Machine
+----------------------------
+
+We will now create the virtual machine. We use the "virsh create command". For the complete file we
+use refer to :ref:`xmlexample`.
+
+It is important to note that in the XML file we specify the socket path that is used to connect to
+FD.io VPP.
+
+This is done with a section that looks like this
+
+.. code-block:: console
+
+ <interface type='vhostuser'>
+ <mac address='52:54:00:4c:47:f2'/>
+ <source type='unix' path='/tmp//vm00.sock' mode='server'/>
+ <model type='virtio'/>
+ <alias name='net1'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </interface>
+
+Notice the **interface type** and the **path** to the socket.
+
+Now we create the VM. The virsh list command shows the VMs that have been created. We start with no VMs.
+
+.. code-block:: console
+
+ $ virsh list
+ Id Name State
+ ----------------------------------------------------
+
+Create the VM with the virsh create command specifying our xml file.
+
+.. code-block:: console
+
+ $ virsh create ./iperf3-vm.xml
+ Domain iperf-server3 created from ./iperf3-vm.xml
+
+ $ virsh list
+ Id Name State
+ ----------------------------------------------------
+ 65 iperf-server3 running
+
+The VM is now created.
+
+.. note::
+
+ After a VM is created an xml file can created with "virsh dumpxml".
+
+.. code-block:: console
+
+ $ virsh dumpxml iperf-server3
+ <domain type='kvm' id='65'>
+ <name>iperf-server3</name>
+ <uuid>e23d37c1-10c3-4a6e-ae99-f315a4165641</uuid>
+ <memory unit='KiB'>262144</memory>
+ .....
+
+Once the virtual machine is created notice the socket filename shows **Success** and
+there are **Memory Regions**. At this point the VM and FD.io VPP are connected. Also
+notice **qsz 256**. This system is running an older version of qemu. A queue size of 256
+will affect vhost throughput. The qsz should be 1024. On the web you should be able to
+find ways to install a newer version of qemu or change the queue size.
+
+.. code-block:: console
+
+ vpp# show vhost
+ Virtio vhost-user interfaces
+ Global:
+ coalesce frames 32 time 1e-3
+ number of rx virtqueues in interrupt mode: 0
+ Interface: VirtualEthernet0/0/0 (ifindex 3)
+ virtio_net_hdr_sz 12
+ features mask (0xffffffffffffffff):
+ features (0x58208000):
+ VIRTIO_NET_F_MRG_RXBUF (15)
+ VIRTIO_NET_F_GUEST_ANNOUNCE (21)
+ VIRTIO_F_ANY_LAYOUT (27)
+ VIRTIO_F_INDIRECT_DESC (28)
+ VHOST_USER_F_PROTOCOL_FEATURES (30)
+ protocol features (0x3)
+ VHOST_USER_PROTOCOL_F_MQ (0)
+ VHOST_USER_PROTOCOL_F_LOG_SHMFD (1)
+
+ socket filename /tmp/vm00.sock type client errno "Success"
+
+ rx placement:
+ thread 1 on vring 1, polling
+ tx placement: spin-lock
+ thread 0 on vring 0
+ thread 1 on vring 0
+
+ Memory regions (total 2)
+ region fd guest_phys_addr memory_size userspace_addr mmap_offset mmap_addr
+ ====== ===== ================== ================== ================== ================== =============== ===
+ 0 31 0x0000000000000000 0x00000000000a0000 0x00007f1db9c00000 0x0000000000000000 0x00007f7db0400 000
+ 1 32 0x00000000000c0000 0x000000000ff40000 0x00007f1db9cc0000 0x00000000000c0000 0x00007f7d94ec0 000
+
+ Virtqueue 0 (TX)
+ qsz 256 last_avail_idx 0 last_used_idx 0
+ avail.flags 0 avail.idx 256 used.flags 1 used.idx 0
+ kickfd 33 callfd 34 errfd -1
+
+ Virtqueue 1 (RX)
+ qsz 256 last_avail_idx 8 last_used_idx 8
+ avail.flags 0 avail.idx 8 used.flags 1 used.idx 8
+ kickfd 29 callfd 35 errfd -1
diff --git a/docs/usecases/vhost/vhost03.rst b/docs/usecases/vhost/vhost03.rst
new file mode 100644
index 00000000000..ed583349bc6
--- /dev/null
+++ b/docs/usecases/vhost/vhost03.rst
@@ -0,0 +1,88 @@
+.. _vhost03:
+
+Bridge the Interfaces
+---------------------
+
+To connect the 2 interfaces we put them on an L2 bridge.
+
+Use the "set interface l2 bridge" command.
+
+.. code-block:: console
+
+ vpp# set interface l2 bridge VirtualEthernet0/0/0 100
+ vpp# set interface l2 bridge TenGigabitEthernet86/0/0 100
+ vpp# show bridge
+ BD-ID Index BSN Age(min) Learning U-Forwrd UU-Flood Flooding ARP-Term BVI-Intf
+ 100 1 0 off on on on on off N/A
+ vpp# show bridge 100 det
+ BD-ID Index BSN Age(min) Learning U-Forwrd UU-Flood Flooding ARP-Term BVI-Intf
+ 100 1 0 off on on on on off N/A
+
+ Interface If-idx ISN SHG BVI TxFlood VLAN-Tag-Rewrite
+ VirtualEthernet0/0/0 3 1 0 - * none
+ TenGigabitEthernet86/0/0 1 1 0 - * none
+ vpp# show vhost
+
+Bring the Interfaces Up
+-----------------------
+
+We can now bring all the pertinent interfaces up. We can then we will then be able to communicate
+with the VM from the remote system running Linux.
+
+Bring the interfaces up with :ref:`setintstate` command.
+
+.. code-block:: console
+
+ vpp# set interface state VirtualEthernet0/0/0 up
+ vpp# set interface state TenGigabitEthernet86/0/0 up
+ vpp# sh int
+ Name Idx State Counter Count
+ TenGigabitEthernet86/0/0 1 up rx packets 2
+ rx bytes 180
+ TenGigabitEthernet86/0/1 2 down
+ VirtualEthernet0/0/0 3 up tx packets 2
+ tx bytes 180
+ local0 0 down
+
+Ping from the VM
+----------------
+
+The remote Linux system has an ip address of "10.0.0.2" we can now reach it from the VM.
+
+Use the "virsh console" command to attach to the VM. "ctrl-D" to exit.
+
+.. code-block:: console
+
+ $ virsh console iperf-server3
+ Connected to domain iperf-server3
+ Escape character is ^]
+
+ Ubuntu 16.04.3 LTS iperfvm ttyS0
+ .....
+
+ root@iperfvm:~# ping 10.0.0.2
+ 64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.285 ms
+ 64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.154 ms
+ 64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.159 ms
+ 64 bytes from 10.0.0.2: icmp_seq=4 ttl=64 time=0.208 ms
+
+
+On VPP you can now see the packet counts increasing. The packets from the VM are seen as **rx packets**
+on **VirtualEthernet0/0/0**, they are then bridged to **TenGigabitEthernet86/0/0** and are seen leaving the
+system as **tx packets**. The reverse is true on the way in.
+
+.. code-block:: console
+
+ vpp# sh int
+ Name Idx State Counter Count
+ TenGigabitEthernet86/0/0 1 up rx packets 16
+ rx bytes 1476
+ tx packets 14
+ tx bytes 1260
+ TenGigabitEthernet86/0/1 2 down
+ VirtualEthernet0/0/0 3 up rx packets 14
+ rx bytes 1260
+ tx packets 16
+ tx bytes 1476
+ local0 0 down
+ vpp#
diff --git a/docs/usecases/vhost/vhost04.rst b/docs/usecases/vhost/vhost04.rst
new file mode 100644
index 00000000000..256c0b8ffa4
--- /dev/null
+++ b/docs/usecases/vhost/vhost04.rst
@@ -0,0 +1,43 @@
+.. _vhost04:
+
+Cleanup
+-------
+
+Destroy the VMs with "virsh destroy"
+
+.. code-block:: console
+
+ cto@tf-ucs-3:~$ virsh list
+ Id Name State
+ ----------------------------------------------------
+ 65 iperf-server3 running
+
+ cto@tf-ucs-3:~$ virsh destroy iperf-server3
+ Domain iperf-server3 destroyed
+
+
+Delete the Virtual port in FD.io VPP
+
+.. code-block:: console
+
+ vpp# delete vhost-user VirtualEthernet0/0/0
+ vpp# show int
+ Name Idx State Counter Count
+ TenGigabitEthernet86/0/0 1 up rx packets 21
+ rx bytes 1928
+ tx packets 19
+ tx bytes 1694
+ TenGigabitEthernet86/0/1 2 down
+ local0 0 down
+
+Restart FD.io VPP
+
+.. code-block:: console
+
+ # service vpp restart
+ # vppctl show int
+ Name Idx State Counter Count
+ TenGigabitEthernet86/0/0 1 down
+ TenGigabitEthernet86/0/1 2 down
+ local0 0 down
+
diff --git a/docs/usecases/vhost/vhost05.rst b/docs/usecases/vhost/vhost05.rst
new file mode 100644
index 00000000000..4eba6e17101
--- /dev/null
+++ b/docs/usecases/vhost/vhost05.rst
@@ -0,0 +1,25 @@
+.. _vhost05:
+
+Limitations
+-----------
+There are some limitations when using the qemu vhost driver. Some are described in this section.
+
+Performance
+^^^^^^^^^^^
+
+VPP performance with vHost is limited by the Qemu vHost driver. FD.io VPP 18.04 CSIT vHost testing
+shows with 2 threads, 2 cores and a Queue size of 1024 the maximum NDR throughput was about 7.5 Mpps.
+This is about the limit at this time.
+
+For all the details on the CSIT VM vhost connection refer to the
+`CSIT VM vHost performance tests <https://docs.fd.io/csit/rls1804/report/vpp_performance_tests/packet_throughput_graphs/vm_vhost.html>`_.
+
+
+Features
+^^^^^^^^
+
+These are the features not supported with FD.io VPP vHost.
+
+* VPP implements vHost in device mode only. VPP is intended to work with Qemu which implements vHost in driver mode, it does not implement vHost driver mode.
+* VPP vHost implementation does not support checksum or transmit segmentation offload.
+* VPP vHost implementation does not support packet receive filtering feature for controlling receive traffic.
diff --git a/docs/usecases/vhost/xmlexample.rst b/docs/usecases/vhost/xmlexample.rst
new file mode 100644
index 00000000000..34445da0ccb
--- /dev/null
+++ b/docs/usecases/vhost/xmlexample.rst
@@ -0,0 +1,11 @@
+.. _xmlexample01:
+
+The XML File
+------------
+
+An example of a file that could be used with the virsh create command.
+
+.. literalinclude:: iperf-vm.xml
+ :language: XML
+ :emphasize-lines: 42-49, 74-80
+