接触了SDN网络有一段时间了,还有做几个小实验不断失败、不断产生问题的过程,让我对SDN有了自己的认识,对SDN架构有了理解,之前一直误认为SDN就是下一代互联网的解决技术,现在看来,这种理解大错特错,SDN其实提供的是一种思想,一种能够使网络更加灵活、更加便捷的思想。还有以前之前理解的SDN太狭义了,认为SDN网络中设备必须将转发层面和控制层面进行物理分离,接触了许多文档中提到了许多新的思维,将转发层面和控制层面进行逻辑分离也是可以的,这就要求我以后再研究SDN思想的时候要时刻考虑下与传统网络的区别以及更好的融合,毕竟我觉得现在完全抛弃传统的设备,这无疑是一种浪费。
在SDN网络中,OpenFlow协议仅仅是南向接口的一种协议之一,但不是唯一的,但不得不承认该技术目前还是比较完善以及不断发展的。SDN控制器对网络的控制主要是通过南向接口协议实现,包括链路发现、拓扑管理、策略制定、表项下发等,其中链路发现和拓扑管理主要是控制其利用南向接口的上行通道对底层交换设备上报信息进行统一监控和统计;而策略制定和表项下发则是控制器利用南向接口的下行通道对网络设备进行统一控制。
但是我们很少讨论SDN网络的上层的用户体验,即用户自定义的APP,也就是SDN北向接口,它是通过控制器向上层业务应用开放的接口,其目标是使得业务应用能够便利地调用底层的网络资源和能力。通过北向接口,网络业务的开发者能以软件编程的形式调用各种网络资源;同时上层的网络资源管理系统可以通过控制器的北向接口全局把控整个网网络的资源状态,并对资源进行统一调度。因为北向接口是直接为业务应用服务的,因此其设计需要密切联系业务应用需求,具有多样化的特征。同时,北向接口的设计是否合理、便捷,以便能被业务应用广泛调用,会直接影响到SDN控制器厂商的市场前景。
接下来就是主要研究OpenFlow协议的工作原理。
OpenFlow协议现在已经发展到了1.3了,但是基于OpenFlow1.0协议发展过来的,所以先掌握OpenFlow1.0协议,再了解作了哪些改进就可以了。
可以看出:一台OpenFlow交换机需要包括OpenFlow协议、安全通道(Secure Channel)以及流表(Flow Table)。
流表包括包头域(header fileds,匹配包头多个域)、活动计数器(counters)、0 个或多个执行行动(actions)。对每一个包进行查找,如果匹配则执行相关策略,否则通过安全通道将包转发到控制器,控制器来决策相关行为。流表项可以将包转发一个或者多个接口。
计数器可以针对每张表、每个流、每个端口、每个队列来维护。用来统计流量的一些信息,例如活动表项、查找次数、发送包数等。
Openflow1.0提供两种数据包的处理方法:
• 转发(Forward)
• 修改包头(Modify field)
其中修改包头包括:
SET_VLAN_VID //修改VLAN标签
SET_VLAN_PCP //修改VLAN优先级
STRIP_VLAN //弹出VLAN标签
SET_DL_SRC //修改源MAC地址
SET_DL_DST // 修改目的MAC地址
SET_NW_SRC // 修改源IP地址
SET_NW_DST // 修改目的IP地址
SET_NW_TOS //修改IP服务类型字段
SET_TP_SRC //修改源端口号
SET_TP_DST // 修改目的端口号
以上每一种操作称为一个动作(Action),流表中的数据包处理方法是一个动作列表(Action List),动作列表由以上各种动作组合合成。
在Actions头,包括Type和len字段:(数据结构如下)
其中type的数据结构如下:
除了OFPAT_OUTPUT和OFPAT_ENQUEUE为转发操作,其他类型为修改包头操作。
Action——OUTPUT类型:
由output类型的数据结构可以看出Port选项:
ALL:将数据包从除入端口以外其他所有端口发出
CONTROLLER:将数据包发送给控制器
LOCAL:将数据包发送给交换机本地端口
TABLE:将数据包按照流表匹配条目处理
IN_PORT:将数据包从入端口发出
NORMAL:按照普通二层交换机流程处理数据包
FLOOD:将数据包从最小生成树使能端口转发(不包括入端口)
其中当port为CONTROLLER时,max_len指定了发给CONTROLLER的数据包最大长度。当port为其他参数时,max_len无意义。
这时问题产生了:在SDN网络中控制器如何写流表?
1、Controller‐to‐Switch
控制器至交换机消息此类消息由控制器主动发出
Features 用来获取交换机特性
Configuration 用来配置Openflow交换机
Modify‐State 用来修改交换机状态(修改流表)
Read‐Stats 用来读取交换机状态
Send‐Packet 用来发送数据包
Barrier 阻塞消息
2、Asynchronous
异步消息此类消息由交换机主动发出
Packet‐in 用来告知控制器交换机接收到数据包
Flow‐Removed 用来告知控制器交换机流表被删除
Port‐Status 用来告知控制器交换机端口状态更新
Error 用来告知控制器交换机发生错误
3、Symmetric
对称消息,可以由控制器或交换机主动发起
Hello 用来建立Openflow连接
Echo 用来确认交换机与控制器之间的连接状态
Vendor 厂商自定义消息
控制器与交换机互相发送Hello消息,Hello消息中只包含OpenFlow Header中的version字段为发送方所支持的最高版本OpenFlow协议。双方选取Hello消息中最低版本的协议作为通信协议,如果有一方不支持OpenFlow协议版本,应发送Error消息后断开连接,如果双方OpenFlow版本可以兼容,则OpenFlow连接建立成功。
这时问题也来了:OpenFlow连接建立后,控制器最关心的事情是什么?
OpenFlow连接建立后,控制器最需要获得交换机的特性信息,交换机的特性信息包括交换机的ID(DPID),交换机缓冲区数量,交换机端口及端口属性等等。控制器向交换机发送Features Request消息查询交换机特性,Features Request消息只包OpenFlow Header。交换机在收到Features Request消息后返回Features Reply消息, Features Reply消息包括Openflow Header 和Features Reply Message。
Features Reply Message结构:
datapath_id为交换机独一无二的ID号
n_buffers为交换机可以同时缓存的最大数据包个数
n_tables为交换机的流表数量
Capabilities表示交换机支持的特殊功能
Actions表示交换机支持的动作(见ofp_action_type)
ofp_phy_ports为交换机的物理端口描述列表
物理端口描述:
port_no为物理端口的编号
hw_addr为端口的MAC地址
name为端口的名称
config为端口的配置
State为端口状态
curr, advertised supported,peer为端口物理属性
配置交换机Openflow属性:
Openflow交换机只有两个属性需要控制器配置:
第一个属性为flags,用来指示交换机如何处理IP分片数据包;
第二个属性为miss_send_len,用来指示当一个交换机无法处理的数据包到达时,将数据包的发给控制器的最大字节数。
Packet‐in事件(交换机接收数据包)
Packet‐in消息触发情况1:
当交换机收到一个数据包后,会查找流表,找出与数据包包头相匹配的条目。如果流表中有匹配条目,则交换机按照流表所指示的action列表处理数据包。如果流表中没有匹配条目,则交换机会将数据包封装在Packet‐in消息中发送给控制器处理。此时数据包会被缓存在交换机中等待处理。
Packet‐in消息触发情况2:
交换机流表所指示的action列表中包含转发给控制器的动作(Output=CONTROLLER)。此时数据包不会被缓存在交换机中。
Packet‐in消息格式:
buffer_id为packet‐in事件所携带的数据包在交换机中的缓存区ID
total_len为data段的长度
in_port数据包进入交换机的入接口号
Reason为packet‐in事件产生的原因
控制器配置流表(Flow‐Mod消息)
Flow‐Mod消息用来添加、删除、修改Openflow交换机的流表信息
Flow‐Mod消息共有五种类型:
ADD、DELETE、DELETE‐STRICT、MODIFY、MODIFY‐STRICT
用Flow‐Mod消息响应Packet‐in消息
- ADD类型的flow‐mod消息用来添加一条新的流表项
- DELETE类型的flow‐mod消息用来删除所有符合一定条件的流表项
- DELETE‐STRICT类型的flow‐mod消息用来删除某一条指定的流表项
- MODIFY类型的flow‐mod消息用来修改所有符合一定条件的流表项
- MODIFY‐STRICT类型的flow‐mod消息用来修改某一条指定的流表项
当交换机收到一个数据包并且交换机中没有与该数据包匹配的流表项时,交换机将此数据包封装到Packet‐in消息中发送给控制器,并且交换机会将该数据包缓存。
控制器收到Packet‐in消息后,可以发送flow‐mod消向交换机写一个流表项。并且将flow‐mod消息中的buffer_id字段设置为packet‐in消息中的buffer_id值。从而控制器向交换机写入了一条与数据包相关的流表项,并且指定该数据包按照此流表项的aciton列表处理。
交换机转发数据包(Packet‐Out)
并不是所有的数据包都需要向交换机中添加一条流表项来匹配处理,网络中还存在多种数据包,它出现的数量很少(如ARP、IGMP等),以至于没有必要通过流表项来指定这一类数据包的处理方法。此时,控制器可以使用PacketOut消息,告诉交换机某一个数据包如何处理。
通过对OpenFlow1.0协议的学习,对OpenFlow协议有了更深的掌握,更加理解了控制器与交换机之间数据通信的过程,在分析了OpenFlow数据结构后,对其功能的实现更加明朗,任何形式的通信都是需要协议来进行实现,而在数据结构中就得设计相对应的函数。
对OpenFlow1.3协议用的还不是很多,现在仅仅总结与1.0版本的几个不同:将actions改为 instruction,其中actions是对数据包进行处理,而instruction是对流表进行处理;并且OF1.3支持Mutli Controller,但是还仅仅是对交换机而言的,但是控制器之间的同步没有具体的协议来实现,这样SDN网络中依然存在扩展性的问题。
所以OpenFlow协议还有好多的网络性能不能支持,因而还需要不断地完善。
在Mininet启动1.3版本OF:
sudo mn --toposingle,3 --mac --controller remote --switch ovsk,protocols=OpenFlow13
从以上可知,启动1.3版本的命令是protocols=OpenFlow13,但是这只是启动了mininet的1.3版本,还需要对交换机进行配置。命令如下:
ovs-vsctl setbridge s1 protocols=OpenFlow13
其中查看1.3版本的流表命令为:
sudo ovs-ofctldump-flows s1 -O OpenFlow13
总之,SDN网络还有很长的路要走,OpenFlow协议也需要不断地去完善,同时,我的SDN技术之旅也会一直继续下去,愿自己也能够为这个技术的发展贡献出自己的一份力量~~