OVS Faucet Tutorial笔记(下)

发布于:2025-06-15 ⋅ 阅读:(20) ⋅ 点赞:(0)

官方文档:

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: 0x1
        timeout: 8000
        arp_neighbor_timeout: 3600
        interfaces:
            1:
                native_vlan: 100
            2:
                native_vlan: 100
            3:
                native_vlan: 100
            4:
                native_vlan: 200
            5:
                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, br0

root@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-band

2、输入简化格式命令:
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 0 vlan Ingress VLAN processing 打上 VLAN 标签(入口 VLAN 处理)
Table 1 eth_src Ingress L2 processing, MAC learning MAC 地址学习(二层入口处理)
Table 2 ipv4_fib L3 forwarding for IPv4 路由表,进行 IPv4 的三层转发
Table 3 vip Virtual IP processing (e.g., for router IP addresses by Faucet) 处理发给路由器自身(MAC 或 IP)的报文
Table 4 eth_dst Egress L2 processing 根据目的 MAC 地址进行二层转发(出口二层处理)
Table 5 flood Flooding 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 br0
 priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
 priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
 priority=0 actions=drop
 table=1, priority=20490,dl_type=0x9000 actions=drop
 table=1, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=drop
 table=1, priority=20480,dl_src=0e:00:00:00:00:01 actions=drop
 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=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=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=3, priority=0 actions=drop
 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:p1,output:p2,output:p3
 table=5, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5
 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:p1,output:p2,output:p3
 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:p1,output:p2,output:p3
 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:p4,output:p5
 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:p4,output:p5
 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:p1,output:p2,output:p3
 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:p4,output:p5
 table=5, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3
 table=5, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5
 table=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:ff

bridge("br0")
-------------
 0. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0
    push_vlan:0x8100
    set_field:4196->vlan_vid
    goto_table:1
 1. arp,dl_vlan=100, priority 16384, cookie 0x5adc15c0
    goto_table:3
 3. arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254, priority 12320, cookie 0x5adc15c0
    CONTROLLER:64

Final 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_spa ARP Sender Protocol Address 发送方的 IP 地址(谁在发 ARP)
arp_tpa ARP Target Protocol Address 目标 IP 地址(谁的 MAC 我要找)
arp_sha ARP Sender Hardware Address 发送方的 MAC 地址
arp_tha ARP Target Hardware Address 目标的 MAC 地址(填广播或未知)
 ovs log
step1:>>>>>>>>>>>>>>>>>>>>ovs log

2025-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 log

Jun 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 br0
 priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
 priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
 priority=0 actions=drop
 table=1, priority=20490,dl_type=0x9000 actions=drop
 table=1, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=drop
 table=1, priority=20480,dl_src=0e:00:00:00:00:01 actions=drop
 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, hard_timeout=7831, priority=8191,in_port=p1,dl_vlan=100,dl_src=00:01:02:03:04:05 actions=goto_table:4
 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=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=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=3, priority=0 actions=drop
 table=4, idle_timeout=11831, priority=8192,dl_vlan=100,dl_dst=00:01:02:03:04:05 actions=pop_vlan,output:p1
 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:p1,output:p2,output:p3
 table=5, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5
 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:p1,output:p2,output:p3
 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:p1,output:p2,output:p3
 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:p4,output:p5
 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:p4,output:p5
 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:p1,output:p2,output:p3
 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:p4,output:p5
 table=5, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3
 table=5, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5
 table=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:ff

bridge("br0")
-------------
 0. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0
    push_vlan:0x8100
    set_field:4196->vlan_vid
    goto_table:1
 1. arp,dl_vlan=100, priority 16384, cookie 0x5adc15c0
    goto_table:3
 3. arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254, priority 12320, cookie 0x5adc15c0
    CONTROLLER:64

Final 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=0

bridge("br0")
-------------
 0. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0
    push_vlan:0x8100
    set_field:4196->vlan_vid
    goto_table:1
 1. ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01, priority 16384, cookie 0x5adc15c0
    goto_table:2
 2. ip,dl_vlan=100,nw_dst=10.200.0.0/24, priority 12312, cookie 0x5adc15c0
    goto_table:3
 3. ip,dl_dst=0e:00:00:00:00:01, priority 12317, cookie 0x5adc15c0
    CONTROLLER:194

