Difference between revisions of "VPP/Tutorial Routing and Switching"

From fd.io
< VPP
Jump to: navigation, search
 
(13 intermediate revisions by 7 users not shown)
Line 1: Line 1:
This is a basic tutorial intended for VPP newcomers. It progressivly introduces main CLI commands for creating a switched and routed network. For the purpose of this tutorial, a virtual network will be created by the mean of Linux network namespaces, veth, and tap interfaces.
+
Please see [https://fd.io/docs/vpp/master/gettingstarted/progressivevpp/index.html the new documentation]
 
+
 
+
== Prerequisites ==
+
 
+
For this tutorial, you will need a Linux environment with VPP installed.
+
You can follow [[VPP/Setting_Up_Your_Dev_Environment|this tutorial]] to setup your development environment.
+
 
+
== Running vpp ==
+
 
+
=== Start VPP ===
+
 
+
If you installed VPP using the vagrant tutorial, do <code>vagrant up</code> and <code>vagrant ssh</code> in VPP's vagrant directory. VPP should be already be running.
+
 
+
~$ sudo vppctl show version
+
vpp v1.0.0-433~gb53693a-dirty built by vagrant on localhost at Wed May  4 03:03:02 PDT 2016
+
 
+
If it is not running, try:
+
 
+
~$ sudo start vpp
+
 
+
If you played with VPP. It might be a good idea to restart it.
+
 
+
~# sudo stop vpp
+
~# sudo start vpp
+
 
+
If you have installed vpp through other means, you can execute VPP directly.
+
 
+
~$ sudo vpp unix { interactive log /tmp/vpp.log full-coredump } api-trace { on }
+
 
+
This command will start VPP in interactive mode. Which means you will be able to enter VPP CLI commands just like if they were executed using <code>sudo vppctl ''your command''</code>.
+
 
+
From now on, we will use <code>vppctl</code> and ommit <code>sudo</code>, but you can use VPP's interactive mode if you want.
+
 
+
 
+
=== Basic VPP commands ===
+
 
+
Execute the following commands.
+
 
+
~$ vppctl show interface
+
              Name              Idx      State          Counter          Count
+
GigabitEthernet0/8/0              5        down
+
GigabitEthernet0/9/0              6        down
+
local0                            0        down
+
pg/stream-0                      1        down
+
pg/stream-1                      2        down
+
pg/stream-2                      3        down
+
pg/stream-3                      4        down
+
 
+
In this example, the VM has two PCI interfaces, owned by DPDK drivers. DPDK runs in polling mode, which means that the single VPP thread currently takes 100% CPU.
+
 
+
~$ top
+
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM    TIME+ COMMAND
+
8510 root      20  0 2123488  28876  9672 R  89.6  0.7  1:43.84 vpp_main
+
 
+
VPP Debug CLI implements a lot of different commands. You can display CLI help with '?'.
+
 
+
~$ vppctl ?
+
  ...
+
~$ vppctl show ?
+
  ...
+
 
+
== Virtual Network Setup ==
+
 
+
VPP supports two non-DPDK drivers enabling communications with Linux namespaces:
+
* '''veth''' interfaces with vpp ''host'' interfaces (based on efficient AF_PACKET shared memory with kernel). Click here for more information about [http://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/|veth interfaces and Linux network namespaces].
+
* '''tap''' interfaces from Linux's tuntap support.
+
 
+
This tutorial is going to use 3 different namespaces: ''ns0'', ''ns1'', and ''ns2''. ''ns0'' and ''ns1'' will be connected to VPP by the mean of veth interfaces, while ''ns2'' will be using a tap interface.
+
 
+
=== ns0, ns1 and veth interfaces ===
+
 
+
Let's configure ns0.
+
 
+
~$ ip netns add ns0
+
~$ ip link add vpp0 type veth peer name vethns0
+
~$ ip link set vethns0 netns ns0
+
~$ ip netns exec ns0 ip link set lo up
+
~$ ip netns exec ns0 ip link set vethns0 up
+
~$ ip netns exec ns0 ip addr add 2001::1/64 dev vethns0
+
~$ ip netns exec ns0 ip addr add 10.0.0.1/24 dev vethns0
+
~$ ip link set vpp0 up
+
 
+
And do the same for ns1.
+
 
+
~$ ip netns add ns1
+
~$ ip link add vpp1 type veth peer name vethns1
+
~$ ip link set vethns1 netns ns1
+
~$ ip netns exec ns1 ip link set lo up
+
~$ ip netns exec ns1 ip link set vethns1 up
+
~$ ip netns exec ns1 ip addr add 2001::2/64 dev vethns0
+
~$ ip netns exec ns1 ip addr add 10.0.0.2/24 dev vethns0
+
~$ ip link set vpp1 up
+
 
+
Now on VPP side.
+
 
+
Let's create the host (af-packet) interfaces and set them up.
+
~$ vppctl create host-interface name vpp0
+
~$ vppctl create host-interface name vpp1
+
~$ vppctl set interface state host-vpp0 up
+
~$ vppctl set interface state host-vpp1 up
+
 
+
Host interfaces are created with names like host-<linux-ifname>.
+
 
+
~$ sudo vppctl show interface
+
              Name              Idx      State          Counter          Count
+
GigabitEthernet0/8/0              5        down
+
GigabitEthernet0/9/0              6        down
+
host-vpp0                        7        up
+
host-vpp1                        8        up
+
local0                            0        down
+
pg/stream-0                      1        down
+
pg/stream-1                      2        down
+
pg/stream-2                      3        down
+
pg/stream-3                      4        down
+
 
+
~$ sudo vppctl show hardware
+
              Name                Idx  Link  Hardware
+
GigabitEthernet0/8/0              5    down  GigabitEthernet0/8/0
+
  Ethernet address 08:00:27:1b:35:da
+
  Intel 82540EM (e1000)
+
    carrier up full duplex speed 1000 mtu 9216
+
+
GigabitEthernet0/9/0              6    down  GigabitEthernet0/9/0
+
  Ethernet address 08:00:27:59:74:1a
+
  Intel 82540EM (e1000)
+
    carrier up full duplex speed 1000 mtu 9216
+
+
host-vpp0                          7    up  host-vpp0
+
  Ethernet address 02:fe:0b:67:bd:b0
+
  Linux PACKET socket interface
+
host-vpp1                          8    up  host-vpp1
+
  Ethernet address 02:fe:da:fd:40:19
+
  Linux PACKET socket interface
+
[...]
+
 
+
=== Give ns3 a tap interface ===
+
 
+
<code>tap connect</code> is used to create a tap interface. It can also be used to connect to an existing detached tap interface.
+
 
+
~# vppctl tap connect tap0
+
~# vppctl show int
+
[...]
+
tap-0                            10      down      drops                          8
+
[...]
+
 
+
The tap interface is created in VPP's namespace (default one). We need to move it to ns2 and configure it.
+
 
+
~# ip netns add ns2
+
~# ip link set tap0 netns ns2
+
~# ip netns exec ns2 ip link set lo up
+
~# ip netns exec ns2 ip link set tap0 up
+
~# ip netns exec ns2 ip addr add 10.0.1.1/24 dev tap0
+
~# ip netns exec ns2 ip addr add 2001:1::1/64 dev tap0
+
 
+
Now we are good to go to configure VPP.
+
 
+
== Routing and Switching ==
+
 
+
This section will show how to configure our little virtual network with switching and routing.
+
 
+
=== Switching ns0 and ns1 ===
+
 
+
In this section, we are going to switch ns0, ns1, and VPP within a common bridging domain.
+
 
+
~# vppctl set interface l2 bridge host-vpp0 1
+
~# vppctl set interface l2 bridge host-vpp1 1
+
 
+
The two interfaces are now bridged !
+
Let's try and see packets coming in and out by using VPP's tracing.
+
 
+
~# vppctl trace add af-packet-input 8
+
~# ip netns exec ns0 ping6 2001::2
+
~# vppctl show trace
+
~# vppctl clear trace
+
 
+
You should be able to see NDP packets followed by echo requests and responses.
+
 
+
The two namespaces are connected but VPP is not. Let's change that by adding a loopback interface to the bridge domain.
+
 
+
~# vppctl create loopback interface
+
~# vppctl show interface
+
              Name              Idx      State          Counter          Count
+
[...]
+
loop0                            9        down
+
[...]
+
 
+
~# vppctl set interface l2 bridge loop0 1 bvi
+
~# vppctl set interface state loop0 up
+
~# vppctl set interface ip address loop0 2001::ffff/64
+
~# vppctl set interface ip address loop0 10.0.0.10/24
+
 
+
VPP is now plugged to the bridge and configured. You should be able to ping VPP.
+
 
+
~# vppctl trace add af-packet-input 15
+
~# ip netns exec ns0 ping6 2001::ffff
+
~# ip netns exec ns0 ping 10.0.0.10
+
~# vppctl show trace
+
~# vppctl clear trace
+
 
+
 
+
=== Routing ===
+
 
+
Now that ns0 and ns1 are switched, let's configure the tap interface such that we can do routing between ns2 and ns0+ns1.
+
 
+
~# vppctl set interface state tap-0 up
+
~# vppctl set interface ip address tap-0 2001:1::ffff/64
+
~# vppctl set interface ip address tap-0 10.0.1.10/24
+
 
+
On VPP side, we are good to go. But we just need to setup default routes in every namespaces.
+
Depending on your linux configuration, IPv6 routes may already exist as VPP automatically sends router advertisements.
+
 
+
~# ip netns exec ns0 ip route add default via 10.0.0.10
+
~# ip netns exec ns0 ip -6 route add default via 2001::ffff
+
~# ip netns exec ns1 ip route add default via 10.0.0.10
+
~# ip netns exec ns1 ip -6 route add default via 2001::ffff
+
~# ip netns exec ns2 ip route add default via 10.0.1.10
+
~# ip netns exec ns2 ip -6 route add default via 2001:1::ffff
+
 
+
And now we can ping through VPP forwarding engine.
+
 
+
~# vppctl trace add af-packet-input 15
+
~# ip netns exec ns0 ping6 2001:1::1
+
~# ip netns exec ns0 ping 10.0.1.1
+
~# vppctl show trace
+
~# vppctl clear trace
+
 
+
== Cleaning up ==
+
 
+
In order to cleanup this hands-on:
+
 
+
~# ip netns del ns0
+
~# ip netns del ns1
+
~# ip netns del ns2
+
~# ip link del vpp0
+
~# ip link del vpp1
+
~# ip link del tap0
+
~# stop vpp
+
~# start vpp
+

Latest revision as of 07:51, 30 July 2020

Please see the new documentation