基于Linux的点对点VXLAN通信

网友投稿 535 2022-10-18


基于Linux的点对点VXLAN通信

一、VXLAN基本概念

VXLAN是NVOS3中的一种网络虚拟化技术,通过将虚拟机发出的数据包封装在UDP报文中,并使用物理网络中宿主机的IP地址以及MAC地址作为outer-header进行封装,然后在传统的IP网络中进行传输,到达目的地后由隧道接点解封装并将数据发送给目标虚拟机。

通过VXLAN,虚拟网络可接入大量租户,且租户可以规划自己的虚拟网络,不需要考虑物理网络IP地址和广播域的限制,降低了网络管理的难度。

1.1 Underlay网络和Overlay网络

VXLAN技术将已有的宿主机所在的物理网络作为Underlay网络,在其上构建出虚拟的二层或三层网络,即Overlay网络。Overlay网络通过封装技术、利用Underlay网络提供的三层转发路径,实现租户报文在不同站点间传递。对于租户来说,Underlay网络是透明的,只能感知到Overlay网络。

1.2 NVE(Network Virtualization Edge)

网络虚拟边缘节点NVE,实现网络虚拟化功能的网络实体。报文经过NVE封装转发后,NVE间就可基于三层基础网络建立二层虚拟化网络。

​说明​:设备和服务器上的虚拟交换机VSwitch都可以作为NVE。

按照NVE部署位置的不同,可以分为以下三种模式:

硬件模式:所有的NVE都部署在支持NVE的设备上,所有的VXLAN报文封装与解封装都在设备上进行。软件模式:所有的NVE都部署在VSwitch上,所有的VXLAN报文封装与解封装都在VSwitch上进行。混合模式:部分NVE部署在VSwitch上,部分NVE部署在支持NVE的设备上,在VSwitch和设备上都有可能会进行VXLAN报文的封装与解封装。

1.3 VTEP(VXLAN Tunnel Endpoints)

VTEP是VXLAN隧道端点,封装在NVE中,用于VXLAN报文的封装和解封装。

VTEP与物理网络相连,分配有物理网络的IP地址,该地址与虚拟网络无关。

VXLAN报文中源IP地址为本节点的VTEP地址,VXLAN报文中目的IP地址为对端节点的VTEP地址,一对VTEP地址就对应着一个VXLAN隧道。

1.4 VNI(VXLAN Network Identifier)

VXLAN网络标识VNI类似VLAN ID,用于区分VXLAN段,不同VXLAN段的虚拟机不能直接二层相互通信。

一个VNI表示一个租户,即使多个终端用户属于同一个VNI,也表示一个租户。VNI由24比特组成,支持多达16M的租户。

在分布式网关部署场景下,VNI分为二层VNI和三层VNI。

二层VNI是普通的VNI,以1:1方式映射到广播BD,实现VXLAN报文同子网的转发。三层VNI和VPN实例进行关联,用于VXLAN报文跨子网的转发。

二、VXLAN报文格式

2.1 报文格式

VXLAN是MAC in UDP的网络虚拟化技术,所以其报文封装是在原始以太网报文之前添加了一个UDP封装及VXLAN头封装。具体报文格式如图所示:

2.2 报文格式说明

字段

描述

VXLAN header

  • VXLAN Flags:8比特,取值为000010000。
  • VNI:VXLAN网络标识,24比特,用于区分VXLAN段。
  • Reserved:24比特和8比特,必须设置为0。

Outer UDP header

  • DestPort:目的UDP端口号是4789。
  • Source Port:源端口号是内层报文通过哈希算法计算后的值。

Outer IP header

  • IP SA:源IP地址是VXLAN隧道本端VTEP的IP地址。
  • IP DA:目标IP地址是VXLAN隧道远端VTEP的IP地址。

如果Underlay网络为IPv4网络,VTEP IP为IPv4类型;如果Underlay网络为IPv6网络,VTEP IP为IPv6类型

Outer Ethernet header

  • MAC DA:在发送报文的虚拟机所属VTEP上根据目的VTEP地址查找路由表,路由表中下一跳IP地址对应的MAC地址。
  • MAC SA:发送报文的虚拟机所属的VTEP的MAC地址。
  • 802.1Q Tag:可选字段,该字段为报文中携带的VLAN Tag。
  • Ethernet Type:以太网报文类型。