Final 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 br0
 priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
 priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
 priority=0 actions=drop
 table=1, priority=20490,dl_type=0x9000 actions=drop
 table=1, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=drop
 table=1, priority=20480,dl_src=0e:00:00:00:00:01 actions=drop
 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, hard_timeout=7831, priority=8191,in_port=p1,dl_vlan=100,dl_src=00:01:02:03:04:05 actions=goto_table:4
 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=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=2, hard_timeout=696, priority=12320,ip,dl_vlan=100,nw_dst=10.200.0.1 actions=drop
 table=2, hard_timeout=696, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.1 actions=drop
 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=3, priority=0 actions=drop
 table=4, idle_timeout=11831, priority=8192,dl_vlan=100,dl_dst=00:01:02:03:04:05 actions=pop_vlan,output:p1
 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:p1,output:p2,output:p3
 table=5, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5
 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:p1,output:p2,output:p3
 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:p1,output:p2,output:p3
 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:p4,output:p5
 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:p4,output:p5
 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:p1,output:p2,output:p3
 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:p4,output:p5
 table=5, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3
 table=5, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5
 table=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:01

bridge("br0")
-------------
 0. in_port=4,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0
    push_vlan:0x8100
    set_field:4296->vlan_vid
    goto_table:1
 1. arp,dl_vlan=200, priority 16384, cookie 0x5adc15c0
    goto_table:3
 3. arp,dl_dst=0e:00:00:00:00:01, priority 12320, cookie 0x5adc15c0
    CONTROLLER:64

Final 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 br0
 priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
 priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
 priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
 priority=0 actions=drop
 table=1, priority=20490,dl_type=0x9000 actions=drop
 table=1, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=drop
 table=1, priority=20480,dl_src=0e:00:00:00:00:01 actions=drop
 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, hard_timeout=7991, priority=8191,in_port=p1,dl_vlan=100,dl_src=00:01:02:03:04:05 actions=goto_table:4
 table=1, hard_timeout=7972, priority=8191,in_port=p4,dl_vlan=200,dl_src=00:10:20:30:40:50 actions=goto_table:4
 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=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=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=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=3, priority=0 actions=drop
 table=4, idle_timeout=11991, priority=8192,dl_vlan=100,dl_dst=00:01:02:03:04:05 actions=pop_vlan,output:p1
 table=4, idle_timeout=11972, priority=8192,dl_vlan=200,dl_dst=00:10:20:30:40:50 actions=pop_vlan,output:p4
 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:p1,output:p2,output:p3
 table=5, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5
 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:p1,output:p2,output:p3
 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:p1,output:p2,output:p3
 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:p4,output:p5
 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:p4,output:p5
 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:p1,output:p2,output:p3
 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:p4,output:p5
 table=5, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3
 table=5, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5
 table=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=0

bridge("br0")
-------------
 0. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0
    push_vlan:0x8100
    set_field:4196->vlan_vid  <--设置为vlan200
    goto_table:1
 1. ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01, priority 16384, cookie 0x5adc15c0
    goto_table:2
 2. ip,dl_vlan=100,nw_dst=10.200.0.1, priority 12320, cookie 0x5adc15c0
    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
 4. dl_vlan=200,dl_dst=00:10:20:30:40:50, priority 8192, cookie 0x5adc15c0
    pop_vlan
    output:4

