OpenFlow 流表组成
流规则组成:每条流规则由一系列字段组成,分为基本字段、条件字段和动作字段三部分
一:基本字段
基本字段包括生效时间duration_sec、所属表项table_id、优先级priority、处理的数据包数n_packets,空闲超时时间idle_timeout等,空闲超时时间idle_timeout以秒为单位,超过设置的空闲超时时间后该流规则将被自动删除,空闲超时时间设置为0表示该流规则永不过期,idle_timeout将不包含于ovs-ofctl dump-flows brname的输出中。
cookie=value 流表标识字段:
cookie字段有两种书写方式:cookie=value和cookie=value/mask。mask中对应位为1时cookie中值相应的位须严格匹配,为0时cookie中值对应的位通配,当mask为-1时,必须严格匹配cookie值。
duration=value:
流表生效时间,标识流表从下发到现在所持续的时间
table=tableid:
流表所属表项,标识流表所属的表,默认为0
priority=priority:
标识流表的优先级,范围为0-65535,值越大,优先级越高
n_packets:
标识流表匹配包数
n_bytes:
标识流表匹配字节数
idle_timeout=sec:
流表空闲超时时间,流表会在空闲时间达到给定的时间时被删除。设置为0(默认值)时,流表不会因空闲时间被删除。
hard_timeout=sec:
流表可存在的时间。设置此值后,流表会在到达给定时间后被删除。
idle_age=sec:
流表空闲时间
hard_age=sec:
流表存在时间。此字段与duration字段的区别在当流表被修改后,会重新设置hard_timer但是不会重置duration
二:条件字段
条件字段包括输入端口号in_port、源目的mac地址dl_src/dl_dst、源目的ip地址nw_src/nw_dst、数据包类型dl_type、网络层协议类型nw_proto等,可以为这些字段的任意组合,但在网络分层结构中底层的字段未给出确定值时上层的字段不允许给确定值,即一条流规则中允许底层协议字段指定为确定值,高层协议字段指定为通配符(不指定即为匹配任何值),而不允许高层协议字段指定为确定值,而底层协议字段却为通配符(不指定即为匹配任何值),否则,ovs-vswitchd 中的流规则将全部丢失,网络无法连接。
in_port=port
标识匹配接收数据包的端口号
dl_vlan_pcp=priority
匹配IEEE 802.1q优先码点(PCP)优先级,该优先级指定为0到7之间的值,包括0和7。更高的值表示更高的帧优先级。
dl_type=ethertype
匹配以太网协议类型ethertype,该类型指定为0到65535之间的整数
匹配数据包的二层协议类型,IP数据包为0x0800,IPv6数据包为0x86dd,ARP数据包为0x0806
dl_src=xx:xx:xx:xx:xx:xx
dl_dst=xx:xx:xx:xx:xx:xx
匹配指定的链路层源或者目的MAC地址
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
匹配指定的链路层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)数据包
vlan_tci=tci[/mask]
匹配修改后的VLAN TCI TCI。如果省略掩码,则tci就是要匹配的VLAN tci;如果指定了掩码,那么掩码中的1位表示tci中的对应位必须完全匹配,0位的通配符表示该位。
nw_proto=proto
匹配数据包协议类型。当dl_type=0x0800时,匹配IP协议族的协议,例如tcp,udp,icmp等
当指定ip或dl_type=0x0800时,匹配ip协议类型proto, proto指定为0到255之间的十进制数(例如1匹配ICMP包或6匹配TCP包)。
当指定ipv6或dl_type=0x86dd时,匹配ipv6报头类型proto,它被指定为0到255之间的十进制数(例如58匹配ICMPv6包或6匹配TCP)。
当指定arp或dl_type=0x0806时,匹配arp操作码的较低8位。
当指定rarp或dl_type=0x8035时,匹配ARP操作码的较低8位。
nw_tos=tos
匹配IP Tos/DSCP或者IPv6的tos字段,值为0-255
nw_ecn=ecn
匹配IP ToS或IPv6流量类字段中的ecn位,该字段指定为0到3之间的十进制数(包括3)。
nw_ttl=ttl
匹配IP TTL或IPv6跳限值TTL, TTL指定为0到255之间的小数,包括在内。
tp_src=port
tp_dst=port
若指定了udp或者tcp协议,则匹配udp/tcp的端口号
icmp_type=type
icmp_code=code
若指定了icmp或者icmpv6协议,则匹配对应的icmp 类型或者code字段
table=number
如果指定,则限制流操作和流转储命令仅应用于给定数字在0到254之间的表。
ip_frag=frag_type:
当dl_type指定为IP或者IPv6,frag_type指定匹配的IP分片包或者非分片包的匹配 frag_type支持的值为:
no: 仅匹配非分片报文
yes:匹配所有分片报文
first:仅匹配offset为0的分片报文
later:仅匹配offset非0的分片报文
not_later:匹配非分片报文和offset为0的分片报文
arp_sha=xx:xx:xx:xx:xx:xx
arp_tha=xx:xx:xx:xx:xx:xx
当设置dl_type为ARP或者RARP,则arp_sha和arp_tha匹配数据包的源、目的MAC地址
tun_id=tunnel-id[/mask]
匹配隧道标识符--隧道id。只有通过带有密钥的隧道到达的数据包(例如带有RFC 2890密钥扩展名和非零密钥值的GRE)才具有非零的隧道ID。
三:动作字段
动作字段包括正常转发normal、定向到某交换机端口output:port、丢弃drop、更改源目的mac地址mod_dl_src/mod_dl_dst等,一条流规则可有多个动作,动作执行按指定的先后顺序依次完成。
output:port
将数据包从port接口发送
output:src[start..end]
将包输出到从src读取的OpenFlow端口号,该src是NXM字段所包含数据。例如:output:NXM_NX_REG0[16..31],表示输出端口号是从NXM_NX_REG0寄存器的16-31为中读取的数据
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:指明控制器ID
in_port
将数据包从接收的接口发送出去
drop
丢弃数据包
mod_vlan_vid:vlan_vid
修改数据包的vlan id
mod_vlan_pcp:vlan_pcp
vlan_pcp 修改数据包的vlan priority
strip_vlan
如果数据包中存在vlan tag,则剥离vlan tag
push_vlan:ethertype
为数据包添加新的vlan tag
push_mpls:ethertype
如果包还没有包含任何MPLS标签,则将包的Ethertype更改为Ethertype,它必须是MPLS单播Ethertype 0x8847或MPLS多播Ethertype 0x8848,然后推送一个初始标签堆栈条目。
pop_mpls:ethertype
去掉最外层的MPLS标签堆栈条目
mod_dl_src:mac
设置数据包的源MAC地址
mod_dl_dst:mac
设置数据包的目的MAC地址
mod_nw_src:ip
设置数据包的源IP地址
mod_nw_dst:ip
设置数据包的目的IP地址
mod_tp_src:port
设置TCP或者UDP的源端口
mod_tp_dst:port
设置TCP或UDP的目的端口
mod_nw_tos:tos
将IPv4 ToS/DSCP字段设置为ToS,该字段必须是0到255之间的4的倍数。
resubmit([port],[table])
第一个参数:使用端口替换in_port字段(如果指定了端口),重第二个参数:重新指定流表,搜索这个OpenFlow流表(或表指定其编号的表)
set_tunnel:id
set_tunnel64:id
如果输出到将包封装在隧道中并支持标识符(如GRE)的端口,则将标识符设置为id。
set_queue:queue
设置输出包时应用于排队的队列。
pop_queue
将队列恢复到应用任何set_queue操作之前的值。
dec_ttl
dec_ttl[(id1,id2)]
减少IPv4包或跳限制的IPv6包的TTL。
set_mpls_ttl:ttl
设置包的外部MPLS标签堆栈条目的TTL。ttl应该在0到255之间(包括255)。
dec_mpls_ttl
外部MPLS标签栈的TTL递减
move:src[start..end]−>dst[start..end]
将指定的位从字段src复制到字段dst。src和dst必须是nicira−ext.h中定义的NXM字段名,例如NXM_OF_UDP_SRC 或者 NXM_NX_REG0.
例如:
move:NXM_NX_REG0 [0 . . 5]−> NXM_NX_REG1 [26 . .31]将寄存器0中编号为0到5(含5)的6位拷贝到寄存器26到31(含31)中; move:NXM_NX_REG0 [0 . .15]−>NXM_OF_VLAN_TCI[]将寄存器0中最不重要的16位复制到VLAN TCI字段中。
load:value−>dst[start..end]
写值value到dst指定位置(从start位到end位),例如:load:55−>NXM_NX_REG2[0..5] 就是将55写入NAX_NX_REG2[0..5],数据存放位数为6位,110111
push:src[start..end]
从开始到结束的比特包括在内,均存放在栈顶的字段中。 例如:push:NXM_NX_REG2 [0 . .5]将存储在寄存器2中从0到5(含5位)中的值推送到内部堆栈。
pop:dst[start..end]
从堆栈顶部弹出,从弹出的值中检索包含开始到结束的位,并将它们存储到dst中相应的位。 例如:pop:NXM_NX_REG2 [0 . .5]从堆栈顶部弹出值。设置寄存器2从0到5,将栈顶数据存放到该寄存器0-5。
set_field:value−>dst
将文字值写入dst字段,该字段应指定为用于匹配的名称。 例如: set_field:fe80:0123:4567:890a:a6ba:dbff:fefe:59fa−>ipv6_src
learn(argument[,argument]…)
此操作在OpenFlow表中添加或修改一个流,类似于ovs−ofctl−strict mod−flow。参数指定流的匹配字段、操作和其他属性,如下所示: idle_timeout=seconds hard_timeout=seconds priority=value 这些键值对的含义与通常的ovs - ofctl流语法中的含义相同 fin_idle_timeout=seconds fin_hard_timeout=seconds 将带有指定参数的fin_timeout操作添加到新流。 table=number 应该插入新流的表。指定一个0到254之间的小数。如果表未指定,则默认为表1 field=value field[start..end]=src[start..end] field[start..end] 向新流添加匹配条件 load:value−>dst[start..end] load:src[start..end]−>dst[start..end] 向新流添加加载操作。 output:field[start..end] 将输出操作添加到新流的操作中,该操作将输出到从字段[start..]获取的OpenFlow端口。end],它必须是上面描述的NXM字段