一、实验目的

OpenvSwitch简称OVS,是一款高质量、多次层的虚拟交换软体,可以实现物理设备之间、虚拟设备之间以及物理设备和虚拟设备之间的数据交换。本次实验主要验证以下方案的可行性:当一台设备同时安装OVS和一些伺服器应用时,该设备既可以作为转发节点转发数据,也可以作为终端节点被访问。


二、实验环境

实验环境

本次实验的实验环境如图所示,主机A与主机B的有线网卡通过有线网路相连(非直连),主机B的无线网卡和主机C通过一个无线转发设备(无线路由器)相连。主机A作为客户端来访问主机C中搭建的apache2伺服器,主机B和主机C中均装有OVS软体,支持数据包的转发功能。


三、逻辑拓扑

本次实验的逻辑拓扑如图所示,主机B的两个物理网卡分别挂在了br0和br1两个虚拟网桥上,10.8.0.111和192.168.0.104分别为br0和br1的地址,物理网卡没有地址;同理,主机C的无线网卡也挂在了虚拟网桥br0上,192.168.0.102为br0的地址,无线网卡没有地址。主机B的br0为主机A的网关,主机B的br1为主机C的网关。本实验要实现A能够通过OVS的转发和处理,成功访问到C中搭建的apache2伺服器。

实验逻辑拓扑

四、实验步骤及讲解

1.软体安装

在主机B和主机C中安装OVS软体,使用如下命令:

sudo apt-get install openvswitch-switch #安装OVS

在主机C中安装apache2伺服器:

sudo apt-get install apache2 #安装apache2

2.配置环境

将主机B中物理网卡的IP地址清除:

sudo ifconfig enp3s0 0 #清除B中有线网卡的IP地址
sudo ifconfig wlx002f82818d37 0 #清除B中无线网卡的IP地址

在主机B中用OVS创建虚拟网桥br0和br1:

sudo ovs-vsctl add-br br0 #在B中创建br0
sudo ovs-vsctl add-br br1 #在B中创建br1

将有线网卡挂在br0上,将无线网卡挂在br1上:

sudo ovs-vsctl add-port br0 enp3s0 #将有线网卡enp3s0挂在br0上
sudo ovs-vsctl add-port br1 wlx002f82818d37 #将无线网卡wlx002f82818d37挂在br1上

此时虚拟网桥下会有一条默认的流表,为了排除这条流表对实验的干扰,将这条流表清除:

sudo ovs-ofctl del-flows br0 #将br0中的默认流表清除
sudo ovs-ofctl del-flows br1 #将br1中的默认流表清除

为br0和br1配置相应的IP地址:

sudo ifconfig br0 10.8.0.111/24 #给br0配置IP地址
sudo ifconfig br1 192.168.0.104/24 #给br1配置IP地址

同理,在主机C上也进行类似的操作:

sudo ifconfig wlp3s0 0 #清除C中无线网卡的IP地址
sudo ovs-vsctl add-br br0 #在C中创建br0
sudo ovs-vsctl add-port br0 wlp3s0 #将无线网卡wlp3s0挂在br0上
sudo ovs-ofctl del-flows br0 #将br0中的默认流表清除
sudo ifconfig br0 192.168.0.102/24 #给br0配置IP地址

至此,实验环境配置完成,之后进行添加流表的工作。

3.添加主机B中的流表

为了正确地添加流表,需要先了解主机A在访问主机C时的整个通信流程。以主机A ping 主机C为例,首先A需要知道自己的网关(B中的br0)的MAC地址,因此需要在br0中添加流表保证arp协议数据包可以通过enp3s0到达br0,同时br0可以根据arp请求进行正确的响应,且响应数据包可以通过enp3s0网口发出。为了实现上述过程,我们利用ovs流表动作项里的normal来完成,normal表示数据包按照正常的L2/L3处理,使用如下指令:

sudo ovs-ofctl add-flow br0 table=0,arp,actions=normal #匹配br0中所有arp数据包,并按照正常的处理流程处理

主机A在获取到自己网关的MAC地址后,会发送目的地址为192.168.0.102的ICMP请求包,该请包首先会到达enp3s0,为了让数据包可以利用br0转发,我们需要配置相应的流表来实现。在这里,我们同样使用normal动作:

sudo ovs-ofctl add-flow br0 table=0,ip,ip_src=10.8.0.0/24,actions=normal #匹配br0中源地址为10.8.0.0/24网段的数据包,并按照正常的处理流程处理

数据包经过br0处理后,下一步是通过br1转发给C,br1要实现转发,首先得获取C的MAC地址,因此,在br1中加入允许arp数据包处理的流表:

sudo ovs-ofctl add-flow br1 table=0,arp,actions=normal #匹配br1中所有arp数据包,并按照正常的处理流程处理

当br1获取到C的MAC地址后,会把数据包从网口wlx002f82818d37发出,需要添加相应的流表:

sudo ovs-ofctl add-flow br1 table=0,ip,ip_dst=192.168.0.0/24,actions=normal #匹配br1中目的地址为192.168.0.0/24网段的数据包,并按照正常的处理流程处理

至此,数据包从A到C的过程中B的流表配置完毕,数据包已经从网口wlx002f82818d37发出。在处理C的ICMP响应包时,只需要配类似的流表:

sudo ovs-ofctl add-flow br1 table=0,ip,ip_src=192.168.0.0/24,actions=normal #匹配br1中源地址为192.168.0.0/24网段的数据包,并按照正常的处理流程处理
sudo ovs-ofctl add-flow br0 table=0,ip,ip_dst=10.8.0.0/24,actions=normal #匹配br0中目的地址为10.8.0.0/24网段的数据包,并按照正常的处理流程处理

4.添加主机C中的流表

当主机A访问主机C的apache2伺服器时,主机C的网口wlp3s会获取到http请求数据包,我们此时希望将该数据包交给上层的apache2应用来处理,而不是转发出去。为了实现这一功能,我们还是采用normal动作,按照Linux内核的正常处理流程,该数据包的目的地址是自己,所以内核会上交上层的应用处理数据包,指令如下:

sudo ovs-ofctl add-flow br0 table=0,ip,ip_dst=192.168.0.102,actions=normal #匹配目的地址为192.168.0.102(本地)的数据包,并按照正常的处理流程处理

同时,还应该加一条反向的流表,使得http响应数据包可以正常发出:

sudo ovs-ofctl add-flow br0 table=0,ip,ip_src=192.168.0.102,actions=normal #匹配源地址为192.168.0.102(本地)的数据包,并按照正常的处理流程处理

添加上述两条流表后,会发现依然不能正常访问,这是因为流表中没有对arp数据包的处理项,导致主机C的网关无法获取到主机C的MAC地址,因此需要添加一条针对arp数据包的流表:

sudo ovs-ofctl add-flow br0 table=0,arp,actions=normal #匹配br0中所有arp数据包,并按照正常的处理流程处理

至此,所有流表配置完成,主机A可以正常访问主机C中的apache2伺服器,访问结果如下图所示:

正常访问页面

五、实验结果

根据本次实验可知,利用OVS软体中的normal动作,可以实现转发节点同时作为伺服器终端提供服务,同时,在转发时合理使用normal动作,可以很大程度上兼容传统的网路协议,而不需要人为配置相关协议的流表项进行处理。


感谢@柳玉儿


推荐阅读:
相关文章