OVS Faucet Tutorial笔记(下)

官方文档:

OVS Faucet Tutorial

5、Routing

Faucet Router 通过控制器模拟三层网关,提供 ARP 应答、路由转发功能。

5.1 控制器配置

5.1.1 编辑控制器yaml文件,增加router配置

root@server1:~/faucet/inst# vi faucet.yaml
dps:switch-1:dp_id: 0x1timeout: 8000arp_neighbor_timeout: 3600interfaces:1:native_vlan: 1002:native_vlan: 1003:native_vlan: 1004:native_vlan: 2005:native_vlan: 200
vlans:100:faucet_vips: ["10.100.0.254/24"]200:faucet_vips: ["10.200.0.254/24"]
routers:router-1:vlans: [100, 200]
  • 配置了两个 VLAN,并为每个 VLAN 指定了一个虚拟网关地址(faucet_vips,用于三层路由。

  • 这意味着 Faucet 会在每个 VLAN 上充当默认网关:

    • VLAN 100 的主机默认网关是 10.100.0.254

    • VLAN 200 的主机默认网关是 10.200.0.254

  • 定义了一个逻辑路由器 router-1,连接 VLAN 100 和 VLAN 200。

  • 这启用了 VLAN 间的三层互联(即路由),比如 VLAN 100 的主机可以访问 VLAN 200。

5.1.2 进入ovs沙箱

root@server1:~/ovs# tutorial/ovs-sandbox

5.1.3 开启实时日志查看

开启tail -f实时查看faucet、ovs的日志输出:

1、开启实时ovs log:
开新窗口1,/root/ovs/sandbox目录下,执行:
root@server1:~/ovs/sandbox# echo -n > ovs-vswitchd.log
root@server1:~/ovs/sandbox# tail -f ovs-vswitchd.log | grep -v -e "OFPT_ECHO_REQUEST" -e "OFPT_ECHO_REPLY"2、开启实时faucet log:
开新窗口2,/root/faucet/inst目录下,执行:
root@server1:~/faucet/inst# echo -n > faucet.log
root@server1:~/faucet/inst# tail -f faucet.log另外,为了方便查看日志,可以在执行每个命令之前,在log窗口输入文本提示用来分隔输出内容,比如:
>>docker restart faucet......................

5.1.4 重启控制器

Faucet 重新加载其配置:

root@server1:~/faucet/inst# docker exec faucet pkill -HUP -f faucet.faucet

或者

root@server1:~/faucet/inst# docker restart faucet
faucet
faucet log 
>>docker restart faucet......................
Jun 08 22:20:57 faucet INFO     version 1.10.11
Jun 08 22:20:57 faucet INFO     Reloading configuration
Jun 08 22:20:57 faucet INFO     configuration /etc/faucet/faucet.yaml changed, analyzing differences
Jun 08 22:20:57 faucet INFO     Add new datapath DPID 1 (0x1)
Jun 08 22:20:57 faucet.valve INFO     DPID 1 (0x1) switch-1 IPv4 routing is active on VLAN 100 vid:100 untagged: Port 1,Port 2,Port 3 with VIPs ['10.100.0.254/24']
Jun 08 22:20:57 faucet.valve INFO     DPID 1 (0x1) switch-1 IPv4 routing is active on VLAN 200 vid:200 untagged: Port 4,Port 5 with VIPs ['10.200.0.254/24']

5.1.5 创建ovs-sandbox bridge,连接控制器

ovs-sandbox创建的ovs bridge,每次重启,都需要重新建立。

如果需要,重新创建ovs bridge:

ovs-vsctl add-br br0 \
         -- set bridge br0 other-config:datapath-id=0000000000000001 \
         -- add-port br0 p1 -- set interface p1 ofport_request=1 \
         -- add-port br0 p2 -- set interface p2 ofport_request=2 \
         -- add-port br0 p3 -- set interface p3 ofport_request=3 \
         -- add-port br0 p4 -- set interface p4 ofport_request=4 \
         -- add-port br0 p5 -- set interface p5 ofport_request=5 \
         -- set-controller br0 tcp:127.0.0.1:6653 \
         -- set controller br0 connection-mode=out-of-band

1、进入ovs-sandbox,创建ovs bridge, br0root@server1:~/ovs# ovs-vsctl add-br br0 \
>          -- set bridge br0 other-config:datapath-id=0000000000000001 \
>          -- add-port br0 p1 -- set interface p1 ofport_request=1 \
>          -- add-port br0 p2 -- set interface p2 ofport_request=2 \
>          -- add-port br0 p3 -- set interface p3 ofport_request=3 \
>          -- add-port br0 p4 -- set interface p4 ofport_request=4 \
>          -- add-port br0 p5 -- set interface p5 ofport_request=5 \
>          -- set-controller br0 tcp:127.0.0.1:6653 \
>          -- set controller br0 connection-mode=out-of-band2、输入简化格式命令:
dump-flows () {ovs-ofctl -OOpenFlow13 --names --no-stat dump-flows "$@" \| sed 's/cookie=0x5adc15c0, //'
}save-flows () {ovs-ofctl -OOpenFlow13 --no-names --sort dump-flows "$@"
}diff-flows () {ovs-ofctl -OOpenFlow13 diff-flows "$@" | sed 's/cookie=0x5adc15c0 //'
}

ovs bridge创建成功,并成功连接控制器,控制器会下发相应的流表。 

faucet log
>>ovs-vsctl addbr br0 ...................... 
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 port desc stats
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 delta in up state: set() => {1, 2, 3, 4, 5, 4294967294}
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 1 fabricating ADD status True
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 status change: Port 1 up status True reason ADD state 0
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 1 (1) up
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 100 vid:100 untagged: Port 1,Port 2,Port 3
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 2 fabricating ADD status True
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 status change: Port 2 up status True reason ADD state 0
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 2 (2) up
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 100 vid:100 untagged: Port 1,Port 2,Port 3
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 3 fabricating ADD status True
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 status change: Port 3 up status True reason ADD state 0
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 3 (3) up
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 100 vid:100 untagged: Port 1,Port 2,Port 3
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 4 fabricating ADD status True
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 status change: Port 4 up status True reason ADD state 0
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 4 (4) up
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 200 vid:200 untagged: Port 4,Port 5
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 5 fabricating ADD status True
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 status change: Port 5 up status True reason ADD state 0
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 5 (5) up
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 200 vid:200 untagged: Port 4,Port 5
Jun 08 22:24:51 faucet.valve ERROR    DPID 1 (0x1) switch-1 send_flow_msgs: DP not up
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Cold start configuring DP
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 1 (1) configured
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 2 (2) configured
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 3 (3) configured
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 4 (4) configured
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 5 (5) configured
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 100 vid:100 untagged: Port 1,Port 2,Port 3
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 200 vid:200 untagged: Port 4,Port 5
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 0 table config match_types: (('eth_dst', True), ('eth_type', False), ('in_port', False), ('vlan_vid', False)) name: vlan next_tables: ['eth_src'] output: True set_fields: ('vlan_vid',) size: 32 vlan_port_scale: 3
table ID 1 table config match_types: (('eth_dst', True), ('eth_src', False), ('eth_type', False), ('in_port', False), ('vlan_vid', False)) miss_goto: eth_dst name: eth_src next_tables: ['ipv4_fib', 'vip', 'eth_dst', 'flood'] output: True set_fields: ('vlan_vid', 'eth_dst') size: 64 table_id: 1 vlan_port_scale: 4.1
table ID 2 table config dec_ttl: True match_types: (('eth_type', False), ('ipv4_dst', True), ('vlan_vid', False)) name: ipv4_fib next_tables: ['vip', 'eth_dst', 'flood'] output: True set_fields: ('eth_dst', 'eth_src', 'vlan_vid') size: 32 table_id: 2 vlan_port_scale: 3.1
table ID 3 table config match_types: (('arp_tpa', False), ('eth_dst', False), ('eth_type', False), ('icmpv6_type', False), ('ip_proto', False)) name: vip next_tables: ['eth_dst', 'flood'] output: True size: 32 table_id: 3 vlan_scale: 8
table ID 4 table config exact_match: True match_types: (('eth_dst', False), ('vlan_vid', False)) miss_goto: flood name: eth_dst output: True size: 64 table_id: 4 vlan_port_scale: 4.1
table ID 5 table config match_types: (('eth_dst', True), ('in_port', False), ('vlan_vid', False)) name: flood output: True size: 96 table_id: 5 vlan_port_scale: 8.0

关于OVS网桥与Faucet的连接日志已在前文详述,流表的具体说明如下。  

5.2 下发流表

5.2.1 控制器下发流表日志

ovs bridge成功连接控制器后,控制器根据yaml文件里ovs bridge配置,下发相关流表。

faucet.log
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 200 vid:200 untagged: Port 4,Port 5
Jun 08 22:24:51 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 0 table config match_types: (('eth_dst', True), ('eth_type', False), ('in_port', False), ('vlan_vid', False)) name: vlan next_tables: ['eth_src'] output: True set_fields: ('vlan_vid',) size: 32 vlan_port_scale: 3
table ID 1 table config match_types: (('eth_dst', True), ('eth_src', False), ('eth_type', False), ('in_port', False), ('vlan_vid', False)) miss_goto: eth_dst name: eth_src next_tables: ['ipv4_fib', 'vip', 'eth_dst', 'flood'] output: True set_fields: ('vlan_vid', 'eth_dst') size: 64 table_id: 1 vlan_port_scale: 4.1
table ID 2 table config dec_ttl: True match_types: (('eth_type', False), ('ipv4_dst', True), ('vlan_vid', False)) name: ipv4_fib next_tables: ['vip', 'eth_dst', 'flood'] output: True set_fields: ('eth_dst', 'eth_src', 'vlan_vid') size: 32 table_id: 2 vlan_port_scale: 3.1
table ID 3 table config match_types: (('arp_tpa', False), ('eth_dst', False), ('eth_type', False), ('icmpv6_type', False), ('ip_proto', False)) name: vip next_tables: ['eth_dst', 'flood'] output: True size: 32 table_id: 3 vlan_scale: 8
table ID 4 table config exact_match: True match_types: (('eth_dst', False), ('vlan_vid', False)) miss_goto: flood name: eth_dst output: True size: 64 table_id: 4 vlan_port_scale: 4.1
table ID 5 table config match_types: (('eth_dst', True), ('in_port', False), ('vlan_vid', False)) name: flood output: True size: 96 table_id: 5 vlan_port_scale: 8.0

控制器一共下发了Table0~5。

Table 编号名称功能描述备注
Table 0vlanIngress VLAN processing打上 VLAN 标签(入口 VLAN 处理)
Table 1eth_srcIngress L2 processing, MAC learningMAC 地址学习(二层入口处理)
Table 2ipv4_fibL3 forwarding for IPv4路由表,进行 IPv4 的三层转发
Table 3vipVirtual IP processing (e.g., for router IP addresses by Faucet)处理发给路由器自身(MAC 或 IP)的报文
Table 4eth_dstEgress L2 processing根据目的 MAC 地址进行二层转发(出口二层处理)
Table 5floodFlooding for BUM packets处理 BUM(广播、未知单播、多播)报文并进行泛洪

下面是对这个 OpenFlow 流表结构的中文解释,这是典型的 Faucet 控制器下发给 Open vSwitch(OVS)的多表处理流程:
✅ 表 0(vlan):入口 VLAN 处理

  • 作用: 对进入的报文进行 VLAN 分类和检查。

  • 处理内容:

    • 检查报文是否带有 VLAN 标签,如果没有可能加标签

    • 验证 VLAN 是否允许,不允许则丢弃。

    • 合法的 VLAN 报文进入下一表。


✅ 表 1(eth_src):二层源地址学习处理

  • 作用: 学习源 MAC 地址,用于构建转发表。

  • 处理内容:

    • 将源 MAC 和入口端口关联,写入转发表。

    • 可选:过滤非法 MAC 地址。

    • 报文继续进入下一处理表。


✅ 表 2(ipv4_fib):三层 IPv4 路由处理

  • 作用: 根据 IPv4 目的地址进行 L3 转发。

  • 处理内容:

    • 匹配目的 IP 地址,查找 FIB(Forwarding Information Base)。

    • 设置下一跳 MAC、出接口等。

    • 若为特殊 IP(如虚拟网关 IP),跳转到 vip 表。

    • 否则,继续进入下一表。


✅ 表 3(vip):虚拟 IP 处理

  • 作用: 处理虚拟网关 IP(如虚拟路由器接口 IP)。

  • 处理内容:

    • 回应 ARP 请求(如果目标 IP 是虚拟网关 IP)。

    • 处理 ICMP(如 ping 路由器)。

    • 可将报文发给控制器,模拟网关行为。


✅ 表 4(eth_dst):二层目的地址处理

  • 作用: 根据目的 MAC 地址选择出端口。

  • 处理内容:

    • 查找目的 MAC 地址对应的端口。

    • 找到则输出。

    • 未知 MAC 可跳转到泛洪表。


✅ 表 5(flood):广播/泛洪处理

  • 作用: 用于 ARP、DHCP 等广播流量处理。

  • 处理内容:

    • 向 VLAN 内的所有端口泛洪。

    • 支持未知单播转广播等策略。

此时也可以查看~/ovs/sandbox/ovs-vswitchd.log流表下发的相关日志。

5.2.2 OVS查看新增加的流表

新下发的流表(和flows1比较)

diff-flows flows1 br0 | grep '^+'

root@server1:~/ovs# diff-flows flows1 br0 | grep '^+'
+table=1 priority=16384,arp,dl_vlan=100 actions=goto_table:3
+table=1 priority=16384,arp,dl_vlan=200 actions=goto_table:3
+table=1 priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:2
+table=1 priority=16384,ip,dl_vlan=200,dl_dst=0e:00:00:00:00:01 actions=goto_table:2
+table=1 priority=4096,dl_vlan=100 actions=CONTROLLER:96,goto_table:4
+table=1 priority=4096,dl_vlan=200 actions=CONTROLLER:96,goto_table:4
+table=1 priority=0 actions=goto_table:4
+table=2 priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.254 actions=goto_table:3
+table=2 priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.254 actions=goto_table:3
+table=2 priority=12312,ip,dl_vlan=100,nw_dst=10.100.0.0/24 actions=goto_table:3
+table=2 priority=12312,ip,dl_vlan=200,nw_dst=10.100.0.0/24 actions=goto_table:3
+table=2 priority=12312,ip,dl_vlan=100,nw_dst=10.200.0.0/24 actions=goto_table:3
+table=2 priority=12312,ip,dl_vlan=200,nw_dst=10.200.0.0/24 actions=goto_table:3
+table=2 priority=0 actions=drop
+table=3 priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254 actions=CONTROLLER:64
+table=3 priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.200.0.254 actions=CONTROLLER:64
+table=3 priority=12320,arp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:64
+table=3 priority=12317,ip,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:194
+table=3 priority=12319,arp actions=goto_table:4
+table=3 priority=12316,ip actions=CONTROLLER:194,goto_table:4
+table=3 priority=12319,icmp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:174
+table=3 priority=12318,icmp actions=CONTROLLER:194,goto_table:4
+table=4 priority=0 actions=goto_table:5
+table=5 priority=8240,dl_dst=01:00:0c:cc:cc:cc actions=drop
+table=5 priority=8240,dl_dst=01:00:0c:cc:cc:cd actions=drop
+table=5 priority=8240,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:1,output:2,output:3
+table=5 priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:4,output:5
+table=5 priority=8236,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=drop
+table=5 priority=8216,dl_vlan=100,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:1,output:2,output:3
+table=5 priority=8216,dl_vlan=100,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:1,output:2,output:3
+table=5 priority=8216,dl_vlan=200,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:4,output:5
+table=5 priority=8216,dl_vlan=200,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:4,output:5
+table=5 priority=8208,dl_vlan=100,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:1,output:2,output:3
+table=5 priority=8208,dl_vlan=200,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:4,output:5
+table=5 priority=8192,dl_vlan=100 actions=pop_vlan,output:1,output:2,output:3
+table=5 priority=8192,dl_vlan=200 actions=pop_vlan,output:4,output:5
+table=5 priority=0 actions=drop
root@server1:~/ovs# 

 其中:

+table=1 priority=16384,arp,dl_vlan=100 actions=goto_table:3
+table=1 priority=16384,arp,dl_vlan=200 actions=goto_table:3
+table=1 priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:2
+table=1 priority=16384,ip,dl_vlan=200,dl_dst=0e:00:00:00:00:01 actions=goto_table:2

表1主要用于mac地址学习。

arp流量,先发到表3,查看是不是发给路由器自己的;

ip流量,如果目的mac是0e:00:00:00:00:01,这是网关mac,发到表2查询路由表。

+table=2 priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.254 actions=goto_table:3
+table=2 priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.254 actions=goto_table:3
+table=2 priority=12312,ip,dl_vlan=200,nw_dst=10.100.0.0/24 actions=goto_table:3
+table=2 priority=12312,ip,dl_vlan=100,nw_dst=10.100.0.0/24 actions=goto_table:3
+table=2 priority=12312,ip,dl_vlan=200,nw_dst=10.200.0.0/24 actions=goto_table:3
+table=2 priority=12312,ip,dl_vlan=100,nw_dst=10.200.0.0/24 actions=goto_table:3

表2是路由表:
ip流量,如果目的ip是网关IP,转到表3处理

ip流量,如果目的ip属于本地网段,转到表3处理

+table=3 priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254 actions=CONTROLLER:64
+table=3 priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.200.0.254 actions=CONTROLLER:64
+table=3 priority=12320,arp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:64
+table=3 priority=12317,ip,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:194
+table=3 priority=12319,arp actions=goto_table:4
+table=3 priority=12316,ip actions=CONTROLLER:194,goto_table:4
+table=3 priority=12319,icmp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:174
+table=3 priority=12318,icmp actions=CONTROLLER:194,goto_table:4

表3主要处理发给自己的二层或者三层流量:

arp流量,如果是查询网关IP的mac,发给控制器处理;

arp流量,如果是发给网关mac的,发给控制器处理

ip流量,如果目的mac是网关mac的,发给控制器处理

其他arp,发给表4

其他IP流量,发给控制器,同时发给表4

Performance is clearly going to be poor if every packet that needs to be routed has to go to the controller, but it’s unlikely that’s the full story. In the next section, we’ll take a closer look.

删除的流表(和flows1比较)
root@server1:~/ovs# diff-flows flows1 br0 | grep '^-'
-table=1 priority=4096,dl_vlan=100 actions=CONTROLLER:96,goto_table:2
-table=1 priority=4096,dl_vlan=200 actions=CONTROLLER:96,goto_table:2
-table=1 priority=0 actions=goto_table:2
-table=2 priority=0 actions=goto_table:3
-table=3 priority=8240,dl_dst=01:00:0c:cc:cc:cc actions=drop
-table=3 priority=8240,dl_dst=01:00:0c:cc:cc:cd actions=drop
-table=3 priority=8240,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:1,output:2,output:3
-table=3 priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:4,output:5
-table=3 priority=8236,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=drop
-table=3 priority=8216,dl_vlan=100,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:1,output:2,output:3
-table=3 priority=8216,dl_vlan=100,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:1,output:2,output:3
-table=3 priority=8216,dl_vlan=200,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:4,output:5
-table=3 priority=8216,dl_vlan=200,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:4,output:5
-table=3 priority=8208,dl_vlan=100,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:1,output:2,output:3
-table=3 priority=8208,dl_vlan=200,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:4,output:5
-table=3 priority=8192,dl_vlan=100 actions=pop_vlan,output:1,output:2,output:3
-table=3 priority=8192,dl_vlan=200 actions=pop_vlan,output:4,output:5
root@server1:~/ovs# 
完整流表(命名为flows2)
root@server1:~/ovs# dump-flows br0priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1priority=0 actions=droptable=1, priority=20490,dl_type=0x9000 actions=droptable=1, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=droptable=1, priority=20480,dl_src=0e:00:00:00:00:01 actions=droptable=1, priority=16384,arp,dl_vlan=100 actions=goto_table:3table=1, priority=16384,arp,dl_vlan=200 actions=goto_table:3table=1, priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:2table=1, priority=16384,ip,dl_vlan=200,dl_dst=0e:00:00:00:00:01 actions=goto_table:2table=1, priority=4096,dl_vlan=100 actions=CONTROLLER:96,goto_table:4table=1, priority=4096,dl_vlan=200 actions=CONTROLLER:96,goto_table:4table=1, priority=0 actions=goto_table:4table=2, priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.254 actions=goto_table:3table=2, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.254 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=200,nw_dst=10.100.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=100,nw_dst=10.100.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=100,nw_dst=10.200.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=200,nw_dst=10.200.0.0/24 actions=goto_table:3table=2, priority=0 actions=droptable=3, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254 actions=CONTROLLER:64table=3, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.200.0.254 actions=CONTROLLER:64table=3, priority=12320,arp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:64table=3, priority=12317,ip,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:194table=3, priority=12319,arp actions=goto_table:4table=3, priority=12316,ip actions=CONTROLLER:194,goto_table:4table=3, priority=12319,icmp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:174table=3, priority=12318,icmp actions=CONTROLLER:194,goto_table:4table=3, priority=0 actions=droptable=4, priority=0 actions=goto_table:5table=5, priority=8240,dl_dst=01:00:0c:cc:cc:cc actions=droptable=5, priority=8240,dl_dst=01:00:0c:cc:cc:cd actions=droptable=5, priority=8240,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5table=5, priority=8236,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=droptable=5, priority=8216,dl_vlan=100,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8216,dl_vlan=100,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8216,dl_vlan=200,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8216,dl_vlan=200,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8208,dl_vlan=100,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8208,dl_vlan=200,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5table=5, priority=0 actions=drop
root@server1:~/ovs# 
 保存流表flows2
root@server1:~/ovs# save-flows br0 > flows2

5.3 模拟测试

主机10.100.0.1和主机10.200.0.1相互通信,假设之前没有通信,通常的通信过程为:

  1. 主机 10.100.0.1 向路由器 10.100.0.254 发送 ARP 请求。(请求网关的MAC)
  2. 路由器向主机发送 ARP 应答。(应答网关的MAC)
  3. 主机 10.100.0.1 向 10.200.0.1 发送 IP 数据包。(目的MAC为网关MAC)
  4. 路由器向端口 p4 和 p5(即承载 10.200.0.<x> 网络的端口)广播 ARP 请求。(路由器暂时不知道10.200.0.1的MAC,请求10.200.0.1的MAC)主机 10.200.0.1 向路由器发送 ARP 应答。(应答10.200.0.1的MAC)
  5. 然后,路由器将之前缓存在本地的 IP 数据包发送给 10.200.0.1,或者最终 10.100.0.1 超时并重新发送该数据包。(源MAC为网关10.200.0.254的MAC)

Step 1: Host ARP for Router(模拟主机1发arp request)

Step1:主机1发送arp request


如果之前没有开启日志,建议开启日志方便查看:

ovs log:
root@server1:~/ovs/sandbox# tail -f ovs-vswitchd.log | grep -v -e "OFPT_ECHO_REQUEST" -e "OFPT_ECHO_REPLY"faucet log:
root@server1:~/faucet/inst# tail -f faucet.log

模拟 IP 地址为 10.100.0.1 的主机向其网关路由器 10.100.0.254 发出的 ARP 请求。

root@server1:~/ovs# ovs-appctl ofproto/trace br0 in_port=p1,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x806,arp_spa=10.100.0.1,arp_tpa=10.100.0.254,arp_sha=00:01:02:03:04:05,arp_tha=ff:ff:ff:ff:ff:ff,arp_op=1 -generate
Flow: arp,in_port=1,vlan_tci=0x0000,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.100.0.1,arp_tpa=10.100.0.254,arp_op=1,arp_sha=00:01:02:03:04:05,arp_tha=ff:ff:ff:ff:ff:ffbridge("br0")
-------------0. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0push_vlan:0x8100set_field:4196->vlan_vidgoto_table:11. arp,dl_vlan=100, priority 16384, cookie 0x5adc15c0goto_table:33. arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254, priority 12320, cookie 0x5adc15c0CONTROLLER:64Final flow: arp,in_port=1,dl_vlan=100,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.100.0.1,arp_tpa=10.100.0.254,arp_op=1,arp_sha=00:01:02:03:04:05,arp_tha=ff:ff:ff:ff:ff:ff
Megaflow: recirc_id=0,eth,arp,in_port=1,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254
Datapath actions: push_vlan(vid=100,pcp=0),userspace(pid=0,controller(reason=1,dont_send=0,continuation=0,recirc_id=1,rule_cookie=0x5adc15c0,controller_id=0,max_len=64))
root@server1:~/ovs# 
通过匹配flows2:

 priority= 4096, in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1

 table=1, priority= 16384, arp,dl_vlan=100 actions=goto_table:3

 table=3, priority= 12320, arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254 actions=CONTROLLER:64
一些字段解释:
字段名全称中文解释
arp_spaARP Sender Protocol Address发送方的 IP 地址(谁在发 ARP)
arp_tpaARP Target Protocol Address目标 IP 地址(谁的 MAC 我要找)
arp_shaARP Sender Hardware Address发送方的 MAC 地址
arp_thaARP Target Hardware Address目标的 MAC 地址(填广播或未知)
 ovs log
step1:>>>>>>>>>>>>>>>>>>>>ovs log2025-06-08T22:37:08.824Z|00456|vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPT_PACKET_IN (OF1.3) (xid=0x0): table_id=3 cookie=0x5adc15c0 total_len=46 in_port=1 (via action) data_len=46 (unbuffered)
arp,dl_vlan=100,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.100.0.1,arp_tpa=10.100.0.254,arp_op=1,arp_sha=00:01:02:03:04:05,arp_tha=ff:ff:ff:ff:ff:ff
2025-06-08T22:37:08.832Z|00457|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd360239e): ADD table:4 priority=8192,dl_vlan=100,dl_dst=00:01:02:03:04:05 cookie:0x5adc15c0 idle:11972 out_port:0 actions=pop_vlan,output:1
2025-06-08T22:37:08.832Z|00458|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd360239f): ADD table:2 priority=12320,ip,dl_vlan=200,nw_dst=10.100.0.1 cookie:0x5adc15c0 out_port:0 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4
2025-06-08T22:37:08.832Z|00459|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023a0): ADD table:2 priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.1 cookie:0x5adc15c0 out_port:0 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4
2025-06-08T22:37:08.832Z|00460|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023a1): ADD table:1 priority=8191,in_port=1,dl_vlan=100,dl_src=00:01:02:03:04:05 cookie:0x5adc15c0 hard:7972 out_port:0 actions=goto_table:4
2025-06-08T22:37:08.832Z|00461|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_PACKET_OUT (OF1.3) (xid=0xd36023a2): in_port=CONTROLLER actions=output:1 data_len=60
arp,vlan_tci=0x0000,dl_src=0e:00:00:00:00:01,dl_dst=00:01:02:03:04:05,arp_spa=10.100.0.254,arp_tpa=10.100.0.1,arp_op=2,arp_sha=0e:00:00:00:00:01,arp_tha=00:01:02:03:04:05
2025-06-08T22:37:18.833Z|00465|connmgr|INFO|br0<->tcp:127.0.0.1:6653: 4 flow_mods 10 s ago (4 adds)
  1. 交换机收到一个 ARP 请求报文,并将其作为 OFPT_PACKET_IN 消息发送给控制器。

  2. 控制器根据该 ARP 请求,向交换机下发了多条 OFPT_FLOW_MOD 消息,用于修改交换机的流表,以实现对后续报文的转发规则。

  3. 控制器还发送了一个 OFPT_PACKET_OUT 消息,向交换机指定端口发送了一个 ARP 应答报文。

