流表組成
每條流表規則由一些列字段組成,可以分為**基礎字段、匹配字段和動作字段**三部分。 在打印流表時,在流表中還存在一些顯示字段,如duration,idle_age等,此處把這些字段也暫時歸之於基礎字段之中.
流表組成部分字段說明
基礎字段:
cookie=value流表標識字段,cookie字段有兩種書寫方式:cookie=value和cookie=value/mask。mask中對應位為1時cookie中值相應的位須嚴格匹配,為0時cookie中值對應的位通配,當mask為-1時,必須嚴格匹配cookie值。duration=value流表生效時間,標識流表從下發到現在所持續的時間table=tableid流表所屬表項,標識流表所屬的表,默認為0priority=priority標識流表的優先級,范圍為0-65535,值越大,優先級越高n_packets標識流表匹配包數n_bytes標識流表匹配字節數idle_timeout=sec流表空閑超時時間,流表會在空閑時間達到給定的時間時被刪除。設置為0(默認值)時,流表不會因空閑時間被刪除。hard_timeout=sec流表可存在的時間。設置此值后,流表會在到達給定時間后被刪除。idle_age=sec流表空閑時間hard_age=sec流表存在時間。此字段與duration字段的區別在當流表被修改后,會重新設置hard_timer但是不會重置durationip_frag=frag_type當dl_type指定為IP或者IPv6,frag_type指定匹配的IP分片包或者非分片包的匹配frag_type支持的值為:no: 僅匹配非分片報文yes:匹配所有分片報文first:僅匹配offset為0的分片報文later: 僅匹配offset非0的分片報文not_later:匹配非分片報文和offset為0的分片報文
匹配字段
in_port=port標識匹配接收數據包的端口號dl_type=ethertype匹配數據包的二層協議類型,IP數據包為0x0800,IPv6數據包為0x86dd,ARP數據包為0x0806dl_src=xx:xx:xx:xx:xx:xxdl_dst=xx:xx:xx:xx:xx:xx匹配指定的鏈路層源或者目的MAC地址dl_src=xx:xx:xx:xx:xx:xx/xx:xx:xx:xx:xx:xxdl_dst=xx:xx:xx:xx:xx:xx/xx:xx:xx:xx:xx:xx匹配指定的鏈路層MAC地址,MAC地址格式為ADDR/MASK,當MASK值為01:00:00:00:00:00時,僅匹配多播位。當dl_dst=01:00:00:00:00:00/01:00:00:00:00:00時,匹配所有的組播報文和廣播報文。dl_dst=00:00:00:00:00:00/01:00:00:00:00:00匹配所有的單播報文。nw_src=ip[/mask]nw_dst=ip[/mask]當dl_type=0x0800或指定ip時,匹配數據包的源、目的IP地址 當dl_type=0x0806或指定arp時,匹配ARP數據包的ar_spa或者ar_tpa字段dl_vlan=vlan匹配802.1Q類型(即vlan)數據包nw_proto=proto匹配數據包協議類型。當dl_type=0x0800時,匹配IP協議族的協議,例如tcp,udp,icmp等nw_tos=tos匹配IP Tos/DSCP或者IPv6的tos字段,值為0-255nw_ecn=ecn匹配IP或者IPv6的ecn字段,值為0~3nw_ttl=ttl匹配TTL值tp_src=porttp_dst=port若指定了udp或者tcp協議,則匹配udp/tcp的端口號icmp_type=typeicmp_code=code若指定了icmp或者icmpv6協議,則匹配對應的icmp 類型或者code字段arp_sha=xx:xx:xx:xx:xx:xxarp_tha=xx:xx:xx:xx:xx:xx當設置dl_type為ARP或者RARP,則arp_sha和arp_tha匹配數據包的源、目的MAC地址
動作字段
output:port將數據包從port接口發送enqueue:port:queue將數據包入隊到指定端口的指定隊列里normal將數據包按照設備上的正常L2/L3層處理方式進行處理flood將數據包發送到交換機上除接收接口和禁止flood的接口外的所有接口all將數據包發送到除接收接口外的所有接口controller(key=value…)將數據包作為PACKET IN消息發送到OpenFlow控制器。 支持的鍵值對:max_len=nbytes:限制發送到控制器的數據包長度字節數,默認情況是發送整個數據包;reason=reason:在PACKET IN消息中指明發送消息的原因,支持的reason為action(default),no_match和invalid_ttl;id=controller-id:指明控制器IDin_port將數據包從接收的接口發送出去drop丟棄數據包mod_vlan_vid:vlan_vid修改數據包的vlan idmod_vlan_pcp:vlan_pcp修改數據包的vlan prioritystrip_vlan如果數據包中存在vlan tag,則剝離vlan tagpush_vlan:ethertype為數據包添加新的vlan tagmod_dl_src:mac設置數據包的源MAC地址mod_dl_dst:mac設置數據包的目的MAC地址mod_nw_src:ip設置數據包的源IP地址mod_nw_dsp:ip設置數據包的目的IP地址mod_tp_src:port設置TCP或者UDP的源端口mod_tp_dst:port設置TCP或UDP的目的端口
下發流表
查詢對應的網口序號
對應網口名稱已知
如果明確的知道對應網口的名稱,如vnet1,可以通過如下方式查詢其對應的OpenFlow接口序號:
[root@localhost ~]$ ovs-vsctl get interface vnet1 ofport
對應網口名稱未知
如果不知道對應網口的名稱,但是知道其對應的MAC地址,則可以通過如下命令查找對應的網口序號:
[root@localhost ~]$ ovs-ofctl show ovsBusiness
OFPT_FEATURES_REPLY (xid=0x2): dpid:000090e2ba0115e4
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
1(vnet1): addr:fe:ea:4a:e6:01:db
config: 0
state: 0
current: 10MB-FD COPPER
speed: 10 Mbps now, 0 Mbps max
2(vnet2): addr:fe:ea:4a:e6:01:dc
config: 0
state: 0
current: 10MB-FD COPPER
speed: 10 Mbps now, 0 Mbps max
3(vnet3): addr:fe:ea:4a:e6:01:5b
config: 0
state: 0
current: 10MB-FD COPPER
speed: 10 Mbps now, 0 Mbps max
4(vnet4): addr:fe:ea:4a:e6:01:5c
config: 0
state: 0
current: 10MB-FD COPPER
speed: 10 Mbps now, 0 Mbps max
LOCAL(ovsBusiness): addr:90:e2:ba:01:15:e4
config: 0
state: 0
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
可以看到接口對應的MAC地址及接口對應的OpenFlow接口序號。
下發流表示例
如上面ovs-ofctl show ovsBusiness命令所顯示的接口信息,vnet1和vnet2對應OVS的入口和出口,分別連接着客戶端和服務端,vnet3和vnet4對應虛擬機的入口和出口,下面就以以上四個網口來下發流表:
根據接收端口
從一個接口接收從其他接口發送
從vnet1接收的數據包經過虛擬機后從vnet2發送出去
# 客戶端訪問服務端 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,in_port=1 actions=output:3" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,in_port=4 actions=output:2" # 服務端應答客戶端請求 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,in_port=2 actions=output:4" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,in_port=3 actions=output:1"
將數據包從接收端口發送
將從vnet1接收到的數據包從vnet1發送出去
ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,in_port=1 actions=in_port"
根據接收端口及IP信息
客戶端IP地址為:1.1.1.12, 服務端IP地址為1.1.1.13
# 客戶端訪問服務端 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=1,nw_src=1.1.1.12,nw_dst=1.1.1.13 actions=output:3" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=4,nw_src=1.1.1.12,nw_dst=1.1.1.13 actions=output:2" # 服務端相應客戶端請求 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=2,nw_src=1.1.1.13,nw_dst=1.1.1.12 actions=output:4" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=3,nw_src=1.1.1.13,nw_dst=1.1.1.12 actions=output:1" # 放通arp數據包 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=1 actions=output:3" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=4 actions=output:2" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=2 actions=output:4" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=3 actions=output:1"
根據接收端口、VLAN及IP信息
在將數據包發給虛擬機之前去vlan tag,然后數據包發送出OVS時添加vlan tag
客戶端IP地址為:1.1.1.12, 服務端IP地址為1.1.1.13,vlan為10
# 客戶端訪問服務端 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=1,dl_vlan=10,nw_src=1.1.1.12,nw_dst=1.1.1.13 actions=strip_vlan,output:3" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=4,nw_src=1.1.1.12,nw_dst=1.1.1.13 actions=mod_vlan_vid:10,output:2" # 服務端相應客戶端請求 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=2,dl_vlan=10,nw_src=1.1.1.13,nw_dst=1.1.1.12 actions=strip_vlan,output:4" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=3,nw_src=1.1.1.13,nw_dst=1.1.1.12 actions=mod_vlan_vid:10,output:1" # 放通arp數據包 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=1 actions=output:3" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=4 actions=output:2" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=2 actions=output:4" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=3 actions=output:1"
根據接收端口及MAC地址信息
客戶端IP地址為:1.1.1.12, 服務端IP地址為1.1.1.13 客戶端MAC地址為:01:01:01:01:01:02,服務端MAC地址為:01:01:01:01:01:01
# 客戶端訪問服務端 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=1,dl_dst=01:01:01:01:01:01 actions=strip_vlan,output:3" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=4,dl_dst=01:01:01:01:01:01 actions=mod_vlan_vid:10,output:2" # 服務端相應客戶端請求 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=2,dl_dst=01:01:01:01:01:02 actions=output:4" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,ip,in_port=3,dl_dst=01:01:01:01:01:02 actions=output:1" # 放通arp數據包 ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=1 actions=output:3" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=4 actions=output:2" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=2 actions=output:4" ovs-ofctl add-flow ovsBusiness "cookie=0,priority=40001,arp,in_port=3 actions=output:1"
設置NORMAL轉發
ovs-ofctl add-flows "priority=0 actions=NORMAL"
其他形式的流表
# 丟棄所有port 1上接收的數據包 ovs-ofctl add-flow ovsBusiness "in_port=2 actions=drop" # 丟棄所有port 1上接收的廣播報文(此處網上給出的是dl_src,我怎么感覺是dl_dst?) ovs-ofctl add-flow ovsBusiness "priority=40001,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=drop" # 丟棄所有STP協議的廣播數據包 ovs-ofctl add-flow ovsBusiness "priority=40001,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=drop" # 修改從port 1上接收的數據包的源IP地址為"192.168.13.1",並從port 2口發送 ovs-ofctl add-flow ovsBusiness "priority=40001,in_port=1 actions=mod_nw_src:192.168.13.1,output:2" # 將所有port 1接收的ICMP報文發送到port 2上去 ovs-ofctl add-flow ovsBusiness "priority=40001,dl_type=0x0800,in_port=1,nw_proto=1 actions=output:2" # 將所有port 1接收的TCP目的端口為80的報文發送到port 2口 ovs-ofctl add-flow ovsBusiness "priority=4001,dl_type=0x0800,in_port=1,nw_proto=6,tp_dst=80 actions=output:2"
刪除流表
刪除全部流表
刪除全部流表的命令如下:
ovs-ofctl del-flows ovsBusiness
按匹配條件刪除流表
# 刪除"in_port=1"的流表 ovs-ofctl del-flows ovsBusiness "in_port=1" # 刪除匹配條件為"priority=40001"的流表 ovs-ofctl del-flows ovsBusiness "priority=40001" # 刪除匹配條件為"priority=4001,ip,in_port=1,nw_src=1.1.1.12"的流表 ovs-ofctl del-flows ovsBusiness "priority=4001,ip,in_port=1,nw_src=1.1.1.12" # 刪除匹配條件為"priority=4001,ip,in_port=1,nw_src=1.1.1.12 action=output:2"的流表 ovs-ofctl del-flows ovsBusiness "priority=4001,ip,in_port=1,nw_src=1.1.1.12 action=output:2"
查看流表
查看配置的所有流表信息
查看流表命令為:
ovs-ofctl dump-flows ovsBusiness
上述命令可以查看現在OVS橋上配置的流表
查看現在生效的流表信息
查看現在生效的流表命令:
# 查看默認的datapath類型的OVS橋的生效流表 ovs-appctl dpctl/dump-flows system@ovs-system # 查看datapath類型為netdev的OVS橋的生效流表 ovs-appctl dpctl/dump-flows netdev@ovs-netdev
上述兩條命令顯示結果中的in_port(port_num)和actions:port_num,port_num值可能與使用ovs-ofctl命令查看到的不一致,這是因為使用ovs-appctl命令顯示的端口號是所有datapath類型的橋下接口的編號,而ovs-ofctl命令下的端口號是此OVS橋下的端口號。 查看完整的datapath類型的接口編號命令為:
# 查看當前OVS中的datapath類型 ovs-appctl dpctl/dump-dps # 查看默認datapath類型的接口編號 ovs-appctl dpctl/show system@ovs-system # 查看datapath=netdev類型的接口編號 ovs-appctl dpctl/show netdev@ovs-netdev
查看當前網橋的所有流表
每個網橋默認情況下會配置有默認流表,查看所有的流表信息的命令為:
ovs-appctl bridge/dump-flows ovsBusiness
注意
在配置流表時,如果需要對數據包進行修改,則對數據包的修改動作應該在output動作之前完成,否則會不生效(因為數據包已經發送出去).