Final 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: 0x1
        timeout: 8000
        arp_neighbor_timeout: 3600
        interfaces:
            1:
                native_vlan: 100
                acl_in: 1
            2:
                native_vlan: 100
            3:
                native_vlan: 100
            4:
                native_vlan: 200
            5:
                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: 0x800
            nw_proto: 6
            tcp_dst: 8080
            actions:
                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 br0
 priority=20480,tcp,in_port=p1,tp_dst=8080 actions=drop
 priority=20480,in_port=p2 actions=goto_table:1
 priority=20480,in_port=p3 actions=goto_table:1
 priority=20480,in_port=p4 actions=goto_table:1
 priority=20480,in_port=p5 actions=goto_table:1
 priority=20479,in_port=p1 actions=goto_table:1
 priority=0 actions=drop
 table=1, priority=4096,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:2
 table=1, priority=4096,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:2
 table=1, priority=4096,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:2
 table=1, priority=4096,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:2
 table=1, priority=4096,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:2
 table=1, priority=0 actions=drop
 table=2, priority=20490,dl_type=0x9000 actions=drop
 table=2, priority=20480,dl_src=ff:ff:ff:ff:ff:ff actions=drop
 table=2, priority=20480,dl_src=0e:00:00:00:00:01 actions=drop
 table=2, priority=16384,arp,dl_vlan=100 actions=goto_table:4
 table=2, priority=16384,arp,dl_vlan=200 actions=goto_table:4
 table=2, priority=16384,ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01 actions=goto_table:3
 table=2, priority=16384,ip,dl_vlan=200,dl_dst=0e:00:00:00:00:01 actions=goto_table:3
 table=2, priority=4096,dl_vlan=100 actions=CONTROLLER:96,goto_table:5
 table=2, priority=4096,dl_vlan=200 actions=CONTROLLER:96,goto_table:5
 table=2, priority=0 actions=goto_table:5
 table=3, priority=12320,ip,dl_vlan=100,nw_dst=10.100.0.254 actions=goto_table:4
 table=3, priority=12320,ip,dl_vlan=200,nw_dst=10.200.0.254 actions=goto_table:4
 table=3, priority=12312,ip,dl_vlan=200,nw_dst=10.100.0.0/24 actions=goto_table:4
 table=3, priority=12312,ip,dl_vlan=100,nw_dst=10.100.0.0/24 actions=goto_table:4
 table=3, priority=12312,ip,dl_vlan=200,nw_dst=10.200.0.0/24 actions=goto_table:4
 table=3, priority=12312,ip,dl_vlan=100,nw_dst=10.200.0.0/24 actions=goto_table:4
 table=3, priority=0 actions=drop
 table=4, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.100.0.254 actions=CONTROLLER:64
 table=4, priority=12320,arp,dl_dst=ff:ff:ff:ff:ff:ff,arp_tpa=10.200.0.254 actions=CONTROLLER:64
 table=4, priority=12320,arp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:64
 table=4, priority=12317,ip,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:194
 table=4, priority=12319,arp actions=goto_table:5
 table=4, priority=12316,ip actions=CONTROLLER:194,goto_table:5
 table=4, priority=12319,icmp,dl_dst=0e:00:00:00:00:01 actions=CONTROLLER:174
 table=4, priority=12318,icmp actions=CONTROLLER:194,goto_table:5
 table=4, priority=0 actions=drop
 table=5, priority=0 actions=goto_table:6
 table=6, priority=8240,dl_dst=01:00:0c:cc:cc:cc actions=drop
 table=6, priority=8240,dl_dst=01:00:0c:cc:cc:cd actions=drop
 table=6, priority=8240,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p1,output:p2,output:p3
 table=6, priority=8240,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5
 table=6, priority=8236,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=drop
 table=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:p3
 table=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:p3
 table=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:p5
 table=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:p5
 table=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:p3
 table=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:p5
 table=6, priority=8192,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3
 table=6, priority=8192,dl_vlan=200 actions=pop_vlan,output:p4,output:p5
 table=6, priority=0 actions=drop
root@server1:~/ovs# 

✅ Faucet/OVS Flow Tables 功能归纳表

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

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

 priority=20480,tcp,in_port=p1,tp_dst=8080 actions=drop
 priority=20480,in_port=p2 actions=goto_table:1
 priority=20480,in_port=p3 actions=goto_table:1
 priority=20480,in_port=p4 actions=goto_table:1
 priority=20480,in_port=p5 actions=goto_table:1
 priority=20479,in_port=p1 actions=goto_table:1
 priority=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: 0x800
            nw_proto: 6
            tcp_dst: 8080
            actions:
              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=0

bridge("br0")
-------------
 0. in_port=1, priority 20479, cookie 0x5adc15c0
    goto_table:1
 1. in_port=1,vlan_tci=0x0000/0x1fff, priority 4096, cookie 0x5adc15c0
    push_vlan:0x8100
    set_field:4196->vlan_vid
    goto_table:2
 2. ip,dl_vlan=100,dl_dst=0e:00:00:00:00:01, priority 16384, cookie 0x5adc15c0
    goto_table:3
 3. ip,dl_vlan=100,nw_dst=10.200.0.0/24, priority 12312, cookie 0x5adc15c0
    goto_table:4
 4. ip,dl_dst=0e:00:00:00:00:01, priority 12317, cookie 0x5adc15c0
    CONTROLLER:194

Final 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 目的端口生成带有掩码的巨流,只匹配端口值的关键位(例如最高几位),从而有效地将多个逻辑上不同的端口分组到少数几个巨流中,显著减少了巨流的数量,提高了缓存性能和整体转发效率。