三、基于Linux的点对点VXLAN通信实验

3.1 实验逻辑拓扑

3.2 实验目的

两台主机之间的ns1 namespace和ns2 namespace之间通过VXLAN相互通讯。

描述网络架构图(包的构成和转发依据)

3.3 实验步骤

3.3.1 关闭防火墙

vxlan-server1:[root@vxlan-server1 ~]#systemctl disable --now firewalld.servicevxlan-server2:[root@vxlan-server2 ~]#systemctl disable --now firewalld.service

3.3.2 创建VXLAN设备,并配置IP

vxlan-server1:[root@vxlan-server1 ~]#ip link add vxlan1 type vxlan id 100 \dstport 4789 remote 172.31.0.17 local 172.31.0.7 dev eth0vxlan-server2:[root@vxlan-server2 ~]#ip link add vxlan2 type vxlan id 100 \dstport 4789 remote 172.31.0.7 local 172.31.0.17 dev eth0

3.3.2.1 参数解释

id 100:指定VNI的值,有效值在1到2^24之间。dstport 4789:VTEP通信的端口,IANA分配的端口是4789。如果不指定,Linux默认使用8472。ovs创建的VXLAN port也是默认使用端口4789。remote:对端VTEP的地址。local:当前节点VTEP要是用的IP地址,即当前节点隧道口的IP地址。dev eth0:当前节点用于VTEP通信的设备,用来获取VTEP IP地址。这个参数与local参数目的相同,二选一即可。

3.3.2.2 查看VXLAN的详细信息

vxlan-server1:[root@vxlan-server1 ~]#ip -d link show vxlan1 3: vxlan1: mtu 1450 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 8a:cf:54:54:26:9e brd ff:ff:ff:ff:ff:ff promiscuity 0 vxlan id 100 remote 172.31.0.17 local 172.31.0.7 dev eth0 srcport 0 0 dstport 4789 ageing 300 noudpcsum noudp6zerocsumtx noudp6zerocsumrx addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535vxlan-server2:[root@vxlan-server2 ~]#ip -d link show vxlan2 3: vxlan2: mtu 1450 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether c6:93:97:8a:58:cf brd ff:ff:ff:ff:ff:ff promiscuity 0 vxlan id 100 remote 172.31.0.7 local 172.31.0.17 dev eth0 srcport 0 0 dstport 4789 ageing 300 noudpcsum noudp6zerocsumtx noudp6zerocsumrx addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535

3.3.2.3 同时会增加一条fdb转发表

vxlan-server1:[root@vxlan-server1 ~]#bridge fdb01:00:5e:00:00:01 dev eth0 self permanent00:00:00:00:00:00 dev vxlan1 dst 172.31.0.17 via eth0 self permanentvxlan-server2:[root@vxlan-server2 ~]#bridge fdb01:00:5e:00:00:01 dev eth0 self permanent33:33:00:00:00:01 dev eth0 self permanent00:00:00:00:00:00 dev vxlan2 dst 172.31.0.7 via eth0 self permanent

​注​:全零表项表示没有匹配的MAC地址时,就发送到该表项中的VTEP。这条表项的意思是,默认的VTEP对端地址为172.31.0.17,原始报文经过VXLAN1后会添加VXLAN头部,而外部UDP头的目的IP地址会被加上172.31.0.17。

3.3.2.4 为VXLAN1配置IP地址并启用

vxlan-server1:[root@vxlan-server1 ~]#ip link set dev vxlan1 up[root@vxlan-server1 ~]#ip addr add 192.168.1.254/32 dev vxlan1vxlan-server2:[root@vxlan-server2 ~]#ip link set dev vxlan2 up[root@vxlan-server2 ~]#ip addr add 192.168.2.254/32 dev vxlan2

3.3.2.5 创建bridge,并设置IP