faucet log
step1:>>>>>>>>>>>>>>>>>>>>faucet logJun 08 22:37:08 faucet.valve INFO     DPID 1 (0x1) switch-1 L2 learned on Port 1 00:01:02:03:04:05 (L2 type 0x0806, L2 dst ff:ff:ff:ff:ff:ff, L3 src 10.100.0.1, L3 dst 10.100.0.254) Port 1 VLAN 100 (1 hosts total)
Jun 08 22:37:08 faucet.valve INFO     DPID 1 (0x1) switch-1 Adding new route 10.100.0.1/32 via 10.100.0.1 (00:01:02:03:04:05) on VLAN 100
Jun 08 22:37:08 faucet.valve INFO     DPID 1 (0x1) switch-1 Resolve response to 10.100.0.254 from 00:01:02:03:04:05 (L2 type 0x0806, L2 dst ff:ff:ff:ff:ff:ff, L3 src 10.100.0.1, L3 dst 10.100.0.254) Port 1 VLAN 100

主机 10.100.0.1 加入网络后,发送 ARP 请求广播询问网关 10.100.0.254:

  1. Faucet 控制器看到这个广播后,学习了主机的 MAC 地址和 IP;

  2. 为该主机动态添加了一条 /32 的路由;

  3. 准备回复主机的 ARP 请求,告诉主机网关的 MAC 地址(通常是 Faucet 虚拟路由接口的 MAC)。

