参考: https://opengers.github.io/openstack/openstack-base-use-openvswitch/
这篇原理部分就不贴出来了,请自行参考上文,并根据自行实验总结,上文写的很深入,但仍有部分遗漏或或者说是作者认为不重要的东西吧,这些根据个人情况进行补充,内容重复太多,补充部分仅为自己理解,因此感觉还是交给认真的道友自行学习吧。
下面仅将自己总结的一些关于ovs-ofctl的更多详细用法做一点说明
ovs-ofctl
是专门管理配置OpenFlow交换机的命令行工具,我们可以用它手动配置OVS中的OpenFlow flows,注意其不能操作datapath flows和”hidden” flows。【更多详细匹配参数和Actions Set参数可参考后文.】
#查看br-tun中OpenFlow flows
ovs-ofctl dump-flows br-tun
#查看br-tun端口信息
ovs-ofctl show br-tun
#添加新的flow:对于从端口p0进入交换机的数据包,如果它不包含任何VLAN tag,则自动为它添加VLAN tag 101
ovs-ofctl add-flow br0 "priority=3,in_port=100,dl_vlan=0xffff,actions=mod_vlan_vid:101,normal"
#对于从端口3进入的数据包,若其vlan tag为100,去掉其vlan tag,并从端口1发出
ovs-ofctl add-flow br0 in_port=3,dl_vlan=101,actions=strip_vlan,output:1
#添加新的flow: 修改从端口p1收到的数据包的源地址为9.181.137.1,show 查看p1端口ID为100
ovs-ofctl add-flow br0 "priority=1 idle_timeout=0,in_port=100,actions=mod_nw_src:9.181.137.1,normal"
#添加新的flow: 重定向所有的ICMP数据包到端口 p2
ovs-ofctl add-flow br0 idle_timeout=0,dl_type=0x0800,nw_proto=1,actions=output:102
#删除编号为 100 的端口上的所有流表项
ovs-ofctl del-flows br0 "in_port=100"
ovs-ofctl 中规则参数和Actions Set参数说明:
#添加新的flow:对于从端口p0进入交换机的数据包,如果它不包含任何VLAN tag,则自动为它添加VLAN tag 101
ovs-ofctl add-flow br0 "priority=3,in_port=100,dl_vlan=0xffff,actions=mod_vlan_vid:101,normal"
匹配规则参数:
ip Same as dl_type=0x0800.
icmp Same as dl_type=0x0800,nw_proto=1.
tcp Same as dl_type=0x0800,nw_proto=6.
udp Same as dl_type=0x0800,nw_proto=17.
sctp Same as dl_type=0x0800,nw_proto=132.
arp Same as dl_type=0x0806.
rarp Same as dl_type=0x8035.
in_port=port
匹配OpenFlow端口,该端口可以是OpenFlow端口号或关键字(例如LOCAL)。
执行: ovs-ofctl show SWITCH-Name
# 1(tun0): addr:5e:6a:a2:db:09:a4 #1:就是端口号
(resubmit操作可以搜索带有任意in_port值的OpenFlow流表,因此从OpenFlow的角度来看,匹配端口号的流并不存在,但仍然可以进行匹配。)
dl_vlan=VLAN_Tag
匹配IEEE 802.1q虚拟LAN标签。若VLAN_Tag=0xffff: 则表示匹配所有没有VLAN标签的包;否则,指定一个介于0到4095之间的数字,如12位vlan ID匹配。
dl_vlan_pcp=priority
匹配IEEE 802.1q优先代码点(PCP:Priority Code Point)优先级,指定为0到7之间的值。更高的值表示更高的帧优先级。
dl_src=xx:xx:xx:xx:xx:xx
dl_dst=xx:xx:xx:xx:xx:xx
匹配一个以太网源(或目的地)地址,指定为6对十六进制数字。
dl_src=xx:xx:xx:xx:xx:xx/xx:xx:xx:xx:xx:xx
dl_dst=xx:xx:xx:xx:xx:xx/xx:xx:xx:xx:xx:xx
匹配一个以太网目的地地址,指定为6对十六进制数字。
OpenvSwitch 1.8,然后支持任意的掩模来提供源和/或目的地。早期版本只支持用以下面具掩盖目的地:
01: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匹配所有的unicast以太网包。
fe:ff:ff:ff:ff:ff
匹配所有的比特,除了多播比特。这可能是没有用的。
ff:ff:ff:ff:ff:ff
精确匹配(相当于省略掩模)。
00:00:00:00:00:00
通配符所有位(等价于dl_dst = *)。
arp_sha=xx:xx:xx:xx:xx:xx
arp_tha=xx:xx:xx:xx:xx:xx
当dl_type指定ARP或RARP时,arp_sha和arp_tha分别匹配源和目标硬件地址。地址指定为6对十六进制数字,用冒号分隔。
dl_type = ethertype
匹配以太网协议类型以太类型,它被指定为一个整数在0和65535之间,包括十进制,或者作为一个十六进制数字,按0x(如0x0806匹配ARP包)。
nw_src = ip[/ netmask]
nw_dst = ip[/ netmask]
若dl_type=0x0800(或ip/tcp),则nw_src和nw_dst可匹配源或目的IP。可支持Netmask或CIDR。
当dl_type = 0x0806或arp时,在IPv4和以太网的arp包中分别匹配ar_spa或ar_tpa字段。
当dl_type = 0x8035或rarp时,在IPv4和以太网的rp包中,将分别匹配ar_spa或ar_tpa字段
当dl_type设置为 通配符或设置为0x0800,0x0806或0x8035的值,nw_src和nw_dst的值被忽略(见前面的流语法)。【不明白】
nw_proto = proto
当ip或dl_type = 0x0800被指定时,匹配ip协议类型proto,它被指定为0到255之间的十进制,包括(例如,匹配ICMP数据包或6来匹配TCP数据包)。
当指定ipv6或dl_type = 0x86dd时,匹配ipv6标题proto,它被指定为0到255之间的十进制,包括(例如,与ICMPv6包匹配,或6个匹配TCP)。头类型是设计文档中描述的终端头。
当指定arp或dl_type = 0x0806时,与arp opcode的下8位相匹配。ARP码大于255被视为0。
当指定了rp或dl_type = 0x8035时,与ARP opcode的下8位相匹配。ARP码大于255被视为0。
当dl_type被通车或设置为一个大于0x0806、0x8035或0x86dd的值时,nw_proto的值就被忽略了(参见前面的流语法)。
nw_tos=tos
匹配IP ToS / DSCP或IPv6流量类字段,它被指定为0到255之间的十进制。注意,两个较低的保留位被忽略为匹配的目的。
当dl_type被通配或设置为0x0800 / 0x0x86dd的值时,nw_tos的值就被忽略了(参见上面的流语法)。
tp_src=port
tp_dst=port
当dl_type和nw_proto指定为TCP/UDP/SCTP时,tp_src和tp_dst将匹配UDP或TCP或SCTP源或目的端口,分别指定为0到65535的整数
当dl_type和nw_proto使用其他值时,这些设置的值被忽略(见上面的流语法)。
tp_src=port/mask
tp_dst=port/mask
例如:
tcp,tp_src=0x03e8/0xfff8 #mask:要使用十六进制表示,它们最终要转换为二进制做掩码匹配。
tcp,tp_src=0x03f0/0xfff0
icmp_type=type
icmp_code=code
table=number
如果指定,则将流操作和流转储命令限制为仅应用于给定数字在0到254之间的表。如果没有指定表,则行为会发生变化(相当于将255指定为数字)。对于没有 --strict的流表修改命令,交换机将选择这些命令要操作的表。对于带有 --strict的流表修改命令,该命令将对任何表中任何匹配的流进行操作;如果在多个表中有匹配项,则不会执行任何操作。转储流和转储聚合命令将从所有表收集关于流的统计信息。
tun_id=tunnel-id[/mask]
匹配隧道标识符ID。只有通过带有密钥的隧道到达的数据包(例如grewith RFC 2890 key extension and a nonzero key value)才具有非零的隧道ID。如果指定了掩码,则掩码中的1位表示隧道id中对应的位必须精确匹配,并且该位必须匹配0位通配符。
tun_src=ip[/netmask]
tun_dst=ip[/netmask]
匹配隧道IPv4源(或目标)地址ip。只有通过隧道到达的数据包才有非零的隧道地址。地址可以指定为IP地址或主机名(例如192.168.1.1或www.example.com)。可选的网掩码允许将匹配限制到屏蔽的IPv4地址。网络掩码可以指定为掩码(例如192.168.1.0/255.255.255.0)或一个CIDR块(例如192.168.1.0/24)。
Actions Set动作集参数:
add-flow、add-flows和mod-flows命令需要指定action= 用于设置动作集.
指定在流条目匹配时,对数据包采取的操作,它们之间用逗号分隔。如果没有指定目标,则删除与流匹配的包。目标可以是一个OpenFlow端口号,指定输出数据包的物理端口,或者以下关键字之一:
output:port
将数据包输出到端口,端口必须是OpenFlow端口号或关键字(例如LOCAL)。
output:src[start..end]
将数据包输出到从src读取的OpenFlow端口号,该端口号必须是如上所述的NXM字段。例如,输出:NXM_NX_REG0 [16..31]输出到寄存器0上半部分写入的OpenFlow端口号。这种形式的输出使用标准OpenFlow开关不支持的OpenFlow扩展。
enqueue:port:queue
在端口内的指定队列上对数据包进行排队,该队列必须是OpenFlow端口号或关键字(例如LOCAL)。受支持队列的数量取决于交换机;一些OpenFlow实现根本不支持排队。
normal
使数据包服从设备正常的L2/L3处理。(并非所有OpenFlow开关都实现此操作。)
flood
将数据包输出到所有交换机物理端口上,但不包括接收它的端口和禁用泛洪的端口(通常,这些端口是IEEE 802.1生成树协议禁用的端口)。
all
在接收数据包的端口之外的所有交换机物理端口上输出数据包。
controller(key=value...)
当发生“package in”事件时,向控制器发送指定消息
max_len = Bytes 设置发送的最大字节数
reason= Reason 设置发送消息的原因关键字,默认:action, no_match和invalid_ttl
id= Controller-ID 设置将'package in'事件消息发送给指定ID的控制器,ID:16位整数.
默认:0, 0:也是每个控制器连接的默认ID.
local
在“本地端口”上输出数据包,“本地端口”对应于与网桥名称相同的网络设备。
in_port
在接收数据包的端口上输出数据包。
drop
丢弃数据包,若指定它,则不能在指定其它动作.
mod_vlan_vid:vlan_vid
修改包上的VLAN id。根据需要添加或修改VLAN标记,以匹配指定的值。如果添加了VLAN标记,则使用零优先级.
mod_vlan_pcp:vlan_pcp
修改数据包上的VLAN优先级。根据需要添加或修改VLAN标记,以匹配指定的值。有效值介于0(最低)和7(最高)之间。如果添加了VLAN标记,则使用0的vid(请参阅设置此值的mod_vlan_vid操作)。
strip_vlan
若数据包中包含VLAN 标签则删除
push vlan:ethertype
将一个新的VLAN标签推到包上。Ethertype用作标记的Ethertype。应该只使用ethertype 0x8100。(规范允许的0x88a8目前不受支持)新标记使用的优先级为零,标记为零。
mod_dl_src:mac
修改源MAC为指定MAC
mod_dl_dst:mac
修改目标MAC为指定MAC
mod_nw_src:ip
修改源IPv4地址为指定ip。
mod_nw_dst:ip
修改目标IPv4地址为指定ip。
mod_tp_src:port
修改TCP或UDP或SCTP源端口为指定端口。
mod_tp_dst:port
修改TCP或UDP或SCTP目标端口为指定端口。
mod_nw_tos:tos
将IPv4 ToS/DSCP字段设置为ToS,该字段必须是0到255之间4的倍数。此操作不修改ToS字段的两个最不重要的位(ECN位)。
priority
通配符项与其他项相匹配的优先级。值是一个介于0和65535之间的数字,包括0和65535。较高的值将在较低的值之前匹配。与包含通配符的条目相比,精确匹配条目始终具有优先级,因此它的优先级值为65535。添加流时,如果没有指定字段,则流的优先级默认为32768。
当具有相同优先级的两个或多个流可以匹配一个包时,OpenFlow将不定义行为。一些用户期望“合理”的行为,比如更特定的流优先于更不特定的流,但是OpenFlow没有指定这一点,Open vSwitch也没有实现这一点。因此,用户应该注意使用优先级来确保他们期望的行为。