0x00 目录
- 0x00 目录
- 0x01 流表项操作与Flow_Mod消息
- 0x02 流表项删除DELETE与DELETE_STRICT区别
- 0x03 POX + Mininet实验验证
- 0x04 总结
- 0x05 参考
0x01 流表项操作与Flow_Mod消息
在OpenFlow中,对流表项的操作,例如增加、修改、删除流表项,都是通过控制器下发Flow_Mod消息完成的。Flow_Mod消息的格式如图所示,其中command字段定义了对流表项的操作(增加、修改、删除),而对于修改和删除操作又分为NON_STRICT和STRICT两个版本。
0x02 流表项删除DELETE与DELETE_STRICT区别
要想删除流表项,只需要构造command = DELETE或command = DELETE_STRICT的Flow_Mod消息即可,两者的区别如下:
- DELETE:根据匹配域,删除所有匹配的流表项,意味着可能有多条流表项被删除
- DELETE_STRICT:根据匹配域以及优先级,删除特定的流表项,只有一条流表项被删除
例子:假设使用openflow1.0,且openflow交换机流表中只有以下两条流表项
flow entry1:
{
prioirity : 42
match :
{
dl_type : 0x0800
ip_src : 10.0.0.1
ip_dst : 10.0.0.2
}
actions : output : 'sw1-eth2'
}
flow entry2:
{
prioirity : 42
match :
{
dl_type : 0x0800
ip_src : 10.0.0.1
ip_dst : 10.0.0.2
ip_protocol : 6
tp_dst : 80
}
actions : output : 'sw1-eth2'
}
若控制器下发command = DELETE的Flow_Mod消息
flow_mod msg: { command : DELETE prioirity : 42 match : { dl_type : 0x0800 ip_src : 10.0.0.1 ip_dst : 10.0.0.2 } actions : output : 'sw1-eth2' }
那么openflow交换机将会根据Flow_Mod消息中的匹配域(match)去流表中查找所有匹配的流表项(若流表项中的匹配域描述比Flow_Mod消息中的匹配域更详细,也算查找成功),这里flow entry1和flow entry2都满足,因为它们都含有
match : { dl_type : 0x0800 ip_src : 10.0.0.1 ip_dst : 10.0.0.2 }
因此,两条流表项都会被删除
若控制器下发command = DELETE_STRICT的Flow_Mod消息
flow_mod msg:
{
command : DELETE_STRICT
prioirity : 42
match :
{
dl_type : 0x0800
ip_src : 10.0.0.1
ip_dst : 10.0.0.2
}
actions : output : 'sw1-eth2'
}
openflow交换机会根据Flow_Mod消息中的匹配域(match)和优先级(prioirity)去流表中查找特定的流表项,这里只有flow entry1满足条件,因为flow entry2的匹配域多了两个字段
ip_protocol : 6
tp_dst : 80
因此只有flow entry1被删除
0x03 POX + Mininet实验验证
按照0x02中提到的例子,使用POX和Mininet进行验证
实验环境
- OpenFlow 1.0 : SDN控制器与openflow交换机之间通信的协议
- POX-eel : python实现的SDN控制器,用于构造Flow_Mod消息,并下发至openflow交换机
- Mininet 2.3.0d1 : 创建" h1 -- sw1 -- h2 "拓扑
- POX与Mininet均部署在同一台运行ubuntu 18.04 LTS的机器上
实验步骤
1.启动POX
打开终端,输入
home/ctz/pox-eel/pox.py openflow.of_01 --address=127.0.0.1 --port=6653 py
- home/ctz/pox-eel/pox.py : POX程序的入口
- openflow.of_01 : POX的组件,使用openflow1.0进行通信
- address : openflow.of_01的参数,定义POX控制器的IP地址,这里定义为本地回环
- port : openflow.of_01的参数,定义POX控制器的监听端口,用于监听openflow交换机发来的消息
- py:使用POX交互模式,可在终端与POX控制器进行交互,例如构造Flow_Mod消息并发送给交换机
2.运行Mininet
另开一终端,输入
sudo mn --controller=remote,ip=127.0.0.1,port=6653 --mac
- controller=remote : mininet连接远程控制器
- ip : controller的参数,定义要连接的远程控制器IP地址
- port : controller的参数,定义要连接的远程控制器端口
- --mac : 从00:00:00:00:00:01开始,按递增序为主机设置MAC地址
3.添加两条流表项
在运行POX的终端上,构造两条Flow_Mod消息,用于添加两条流表项到交换机
# 以下三条命令在POX控制器同openflow交换机连接上后只需要输入一次
import pox.openflow.libopenflow_01 as of
from pox.lib.addresses import IPAddr
core.openflow.connections.keys() # 获取连接的交换机dpid,会在终端上显示dpid
# 下发一条流表项(h1 -> h2 基于源目IP)
msg = of.ofp_flow_mod()
msg.priority = 42
msg.command = of.OFPFC_ADD
msg.match.dl_type = 0x800
msg.match.nw_src = IPAddr("10.0.0.1")
msg.match.nw_dst = IPAddr("10.0.0.2")
msg.actions.append(of.ofp_action_output(port = 2))
core.openflow.connections[1].send(msg) # 1为交换机的dpid
# 下发一条流表项(h1 -> h2 基于源目IP和TCP目的端口号)
msg = of.ofp_flow_mod()
msg.priority = 42
msg.command = of.OFPFC_ADD
msg.match.dl_type = 0x800
msg.match.nw_src = IPAddr("10.0.0.1")
msg.match.nw_dst = IPAddr("10.0.0.2")
msg.match.nw_proto = 6
msg.match.tp_dst = 80
msg.actions.append(of.ofp_action_output(port = 2))
core.openflow.connections[1].send(msg) # 1为交换机的dpid
在运行Mininet的终端中输入
dpctl dump-flows
显示交换机中流表信息
4.DELETE删除流表项
在运行POX的终端上,构造一条command = DELETE的Flow_Mod消息,删除所有匹配的流表项
# 删除所有匹配流表项(h1 -> h2 基于源目IP)
msg = of.ofp_flow_mod()
msg.priority = 42
msg.command = of.OFPFC_DELETE
msg.match.dl_type = 0x800
msg.match.nw_src = IPAddr("10.0.0.1")
msg.match.nw_dst = IPAddr("10.0.0.2")
msg.actions.append(of.ofp_action_output(port = 2))
core.openflow.connections[1].send(msg) # 1为交换机的dpid
如下图所示,交换机根据Flow_Mod消息的match字段查找流表项,所有流表项均被删除
5.添加两条流表项
按照步骤3,重新添加两条流表项
6.DELETE_STRICT删除流表项
在运行POX的终端上,构造一条command = DELETE_STRICT的Flow_Mod消息,删除指定流表项
# 删除所有匹配流表项(h1 -> h2 基于源目IP)
msg = of.ofp_flow_mod()
msg.priority = 42
msg.command = of.OFPFC_DELETE_STRICT
msg.match.dl_type = 0x800
msg.match.nw_src = IPAddr("10.0.0.1")
msg.match.nw_dst = IPAddr("10.0.0.2")
msg.actions.append(of.ofp_action_output(port = 2))
core.openflow.connections[1].send(msg) # 1为交换机的dpid
如下图所示,交换机根据Flow_Mod消息的match字段和priority字段查找流表项,匹配域中含有端口号的流表项被保留,匹配域中不含端口号的流表项被删除
0x04 总结
使用Flow_Mod删除流表项时,command =
DELETE:删除所有匹配的流表项,只要流表项中Match字段描述 >= Flow_Mod消息中的Match字段(如流表项中Match:{in_port:1,ip_src:10.0.0.1},Flow_Mod消息中Match:{in_port:1}),则相关流表项均会被删除,因此被删除的流表项可能有多个
DELETE_STRICT:删除特定的流表项,只有同时满足Flow_Mod消息中匹配域以及优先级的流表项会被删除,被删除的流表项只有一个
0x05 参考
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!