新下发的流表(和flows2比较)
root@server1:~/ovs# diff-flows flows2 br0 | grep '^+' 
+table=1 priority=8191,in_port=1,dl_vlan=100,dl_src=00:01:02:03:04:05 hard_timeout=7902 actions=goto_table:4
+table=2 priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.1 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4
+table=2 priority=12320,ip,dl_vlan=200,nw_dst=10.100.0.1 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4
+table=4 priority=8192,dl_vlan=100,dl_dst=00:01:02:03:04:05 idle_timeout=11902 actions=pop_vlan,output:1
root@server1:~/ovs# 

+表1: 主机1发出的二层报文,源地址已经学习过了,直接转到表4处理。(优先级比较低)

+表2:处理发往主机1的IP报文

+表4:处理目的mac为主机1的报文,从P1端口转发出去

删除的流表(和flows2比较)
root@server1:~/ovs# diff-flows flows2 br0 | grep '^-'
root@server1:~/ovs# 
 完整流表flow3
root@server1:~/ovs# dump-flows br0priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1priority=0 actions=droptable=1, priority=20490,dl_type=0x9000 actions=droptable=1, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=droptable=1, priority=20480,dl_src=0e:00:00:00:00:01 actions=droptable=1, priority=16384,arp,dl_vlan=100 actions=goto_table:3table=1, priority=16384,arp,dl_vlan=200 actions=goto_table:3table=1, priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:2table=1, priority=16384,ip,dl_vlan=200,dl_dst=0e:00:00:00:00:01 actions=goto_table:2table=1, hard_timeout=7831, priority=8191,in_port=p1,dl_vlan=100,dl_src=00:01:02:03:04:05 actions=goto_table:4table=1, priority=4096,dl_vlan=100 actions=CONTROLLER:96,goto_table:4table=1, priority=4096,dl_vlan=200 actions=CONTROLLER:96,goto_table:4table=1, priority=0 actions=goto_table:4table=2, priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.254 actions=goto_table:3table=2, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.254 actions=goto_table:3table=2, priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.1 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4table=2, priority=12320,ip,dl_vlan=200,nw_dst=10.100.0.1 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4table=2, priority=12312,ip,dl_vlan=100,nw_dst=10.100.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=200,nw_dst=10.100.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=100,nw_dst=10.200.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=200,nw_dst=10.200.0.0/24 actions=goto_table:3table=2, priority=0 actions=droptable=3, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254 actions=CONTROLLER:64table=3, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.200.0.254 actions=CONTROLLER:64table=3, priority=12320,arp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:64table=3, priority=12317,ip,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:194table=3, priority=12319,arp actions=goto_table:4table=3, priority=12316,ip actions=CONTROLLER:194,goto_table:4table=3, priority=12319,icmp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:174table=3, priority=12318,icmp actions=CONTROLLER:194,goto_table:4table=3, priority=0 actions=droptable=4, idle_timeout=11831, priority=8192,dl_vlan=100,dl_dst=00:01:02:03:04:05 actions=pop_vlan,output:p1table=4, priority=0 actions=goto_table:5table=5, priority=8240,dl_dst=01:00:0c:cc:cc:cc actions=droptable=5, priority=8240,dl_dst=01:00:0c:cc:cc:cd actions=droptable=5, priority=8240,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5table=5, priority=8236,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=droptable=5, priority=8216,dl_vlan=100,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8216,dl_vlan=100,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8216,dl_vlan=200,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8216,dl_vlan=200,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8208,dl_vlan=100,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8208,dl_vlan=200,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5table=5, priority=0 actions=drop
root@server1:~/ovs# 
保存流表flows3
root@server1:~/ovs# save-flows br0 > flows3