vxlan-server1:[root@vxlan-server1 ~]#brctl addbr br1[root@vxlan-server1 ~]#ip link set dev br1 up[root@vxlan-server1 ~]#ip addr add 192.168.1.1/24 dev br1vxlan-server2:[root@vxlan-server2 ~]#brctl addbr br1[root@vxlan-server2 ~]#ip link set dev br1 up[root@vxlan-server2 ~]#ip addr add 192.168.2.1/24 dev br1

3.3.2.6 创建namespace,VTEP peer,各自加入ns1和br1,并配置IP

vxlan-server1:[root@vxlan-server1 ~]#ip netns add ns1[root@vxlan-server1 ~]#ip link add tap1 type veth peer name tap2[root@vxlan-server1 ~]#ip link set dev tap2 up[root@vxlan-server1 ~]#ip link set tap1 netns ns1[root@vxlan-server1 ~]#ip netns exec ns1 ip link set dev tap1 up[root@vxlan-server1 ~]#ip netns exec ns1 ip addr add \192.168.1.100/24 dev tap1[root@vxlan-server1 ~]#brctl addif br1 tap2vxlan-server2:[root@vxlan-server2 ~]#ip netns add ns2[root@vxlan-server2 ~]#ip link add tap1 type veth peer name tap2[root@vxlan-server2 ~]#ip link set dev tap2 up[root@vxlan-server2 ~]#ip link set tap1 netns ns2[root@vxlan-server2 ~]#ip netns exec ns2 ip link set dev tap1 up[root@vxlan-server2 ~]#ip netns exec ns2 ip addr add \192.168.2.100/24 dev tap1[root@vxlan-server2 ~]#brctl addif br1 tap2

3.3.2.7 系统网络内核参数修改

vxlan-server1:[root@vxlan-server1 ~]#echo 0 > \/proc/sys/net/ipv4/conf/all/rp_filter [root@vxlan-server1 ~]#echo 0 > \/proc/sys/net/ipv4/conf/br1/rp_filter [root@vxlan-server1 ~]#echo 1 > /proc/sys/net/ipv4/ip_forwardvxlan-server2:[root@vxlan-server2 ~]#echo 0 > \/proc/sys/net/ipv4/conf/all/rp_filter[root@vxlan-server2 ~]#echo 0 > \/proc/sys/net/ipv4/conf/br1/rp_filter [root@vxlan-server2 ~]#echo 1 > /proc/sys/net/ipv4/ip_forward

3.3.2.8 配置路由

vxlan-server1:[root@vxlan-server1 ~]#ip netns exec ns1 ip route add default via 192.168.1.1

问题:

将ns1的网关指向VXLAN1的IP地址(192.168.1.254),此时ns1和ns2的通信也是正常的,但在ns上查看192.168.1.254学到的MAC地址为br1的MAC地址?

本接口收到的arp请求,要把自己的mac回给请求者。

否则后续报文的目的mac是别人的,本接口收到后会丢弃。

[root@vxlan-server1 ~]#ip route add 192.168.2.0/24 via \192.168.2.254 dev vxlan1 onlinkvxlan-server2:[root@vxlan-server2 ~]#ip netns exec ns2 ip route add default via 192.168.2.1[root@vxlan-server2 ~]#ip route add 192.168.1.0/24 via \192.168.1.254 dev vxlan2 onlink注:若不设置onlink,会提示network is unreachable。onlink的意义在于协议栈虽然找不到链路层直连路由,但是还是会发布针对via网关的ARP请求的。

3.3.2.9 状态截图

vxlan-server1:

vxlan-server2:

3.3.3 点对点VXLAN通信过程

主机1的ns1向主机2的ns2发送ICMP数据包,通信结果如图所示:

3.3.3.1 ns1发送ARP报文

当ns1中的tap1网卡去ping另一台主机的ns2中的网卡192.168.2.100时,夸网段访问会将请求发送给网关,先发送ARP请求获取网关192.168.1.1的MAC地址。

ARP请求报文:

Sender IP:192.168.1.100

Sender MAC:a6:15:75:51:38:cc

Target IP:192.168.1.1

Target MAC:全0

以太二层封装:

Source MAC:a6:15:75:51:38:cc

Destination MAC:全F

报文如图所示:

ARP广播请求报文会通过tap1-->tap2到达宿主机,本机MAC地址表会学习并记录该报文的源MAC和接收接口的对应关系。

