VPP是一个与OVS类似的软件交换机,不同的是,它用批量的方式、在用户空间处理数据报文,它可以使用DPDK来实现报文的收发,也可以使用其他方式。它的架构非常灵活,扩展方便,通过插件机制,可以实现大量的功能:二层转发、三层转发、NAT等。

今天主要是对其二层转发功能进行探索,看看如何将它当作一台二层交换机来使用。

环境配置

VPP的安装和部署可以参照上一篇。测试环境的拓扑如下图所示:

测试拓扑

如上图所示,需要创建两对veth设备、两个网络命名空间。将veth设备的一端移到网络命名空间中,另一端则移到VPP中,然后通过配置,使两个原本没有连接在一起的veth设备可以实现网络通信。

安装好了vpp之后,继续如下的操作。

创建两对Veth设备

1
2
3
4
5
6
7
$ ip link add name vnic1 type veth peer name vnic1vpp
$ ip l set dev vnic1 up
$ ip l set dev vnic1vpp up

$ ip link add name vnic2 type veth peer name vnic2vpp
$ ip l set dev vnic2 up
$ ip l set dev vnic2vpp up

创建两个命名空间

1
2
$ ip netns add ns1
$ ip netns add ns2

将设备移到vpp和命名空间

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 将vnic1移到ns1
$ ip l set dev vnic1 netns ns1
# 将vnic2移到ns2
$ ip l set dev vnic2 netns ns2

# 将vnic1vpp和vnic2vpp移到vpp里面
$ vppctl
vpp# create host-interface name vnic1vpp
host-vnic1vpp
vpp# create host-interface name vnic2vpp
host-vnic2vpp
vpp#

配置IP地址

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 设置vnic1的ip地址为10.10.1.1
$ ip netns exec ns1 ip l set lo up
$ ip netns exec ns1 ip a add 10.10.1.1/24 dev vnic1
$ ip netns exec ns1 ip l set vnic1 up

# 设置vnic2的ip地址为10.10.1.2
$ ip netns exec ns2 ip l set lo up
$ ip netns exec ns2 ip a add 10.10.1.2/24 dev vnic2
$ ip netns exec ns2 ip l set vnic2 up

# 测试一下连通性(不通)
$ ip netns exec ns1 ping -c2 10.10.1.2
PING 10.10.1.2 (10.10.1.2) 56(84) bytes of data.
From 10.10.1.1 icmp_seq=1 Destination Host Unreachable
From 10.10.1.1 icmp_seq=2 Destination Host Unreachable

--- 10.10.1.2 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1027ms

配置VPP

VPP不配置的情况下,网络是不通的。我们对VPP进行配置,将其配置为一个二层交换机。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 创建一个bridge-domain
root@vpp-1:~# vppctl create bridge-domain 10 
root@vpp-1:~# vppctl set interface state host-vnic1vpp up
root@vpp-1:~# vppctl set interface state host-vnic2vpp up

# 把host-vnic1vpp/host-vnic2vpp加入bridge domain 10
root@vpp-1:~# vppctl set int l2 bridge host-vnic1vpp 10
root@vpp-1:~# vppctl set int l2 bridge host-vnic2vpp 10
# 查看详情
root@vpp-1:~# vppctl show bridge-domain 10 detail
  BD-ID   Index   BSN  Age(min)  Learning  U-Forwrd   UU-Flood   Flooding  ARP-Term  arp-ufwd Learn-co Learn-li   BVI-Intf
   10       1      0     off        on        on       flood        on       off       off        0    16777216     N/A
             SPAN (span-l2-input)
   INPUT_CLASSIFY (l2-input-classify)
   INPUT_FEAT_ARC (l2-input-feat-arc)
     POLICER_CLAS (l2-policer-classify)
              ACL (l2-input-acl)
            VPATH (vpath-input-l2)
 L2_IP_QOS_RECORD (l2-ip-qos-record)
              VTR (l2-input-vtr)
            LEARN (l2-learn)
               RW (l2-rw)
              FWD (l2-fwd)
         UU_FLOOD (l2-flood)
            FLOOD (l2-flood)
         XCONNECT (l2-output)

           Interface           If-idx ISN  SHG  BVI  TxFlood        VLAN-Tag-Rewrite
         host-vnic1vpp           5     1    0    -      *                 none
         host-vnic2vpp           6     1    0    -      *                 none

测试连通性

配置完vpp之后,我们再次看看网络是否可以通。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
root@vpp-1:~# ip netns exec ns1 ping -c2 10.10.1.2
PING 10.10.1.2 (10.10.1.2) 56(84) bytes of data.
64 bytes from 10.10.1.2: icmp_seq=1 ttl=64 time=17.3 ms
64 bytes from 10.10.1.2: icmp_seq=2 ttl=64 time=7.98 ms

--- 10.10.1.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 7.983/12.664/17.345/4.681 ms

root@vpp-1:~# ip netns exec ns2 ping -c2 10.10.1.1
PING 10.10.1.1 (10.10.1.1) 56(84) bytes of data.
64 bytes from 10.10.1.1: icmp_seq=1 ttl=64 time=10.3 ms
64 bytes from 10.10.1.1: icmp_seq=2 ttl=64 time=9.02 ms

--- 10.10.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 9.016/9.657/10.299/0.641 ms

从上面的结果可以看出,我们使用vpp作为网桥,实现二层转发,vnic1和vnic2是可以通信了。

参考资料

  1. https://s3-docs.fd.io/vpp/22.06/gettingstarted/progressivevpp/index.html
  2. https://s3-docs.fd.io/vpp/22.06/gettingstarted/progressivevpp/switching.html