Step 2: Router Sends ARP Reply(控制器发出arp reply)

Step2: 控制器(router)发送are reply

在接口 p1 上启用数据包捕获(Packet Capture)功能,并将捕获的数据包写入到文件 p1.pcap 中。

root@server1:~/ovs# ovs-vsctl set interface p1 options:pcap=p1.pcap

主机1再次发送ARP报文,请求网关mac:

root@server1:~/ovs# ovs-appctl ofproto/trace br0 in_port=p1,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x806,arp_spa=10.100.0.1,arp_tpa=10.100.0.254,arp_sha=00:01:02:03:04:05,arp_tha=ff:ff:ff:ff:ff:ff,arp_op=1 -generate
Flow: arp,in_port=1,vlan_tci=0x0000,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.100.0.1,arp_tpa=10.100.0.254,arp_op=1,arp_sha=00:01:02:03:04:05,arp_tha=ff:ff:ff:ff:ff:ffbridge("br0")
-------------0. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0push_vlan:0x8100set_field:4196->vlan_vidgoto_table:11. arp,dl_vlan=100, priority 16384, cookie 0x5adc15c0goto_table:33. arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254, priority 12320, cookie 0x5adc15c0CONTROLLER:64Final flow: arp,in_port=1,dl_vlan=100,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.100.0.1,arp_tpa=10.100.0.254,arp_op=1,arp_sha=00:01:02:03:04:05,arp_tha=ff:ff:ff:ff:ff:ff
Megaflow: recirc_id=0,eth,arp,in_port=1,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254
Datapath actions: push_vlan(vid=100,pcp=0),userspace(pid=0,controller(reason=1,dont_send=0,continuation=0,recirc_id=2,rule_cookie=0x5adc15c0,controller_id=0,max_len=64))
root@server1:~/ovs# 
 ovs log
step2:>>>>>>>>>>>>>>>>>>>>2025-06-08T22:38:35.723Z|00497|vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPT_PACKET_IN (OF1.3) (xid=0x0): table_id=3 cookie=0x5adc15c0 total_len=46 in_port=1 (via action) data_len=46 (unbuffered)
arp,dl_vlan=100,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:01:02:03:04:05,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.100.0.1,arp_tpa=10.100.0.254,arp_op=1,arp_sha=00:01:02:03:04:05,arp_tha=ff:ff:ff:ff:ff:ff
2025-06-08T22:38:35.725Z|00498|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_PACKET_OUT (OF1.3) (xid=0xd36023a2): in_port=CONTROLLER actions=output:1 data_len=60
arp,vlan_tci=0x0000,dl_src=0e:00:00:00:00:01,dl_dst=00:01:02:03:04:05,arp_spa=10.100.0.254,arp_tpa=10.100.0.1,arp_op=2,arp_sha=0e:00:00:00:00:01,arp_tha=00:01:02:03:04:05

Open vSwitch将ARP请求转发至控制器处理。

控制器发送ARP响应给Open vSwitch,并通过端口P1转发该响应。

faucet log
step2:>>>>>>>>>>>>>>>>>>>>(没有下发流表的动作,因为已经在step1下发过了)

显示 p1.pcap 文件中所有抓到的数据包内容

root@server1:~/ovs/sandbox# tcpdump -evvvr p1.pcap 
reading from file p1.pcap, link-type EN10MB (Ethernet), snapshot length 1518
23:31:49.561713 0e:00:00:00:00:01 (oui Unknown) > 00:01:02:03:04:05 (oui Unknown), ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Reply 10.100.0.254 is-at 0e:00:00:00:00:01 (oui Unknown), length 46

显示的是一个 ARP 响应(Reply)报文

root@server1:~/ovs# for i in 2 3 4 5; do ovs-vsctl set interface p$i options:pcap=p$i.pcap; done

p2~p5 都启用抓包 

Step 3: Host Sends IP Packet(模拟主机1发包给主机2)

Step 3/4: 主机1发送IP报文到主机2;控制器发送arp request

模拟从主机10.100.0.1发送IP报文到主机10.200.0.1,目的mac为网关mac。

root@server1:~/ovs# ovs-appctl ofproto/trace br0 in_port=p1,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,udp,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_ttl=64 -generate
Flow: udp,in_port=1,vlan_tci=0x0000,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,nw_frag=no,tp_src=0,tp_dst=0bridge("br0")
-------------0. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0push_vlan:0x8100set_field:4196->vlan_vidgoto_table:11. ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01, priority 16384, cookie 0x5adc15c0goto_table:22. ip,dl_vlan=100,nw_dst=10.200.0.0/24, priority 12312, cookie 0x5adc15c0goto_table:33. ip,dl_dst=0e:00:00:00:00:01, priority 12317, cookie 0x5adc15c0CONTROLLER:194Final flow: udp,in_port=1,dl_vlan=100,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,nw_frag=no,tp_src=0,tp_dst=0
Megaflow: recirc_id=0,eth,udp,in_port=1,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_dst=10.200.0.0/25,nw_frag=no
Datapath actions: push_vlan(vid=100,pcp=0),userspace(pid=0,controller(reason=1,dont_send=0,continuation=0,recirc_id=6,rule_cookie=0x5adc15c0,controller_id=0,max_len=194))
root@server1:~/ovs# 

匹配流表flows3:

priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1

table=1, priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:2 

table=2, priority=12312,ip,dl_vlan=100,nw_dst=10.100.0.0/24 actions=goto_table:3

table=3, priority=12317,ip,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:194

在table 3中,该数据包却被发送至控制器。这是因为Faucet尚未解析出目标主机10.200.0.1的mac地址,随后控制器会发出ARP请求。我们将在下一步骤中具体查看。

ovs log
step3:>>>>>>>>>>>>>>>>>>>>2025-06-08T22:39:34.485Z|00521|vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPT_PACKET_IN (OF1.3) (xid=0x0): table_id=3 cookie=0x5adc15c0 total_len=110 in_port=1 (via action) data_len=110 (unbuffered)
udp,dl_vlan=100,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,nw_frag=no,tp_src=0,tp_dst=0 udp_csum:62d
2025-06-08T22:39:34.488Z|00522|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023a3): ADD table:2 priority=12320,ip,dl_vlan=100,nw_dst=10.200.0.1 cookie:0x5adc15c0 hard:748 out_port:0 actions=drop
2025-06-08T22:39:34.488Z|00523|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023a4): ADD table:2 priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 cookie:0x5adc15c0 hard:748 out_port:0 actions=drop
2025-06-08T22:39:34.488Z|00524|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_PACKET_OUT (OF1.3) (xid=0xd36023a5): in_port=CONTROLLER actions=output:5,output:4 data_len=60
arp,vlan_tci=0x0000,dl_src=0e:00:00:00:00:01,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.200.0.254,arp_tpa=10.200.0.1,arp_op=1,arp_sha=0e:00:00:00:00:01,arp_tha=00:00:00:00:00:00
2025-06-08T22:39:41.614Z|00527|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_PACKET_OUT (OF1.3) (xid=0xd36023a6): in_port=CONTROLLER actions=output:4,output:5 data_len=60
arp,vlan_tci=0x0000,dl_src=0e:00:00:00:00:01,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.200.0.254,arp_tpa=10.200.0.1,arp_op=1,arp_sha=0e:00:00:00:00:01,arp_tha=00:00:00:00:00:00
2025-06-08T22:39:44.488Z|00528|connmgr|INFO|br0<->tcp:127.0.0.1:6653: 2 flow_mods 10 s ago (2 adds)
2025-06-08T22:39:48.580Z|00531|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_PACKET_OUT (OF1.3) (xid=0xd36023a7): in_port=CONTROLLER actions=output:5,output:4 data_len=60
arp,vlan_tci=0x0000,dl_src=0e:00:00:00:00:01,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.200.0.254,arp_tpa=10.200.0.1,arp_op=1,arp_sha=0e:00:00:00:00:01,arp_tha=00:00:00:00:00:00
2025-06-08T22:39:59.770Z|00536|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_PACKET_OUT (OF1.3) (xid=0xd36023a8): in_port=CONTROLLER actions=output:5,output:4 data_len=60
arp,vlan_tci=0x0000,dl_src=0e:00:00:00:00:01,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.200.0.254,arp_tpa=10.200.0.1,arp_op=1,arp_sha=0e:00:00:00:00:01,arp_tha=00:00:00:00:00:00
2025-06-08T22:40:17.638Z|00543|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_PACKET_OUT (OF1.3) (xid=0xd36023a9): in_port=CONTROLLER actions=output:5,output:4 data_len=60
arp,vlan_tci=0x0000,dl_src=0e:00:00:00:00:01,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=10.200.0.254,arp_tpa=10.200.0.1,arp_op=1,arp_sha=0e:00:00:00:00:01,arp_tha=00:00:00:00:00:00

