## Bypass网卡测试 ### 测试方案 * 将Bypass网卡以物理网卡的形式接入虚拟机,验证Bypass的切换。 * 将Bypass网卡以SRIOV的形式接入虚拟机,验证Bypass的切换。 * 用测试仪进行倒换时间测试。 ### 测试拓扑1-作为pf接入虚拟机 ![image-20210629104858182](../../_static//Bypass-1.png) 1. 在host172.18.20.162上启动虚机UPGW-Bypass,部署UPGW环境,enp129s0f0和enp129s0f1是Bypass网卡的两个端口,分别作为upstream和downstream,另起一个vf作为lbp。 2. 在host172.18.22.104上启动虚机up,数据口是p5p2,配置ip为192.168.20.110,p5p2和enp129s0f0直连。 3. 交换机数据口ip为192.168.20.100,与enp129s0f1直连。 ### UPGW配置1 ``` [PORT0] name = UP description = 82540EM Gigabit Ethernet Controller pci-address = 0000:00:0a.0 traffic-type = IP traffic-direction = upstream egress-port = 1 [PORT1] name = DOWM description = 82540EM Gigabit Ethernet Controller pci-address = 0000:00:0b.0 traffic-type = IP traffic-direction = downstream egress-port = 0 [PORT2] name = 0000:00:0c.0 description = 82540EM Gigabit Ethernet Controller pci-address = 0000:00:0c.0 traffic-type = IP traffic-direction = lbp egress-port = 0 [VM common] max = 32 number = 2 vhost-dev = /var/lib/appliance/nts/qemu/usvhost-1 [NES_SERVER] ctrl_ip = 0.0.0.0 ctrl_port = 9515 [REDIS_SERVER] host=127.0.0.1 port=6379 [KNI] max = 32 ``` ### 测试内容1 #### 普通网卡功能验证 初始环境:UPGW-Bypass不启动UPGW,up长ping交换机,网络不通。 测试过程和结果:UPGW-Bypass启动UPGW,up到交换机可通。 结论:普通网卡模式可用。 #### 普通网卡切换为Bypass状态 1. 手动切换Bypass 初始环境:设置Bypass初始状态为off(bpctl_util 00:0a.0 set_bypass off),启动UPGW,up一直ping基站,网络可通。 测试过程和结果:设置Bypass为on(bpctl_util 00:0a.0 set_bypass on),可看到端口状态变为down,网络依然可通。 结论:手动切换命令生效。 2. 看门狗切换Bypass 初始环境:设置Bypass初始状态为off(bpctl_util 00:0a.0 set_bypass off),掉电和上电的Bypass状态也都配为off(bpctl_util 00:0a.0 set_bypass_pwoff off和bpctl_util 00:0a.0 set_bypass_pwup off),设置看门狗1000ms超时和500ms自动喂狗(bpctl_util 00:0a.0 set_bypass_wd 1000和bpctl_util 00:0a.0 set_wd_autoreset 500),启动UPGW,up一直ping基站,网络可通。 测试过程和结果1:在初始环境下,重启虚拟机、虚拟机init 0、模拟虚拟机卡死(echo c > /proc/sysrq-trigger)、重启宿主机、模拟宿主机卡死(echo c > /proc/sysrq-trigger),网络依然可通。 测试过程和结果2:在初始环境下,宿主机init 0、宿主机掉电,网络不通。 结论:看门狗可触发Bypass切换,但是在掉电的场景下,只用看门狗就不行了,应该需要和掉电命令配合使用。 3. 掉电切换Bypass 初始环境:设置Bypass初始状态为off(bpctl_util 00:0a.0 set_bypass off),掉电和上电的Bypass状态都配为on(bpctl_util 00:0a.0 set_bypass_pwoff on和bpctl_util 00:0a.0 set_bypass_pwup on),启动UPGW,up一直ping基站,网络可通。 测试过程和结果:在初始环境下,宿主机init 0、宿主机掉电,网络可通。 结论:掉电上电需由专门的命令控制。 #### 实际方案验证-代码控制Bypass切换 初始环境:设置Bypass初始状态为off(bpctl_util 00:0a.0 set_bypass off),掉电和上电的Bypass状态都配为on(bpctl_util 00:0a.0 set_bypass_pwoff on和bpctl_util 00:0a.0 set_bypass_pwup on),在UPGW代码中整合Bypass代码,实现设置看门狗定时器(bpctl_util 00:0a.0 set_bypass_wd 1000)和轮询喂狗(bpctl_util 00:0a.0 reset_bypass_wd ),如下图所示,启动UPGW,这样看门狗可监控进程,up一直ping基站,网络可通。 ![image-20210628162921529](../../_static//Bypass-2.png) ![image-20210628162750400](../../_static//Bypass-3.png) 测试过程和结果:在初始环境下,ctrl+c停止UPGW进程、重启虚拟机、虚拟机init 0、模拟虚拟机卡死(echo c > /proc/sysrq-trigger)、重启宿主机、模拟宿主机卡死(echo c > /proc/sysrq-trigger),宿主机init 0、宿主机掉电,网络可通。 结论:可达到监控进程的目的,只要外部条件使进程挂掉,就能切换为Bypass,同时看门狗和掉电上电切换命令可结合使用。 ### 测试拓扑2-作为vf接入虚拟机 ![image-20210629105051090](../../_static//Bypass-4.png) enp129s0f0和enp129s0f1各出一个SRIOV端口,分别作为upstream和downstream,另起一个vf作为lbp。 ### UPGW配置2 ``` [PORT0] name = UP description = 82540EM Gigabit Ethernet Controller pci-address = 0000:00:0a.0 traffic-type = IP traffic-direction = upstream egress-port = 1 [PORT1] name = DOWM description = 82540EM Gigabit Ethernet Controller pci-address = 0000:00:0b.0 traffic-type = IP traffic-direction = downstream egress-port = 0 [PORT2] name = 0000:00:0c.0 description = 82540EM Gigabit Ethernet Controller pci-address = 0000:00:0c.0 traffic-type = IP traffic-direction = lbp egress-port = 0 [VM common] max = 32 number = 2 vhost-dev = /var/lib/appliance/nts/qemu/usvhost-1 [NES_SERVER] ctrl_ip = 0.0.0.0 ctrl_port = 9515 [REDIS_SERVER] host=127.0.0.1 port=6379 [KNI] max = 32 ``` ### 测试内容2 #### SRIOV网卡基本功能验证 初始环境:UPGW-Bypass不启动UPGW,up长ping交换机,网络不通。 测试过程和结果:UPGW-Bypass启动UPGW,up到交换机可通。 结论:普通网卡模式可用。 #### 控制SRIOV网卡切换Bypass 初始环境:已在虚拟机安装好Bypass驱动。 测试过程和结果:在BP_Control目录执行bpctl_start报错,无法控制Bypass。 ![image-20210616165030717](../../_static//Bypass-5.png) 结论:无法直接控制SRIOV网卡切换Bypass,若使用了SRIOV功能,Bypass的切换需要控制物理网卡实现,即在宿主机去做相关的配置。 #### 控制物理网卡切换Bypass 1. 手动切换Bypass 初始环境:已在宿主机安装好Bypass驱动,设置Bypass初始状态为off(bpctl_util 81:00.0 set_bypass off),启动UPGW,up一直ping基站,网络可通。 测试过程和结果:设置Bypass为on(bpctl_util 81:00.0 set_bypass on),可看到端口状态变为down,网络依然可通。 结论:手动切换命令生效。 2. 看门狗切换Bypass 初始环境:设置Bypass初始状态为off(bpctl_util 81:00.0 set_bypass off),掉电和上电的Bypass状态也都配为off(bpctl_util 81:00.0 set_bypass_pwoff off和bpctl_util 81:00.0 set_bypass_pwup off),设置自动喂狗(bpctl_util 81:00.0 set_bypass_wd 1000和bpctl_util 81:00.0 set_wd_autoreset 500),启动UPGW,up一直ping基站,网络可通。 测试过程和结果1:在初始环境下,重启虚拟机、虚拟机init 0、模拟虚拟机卡死(echo c > /proc/sysrq-trigger),网络不通。 测试过程和结果2:在初始环境下,重启宿主机、模拟宿主机卡死(echo c > /proc/sysrq-trigger),网络依然可通。 测试过程和结果3:在初始环境下,宿主机init 0、宿主机掉电,网络不通。 结论:看门狗可触发Bypass切换,但因为是在宿主机配置的Bypass,若虚拟机出现一些问题,不会影响喂狗,所以Bypass不会切换,掉电的情况,和之前测试物理网卡的场景一致,只用看门狗不行。 3. 掉电切换Bypass 初始环境:设置Bypass初始状态为off(bpctl_util 81:00.0 set_bypass off),掉电和上电的Bypass状态也都配为on(bpctl_util 81:00.0 set_bypass_pwoff on和bpctl_util 81:00.0 set_bypass_pwup on),启动UPGW,up一直ping基站,网络可通。 测试过程和结果:在初始环境下,宿主机init 0、宿主机掉电,网络可通。 结论:掉电上电需由专门的命令控制。 #### 实际方案验证-脚本监控虚拟机控制Bypass切换 初始环境:设置Bypass初始状态为off(bpctl_util 81:00.0 set_bypass off),掉电和上电的Bypass状态都配为on(bpctl_util 81:00.0 set_bypass_pwoff on和bpctl_util 81:00.0 set_bypass_pwup on),启动脚本监控虚拟机状态喂狗,如下所示,只要虚拟机状态不变,就会一直喂狗,启动UPGW,up一直ping基站,网络可通。 ```shell #! /bin/sh # supervisor process LOG_FILE=/var/log/supervisor_sh.log # log function function log() { local t=$(date +"%F %X") echo "[ $t ] $0 : $1 " >> ${LOG_FILE} } # check process number # $1 : process name function check_process() { if [ -z $1 ]; then log "Input parameter is empty." return 0 fi p_num=$(ps aux | grep "$1" | grep -v "grep" | wc -l) log "p_num = $p_num" echo $p_num } # supervisor process bpctl_start bpctl_util 81:00.0 set_bypass_pwoff on bpctl_util 81:00.0 set_bypass_pwup on bpctl_util 81:00.0 set_bypass_wd 1000 while [ 1 ] do declare -i ch_num p_name="UPGW-Bypass" ch_num=$(check_process $p_name) if [ $ch_num -eq 1 ]; then bpctl_util 81:00.0 reset_bypass_wd fi sleep 0.5 done ``` 测试结果和过程1:在初始环境下,重启虚拟机、模拟虚拟机卡死(echo c > /proc/sysrq-trigger),网络不通。 测试结果和过程2:在初始环境下,虚拟机init 0、重启宿主机、模拟宿主机卡死(echo c > /proc/sysrq-trigger)、宿主机init 0、宿主机掉电,网络可通。 结论:重启虚拟机和模拟虚拟机卡死时,虚拟机还处于running状态,所以还会进行喂狗,不会切换Bypass,最好的情况还是想办法去监控到UPGW进程的状态。 #### 实际方案验证-脚本监控UPGW控制Bypass切换 初始环境:设置Bypass初始状态为off(bpctl_util 00:0a.0 set_bypass off),掉电和上电的Bypass状态都配为on(bpctl_util 00:0a.0 set_bypass_pwoff on和bpctl_util 00:0a.0 set_bypass_pwup on),在虚拟机增加watch dog,如下所示: ![image-20210629172426612](../../_static//Bypass-6.png) Action选为No action,因为这个看门狗只有UPGW使用,若看门狗超时,不至于让整个虚拟机重启,编写demo代码进行喂狗,之后可放在UPGW代码中,代码如下: ```c int main() { int fd_watchdog = open("/dev/watchdog", O_WRONLY); if(fd_watchdog == -1) { int err = errno; printf("\n!!! FAILED to open /dev/watchdog, errno: %d, %s\n", err,strerror(err)); } if(fd_watchdog >= 0) { int timeout = 1; ioctl(fd_watchdog, WDIOC_SETTIMEOUT, &timeout); static unsigned char food = 0; for ( ; ; ) { ssize_t eaten = write(fd_watchdog, &food, 1); if(eaten != 1) { puts("\n!!! FAILED feeding watchdog"); } sleep(0.5); } } } ``` 若进程死掉导致看门狗超时,虚拟机会把事件上报给宿主机,在宿主机编写脚本监控此看门狗: ```shell # check process number # $1 : process name function check_process() { if [ -z $1 ]; then log "Input parameter is empty." return 0 fi p_num=$(virsh qemu-monitor-event "$1" | grep WATCHDOG | wc -l) #监控虚拟机看门狗事件 echo $p_num } # supervisor process bpctl_start bpctl_util 81:00.0 set_bypass_pwoff on bpctl_util 81:00.0 set_bypass_pwup on bpctl_util 81:00.0 set_bypass_wd 1000 while [ 1 ] do declare -i ch_num p_name="UPGW-Bypass" ch_num=$(check_process $p_name) if [ $ch_num -eq 1 ]; then break else bpctl_util 81:00.0 reset_bypass_wd fi done ``` 若监控到虚拟机的看门狗状态发生变化,则停止对Bypass进行喂狗,超时后完成Bypass的切换,先运行虚拟机的代码,再运行宿主机的脚本。 测试结果和过程:在初始环境下,ctrl+c结束虚拟机程序、重启虚拟机、模拟虚拟机卡死(echo c > /proc/sysrq-trigger),虚拟机init 0、重启宿主机、模拟宿主机卡死(echo c > /proc/sysrq-trigger)、宿主机init 0、宿主机掉电,网络可通。 结论:使用此方法监控UPGW状态,可满足所有的测试场景,只是每次UPGW进程发生异常重启后,还需人为启动脚本再次监控。 ### 测试拓扑3-pf场景下倒换时间测试 ![image-20210629104729835](../../_static//Bypass-7.png) 使用测试仪代替了up网元,UPGW-Bypass直接接管物理网卡。 ### UPGW配置3 ``` [PORT0] name = UP description = 82540EM Gigabit Ethernet Controller pci-address = 0000:00:0a.0 traffic-type = IP traffic-direction = upstream egress-port = 1 [PORT1] name = DOWM description = 82540EM Gigabit Ethernet Controller pci-address = 0000:00:0b.0 traffic-type = IP traffic-direction = downstream egress-port = 0 [PORT2] name = 0000:00:0c.0 description = 82540EM Gigabit Ethernet Controller pci-address = 0000:00:0c.0 traffic-type = IP traffic-direction = lbp egress-port = 0 [VM common] max = 32 number = 2 vhost-dev = /var/lib/appliance/nts/qemu/usvhost-1 [NES_SERVER] ctrl_ip = 0.0.0.0 ctrl_port = 9515 [REDIS_SERVER] host=127.0.0.1 port=6379 [KNI] max = 32 ``` ### 测试内容3 #### 倒换时间测试 初始环境:设置Bypass初始状态为off(bpctl_util 00:0a.0 set_bypass off),掉电和上电的Bypass状态都配为on(bpctl_util 00:0a.0 set_bypass_pwoff on和bpctl_util 00:0a.0 set_bypass_pwup on),在UPGW代码中整合Bypass代码,实现设置看门狗定时器(bpctl_util 00:0a.0 set_bypass_wd 1000)和轮询喂狗(bpctl_util 00:0a.0 reset_bypass_wd ),启动UPGW,看门狗可监控进程,测试仪以1秒100个包长ping交换机,网络可通。 测试内容和结果1:UPGW进程退出,查看报文计算倒换时间: ![image-20210625151346761](../../_static/Bypass-8.png) ![image-20210625151817553](../../_static/Bypass-9.png) 第5135个包时间在25.659902开始没有回复报文,5543个包时间在29.720899对端开始有arp请求,链路倒换完成,耗时在4秒以上。 测试内容和结果2:虚拟机init 0,查看报文计算倒换时间: ![image-20210625153155203](../../_static/Bypass-10.png) ![image-20210625153311260](../../_static/Bypass-11.png) 第6405个包时间在32.009904开始没有回复报文,6843个包时间在36.370856对端开始有arp请求,链路倒换完成,耗时在4秒以上。 测试内容和结果3:宿主机掉电,查看报文计算倒换时间: ![image-20210625153716252](../../_static/Bypass-12.png) ![image-20210625153854637](../../_static/Bypass-13.png) 第11145个包时间在55.709896开始没有回复报文,11467个包时间在58.900725对端开始有arp请求,链路倒换完成倒换,耗时在3秒以上。 结论:除去看门狗的超时时间,倒换时间都在三秒以上,时间过长,与厂家沟通了解到,耗时可能在端口切为Bypass后,链路的重新协商上面,可将上图的p5p2和交换机的端口关闭自协商,去看下倒换时间。 ### 全部部署场景方案总结 上面测试了将物理网卡或者SRIOV网卡接入虚拟机的场景,根据上面的结论可以推导出将物理网卡或者SRIOV接入宿主机的场景,下面是对所有场景的一个总结和方案初步设计: 1. 将物理网卡接入宿主机:宿主机部署UPGW,一张Bypass网卡的两个口分别作为upstream和downstream,代码中可控制Bypass切换,这样就能应对所有的异常情况,lbp口可用其它网卡或再增加Bypass卡。 2. 将物理网卡接入虚拟机:与1基本一样,只是控制都在虚拟机内部完成。 3. 将SRIOV网卡接入宿主机:宿主机部署UPGW,一张Bypass网卡的两个端口各起一个SRIOV口,一个作为updtream,一个作为downstream,这样代码中也可直接操作物理卡,控制Bypass的切换,可应对所有的异常,lbp口可以另增网卡,也可再增加SRIOV口。 4. 将SRIOV网卡接入虚拟机:与3类似,只是控制Bypass的切换需要由宿主机监控虚拟机来实现,而且UPGW中填充的代码不同,需要分情况去运行不同的代码。 ### 问题记录 1. 进入GRT_BYPASS/BP_Control目录下,先执行make再执行make install。 问题:执行make时报错如下: ![](../../_static/Bypass-14.png) 解决方法:安装相关的内核软件包: ``` yum install kernel-devel-$(uname -r) ``` 2. 虚拟机接入物理网卡时,在GRT_BYPASS/BP_Control目录下输入bpctl_start,然后可输入其它命令来控制Bypass。 问题:因为刚开始用的是passthrough方式接管bypass网卡,所以报错: ![image-20210616165030717](../../_static/Bypass-5.png) 解决方法:需要直接接管pci,下图是passthrough和直接接管pci的对比: ![image-20210616165144206](../../_static/Bypass-15.png) ![image-20210616165222969](../../_static/Bypass-16.png) 3. SRIOV网卡的创建和配置: echo n > /sys/class/net/enp129s0f0/device/sriov_numvfs echo n > /sys/class/net/enp129s0f1/device/sriov_numvfs ip link set enp129s0f0 vf 0 spoofchk off ip link set enp129s0f1 vf 0 spoofchk off ip link set enp129s0f0 vf 0 trust on ip link set enp129s0f1 vf 0 trust on 4. vf接入虚拟机,UPGW启动后会有下面的循环打印,但是对功能没有影响: ![image-20210629103239266](../../_static/Bypass-17.png) 出现下面的打印后,程序就起不来了,目前只遇到了一次: ![image-20210629103404069](../../_static/Bypass-18.png) ![image-20210629103451461](../../_static/Bypass-19.png) 5. 受测试环境影响,关闭自协商的倒换时间暂时无法测出,待环境允许后再进行测试。