3.3.3.2 br1单播响应ns1

收到该ARP广播请求,解封装之后查看ARP请求的IP地址是本地的,那么构建ARP单播响应,根据先学习记录的对应MAC表项出接口是br1设备上的tap2口到达ns1。

ARP响应报文:

Sender IP:192.168.1.1

Sender MAC:7a:06:cd:1d:69:e5

Target IP:192.168.1.100

Target MAC:a6:15:75:51:38:cc

以太二层封装:

Source MAC:7a:06:cd:1d:69:e5(192.168.1.1网关的MAC地址)

Destination MAC:a6:15:75:51:38:cc(192.168.1.100的MAC地址)

报文如图所示:

3.3.3.3 ns1缓存网关ARP

ns1收到网关的ARP响应之后,缓存到本地

3.3.3.4 ns1构建ICMP的请求报文

Source IP:192.168.1.100

Destination IP:192.168.2.100

Source MAC:a6:15:75:51:38:cc

Destination MAC:7a:06:cd:1d:69:e5

报文如图所示:

ICMP请求报文通过tap1-->tap2设备从ns1到达宿主机1时也就是到达默认的namespace时

1) 查看报文目的MAC是本机的br1设备的MAC,解封装拆掉二层帧头,露出IP报文。

2) (br设备的MAC地址是它所有从设备中最小的MAC地址),在这里br1设备只有一个从设备tap2,所以br1的MAC和tap2的MAC一致。

3.3.3.5 br1查询宿主机路由表

主机1的br1发现报文访问的是192.168.2.100,与本地不是同一网段,查看宿主机(default namespace)路由表,匹配路由,发现去往192.168.2.0/24的下一跳为192.168.2.254,出接口为VXLAN1

为什么没有抓到br1到VXLAN1的ARP报文,以及ICMP报文从br1到VXLAN1的转发过程?

因为这个过程是在Linux内部协议栈进行处理完成的。

3.3.3.6 VXLAN1发送ARP报文

不是发往本机的,需要判断本机是否开启了路由转发功能,如果开启则发送ARP请求192.168.2.254的MAC地址,出接口是VXLAN1,需要进行VXLAN封装,会使用出接口的IP,MAC作为报文的源地址。

宿主机1的VXLAN1的抓包截图,VXLAN接口抓到的包是为封装之前或解封装之后的报文:

宿主机1的eth0网卡抓包截图,此时的报文是VXLAN封装之后的报文:

原始ARP请求报文:

Send MAC:be:cf:4d:87:f1:f8

Send IP:192.168.1.254

Target MAC:全0

Target IP:192.168.2.254

内层以太层帧:

Source MAC:be:cf:4d:87:f1:f8

Source MAC:全F

VXLAN封装:

VNI:100

UDP封装:

Source port:39795(随机端口号)

Destination port:4789

外层VTEP IP封装:

Source IP:172.31.0.7

Destination IP:172.31.0.17

外层以太二层帧:

Source MAC:本端VTEP(宿主机1的eth0)接口的MAC

Destination MAC:对端VTEP(宿主机2的eth0)接口的MAC

原始ARP请求报文VXLAN封装前:

原始ARP请求报文VXLAN封装后:

主机2有一条fdb表项:

00:00:00:00:00:00 dev vxlan2 dst 172.31.0.7 via eth0 self permanent是否会直接从host2的vxlan2接口发出,再进入隧道,形成环路

抓包来看是没有环路的,为什么不根据这条fdb表项转发

VETP解封装后根据UDP 4789端口号,发给vxlan进程,进程对报文做解析,知道vxlan2接口,vxlan2接口会收到数据包

水平分割防环,不会再从vxlan2接口发出

报文到达主机2,进行解封装,在主机2的VXLAN2抓取报文。VXLAN2接口这里的报文是已经解封装之后的报文。

根据原始ARP广播报文发现(主机本地fdb mac地址表会记录该广播包的源MAC和接入口绑定)请求的是本机的192.168.2.254的MAC,构建ARP单播响应,目的MAC是be:cf:4d:87:f1:f8,源MAC是f6:8e:cd:3c:8b:1a。根据fdb转发表查看发给be:cf:4d:87:f1:f8这MAC表项出接口是VXLAN2。三层路由出接口和二层的出接口必须一致,三层路由表项和二层转发项都得有,不然会不通(两个表都会查)。