2025-06-08T22:39:34.485Z|00521|vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPT_PACKET_IN (OF1.3) (xid=0x0): table_id=3 cookie=0x5adc15c0 total_len=110 in_port=1 (via action) data_len=110 (unbuffered)
udp,dl_vlan=100,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,nw_frag=no,tp_src=0,tp_dst=0 udp_csum:62d

把主机1发送到主机2的IP报文发到控制器处理

2025-06-08T22:39:34.488Z|00522|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023a3): ADD table:2 priority=12320,ip,dl_vlan=100,nw_dst=10.200.0.1 cookie:0x5adc15c0 hard:748 out_port:0 actions=drop
2025-06-08T22:39:34.488Z|00523|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023a4): ADD table:2 priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 cookie:0x5adc15c0 hard:748 out_port:0 actions=drop

由于控制器需要获得主机2的mac地址,才能正常通信。所以暂时丢弃后续去往主机2的数据包。

接下来控制器发送arp 请求,从端口4、5发出。

faucet log 
step3:>>>>>>>>>>>>>>>>>>>>Jun 07 23:39:55 faucet.valve INFO     DPID 1 (0x1) switch-1 resolving 10.200.0.1 (1 flows) on VLAN 200
Jun 07 23:40:00 faucet.valve INFO     DPID 1 (0x1) switch-1 resolving 10.200.0.1 retry 2 (last attempt was 5s ago; 1 flows) on VLAN 200
Jun 07 23:40:07 faucet.valve INFO     DPID 1 (0x1) switch-1 resolving 10.200.0.1 retry 3 (last attempt was 6s ago; 1 flows) on VLAN 200
Jun 07 23:40:19 faucet.valve INFO     DPID 1 (0x1) switch-1 resolving 10.200.0.1 retry 4 (last attempt was 11s ago; 1 flows) on VLAN 200
Jun 07 23:40:38 faucet.valve INFO     DPID 1 (0x1) switch-1 resolving 10.200.0.1 retry 5 (last attempt was 18s ago; 1 flows) on VLAN 200
Jun 07 23:41:19 faucet.valve INFO     DPID 1 (0x1) switch-1 resolving 10.200.0.1 retry 6 (last attempt was 41s ago; 1 flows) on VLAN 200
Jun 07 23:42:27 faucet.valve INFO     DPID 1 (0x1) switch-1 resolving 10.200.0.1 retry 7 (last attempt was 68s ago; 1 flows) on VLAN 200

faucet日志反映发送arp request,尝试解析10.200.0.1的mac地址。

新下发的流表(和flows3比较)
root@server1:~/ovs# diff-flows flows3 br0 | grep '^+'
+table=2 priority=12320,ip,dl_vlan=100,nw_dst=10.200.0.1 hard_timeout=700 actions=drop
+table=2 priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 hard_timeout=700 actions=drop
root@server1:~/ovs#

只是table 2下发了两条流表,暂时丢弃发往10.200.0.1的报文。 

删除的流表(和flows3比较)
root@server1:~/ovs# diff-flows flows3 br0 | grep '^-'
root@server1:~/ovs# 
完整流表flows4
root@server1:~/ovs# dump-flows br0priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1priority=0 actions=droptable=1, priority=20490,dl_type=0x9000 actions=droptable=1, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=droptable=1, priority=20480,dl_src=0e:00:00:00:00:01 actions=droptable=1, priority=16384,arp,dl_vlan=100 actions=goto_table:3table=1, priority=16384,arp,dl_vlan=200 actions=goto_table:3table=1, priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:2table=1, priority=16384,ip,dl_vlan=200,dl_dst=0e:00:00:00:00:01 actions=goto_table:2table=1, hard_timeout=7831, priority=8191,in_port=p1,dl_vlan=100,dl_src=00:01:02:03:04:05 actions=goto_table:4table=1, priority=4096,dl_vlan=100 actions=CONTROLLER:96,goto_table:4table=1, priority=4096,dl_vlan=200 actions=CONTROLLER:96,goto_table:4table=1, priority=0 actions=goto_table:4table=2, priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.254 actions=goto_table:3table=2, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.254 actions=goto_table:3table=2, priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.1 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4table=2, priority=12320,ip,dl_vlan=200,nw_dst=10.100.0.1 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4table=2, hard_timeout=696, priority=12320,ip,dl_vlan=100,nw_dst=10.200.0.1 actions=droptable=2, hard_timeout=696, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 actions=droptable=2, priority=12312,ip,dl_vlan=100,nw_dst=10.100.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=200,nw_dst=10.100.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=100,nw_dst=10.200.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=200,nw_dst=10.200.0.0/24 actions=goto_table:3table=2, priority=0 actions=droptable=3, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254 actions=CONTROLLER:64table=3, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.200.0.254 actions=CONTROLLER:64table=3, priority=12320,arp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:64table=3, priority=12317,ip,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:194table=3, priority=12319,arp actions=goto_table:4table=3, priority=12316,ip actions=CONTROLLER:194,goto_table:4table=3, priority=12319,icmp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:174table=3, priority=12318,icmp actions=CONTROLLER:194,goto_table:4table=3, priority=0 actions=droptable=4, idle_timeout=11831, priority=8192,dl_vlan=100,dl_dst=00:01:02:03:04:05 actions=pop_vlan,output:p1table=4, priority=0 actions=goto_table:5table=5, priority=8240,dl_dst=01:00:0c:cc:cc:cc actions=droptable=5, priority=8240,dl_dst=01:00:0c:cc:cc:cd actions=droptable=5, priority=8240,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5table=5, priority=8236,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=droptable=5, priority=8216,dl_vlan=100,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8216,dl_vlan=100,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8216,dl_vlan=200,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8216,dl_vlan=200,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8208,dl_vlan=100,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8208,dl_vlan=200,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5table=5, priority=0 actions=drop
root@server1:~/ovs# 
 保存流表flows4
root@server1:~/ovs# save-flows br0 > flows4

 Step 4: Router Broadcasts ARP Request(控制器发出arp request)

路由器(控制器承担这个功能)需要知道10.200.0.1的以太网地址。它知道,如果这台机器存在,它一定连接在端口p4或p5上,因为这些端口配置为VLAN 200。

P4抓包
root@server1:~/ovs/sandbox# tcpdump -evvvr p4.pcap
reading from file p4.pcap, link-type EN10MB (Ethernet), snapshot length 1518
23:39:55.249797 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:40:00.263948 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:40:07.166306 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:40:19.152026 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:40:38.141315 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:41:19.242195 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:42:27.827128 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:43:34.840761 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:44:42.830534 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:45:48.901490 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
root@server1:~/ovs/sandbox# 

日志显示从P4端口发出了arp request。 

 P5抓包
root@server1:~/ovs/sandbox# tcpdump -evvvr p5.pcap
reading from file p5.pcap, link-type EN10MB (Ethernet), snapshot length 1518
23:39:55.249810 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:40:00.263960 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:40:07.166322 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:40:19.152042 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:40:38.141327 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:41:19.242207 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:42:27.827197 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:43:34.840806 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:44:42.830547 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
23:45:48.901522 0e:00:00:00:00:01 (oui Unknown) > Broadcast, ethertype ARP (0x0806), length 60: Ethernet (len 6), IPv4 (len 4), Request who-has 10.200.0.1 tell 10.200.0.254, length 46
root@server1:~/ovs/sandbox# 
P3抓包

(P3属于vlan100,不属于vlan200,所以没有抓包信息)

root@server1:~/ovs/sandbox# tcpdump -evvvr p3.pcap
reading from file p3.pcap, link-type EN10MB (Ethernet), snapshot length 1518
root@server1:~/ovs/sandbox#

Step 5: Host 2 Sends ARP Reply(模拟主机2发arp reply)

Step 5: 主机2发送arp reply

Faucet控制器发送了一个ARP请求,所以可以模拟发送一个ARP回复:

root@server1:~/ovs/sandbox# ovs-appctl ofproto/trace br0 in_port=p4,dl_src=00:10:20:30:40:50,dl_dst=0e:00:00:00:00:01,dl_type=0x806,arp_spa=10.200.0.1,arp_tpa=10.200.0.254,arp_sha=00:10:20:30:40:50,arp_tha=0e:00:00:00:00:01,arp_op=2 -generate
Flow: arp,in_port=4,vlan_tci=0x0000,dl_src=00:10:20:30:40:50,dl_dst=0e:00:00:00:00:01,arp_spa=10.200.0.1,arp_tpa=10.200.0.254,arp_op=2,arp_sha=00:10:20:30:40:50,arp_tha=0e:00:00:00:00:01bridge("br0")
-------------0. in_port=4,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0push_vlan:0x8100set_field:4296->vlan_vidgoto_table:11. arp,dl_vlan=200, priority 16384, cookie 0x5adc15c0goto_table:33. arp,dl_dst=0e:00:00:00:00:01, priority 12320, cookie 0x5adc15c0CONTROLLER:64Final flow: arp,in_port=4,dl_vlan=200,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:10:20:30:40:50,dl_dst=0e:00:00:00:00:01,arp_spa=10.200.0.1,arp_tpa=10.200.0.254,arp_op=2,arp_sha=00:10:20:30:40:50,arp_tha=0e:00:00:00:00:01
Megaflow: recirc_id=0,eth,arp,in_port=4,dl_src=00:10:20:30:40:50,dl_dst=0e:00:00:00:00:01
Datapath actions: push_vlan(vid=200,pcp=0),userspace(pid=0,controller(reason=1,dont_send=0,continuation=0,recirc_id=7,rule_cookie=0x5adc15c0,controller_id=0,max_len=64))
root@server1:~/ovs/sandbox# 

通过比较完整流表(flows4),匹配的流表为:

priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1

table=1, priority=16384,arp,dl_vlan=200 actions=goto_table:3

table=3, priority=12320,arp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:64

处理逻辑:收到arp报文,转到table3处理。

