TLDR:基于LinuxKernel+FRRouting10.4.1运行BGP EVPN实现的VXLAN控制平面
要是以为是科学上网相关内容的话要失望了,本篇与大众认知的软路由内容无关。然而FRR运行在x86虚拟机上,高低也算个软件路由器吧,还是ALL in Boom的那种。不过即便炸了也只影响异地组网的大二层互通,本侧网络还是不受影响的。
起因
目前自己家一侧的wireguard和vxlan隧道是运行在CRS326的ROS上的,交换机赢弱的CPU性能,动不动跑上70%使用率。想着把这部分功能卸载到别的设备上,让交换机只做好交换机的工作。而手头运行v6.2固件的FortiGate还不支持evpn协议簇,要F系列之后运行v7固件FotriGate才支持。Vyos中对evpn的支持也是用的frr,索性选择Ubuntu+frr来上手l2vpn evpn。
为什么需要evpn
之前的文章提过用vxlan的原因,当时用的是静态vtep,手动配置对端vtep的地址。好在只有两个区域一个vni需要连接,如果需要连接更多的区域更多的vni的话,需要每个vtep之间建立全连接,维护工作量就大了,因此考虑引入vxlan控制平面来自动管理vxlan隧道。
vxlan的Remote Discovery方式除了静态配置、组播还有bgp evpn单播,evpn作为bgp协议的一个地址簇,通过BGP协议分发二层MAC信息三层的IP信息。具体有五种路由类型,对网络也是半桶水的自己就不细讲了,只能讲讲自己用到的功能场景。
- evpn可以帮我们自动维护vtep目标,意味着不用去填vtep的remote参数。
- 抑制网络中不必要的BUM(广播、未知单播、组播)包,减少vxlan隧道流量。
- 分布式网关,避免所有主机要到统一的网关进行三层转发,各区域可以从本地的互联网网关出去。准确的说分布式网关并不完全依赖evpn,只是evpn能自动分发MAC/IP实现起来更加方便。
步骤
安装环境
- 开启net.ipv4.ip_forward
- 启用内核模块modprobe vxlan
- 安装frr启用bgpd daemon
这里使用的是Ubuntu22.04,所以用了官方的debian包,默认的apt仓库的版本会比较老。也可以从source编译。
# add GPG key
curl -s https://deb.frrouting.org/frr/keys.gpg | sudo tee /usr/share/keyrings/frrouting.gpg > /dev/null
# possible values for FRRVER:
frr-6 frr-7 frr-8 frr-9 frr-9.0 frr-9.1 frr-10 frr10.0 frr10.1 frr-10.2 frr-10.3 frr-rc frr-stable
# frr-stable will be the latest official stable release. frr-rc is the latest release candidate in beta testing
FRRVER="frr-stable"
echo deb '[signed-by=/usr/share/keyrings/frrouting.gpg]' https://deb.frrouting.org/frr \
$(lsb_release -s -c) $FRRVER | sudo tee -a /etc/apt/sources.list.d/frr.list
# update and install FRR
sudo apt update && sudo apt install frr frr-pythontools
接口配置
手头的FRR版本不支持用vtysh命令创建管理vxlan接口和Bridge接口,因此需要在操作系统手动创建。
network:
ethernets:
ens18:
dhcp4: no
vlans:
vlan254:
id: 254
link: ens18
dhcp4: false
addresses: [10.1.254.10/24]
nameservers:
addresses: [223.5.5.5]
routes:
- to: default
via: 10.1.254.254
vlan80:
id: 80
link: ens18
bridges:
br-vxlan10:
interfaces: [vxlan10,vlan80]
dhcp4: false
dhcp6: false
addresses: [10.1.80.10/24]
macaddress: "62:41:5d:56:1d:79"
tunnels:
vxlan10:
mode: vxlan
local: 10.64.64.1
id: 10
port: 4789
link: ens18
version: 2
这里用的是netplan管理接口,但是要注意netplan不支持设置vxlan接口为nolearning proxy,需要用ip命令设置参数。
接口也可以用ip命令创建。
ip link add name br-vxlan10 type bridge
ip link set br-vxlan10 up
ip address add 10.1.80.10/24 dev br-vxlan10
ip link add link ens18 name vlan80 type vlan id 80
ip link set vlan80 up
ip link set vlan80 master br-vxlan10
ip link add vxlan10 type vxlan id 10 dstport 4789 local 10.64.64.1 proxy nolearning
ip link set dev vxlan10 up
ip link set dev vxlan10 master br-vxlan10
ip link set dev vlan80 master br-vxlan10
由于vxlan隧道和bgp协议跑在wireguard之上,所以这里vxlan接口的local填的是wireguard接口地址。整体思路是把vxlan接口和物理网络的vlanif桥在一起接入vlan流量,通过vxlan隧道到达对测。如果有需要可以用VRF对vxlan多租户之间进行隔离。
建立BGP关系
router bgp 65000
bgp router-id 10.64.64.2
no bgp default ipv4-unicast
neighbor 10.64.64.1 remote-as 65000
检查bgp peer
show bgp summary
建立EVPN关系
address-family l2vpn evpn
neighbor 10.64.64.1 activate
advertise-all-vni
exit-address-family
只要之前vxlan和vlanif桥接配置得没错,这时候就能看到vlan子网内的主机MAC通过Type2路由正常宣告出去了。
show bgp l2vpn evpn route
这里的10.1.80.11和10.1.80.21是用来测试的客户端。这个时候两侧vlan80主机已经可以通过vxlan隧道互通了,客户端主机FDB里能够看到对端子网主机MAC。
主机的FDB表中也能看到对应的表项。
分布式网关
家庭网络v1.2中使用的是vlan200在ihome侧的统一网关,意味着phome侧的vlan200主机需要通过vxlan over wireguard隧道到ihome侧的互联网网关到达公网,要访问phome侧其他子网更是需要到ihome侧网关绕一圈回phome。因此用分布式网关解决这个问题。
根据FRRouting文档的提示,在两侧的br-vxlan10上分别配置相同的网关IP和相同的MAC,这样集群主机在飘到对侧的时候,网关IP/MAC信息不变。
FRR address-family l2vpn evpn配置中增加
advertise-default-gw
advertise-svi-ip
BGP EVPN中就会宣告网关地址。
Type5路由宣告子网
如果vxlan overlay需要承载子网间路由,VTEP可以宣告自己的IP前缀。
FRR address-family l2vpn evpn配置中增加
rd 10.64.64.2:10
route-target import 65000:10
route-target export 65000:10
advertise ipv4 unicast
network 10.1.80.0/24 rd 10.64.64.2:2 ethtag 0 label 0 esi 00:00:00:00:00:00:00:00:00:00 gwip 10.1.80.254 routermac 62:41:5d:56:1d:79
注意不同版本的FRR中命令有些许不同,遇到过文档里写的命令实际没有,因此建议在vtysh中执行命令后write到/etc/frr/frr.conf而不是直接编辑配置文件。
能够看到宣告10.1.80.0/24的type5路由。
至此就实现了异地跨三层的二层组网,同时各area的主机从各自本地的网关进行L3转发。
后记
这篇文章本来应该是家庭网络v1.4的,回过头想想自己的原始需求只有一个vlan需要两地互通,只是为了实现分布式网关从而增加额外的复杂度,有些得不偿失。加之FRR的部分配置仍旧有些存疑,没有完全弄明白,所以最终停留在了实验阶段,或许那天需要把运行在FortiGate上的IPv4单播BGP路由单独剥离出来的时候,会使用这个方案吧。