基于mininet模拟vxlan L3网络互通实验

本篇基于mininet构建L3 Underlay网络,基于Linux命名空间及veth-pair构建vxlan L3 Overlay网络,实现vxlan网络互通实验。

网上大部分基于Linux的vxlan实验都是以Underlay及Overlay网络为二层同一网段为基础,本篇Underlay网络采用三层互通并基于vxlan构建Overlay网络实现三层互通实验,为简便使用mininet来仿真。

拓扑

整体拓扑如下所示:

网络拓扑

  1. Underlay网络基于 mininet构建host1与host2间的L3互通网络
  2. Overlay网络在host1与host2间基于Linux构建vxlan隧道实现container1与container2间的L3互通网络
  3. container与host链路基于 namespaceveth-pair来模拟

脚本

直接上脚本代码(vxlan.py),具体参考注释内容,需要留意的地方为配置过程中 macip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/python
# Mininet model for vxlan

import os
import time

from mininet.cli import CLI
from mininet.log import setLogLevel
from mininet.net import Mininet

"Create vxlan over L3 network custom topo."

net = Mininet(cleanup=True)

# switchs
br0 = net.addSwitch('br0', dpid='000000000000001')

# hosts
# host1 and host2
host1 = net.addHost('host1', mac='00:00:10:00:01:01', ip="192.168.10.10/24")
host2 = net.addHost('host2', mac='00:00:10:00:01:02', ip="192.168.20.20/24")

# host-links
net.addLink('br0','host1')
net.addLink('br0','host2')

# Main
setLogLevel('info')
net.start()

# config host1
# config host1 mac
host1.cmd("ifconfig host1-eth0 hw ether 00:00:10:00:01:01")

# config host1 ip
host1.cmd("ifconfig host1-eth0 192.168.10.10 netmask 255.255.255.0 up")

# config arp
host1.cmd("arp -s 192.168.10.1 10:00:10:00:01:01")

# config host1 route
host1.cmd("ip route add default scope global nexthop via 192.168.10.1 dev host1-eth0")

# config host2
# config host2 mac
host2.cmd("ifconfig host2-eth0 hw ether 00:00:10:00:01:02")

# config host2 ip
host2.cmd("ifconfig host2-eth0 192.168.20.20 netmask 255.255.255.0 up")

# config arp
host2.cmd("arp -s 192.168.20.1 10:00:10:00:01:02")

# config host2 route
host2.cmd("ip route add default scope global nexthop via 192.168.20.1 dev host2-eth0")


# static flow rule
# br0 L3打通host1与host2三层主机网络互通
br0.cmd("ovs-ofctl add-flow br0 priority=30,ip,dl_dst=10:00:10:00:01:02,nw_src=192.168.20.0/24,nw_dst=192.168.10.10,actions=mod_dl_src:10:00:10:00:01:01,mod_dl_dst:00:00:10:00:01:01,output:1")
br0.cmd("ovs-ofctl add-flow br0 priority=30,ip,dl_dst=10:00:10:00:01:01,nw_src=192.168.10.0/24,nw_dst=192.168.20.20,actions=mod_dl_src:10:00:10:00:01:02,mod_dl_dst:00:00:10:00:01:02,output:2")

time.sleep(1)

# vxlan configs

# host1 vxlan config
# host1上基于host1-eth0网口创建vxlan类型接口vxlan0,vni=4096
host1.cmd("ip link add vxlan0 type vxlan id 4096 dev host1-eth0 dstport 4789")
# 设置vxlan0接口mac地址
host1.cmd("ip link set vxlan0 address 00:10:10:00:01:01")
# 设置vxlan0接口ip地址
host1.cmd("ip addr add 10.0.0.1/32 dev vxlan0")
# 接口使能
host1.cmd("ip link set vxlan0 up")