ovs log
step5:>>>>>>>>>>>>>>>>>>>>2025-06-08T22:41:25.569Z|00571|vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPT_PACKET_IN (OF1.3) (xid=0x0): table_id=3 cookie=0x5adc15c0 total_len=46 in_port=4 (via action) data_len=46 (unbuffered)
arp,dl_vlan=200,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:10:20:30:40:50,dl_dst=0e:00:00:00:00:01,arp_spa=10.200.0.1,arp_tpa=10.200.0.254,arp_op=2,arp_sha=00:10:20:30:40:50,arp_tha=0e:00:00:00:00:01
2025-06-08T22:41:25.573Z|00572|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023ab): ADD table:4 priority=8192,dl_vlan=200,dl_dst=00:10:20:30:40:50 cookie:0x5adc15c0 idle:11931 out_port:0 actions=pop_vlan,output:4
2025-06-08T22:41:25.573Z|00573|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023ac): ADD table:2 priority=12320,ip,dl_vlan=100,nw_dst=10.200.0.1 cookie:0x5adc15c0 out_port:0 actions=dec_ttl,set_field:4296->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:10:20:30:40:50->eth_dst,goto_table:4
2025-06-08T22:41:25.573Z|00574|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023ad): ADD table:2 priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 cookie:0x5adc15c0 out_port:0 actions=dec_ttl,set_field:4296->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:10:20:30:40:50->eth_dst,goto_table:4
2025-06-08T22:41:25.573Z|00575|vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xd36023ae): ADD table:1 priority=8191,in_port=4,dl_vlan=200,dl_src=00:10:20:30:40:50 cookie:0x5adc15c0 hard:7931 out_port:0 actions=goto_table:4
2025-06-08T22:41:35.574Z|00578|connmgr|INFO|br0<->tcp:127.0.0.1:6653: 4 flow_mods 10 s ago (4 adds)
  • 模拟主机2发出的arp reply发给控制器
  • 表4添加条目,mac 00:10:20:30:40:50和端口4映射
  • 表2添加条目,发给10.200.0.1的报文,修改相应的源/目mac。
  • 表1添加条目,源mac 00:10:20:30:40:50的主机发出的报文的处理方式,注意优先级比较低。
faucet log
step5:>>>>>>>>>>>>>>>>>>>>Jun 08 22:41:25 faucet.valve INFO     DPID 1 (0x1) switch-1 L2 learned on Port 4 00:10:20:30:40:50 (L2 type 0x0806, L2 dst 0e:00:00:00:00:01, L3 src 10.200.0.1, L3 dst 10.200.0.254) Port 4 VLAN 200 (1 hosts total)
Jun 08 22:41:25 faucet.valve INFO     DPID 1 (0x1) switch-1 Adding new route 10.200.0.1/32 via 10.200.0.1 (00:10:20:30:40:50) on VLAN 200
Jun 08 22:41:25 faucet.valve INFO     DPID 1 (0x1) switch-1 Received advert for 10.200.0.1 from 00:10:20:30:40:50 (L2 type 0x0806, L2 dst 0e:00:00:00:00:01, L3 src 10.200.0.1, L3 dst 10.200.0.254) Port 4 VLAN 200
新下发的流表(和flow4比较)
root@server1:~/ovs# diff-flows flows4 br0 | grep '^+'
+table=1 priority=8191,in_port=4,dl_vlan=200,dl_src=00:10:20:30:40:50 hard_timeout=7972 actions=goto_table:4
+table=2 priority=12320,ip,dl_vlan=100,nw_dst=10.200.0.1 actions=dec_ttl,set_field:4296->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:10:20:30:40:50->eth_dst,goto_table:4
+table=2 priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 actions=dec_ttl,set_field:4296->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:10:20:30:40:50->eth_dst,goto_table:4
+table=4 priority=8192,dl_vlan=200,dl_dst=00:10:20:30:40:50 idle_timeout=11972 actions=pop_vlan,output:4
root@server1:~/ovs#
删除的流表(和flows4比较)
root@server1:~/ovs# diff-flows flows4 br0 | grep '^-'
-table=2 priority=12320,ip,dl_vlan=100,nw_dst=10.200.0.1 hard_timeout=646 actions=drop
-table=2 priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 hard_timeout=646 actions=drop
root@server1:~/ovs# 
完整流表flows5
root@server1:~/ovs# dump-flows br0priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1priority=0 actions=droptable=1, priority=20490,dl_type=0x9000 actions=droptable=1, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=droptable=1, priority=20480,dl_src=0e:00:00:00:00:01 actions=droptable=1, priority=16384,arp,dl_vlan=100 actions=goto_table:3table=1, priority=16384,arp,dl_vlan=200 actions=goto_table:3table=1, priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:2table=1, priority=16384,ip,dl_vlan=200,dl_dst=0e:00:00:00:00:01 actions=goto_table:2table=1, hard_timeout=7991, priority=8191,in_port=p1,dl_vlan=100,dl_src=00:01:02:03:04:05 actions=goto_table:4table=1, hard_timeout=7972, priority=8191,in_port=p4,dl_vlan=200,dl_src=00:10:20:30:40:50 actions=goto_table:4table=1, priority=4096,dl_vlan=100 actions=CONTROLLER:96,goto_table:4table=1, priority=4096,dl_vlan=200 actions=CONTROLLER:96,goto_table:4table=1, priority=0 actions=goto_table:4table=2, priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.254 actions=goto_table:3table=2, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.254 actions=goto_table:3table=2, priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.1 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4table=2, priority=12320,ip,dl_vlan=200,nw_dst=10.100.0.1 actions=dec_ttl,set_field:4196->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:01:02:03:04:05->eth_dst,goto_table:4table=2, priority=12320,ip,dl_vlan=100,nw_dst=10.200.0.1 actions=dec_ttl,set_field:4296->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:10:20:30:40:50->eth_dst,goto_table:4table=2, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 actions=dec_ttl,set_field:4296->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:10:20:30:40:50->eth_dst,goto_table:4table=2, priority=12312,ip,dl_vlan=100,nw_dst=10.100.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=200,nw_dst=10.100.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=100,nw_dst=10.200.0.0/24 actions=goto_table:3table=2, priority=12312,ip,dl_vlan=200,nw_dst=10.200.0.0/24 actions=goto_table:3table=2, priority=0 actions=droptable=3, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254 actions=CONTROLLER:64table=3, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.200.0.254 actions=CONTROLLER:64table=3, priority=12320,arp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:64table=3, priority=12317,ip,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:194table=3, priority=12319,arp actions=goto_table:4table=3, priority=12316,ip actions=CONTROLLER:194,goto_table:4table=3, priority=12319,icmp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:174table=3, priority=12318,icmp actions=CONTROLLER:194,goto_table:4table=3, priority=0 actions=droptable=4, idle_timeout=11991, priority=8192,dl_vlan=100,dl_dst=00:01:02:03:04:05 actions=pop_vlan,output:p1table=4, idle_timeout=11972, priority=8192,dl_vlan=200,dl_dst=00:10:20:30:40:50 actions=pop_vlan,output:p4table=4, priority=0 actions=goto_table:5table=5, priority=8240,dl_dst=01:00:0c:cc:cc:cc actions=droptable=5, priority=8240,dl_dst=01:00:0c:cc:cc:cd actions=droptable=5, priority=8240,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5table=5, priority=8236,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=droptable=5, priority=8216,dl_vlan=100,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8216,dl_vlan=100,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8216,dl_vlan=200,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8216,dl_vlan=200,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8208,dl_vlan=100,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8208,dl_vlan=200,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p4,output:p5table=5, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3table=5, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5table=5, priority=0 actions=drop
root@server1:~/ovs# 
保存流表flows5
root@server1:~/ovs# save-flows br0 > flows5
root@server1:~/ovs# 

 Step 6: IP Packet Delivery(模拟主机1发包给主机2)

Step6: 相关流表已下发,主机1发送报文到主机2,直接通信

首先看p4端口没有发出的报文,说明之前主机1发给主机2的报文到目前没有发出去过。

root@server1:~/ovs/sandbox# tcpdump -evvvr p4.pcap ip        
reading from file p4.pcap, link-type EN10MB (Ethernet), snapshot length 1518
root@server1:~/ovs/sandbox#

 模拟主机1发给主机2报文,完整的报文:

root@server1:~/ovs# ovs-appctl ofproto/trace br0 in_port=p1,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,udp,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_ttl=64 -generate
Flow: udp,in_port=1,vlan_tci=0x0000,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,nw_frag=no,tp_src=0,tp_dst=0bridge("br0")
-------------0. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0push_vlan:0x8100set_field:4196->vlan_vid  <--设置为vlan200goto_table:11. ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01, priority 16384, cookie 0x5adc15c0goto_table:22. ip,dl_vlan=100,nw_dst=10.200.0.1, priority 12320, cookie 0x5adc15c0dec_ttlset_field:4296->vlan_vidset_field:0e:00:00:00:00:01->eth_srcset_field:00:10:20:30:40:50->eth_dstgoto_table:44. dl_vlan=200,dl_dst=00:10:20:30:40:50, priority 8192, cookie 0x5adc15c0pop_vlanoutput:4Final flow: udp,in_port=1,vlan_tci=0x0000,dl_src=0e:00:00:00:00:01,dl_dst=00:10:20:30:40:50,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_tos=0,nw_ecn=0,nw_ttl=63,nw_frag=no,tp_src=0,tp_dst=0
Megaflow: recirc_id=0,eth,udp,in_port=1,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_dst=10.200.0.1,nw_ttl=64,nw_frag=no
Datapath actions: set(eth(src=0e:00:00:00:00:01,dst=00:10:20:30:40:50)),set(ipv4(ttl=63)),4
root@server1:~/ovs# 

匹配流表flows5:
priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1

table=1, priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:2 


table=2, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 actions=dec_ttl,set_field:4296->vlan_vid,set_field:0e:00:00:00:00:01->eth_src,set_field:00:10:20:30:40:50->eth_dst,goto_table:4

table=4, idle_timeout=11897, priority=8192,dl_vlan=200,dl_dst=00:10:20:30:40:50 actions=pop_vlan,output:p4

Finally, we have working IP packet forwarding!

ovs log
step6:>>>>>>>>>>>>>>>>>>>>
(没有日志输出)
faucet log
step6:>>>>>>>>>>>>>>>>>>>>
(没有日志输出)
新下发的流表(和flows5比较)
root@server1:~/ovs# diff-flows flows5 br0 | grep '^+'
(没有新增加)
删除的流表(和flows5比较)
root@server1:~/ovs# diff-flows flows5 br0 | grep '^-'
(没有删除)

 5.4 性能问题