3.3.3.7 VXLAN2响应VXLAN1的ARP报文

ARP单播响应也会进行VXLAN封装:

主机1的VXLAN1接口收到主机2的VXLAN2发过来的ARP单播响应报文之后,将其VXLAN2的MAC地址记录到fdb表,如图所示:

3.3.3.8 主机1发送并进行封装ICMP报文

主机1收到主机2的VXLAN2的ARP响应之后,开始构建发送ICMP请求报文。

根据三层路由表和fdb转发表得知发往f6:8e:cd:3c:8b:1a这个MAC的数据包需要走VXLAN1通道,进行VXLAN封装:

ICMP报文:

内层IP封装:

Source IP:192.168.1.100

Destination IP:192.168.2.100

内层MAC封装:

Source MAC:be:cf:4d:87:f1:f8(宿主机1的VXLAN1的MAC)

Destination MAC:f6:8e:cd:3c:8b:1a(宿主机2的VXLAN2的MAC)

VXLAN封装:

VNI:100

UDP封装:

Source Port:53918(随机端口号)

Destination Port:4789

外层VTEP IP地址封装:

Source IP:172.31.0.7

Destination IP:172.31.0.17

外层VTEP MAC地址封装:

Source MAC:00:0c:29:cb:6a:88(宿主机1的eth0接口MAC)

Destination MAC:00:0c:29:57:d0:06(宿主机2的eth接口MAC)

3.3.3.9 主机2接收并解封装主机1的ICMP报文

VXLAN封装的ICMP请求报文到达主机2的VTEP设备,解封之后二层目的MAC是VXLAN2设备的MAC(192.168.2.254/32)。

ICMP报文:

IP封装:

Source IP:192.168.1.100

Destination IP:192.168.2.100

MAC封装:

Source MAC:be:cf:4d:87:f1:f8(宿主机1的VXLAN1的MAC)

Destination MAC:f6:8e:cd:3c:8b:1a(宿主机2的VXLAN2的MAC)

3.3.3.10 主机2的VXLAN2查询路由

发现原始报文访问的是192.168.2.100,与本地不是同一网段(VXLAN设备32位主机路由),查找路由表发现去往192.168.2.0/24网段的出接口是br1,于是将ICMP请求报文转发给br1。

这里抓不到VXLAN2到主机2br1的报文,因为这个过程是在Linux内部协议栈进行处理完成的。

3.3.3.11 主机2的br1发送ARP报文

当主机2的br1接口收到VXLAN2发过来的ICMP报文,发现报文中目标IP地址是192.168.2.100(ns2的IP地址),此时主机2的fdb表中并没有ns2的MAC地址,因此使用192.168.2.1作为广播源,ARP广播请求192.168.2.100的MAC。

3.3.3.12 主机2的ns2单播报文响应br1

ns2的tap1网卡收到ARP请求会返回ARP响应。

8a:e2:90:0b:08:54-->br1 192.168.2.1网关的MAC

3.3.3.13 主机2的ns2接收ICMP报文

主机2得到ns2的MAC地址之后,构建ICMP报文,目的MAC是192.168.2.100的MAC地址,根据fdb转发表将数据从br1网桥的tap2接口转发出去,最终ns2中的tap1网卡会受到请求包。

报文封装如下:

ICMP报文:

IP封装:

Source IP:192.168.1.100

Destination IP:192.168.2.100

内层以太二层封装:

Source MAC:56:ab:6c:f2:c1:78(主机2 br1设备的MAC地址)

Destination MAC:8a:e2:90:0b:08:54(ns2的tap1的MAC地址)

回包的流程逻辑与以上过程基本一致。

至此VXLAN的相关知识就先介绍这么多,文章写得有不恰当之处,恳请斧正。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:nVisual让网络物理层管理不再缺失
下一篇:国标GB28181协议EasyGBS平台调用设备录像超时,报错“等待ACK请求”的问题排查
相关文章

 发表评论

暂时没有评论,来抢沙发吧~