# 设置fbd表项,目的地址192.168.20.20通过vxlan0基于mac=00:10:10:00:01:02封装转发出去
host1.cmd("bridge fdb add 00:10:10:00:01:02 dev vxlan0 dst 192.168.20.20")
# 设置10.0.1.0/24网关为10.0.1.1
host1.cmd("ip route add 10.0.1.0/24 via 10.0.1.1 dev vxlan0 onlink")
# 设置10.0.0.1网关arp表项mac=00:10:10:00:01:02
host1.cmd("arp -s 10.0.1.1 00:10:10:00:01:02 -i vxlan0")
# 创建namespace=net1的网络命名空间
host1.cmd("ip netns del net1")
host1.cmd("ip netns add net1")
# 使能net1中lo接口
host1.cmd("ip netns exec net1 ip link set lo up")
# 创建veth-pair用于连接host1主机网络及net1命名空间网络
host1.cmd("ip link add type veth")
host1.cmd("ip link set veth0 netns net1")
host1.cmd("ip netns exec net1 ip link set veth0 name eth0")
# 设置net1中eth0网卡ip地址
host1.cmd("ip netns exec net1 ip addr add 10.0.0.10 dev eth0")
host1.cmd("ip netns exec net1 ip link set eth0 up")
# 设置veth1网卡mac地址
host1.cmd("ip link set veth1 address 00:00:20:00:01:01")
host1.cmd("ip link set veth1 up")
# 使能arp代理
host1.cmd("echo 1 > /proc/sys/net/ipv4/conf/veth1/proxy_arp")
# 设置net1命名空间网络默认路由
host1.cmd("ip netns exec net1 ip route add 169.254.1.1 dev eth0 scope link")
host1.cmd("ip netns exec net1 ip route add default via 169.254.1.1 dev eth0")
# 设置host1主机网络到net1命名空间网络路由
host1.cmd("ip route add 10.0.0.10 dev veth1 scope link")

# host2 vxlan config, 配置说明参考host1中设置
host2.cmd("ip link add vxlan0 type vxlan id 4096 dev host2-eth0 dstport 4789")
host2.cmd("ip link set vxlan0 address 00:10:10:00:01:02")
host2.cmd("ip addr add 10.0.1.1/32 dev vxlan0")
host2.cmd("ip link set vxlan0 up")
host2.cmd("bridge fdb add 00:10:10:00:01:01 dev vxlan0 dst 192.168.10.10")
host2.cmd("ip route add 10.0.0.0/24 via 10.0.0.1 dev vxlan0 onlink")
host2.cmd("arp -s 10.0.0.1 00:10:10:00:01:01 -i vxlan0")
host2.cmd("ip netns del net2")
host2.cmd("ip netns add net2")
host2.cmd("ip netns exec net2 ip link set lo up")
host2.cmd("ip link add type veth")
host2.cmd("ip link set veth0 netns net2")
host2.cmd("ip netns exec net2 ip link set veth0 name eth0")
host2.cmd("ip netns exec net2 ip addr add 10.0.1.10 dev eth0")
host2.cmd("ip netns exec net2 ip link set eth0 up")
host2.cmd("ip link set veth1 address 00:00:20:00:01:02")
host2.cmd("ip link set veth1 up")
host2.cmd("echo 1 > /proc/sys/net/ipv4/conf/veth1/proxy_arp")
host2.cmd("ip netns exec net2 ip route add 169.254.1.1 dev eth0 scope link")
host2.cmd("ip netns exec net2 ip route add default via 169.254.1.1 dev eth0")
host2.cmd("ip route add 10.0.1.10 dev veth1 scope link")

time.sleep(3)

# do interactive shell
CLI(net)
net.stop()

运行&分析

运行

1
2
# 需要先安装mininet,xterm,openvswitch
sudo python vxlan.py

分析

基于以上脚本构建出host网络及模拟container网络如下所示:
host-container net

host-container net code

测试

mininet cli中xterm访问host1及host2:

1
xterm host1 host2

在host1中通过container1来ping container2:

1
ip netns exec net1 ping 10.0.1.10

通过wireshark抓host1-eth0和host2-eth0接口icmp请求和响应报文:

wireshark capture

基于mininet模拟vxlan L3网络互通实验

https://xiaohuiluo.github.io/2025/03/18/mininet-vxlan/

作者

HUI

发布于

2025-03-18

更新于

2025-03-28

许可协议

评论