✅ Megaflow 的作用:
  • OVS 会将控制层配置的 OpenFlow 精细规则组合成一条 更粗粒度的匹配项(megaflow entry),缓存到内核 datapath 中

  • 每次有新流量进入,只要符合这个 megaflow 的组合,就可以 直接命中 datapath 缓存,不再上送到用户态

  • 不需要频繁查表、组合动作、重装规则 → 显著提升转发性能(减少控制平面与内核之间通信,减少CPU负担);

Megaflow:

Megaflow: recirc_id=0,eth,udp,in_port=1,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_dst=10.200.0.1,nw_ttl=64,nw_frag=no

datapath action:

Datapath actions: set(eth(src=0e:00:00:00:00:01,dst=00:10:20:30:40:50)),set(ipv4(ttl=63)),4

另外,虽然在 OpenFlow 控制平面下发的动作中,包含了:

  • push_vlan:给数据包打上 VLAN tag;

  • mod_vlan_vid:修改 VLAN ID;

  • pop_vlan:移除 VLAN tag;

这是一个完整的 VLAN 封装—修改—去封装流程。

但是我们在 datapath 层看到的实际执行动作中:

  • 没有出现任何 VLAN 相关的动作(push/pop/mod)

这是因为:

  • OVS 的流表转换引擎(flow translation layer)在将 OpenFlow 规则编译成 datapath 动作时,会对一系列动作进行优化;

  • 如果动作之间抵消了(例如你刚 pushpop,没有留下任何痕迹),就会被认为是无效的

  • 这类动作会被**“优化掉”(optimize out)**,不再生成实际执行代码。

优化的结果:

  • 生成的 datapath cache entry 更精简;

  • 数据包命中 datapath cache 时,只需执行必要动作,减少 CPU 指令数;

  • 提高了 转发性能和处理效率

6、ACLs

(和之前的测试相互独立,所以ovs bridge的流表可能和之前不一致)

6.1 编辑控制器yaml文件,增加ACL配置

root@server1:~/faucet/inst# vi faucet.yaml 
root@server1:~/faucet/inst# cat faucet.yaml 
dps:switch-1:dp_id: 0x1timeout: 8000arp_neighbor_timeout: 3600interfaces:1:native_vlan: 100acl_in: 12:native_vlan: 1003:native_vlan: 1004:native_vlan: 2005:native_vlan: 200
vlans:100:faucet_vips: ["10.100.0.254/24"]200:faucet_vips: ["10.200.0.254/24"]
routers:router-1:vlans: [100, 200]
acls:1:- rule:dl_type: 0x800nw_proto: 6tcp_dst: 8080actions:allow: 0- rule:actions:allow: 1
root@server1:~/faucet/inst# 

其中 端口 1 应用了 ACL 1,用于流量控制。

ACL 控制规则:

  • 第一条规则:禁止访问 TCP 目标端口为 8080 的 IPv4 报文

  • 第二条规则:默认允许其他所有流量

  • ACL 1 仅应用在 端口 1,所以这个控制只对端口 1 的入方向生效。

6.2 重启控制器

root@server1:~/ovs# docker restart faucet

或者:

docker exec faucet pkill -HUP -f faucet.faucet

6.3 完整流表flows6

root@server1:~/ovs# dump-flows br0priority=20480,tcp,in_port=p1,tp_dst=8080 actions=droppriority=20480,in_port=p2 actions=goto_table:1priority=20480,in_port=p3 actions=goto_table:1priority=20480,in_port=p4 actions=goto_table:1priority=20480,in_port=p5 actions=goto_table:1priority=20479,in_port=p1 actions=goto_table:1priority=0 actions=droptable=1, priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:2table=1, priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:2table=1, priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:2table=1, priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:2table=1, priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:2table=1, priority=0 actions=droptable=2, priority=20490,dl_type=0x9000 actions=droptable=2, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=droptable=2, priority=20480,dl_src=0e:00:00:00:00:01 actions=droptable=2, priority=16384,arp,dl_vlan=100 actions=goto_table:4table=2, priority=16384,arp,dl_vlan=200 actions=goto_table:4table=2, priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:3table=2, priority=16384,ip,dl_vlan=200,dl_dst=0e:00:00:00:00:01 actions=goto_table:3table=2, priority=4096,dl_vlan=100 actions=CONTROLLER:96,goto_table:5table=2, priority=4096,dl_vlan=200 actions=CONTROLLER:96,goto_table:5table=2, priority=0 actions=goto_table:5table=3, priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.254 actions=goto_table:4table=3, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.254 actions=goto_table:4table=3, priority=12312,ip,dl_vlan=200,nw_dst=10.100.0.0/24 actions=goto_table:4table=3, priority=12312,ip,dl_vlan=100,nw_dst=10.100.0.0/24 actions=goto_table:4table=3, priority=12312,ip,dl_vlan=200,nw_dst=10.200.0.0/24 actions=goto_table:4table=3, priority=12312,ip,dl_vlan=100,nw_dst=10.200.0.0/24 actions=goto_table:4table=3, priority=0 actions=droptable=4, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254 actions=CONTROLLER:64table=4, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.200.0.254 actions=CONTROLLER:64table=4, priority=12320,arp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:64table=4, priority=12317,ip,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:194table=4, priority=12319,arp actions=goto_table:5table=4, priority=12316,ip actions=CONTROLLER:194,goto_table:5table=4, priority=12319,icmp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:174table=4, priority=12318,icmp actions=CONTROLLER:194,goto_table:5table=4, priority=0 actions=droptable=5, priority=0 actions=goto_table:6table=6, priority=8240,dl_dst=01:00:0c:cc:cc:cc actions=droptable=6, priority=8240,dl_dst=01:00:0c:cc:cc:cd actions=droptable=6, priority=8240,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p1,output:p2,output:p3table=6, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5table=6, priority=8236,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=droptable=6, priority=8216,dl_vlan=100,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=6, priority=8216,dl_vlan=100,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=6, priority=8216,dl_vlan=200,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=6, priority=8216,dl_vlan=200,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5table=6, priority=8208,dl_vlan=100,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3table=6, priority=8208,dl_vlan=200,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p4,output:p5table=6, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3table=6, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5table=6, priority=0 actions=drop
root@server1:~/ovs# 

✅ Faucet/OVS Flow Tables 功能归纳表

Table 编号名称/用途匹配字段示例动作/作用功能说明
0Port ACLin_port, tcp_dst=8080dropgoto_table:1入端口ACL匹配表:处理端口入口的ACL规则(如 TCP 8080 禁止)
1VLAN Taggingin_port, vlan_tcipush_vlan, set_field, goto_table:2打 VLAN 标签表:给 untagged 报文打上 native VLAN 标签
2VLAN/ARP处理 & Flood控制dl_type, dl_vlan, dl_src, dl_dstgoto_table:3/4/5dropCONTROLLERVLAN 检查、非法报文丢弃、L2 Flood 前处理
3Routing (L3 Forwarding)ip, dl_vlan, nw_dstgoto_table:4L3 路由匹配表:目标 IP 是其他 VLAN 的,通过 router 处理
4VIP/ARP/IP 特殊处理arp, ip, icmpCONTROLLER, goto_table:5Faucet VIP、自身ARP响应、ICMP处理表
5转发决策入口默认所有包goto_table:6转发前的中转表(空逻辑,主要是分层结构清晰)
6Flood & Multicast 转发dl_vlan, dl_dstpop_vlan, output, drop最终转发/广播控制表,做 VLAN pop 并 output 到正确端口

6.4 增加Table 0:端口 ACL 入方向访问控制

 priority=20480,tcp,in_port=p1,tp_dst=8080 actions=droppriority=20480,in_port=p2 actions=goto_table:1priority=20480,in_port=p3 actions=goto_table:1priority=20480,in_port=p4 actions=goto_table:1priority=20480,in_port=p5 actions=goto_table:1priority=20479,in_port=p1 actions=goto_table:1priority=0 actions=drop

OpenFlow 流表输出印证了 Faucet 如何把 YAML 中配置的 ACL 和接口逻辑 编译成具体的 OpenFlow 规则。

priority=20480,tcp,in_port=p1,tp_dst=8080 actions=drop

  • 这条是 ACL 规则编译而来,对应 YAML 中的:

    acls:1:- rule:dl_type: 0x800nw_proto: 6tcp_dst: 8080actions:allow: 0
  • 意思是:匹配从端口 p1(也就是你配置中接口 1)进入的 TCP 报文,目标端口是 8080,直接丢弃

6.5 ACL带来的性能问题

Megaflow 是 OVS 的一种通配缓存机制,它把多个 OpenFlow flow 匹配路径的最终 datapath 动作集合缓存起来。
一旦某条报文触发完整的匹配路径(所有表、所有匹配字段),OVS 会把这个路径结果以 Megaflow 形式缓存下来,供后续相同类型的报文直接复用。

🚨 性能隐患:字段匹配粒度影响缓存命中

问题:某个 flow 匹配字段越多,Megaflow 也必须包括这些字段 → 会导致缓存粒度更细、命中率更低

举例:

  1. Flow 1 仅匹配 in_port

    • Megaflow 只需 match in_port,大部分流量都能复用这条路径。

  2. Flow 2 加了 nw_proto=6tp_dst=8080 的匹配

    • 即使大多数流量不是 TCP 8080,只要 packet 碰到这条规则,

    • 后续生成的 Megaflow 也必须包括 nw_prototp_dst 这些字段,

    • 结果导致缓存命中条件变复杂、Megaflow 数量急剧增多

📉 性能下降的表现:

  • Megaflow cache 中条目数增多,hash 查找变慢;

  • 大量低命中的 Megaflow 占用缓存空间;

  • 对 CPU 资源占用提升显著;

  • 控制器和 datapath 间通信变频繁。

ACL的本质是对数据包的多个字段(如源/目的IP、源/目的端口、协议类型、VLAN ID等)进行精确或范围匹配。当ACL规则非常多(尤其是在大规模网络中)且匹配条件非常细粒度时,设备在处理每个数据包时都需要遍历这些复杂的规则,这会显著增加查找时间。

如果ACL对TCP目的端口这样的高基数(2^16次方,可能值多)字段进行精确匹配,为了区分不同端口,巨流(一种缓存优化)将无法有效聚合流量。OVS可能需要为每个独特的TCP目的端口生成单独的巨流,导致巨流数量爆炸式增长。

OVS在实际设计中已经采取了一些优化措施来缓解这个问题。以下为举例说明:

