openvswitch 流表操作
流表组成
每条流表规则由一些列字段组成,可以分为**基础字段
、匹配字段
和动作字段
**三部分。 在打印流表时,在流表中还存在一些显示字段,如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
但是不会重置duration
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的分片报文
匹配字段
in_port=port
标识匹配接收数据包的端口号dl_type=ethertype
匹配数据包的二层协议类型,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)数据包nw_proto=proto
匹配数据包协议类型。当dl_type=0x0800
时,匹配IP协议族的协议,例如tcp
,udp
,icmp
等nw_tos=tos
匹配IP Tos/DSCP
或者IPv6的tos
字段,值为0-255
nw_ecn=ecn
匹配IP或者IPv6的ecn
字段,值为0~3
nw_ttl=ttl
匹配TTL值tp_src=port
tp_dst=port
若指定了udp
或者tcp
协议,则匹配udp/tcp的端口号icmp_type=type
icmp_code=code
若指定了icmp
或者icmpv6
协议,则匹配对应的icmp 类型或者code字段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地址
动作字段
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
动作之前完成,否则会不生效(因为数据包已经发送出去).
openvswitch 流表操作的更多相关文章
- openvswitch 流表测试 ovs-appctl
[root@ostack170 ~]# ovs-appctl ofproto/trace br-mirror in_port=,dl_vlan=,dl_src=:ea:cb:5d:e4:ee,dl_d ...
- Open vSwitch流表应用实战
本文参考:Open vSwitch流表应用实战 一个通过改变流表下发而实现的互相通信实验. 实验目的: 掌握Open vSwitch下发流表操作: 掌握添加.删除流表命令以及设备通信的原理. 原理:. ...
- FAST:通过Floodlight控制器下发流表
参考: Floodlight+Mininet搭建OpenFlow(四):流表操作 通过Floodlight控制器下发流表 下发流表的方式有两种: 1.借助Floodlight的北向API,利用curl ...
- Floodlight下发流表过程分析
https://blog.csdn.net/vonzhoufz/article/details/32166445 当一个packet到达openflow交换机,会进行流表的匹配,如果没有找到相应的流表 ...
- Openvswitch原理与代码分析(5): 内核中的流表flow table操作
当一个数据包到达网卡的时候,首先要经过内核Openvswitch.ko,流表Flow Table在内核中有一份,通过key查找内核中的flow table,即可以得到action,然后执行acti ...
- Openvswitch原理与代码分析(6):用户态流表flow table的操作
当内核无法查找到流表项的时候,则会通过upcall来调用用户态ovs-vswtichd中的flow table. 会调用ofproto-dpif-upcall.c中的udpif_upcall_hand ...
- openVswitch(OVS)源代码分析之工作流程(flow流表查询)
原文链接: openVswitch(OVS)源代码分析之工作流程(flow流表查询)
- openvswitch datapath 内核态流表创建过程(ovs_flow_cmd_new)
datapath流表更新的入口函数都定义在dp_flow_genl_ops中,流表创建的入口函数是ovs_flow_cmd_new函数,通过该函数,我们可以一窥流表相关信息的建立. 1.ovs_flo ...
- Neutron 理解 (4): Neutron OVS OpenFlow 流表 和 L2 Population [Netruon OVS OpenFlow tables + L2 Population]
学习 Neutron 系列文章: (1)Neutron 所实现的虚拟化网络 (2)Neutron OpenvSwitch + VLAN 虚拟网络 (3)Neutron OpenvSwitch + GR ...
随机推荐
- .NET Core 微服务—API网关(Ocelot) 教程 [二]
上篇文章(.NET Core 微服务—API网关(Ocelot) 教程 [一])介绍了Ocelot 的相关介绍. 接下来就一起来看如何使用,让它运行起来. 环境准备 为了验证Ocelot 网关效果,我 ...
- statsmodels 示例
Statsmodels 示例 https://www.statsmodels.org/stable/examples/index.html
- PHP strptime() 函数
------------恢复内容开始------------ 实例 解析由 strftime() 生成的时间/日期: <?php$format="%d/%m/%Y %H:%M:%S&q ...
- PHP xml_set_unparsed_entity_decl_handler() 函数
定义和用法 xml_set_unparsed_entity_decl_handler() 函数规定当解析器在 XML 文档中找到无法解析的实体时被调用的函数. 如果成功,该函数则返回 TRUE.如果失 ...
- CF613D Kingdom and its Cities 虚树 树形dp 贪心
LINK:Kingdom and its Cities 发现是一个树上关键点问题 所以考虑虚树刚好也有标志\(\sum k\leq 100000\)即关键点总数的限制. 首先当k==1时 答案显然为0 ...
- 【Canal】互联网背景下有哪些数据同步需求和解决方案?看完我知道了!!
写在前面 在当今互联网行业,尤其是现在分布式.微服务开发环境下,为了提高搜索效率,以及搜索的精准度,会大量使用Redis.Memcached等NoSQL数据库,也会使用大量的Solr.Elastics ...
- 学习java 线程池-1: ThreadPoolExecutor
1. Executor 该接口内只有一个接口方法 :该方法的目的就是执行指定的 Runnable (但会不会执行,或者会不会立马执行,则不一定.因为要取决于整个线程池的状态) Executor 中文的 ...
- MySql大表分页(附独门秘技)
问题背景 MySql(InnoDB)中的订单表需要按时间顺序分页查询,且主键不是时间维度递增,订单表在百万以上规模,此时如何高效地实现该需求? 注:本文并非主要讲解如何建立索引,以下的分析均建立在有合 ...
- 实验02——java两个数交换的三种解决方案
package cn.tedu.demo;/** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @version 1.0* @创建时间:2020年7月16 ...
- Elasticsearch从入门到放弃:瞎说Mapping
前面我们聊了 Elasticsearch 的索引.搜索和分词器,今天再来聊另一个基础内容-- Mapping. Mapping 在 Elasticsearch 中的地位相当于关系型数据库中的 sche ...