目录 {#目录 .TOC-Heading}

1 概述 5

1.1 项目背景 5

1.2 环境信息 5

2 环境部署 6

2.1 系统安装 6

2.2 Switch节点 6

2.3 Generator节点/Receiver节点
11

3 l2_switch实验 14

3.1 实验准备 14

3.2 实验操作 16

3.2.1 Switch节点 16

3.2.2 Generator节点 & Receiver节点
19

4 Simple_router实验 23

4.1 实验准备 23

4.2 实验操作 27

4.2.1 Switch节点 27

4.2.2 Generator节点 & Receiver节点
29

表1. 文档修改记录 1

表2. 服务器信息表 5

图1. 网络拓扑连接图 6

图2. dpdk端口绑定情况 9

图3. 大页内存情况 10

图4. dpdk端口绑定情况 13

图5. 大页内存情况 13

图6. l2_switch实验文件 14

图7. ovs网桥情况 18

图8. l2_switch实验流表 19

图9. 发包软件启动 22

图10. 流表变化 23

图11. simple_router实验文件
24

图12. ovs网桥情况 28

图13. simple_router实验流表
29

图14. 流表变化 30

概述

项目背景

参考Github项目。

https://github.com/P4-vSwitch

{#section .图名}

环境信息

项目部署环境为虚拟机,需将其中的脚本和代码迁移至物理机运行。

实验环境共3台服务器,基本信息如下,实验室网络可登录。

  1. []{#_Toc17707 .anchor}服务器信息表

+:———-:+:————–:+:———–:+:———–:+:—————-:+
| 服务器名称 | IP地址 | 用户名 | 密码 | 备注 |
+————+—————-+————-+————-+——————+
| p4switch | 192.168.61.133 | root/ubuntu | abcd@1234 | system |
| | | | | |
| | | | | Ubuntu 14.04.4 |
| | | | | |
| | | | | kernel |
| | | | | |
| | | | | 4.2.0-27-generic |
+————+—————-+ | | |
| p4recv | 192.168.61.135 | | | |
+————+—————-+ | | |
| p4gen | 192.168.61.134 | | | |
+————+—————-+————-+————-+——————+

拓扑连接图如下。

{width=”5.758333333333334in”
height=”3.122916666666667in”}

网络拓扑连接图 {#网络拓扑连接图 .图名}

环境部署

系统安装

Ubuntu 14.04.4,内核版本4.2.0-27-generic。

Switch节点

使用root用户登录Switch节点,更新apt源,下载必要的软件依赖,建议将自带源替换为国内源。

apt-get update

#apt-get upgrade

apt-get -y install git python-pip fuse libfuse-dev dh-autoreconf openssl
libssl-dev cmake libpcap-dev python-yaml

安装ply,且要求版本<3.10,建议使用国内pip源。

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple ply==3.9

创建工作目录,并下载项目代码。

cd /home

git clone https://github.com/P4-vSwitch/vagrant.git

下载安装p4-hlir模块

cd /home/vagrant

git clone https://github.com/p4lang/p4-hlir.git

cd p4-hlir/

python setup.py install

下载安装p4c-behavioral模块

cd /home/vagrant

git clone https://github.com/P4-vSwitch/p4c-behavioral.git

cd p4c-behavioral/

git checkout ovs

python setup.py install

下载OVS模块

cd /home/vagrant

git clone https://github.com/P4-vSwitch/ovs.git

cd ovs/

git checkout p4

git submodule update --init

Build DPDK模块

cd /home/vagrant/ovs/deps/dpdk

patch -p1 -N < ../../setup-scripts/patches/dpdk.patch

make -j 2 install T=x86_64-native-linuxapp-gcc

导入环境变量,建议填入~/.bashrc,避免每次新开窗口都需要手动导入。

export RTE_SDK=/home/vagrant/ovs/deps/dpdk

export RTE_TARGET=x86_64-native-linuxapp-gcc

export DPDK_DIR=$RTE_SDK

export DPDK_BUILD=$DPDK_DIR/$RTE_TARGET/

配置DPDK内核模块

cd /home/vagrant

modprobe uio

insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko

insmod $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko "lo_mode=lo_mode_ring"

将服务器端口绑定至DPDK

ifconfig eth0 down

$RTE_SDK/tools/dpdk_nic_bind.py -b igb_uio eth0

ifconfig eth1 down

$RTE_SDK/tools/dpdk_nic_bind.py -b igb_uio eth1

查看绑定情况

$RTE_SDK/tools/dpdk_nic_bind.py --status

{width=”5.758333333333334in”
height=”1.7638888888888888in”}

dpdk端口绑定情况 {#dpdk端口绑定情况 .图名}

配置大页内存

cd /home/vagrant

mkdir -p /mnt/huge

(mount | grep hugetlbfs) > /dev/null || sudo mount -t hugetlbfs
nodev /mnt/huge

echo 1024 >
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

查看大页内存

grep -i huge /proc/meminfo

{width=”5.763888888888889in”
height=”1.1131944444444444in”}

大页内存情况 {#大页内存情况 .图名}

Build OVS

cd /home/vagrant/ovs/

./boot.sh

./configure --with-dpdk=$DPDK_BUILD CFLAGS="-g -O2 -Wno-cast-align"
\

p4inputfile=./include/p4/examples/l2_switch/l2_switch.p4 \

p4outputdir=./include/p4/src

make -j 2

创建OVS数据库文件和文件路径

mkdir -p /usr/local/etc/openvswitch

mkdir -p /usr/local/var/run/openvswitch

cd /home/vagrant/ovs/ovsdb/

./ovsdb-tool create /usr/local/etc/openvswitch/conf.db
../vswitchd/vswitch.ovsschema

Generator节点/Receiver节点

两节点安装步骤一致,合并描述。

使用root用户登录Generator或Receiver节点,更新apt源,下载必要的软件依赖,建议将自带源替换为国内源。

apt-get update

apt-get upgrade

apt-get -y install git python-pip fuse libfuse-dev dh-autoreconf openssl
libssl-dev cmake libpcap-dev python-yaml

创建工作目录,并下载项目代码。

cd /home

git clone https://github.com/P4-vSwitch/vagrant.git

下载Pktgen项目代码

cd /home/vagrant

git clone https://github.com/P4-vSwitch/pktgen.git

cd pktgen/

git submodule update --init

Build DPDK模块

cd /home/vagrant/pktgen/deps/dpdk

make -j 2 install T=x86_64-native-linuxapp-gcc

导入环境变量,建议填入~/.bashrc,避免每次新开窗口都需要手动导入。

export RTE_SDK=/home/vagrant/pktgen/deps/dpdk

export RTE_TARGET=x86_64-native-linuxapp-gcc

export DPDK_DIR=$RTE_SDK

export DPDK_BUILD=$DPDK_DIR/$RTE_TARGET/

配置DPDK内核模块

cd /home/vagrant

modprobe uio

insmod $RTE_SDK/$RTE_TARGET/kmod/igb_uio.ko

insmod $RTE_SDK/$RTE_TARGET/kmod/rte_kni.ko "lo_mode=lo_mode_ring"

将服务器端口绑定至DPDK

ifconfig eth0 down

$RTE_SDK/tools/dpdk_nic_bind.py -b igb_uio eth0

ifconfig eth1 down

$RTE_SDK/tools/dpdk_nic_bind.py -b igb_uio eth1

查看绑定情况

$RTE_SDK/tools/dpdk_nic_bind.py --status

{width=”5.763888888888889in”
height=”1.7833333333333334in”}

dpdk端口绑定情况 {#dpdk端口绑定情况-1 .图名}

配置大页内存

cd /home/vagrant

mkdir -p /mnt/huge

(mount | grep hugetlbfs) > /dev/null || sudo mount -t hugetlbfs
nodev /mnt/huge

echo 512 >
/sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages

查看大页内存

grep -i huge /proc/meminfo

{width=”5.764583333333333in”
height=”1.332638888888889in”}

大页内存情况 {#大页内存情况-1 .图名}

Build Pktgen模块

cd /home/vagrant/pktgen

make

l2_switch实验

实验准备

实验脚本文件和配置文件中的参数需根据服务器网口实际情况进行修改,实验路径如下图所示。不同节点需要修改的位置不同,以下分别描述。

{width=”5.761805555555555in”
height=”1.2694444444444444in”}

l2_switch实验文件 {#l2_switch实验文件 .图名}

Switch节点:

l2_switch.p4/generator.pkt/receiver.pkt:保持不变

l2_switch.sh:将流表中的mac地址,更换为Generator和Receiver服务器分别连接Switch的网口的mac地址,如下标红位置所示。

#! /bin/sh -ve

# Please make sure that you update the path to the current OVS
directory.

DIR=/home/vagrant/ovs/utilities

$DIR/ovs-ofctl --protocols=OpenFlow15 del-flows br0

# SMAC Table 0

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=0,priority=32768,ethernet__srcAddr=0x74a4b500eee4
actions=resubmit(,1)"

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=0,priority=32768,ethernet__srcAddr=0x74a4b500ef02
actions=resubmit(,1)"

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=0,priority=0 actions=controller"

# DMAC Table 1

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=1,priority=32768,ethernet__dstAddr=0x74a4b500eee4
actions=set_field:1->reg0,resubmit(,2)"

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=1,priority=32768,ethernet__dstAddr=0x74a4b500ef02
actions=set_field:2->reg0,resubmit(,2)"

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=1,priority=0 actions=flood"

# SRC Pruning Table 2

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=2,priority=32768,in_port=1,reg0=1 actions="

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=2,priority=32768,in_port=2,reg0=2 actions="

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=2,priority=32768,in_port=3,reg0=3 actions="

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=2,priority=32768,in_port=4,reg0=4 actions="

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=2,priority=32768,in_port=5,reg0=5 actions="

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=2,priority=32768,in_port=6,reg0=6 actions="

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=2,priority=0 actions=deparse,output:NXM_NX_REG0[]"

generator节点:

只修改generator.pkt文件,将generator与switch连接的网口mac地址填入,如下所示。

set mac 0 74:a4:b5:00:ee:e4

receiver节点:

只修改receiver.pkt文件,将receiver与switch连接的网口mac地址填入,如下所示。

set mac 0 74:a4:b5:00:ef:02

实验操作

Switch节点

使用root用户,登录switch节点。

编译l2_switch.p4

cd /home/vagrant/ovs

./configure --with-dpdk=$DPDK_BUILD CFLAGS="-g -O2 -Wno-cast-align"
p4inputfile=/home/vagrant/examples/l2_switch/l2_switch.p4
p4outputdir=./include/p4/src

make clean

make -j 2

启动ovsdb-server(保持后台运行)

cd /home/vagrant/ovs/ovsdb

nohup ./ovsdb-server
--remote=punix:/usr/local/var/run/openvswitch/db.sock \

--remote=db:Open_vSwitch,Open_vSwitch,manager_options --pidfile &

启动ovs-vswitchd(保持后台运行)

cd /home/vagrant/ovs/vswitchd

nohup ./ovs-vswitchd --dpdk -c 0x1 -n 4 --
unix:/usr/local/var/run/openvswitch/db.sock --pidfile &

创建OVS网桥

cd /home/vagrant/ovs/utilities

./ovs-vsctl --no-wait init

./ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev

./ovs-vsctl set bridge br0 protocols=OpenFlow15

./ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk

./ovs-vsctl add-port br0 dpdk1 -- set Interface dpdk1 type=dpdk

如果需要删除,则执行./ovs-vsctl del-br br0

查看网桥执行./ovs-vsctl show

{width=”5.7659722222222225in”
height=”2.2305555555555556in”}

ovs网桥情况 {#ovs网桥情况 .图名}

加载流表

cd /home/vagrant/examples/l2_switch/

./l2_switch.sh

加载完成后,可执行如下命令查看。

cd /home/vagrant/ovs/utilities

./ovs-ofctl --protocols=OpenFlow15 dump-flows br0

{width=”5.752777777777778in”
height=”1.0763888888888888in”}

l2_switch实验流表 {#l2_switch实验流表 .图名}

Generator节点 & Receiver节点

使用root用户,分别从不同终端窗口登录generator节点和receiver节点。

启动发包程序

Generator节点:

cd /home/vagrant/pktgen

./app/app/x86_64-native-linuxapp-gcc/app/pktgen -c 0x3 -n 4 -- -P -m
"1.0" -f /home/vagrant/examples/l2_switch/generator.pkt

Receiver节点:

cd /home/vagrant/pktgen

./app/app/x86_64-native-linuxapp-gcc/app/pktgen -c 0x3 -n 4 -- -P -m
"1.0" -f /home/vagrant/examples/l2_switch/receiver.pkt

启动后出现如下图所示回显。

{width=”5.759722222222222in”
height=”5.345833333333333in”}

{width=”5.7625in”
height=”4.083333333333333in”}

{width=”5.759722222222222in”
height=”3.6256944444444446in”}

{width=”5.7659722222222225in”
height=”3.7909722222222224in”}

{width=”5.7625in”
height=”3.9631944444444445in”}

发包软件启动 {#发包软件启动 .图名}

开始发包

回到generator节点的界面,输入并执行start 0,开始发包。

此时,在switch节点可查看流表,若数据包数量随时间出现增长,则说明发报成功,如下图所示。

{width=”5.763888888888889in”
height=”1.1402777777777777in”}

{width=”5.764583333333333in”
height=”1.1694444444444445in”}

流表变化 {#流表变化 .图名}

实验结束后,回到genarator节点,输入并执行stop 0,停止发包。

Simple_router实验

实验准备

若接着上述l2_switch实验继续,则需要先将环境清理。

停止generator节点和receiver节点的发包程序,并退出。

stop 0

quit

删除switch节点的ovsdb和ovs主进程。

ps -ef | grep ovs

kill -9 xxxxx

kill -9 xxxxx

实验脚本文件和配置文件中的参数需根据服务器网口实际情况进行修改,实验路径如下图所示。不同节点需要修改的位置不同,以下分别描述。

{width=”5.759722222222222in”
height=”0.8493055555555555in”}

simple_router实验文件 {#simple_router实验文件 .图名}

Switch节点:

simple_router.p4/generator.pkt/receiver.pkt:保持不变

simple_router.sh:将流表中的mac地址,更换为Generator和Receiver服务器分别连接Switch的网口的mac地址,如下标红位置所示。

#! /bin/sh -ve

# Please make sure that you update the path to the current OVS
directory.

DIR=/home/vagrant/ovs/utilities

# For this test we will pre-populate ARP caches at the end-hosts

$DIR/ovs-ofctl --protocols=OpenFlow15 del-flows br0

# Verify Checksum (Table 0)

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=0,priority=32768,ethernet__etherType=0x800 \

actions=calc_fields_verify(ipv4__hdrChecksum,csum16,fields:ipv4__version_ihl,ipv4__diffserv,ipv4__totalLen,ipv4__identification,ipv4__flags_fragOffset,ipv4__ttl,ipv4__protocol,ipv4__srcAddr,ipv4__dstAddr),
\

resubmit(,1)"

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=0,priority=0 actions="

# IPv4 LPM (Table 1)

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=1,priority=32768,ipv4__dstAddr=0x0A00000F/0xFFFFFF00 \

actions=set_field:0x0B00000F->routing_metadata_nhop_ipv4, \

set_field:2->reg0, \

set_field:63->ipv4__ttl, \

resubmit(,2)"

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=1,priority=0 actions="

# Forward (Table 2)

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=2,priority=32768,routing_metadata_nhop_ipv4=0x0B00000F \

actions=set_field:0x74a4b500eee4->ethernet__dstAddr, \

resubmit(,3)"

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=2,priority=0 actions="

# Send Frame (Table 3)

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=3,priority=32768,reg0=2 \

actions=set_field:0x74a4b500ef02->ethernet__srcAddr, \

calc_fields_update(ipv4__hdrChecksum,csum16,fields:ipv4__version_ihl,ipv4__diffserv,ipv4__totalLen,ipv4__identification,ipv4__flags_fragOffset,ipv4__ttl,ipv4__protocol,ipv4__srcAddr,ipv4__dstAddr),
\

deparse, \

output:NXM_NX_REG0[]"

$DIR/ovs-ofctl --protocols=OpenFlow15 add-flow br0
"table=3,priority=0 actions="

generator节点:

只修改generator.pkt文件,将generator与switch连接的网口mac地址填入,如下所示。

set mac 0 74:a4:b5:00:ee:e4

set ip src 0 10.0.0.14/24

set ip dst 0 10.0.0.15

receiver节点:

只修改receiver.pkt文件,将receiver与switch连接的网口mac地址填入,如下所示。

set mac 0 74:a4:b5:00:ef:02

set ip src 0 10.0.0.15/24

set ip dst 0 10.0.0.14

实验操作

Switch节点

使用root用户,登录switch节点。

编译simple_router.p4

cd /home/vagrant/ovs

./configure --with-dpdk=$DPDK_BUILD CFLAGS="-g -O2 -Wno-cast-align"
p4inputfile=/home/vagrant/examples/simple_router/simple_router.p4
p4outputdir=./include/p4/src

make clean

make -j 2

启动ovsdb-server(保持后台运行)

cd /home/vagrant/ovs/ovsdb

nohup ./ovsdb-server
--remote=punix:/usr/local/var/run/openvswitch/db.sock \

--remote=db:Open_vSwitch,Open_vSwitch,manager_options --pidfile &

启动ovs-vswitchd(保持后台运行)

cd /home/vagrant/ovs/vswitchd

nohup ./ovs-vswitchd --dpdk -c 0x1 -n 4 --
unix:/usr/local/var/run/openvswitch/db.sock --pidfile &

创建OVS网桥

cd /home/vagrant/ovs/utilities

./ovs-vsctl --no-wait init

./ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev

./ovs-vsctl set bridge br0 protocols=OpenFlow15

./ovs-vsctl add-port br0 dpdk0 -- set Interface dpdk0 type=dpdk

./ovs-vsctl add-port br0 dpdk1 -- set Interface dpdk1 type=dpdk

如果需要删除,则执行./ovs-vsctl del-br br0

查看网桥执行./ovs-vsctl show

{width=”5.7659722222222225in”
height=”2.2305555555555556in”}

ovs网桥情况 {#ovs网桥情况-1 .图名}

加载流表

cd /home/vagrant/examples/simple_router/

./simple_router.sh

加载完成后,可执行如下命令查看。

cd /home/vagrant/ovs/utilities

./ovs-ofctl --protocols=OpenFlow15 dump-flows br0

{width=”5.767361111111111in”
height=”1.229861111111111in”}

simple_router实验流表 {#simple_router实验流表 .图名}

Generator节点 & Receiver节点

使用root用户,分别从不同终端窗口登录generator节点和receiver节点。

启动发包程序

Generator节点:

cd /home/vagrant/pktgen

./app/app/x86_64-native-linuxapp-gcc/app/pktgen -c 0x3 -n 4 -- -P -m
"1.0" -f /home/vagrant/examples/simple_router/generator.pkt

Receiver节点:

cd /home/vagrant/pktgen

./app/app/x86_64-native-linuxapp-gcc/app/pktgen -c 0x3 -n 4 -- -P -m
"1.0" -f /home/vagrant/examples/simple_router/receiver.pkt

启动后出现回显与l2_switch实验一致。

开始发包

回到generator节点的界面,输入并执行start 0,开始发包。

此时,在switch节点可查看流表,若数据包数量随时间出现增长,则说明发报成功,如下图所示。

{width=”5.763888888888889in”
height=”1.1472222222222221in”}

{width=”5.759722222222222in”
height=”1.1659722222222222in”}

流表变化 {#流表变化-1 .图名}

实验结束后,回到genarator节点,输入并执行stop 0,停止发包。