root@server1:~/ovs# ovs-appctl ofproto/trace br0 in_port=p1,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,tcp,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_ttl=64,tp_dst=80 -generate
Flow: tcp,in_port=1,vlan_tci=0x0000,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,nw_frag=no,tp_src=0,tp_dst=80,tcp_flags=0bridge("br0")
-------------0. in_port=1, priority 20479, cookie 0x5adc15c0goto_table:11. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0push_vlan:0x8100set_field:4196->vlan_vidgoto_table:22. ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01, priority 16384, cookie 0x5adc15c0goto_table:33. ip,dl_vlan=100,nw_dst=10.200.0.0/24, priority 12312, cookie 0x5adc15c0goto_table:44. ip,dl_dst=0e:00:00:00:00:01, priority 12317, cookie 0x5adc15c0CONTROLLER:194Final flow: tcp,in_port=1,dl_vlan=100,dl_vlan_pcp=0,vlan_tci1=0x0000,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_src=10.100.0.1,nw_dst=10.200.0.1,nw_tos=0,nw_ecn=0,nw_ttl=64,nw_frag=no,tp_src=0,tp_dst=80,tcp_flags=0
Megaflow: recirc_id=0,eth,tcp,in_port=1,dl_src=00:01:02:03:04:05,dl_dst=0e:00:00:00:00:01,nw_dst=10.200.0.0/25,nw_frag=no,tp_dst=0x0/0xf000
Datapath actions: push_vlan(vid=100,pcp=0),userspace(pid=0,controller(reason=1,dont_send=0,continuation=0,recirc_id=1,rule_cookie=0x5adc15c0,controller_id=0,max_len=194))
  • 端口 800x0000/0xf000 范围

  • 端口 80800x1000/0xf000 范围

  • 它们落在不同 megaflow 里,不会相互污染缓存

这个 trace 输出以及随后的解释展示了 OVS 在Megaflow层面的一种智能优化。为了避免因TCP目的端口的细粒度匹配而导致性能下降,OVS 能够为 TCP 目的端口生成带有掩码的巨流,只匹配端口值的关键位(例如最高几位),从而有效地将多个逻辑上不同的端口分组到少数几个巨流中,显著减少了巨流的数量,提高了缓存性能和整体转发效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/84990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PCB设计教程【大师篇】stm32开发板PCB布线(信号部分)

前言 本教程基于B站Expert电子实验室的PCB设计教学的整理&#xff0c;为个人学习记录&#xff0c;旨在帮助PCB设计新手入门。所有内容仅作学习交流使用&#xff0c;无任何商业目的。若涉及侵权&#xff0c;请随时联系&#xff0c;将会立即处理 1. 布线优先级与原则 - 遵循“重…

Phthon3 学习记录-0613

List&#xff08;列表&#xff09;、Tuple&#xff08;元组&#xff09;、Set&#xff08;集合&#xff09;和 Dictionary&#xff08;字典&#xff09; 在接口自动化测试中&#xff0c;List&#xff08;列表&#xff09;、Tuple&#xff08;元组&#xff09;、Set&#xff08…

UVa12298 3KP-BASH Project

UVa12298 3KP-BASH Project 题目链接题意输入格式输出格式 分析AC 代码 题目链接 UVa12298 3KP-BASH Project 题意 摘自 《算法竞赛入门经典&#xff1a;训练指南》刘汝佳&#xff0c;陈锋著。有删改。 你的任务是为一个假想的 3KP 操作系统编写一个简单的 Bash 模拟器。由于操…

云打包生成的ipa上传构建版本经验分享

在上架ios应用&#xff0c;在苹果开发者中心操作的时候&#xff0c;需要提供一个构建版本&#xff0c;如下图所示&#xff1a; 点击蓝色加号&#xff0c;添加构建版本&#xff0c;但是点击蓝色加号后&#xff0c;并没有构建版本可以选。 原因是需要下载下面它推荐的工具来上传…

ESP32的spi通讯(Arduino)

目录 一.基本配置 1.esp32-wroom-32引脚图 2.接线方式 3.Arduino芯片选择和库文件 3.1Arduino配置&#xff08;2.0.11&#xff09; 3.2 下载ESP32SPISlave库&#xff08;0.6.8&#xff09;文件 二、代码编写 1.主机代码 2.从机代码 3.注意事项 三、运行效果 一.基本…

Spring-rabbit重试消费源码分析

在集成RabbitMQ与Spring Boot 3.1.x时&#xff0c;RetryOperationsInterceptor 是实现消息重试机制的关键组件。这里将深入分析 RetryOperationsInterceptor 的工作原理&#xff0c;尤其是在消费者消费失败时的行为&#xff0c;并结合底层源码进行详解。 一、配置解析 首先&a…

如何使用JacksonTypeHandler处理mysql json字符串转List对象的问题

在使用mysql5.7或更高版本时&#xff0c;json类型字段应用场景越来越多&#xff0c;对于普通的对象或者List<Integer>、List<String>这些基础类型&#xff0c;jacksonTypeHandler都能很好的处理&#xff0c;如下&#xff1a; 1、定义一个person对象 import com.f…

华为云Flexus+DeepSeek征文 | 基于Dify构建股票分析助手

华为云FlexusDeepSeek征文 | 基于Dify构建AI 图片生成应用 一、构建股票分析助手前言二、构建股票分析助手环境2.1 基于FlexusX实例的Dify平台2.2 基于MaaS的模型API商用服务 三、构建股票分析助手实战3.1 配置Dify环境3.2 配置Dify工具3.3 创建股票分析助手3.4 使用股票分析助…

【0.1 漫画计算机组成原理】

🖥️ 漫画计算机组成原理 🎯 学习目标:深入理解计算机硬件基础,为后续Java编程和性能优化打下坚实基础 📋 目录 CPU架构与指令集内存层次结构冯诺依曼架构与哈佛架构总线系统与IO设备计算机性能分析实际应用场景🎭 漫画引言 小明: “为什么我的Java程序有时候跑得飞…

pytorch 实战二 CNN手写数字识别

系列文章目录 文章目录 系列文章目录前言一、torchvision.datasets1. 数据下载2. 数据分批次传入 二、网络1. 网络搭建2. 训练3.测试 完整代码三、保存模型与推理&#xff08;inference&#xff09;模型保存推理鸣谢 前言 手写数字识别&#xff0c;就是要根据手写的数字0~9&…

[Godot] C#读取CSV表格创建双层字典实现本地化

最近研究了一下本地化&#xff0c;给大家用简单易懂的方式说明我是怎么实现的&#xff0c;使用CSV表格填写翻译&#xff0c;然后在Godot中读取为字典 表格填写 首先&#xff0c;我们表格可以按照下面这种格式填写 idzhenjaruesdefrapple苹果appleリンゴяблокоmanzanaA…

Spark 之 Subquery

各类 Subquery src/main/scala/org/apache/spark/sql/catalyst/expressions/predicates.scala /*** Evaluates to `true` if `values` are returned in `query`s result set.*/ case class InSubquery(values: Seq[Expression], query: ListQuery)extends Predicate with Une…

3.1.3_栈的链式存储实现

知识总览&#xff1a; 链栈定义&#xff1a; 头插法建立单链表&#xff1a; 每次要插入一个元素的时候&#xff0c;总是把该元素插在头节点之后的位置&#xff0c;如果规定只能在单链表的链头一端进行操作即为进栈操作 每次删除一个元素的时候&#xff0c;规定只能在单链表…

华为OD机试_2025 B卷_字符串重新排列(Python,100分)(附详细解题思路)

题目描述 给定一个字符串s&#xff0c;s包括以空格分隔的若干个单词&#xff0c;请对s进行如下处理后输出&#xff1a; 1、单词内部调整&#xff1a;对每个单词字母重新按字典序排序 2、单词间顺序调整&#xff1a; 1&#xff09;统计每个单词出现的次数&#xff0c;并按次数降…

http的缓存问题

一句话概括&#xff1a;浏览器请求资源的时候&#xff0c;会首先检查本地是否有缓存&#xff0c;减少向服务器请求的次数 一、缓存类型&#xff1a; 1. 强缓存&#xff08;本地缓存&#xff09;&#xff1a;直接读本地&#xff0c;不发请求 控制方式&#xff1a; ① Cache-C…

【网络安全】SRC漏洞挖掘思路/手法分享

文章目录 Tip1Tip2Tip3Tip4Tip5Tip6Tip7Tip8Tip9Tip10Tip11Tip12Tip13Tip14Tip15Tip16Tip17Tip18Tip19Tip20Tip21Tip22Tip23Tip24Tip25Tip26Tip27Tip28Tip29Tip30Tip1 “复制该主机所有 URL”:包含该主机上的所有接口等资源。 “复制此主机里的链接”:包括该主机加载的第三…

「Linux中Shell命令」Shell常见命令

知识点及案例解析 1. who 命令 功能:显示当前登录系统的用户信息,包括用户名、终端、登录时间、IP等。 案例: who输出示例: root tty1 2025-06-13 19:42 root pts/0 2025-06-13 19:45 (192.168.226.1)解析: 显示两个用户登录信息: 第一列(用…

StampedLock入门教程

文章目录 一、理解“戳” (Stamp)二、为什么 StampedLock 能提高读性能&#xff1f;秘密在于“乐观读”StampedLock性能对比性能对比结果图 总结 StampedLock完整演示代码对代码的疑问之处问题一&#xff1a;为什么 demonstrateOptimisticReadFailure 中写线程能修改成功&#…

基于云计算的振动弦分析:谐波可视化与波动方程参数理解-AI云计算数值分析和代码验证

振动弦方程是一个基础的偏微分方程&#xff0c;它描述了弹性弦的横向振动。其应用范围广泛&#xff0c;不仅可用于模拟乐器和一般的波动现象&#xff0c;更是数学物理以及深奥的弦理论中的重要基石。 ☁️AI云计算数值分析和代码验证 振动弦方程是描述固定两端弹性弦横向振动的…

Qt .pro配置gcc相关命令(三):-W1、-L、-rpath和-rpath-link

目录 1.Linux 动态库相关知识 1.1.动态库查找路径 1.2.查看程序依赖的动态库 1.3.修改动态库查找路径的方法 1.4.动态链接器缓存管理 2.-Wl参数 3.-L选项&#xff08;编译时路径&#xff09; 4.-rpath参数(运行时路径) 5.-rpath-link 参数 6.常见问题与解决方案 7.总…