Sdn

## sdn - 初步分析基于OpenFlow的SDN网络控制功能


题目要求:
1、下发流表项实现 h1 和 h2,h2 和 h3 不能互通、h1 和 h3 可互通。
2、结合捕获的 SDN 相关协议(例如 OpenFlow 协议)报文,分析其报文结构, 并简要描述该类报文的作用。(一种即可,限 500 字)
3、说明在相同的网络拓扑中传统分布式网络如何实现要求 1,并分析与 SDN 实 现之间的差别。

### 第一题
#### 分析
题目已经说的很明白了,现在问题是怎么样去实现。
基于我现在所了解的sdn的知识,在sdn网络中,有一个网络拓扑,里面有各种路由器和主机,同时还有控制器连接着路由。在说控制器之前,先说一下路由。
在路由中, 有着流表,其中的作用就是当网络中的包经过路由,路由就会根据流表进行匹配,从而进行对应的操纵。
现在就有问题了,当一个包出现不匹配任何流表,路由应该怎么办呢。
这时,路由器就会找到控制器,控制器会就可以根据情况下发对应的流表,告诉路由器怎么处理。
以上是简单的对sdn的理解,所以要处理这题就是要给路由添加一条流表,把进入h2或从h2出来的包丢弃就好了。
#### 实现
因为内容比较简单,可以不考虑控制器下发流表的做法,直接使用mininet控制台使用ovs命令进行控制。
另外要求的是ping通h2。
ping是应用层直接使用icmp的回送请求与回送回答报文,就意味着,h1 ping h2 时,h1发送请求后,h2要回报给h1。所以只要限制了h2的发送,外界就无法ping通h2,并且h2也无法ping通其他主机了。

#### 代码
##### topo结构如下:

<code>
class MyTopo(Topo):

def __init(self):
Topo.__init__(self)

h1 = self.addHost('h1')
h2 = self.addHost('h2')
h3 = self.addHost('h3')
s1 = self.addSwitch('s1')
s2 = self.addSwitch('s2')

self.addLink(h1, s1)
self.addLink(h2, s1)
self.addLink(h3, s2)
self.addLink(s1, s1)

topos = { 'mytopo' : (lambad:MyTopo() ) }
<code/>

##### 启动mininet

<code>
sudo mn --custom mytopo.py --topo mytopo --mac
<code/>

##### 手动添加流表

<code>
sh ovs-ofctl add-flow s1 priority=12,in_port=2,action=drop
<code/>

##### 上一条作用就是把从口2进入的包给丢弃,并且这条流表的优先级为12
##### 关于流表的一些简单的知识,来源<a href="http://blog.csdn.net/zhongbeida_xue/article/details/54945496">这里</a>
每条流规则由一系列字段组成,分为基本字段、条件字段和动作字段三部分
1.基本字段包括生效时间duration_sec、所属表项table_id、优先级priority、处理的数据包数n_packets,空闲超时时间idle_timeout等,空闲超时时间idle_timeout以秒为单位,超过设置的空闲超时时间后该流规则将被自动删除,空闲超时时间设置为0表示该流规则永不过期,idle_timeout将不包含于ovs-ofctl dump-flows brname的输出中。
2.条件字段包括输入端口号in_port、源目的mac地址dl_src/dl_dst、源目的ip地址nw_src/nw_dst、数据包类型dl_type、网络层协议类型nw_proto等,可以为这些字段的任意组合,但在网络分层结构中底层的字段未给出确定值时上层的字段不允许给确定值,即一条流规则中允许底层协议字段指定为确定值,高层协议字段指定为通配符(不指定即为匹配任何值),而不允许高层协议字段指定为确定值,而底层协议字段却为通配符(不指定即为匹配任何值),否则,ovs-vswitchd 中的流规则将全部丢失,网络无法连接。
3.动作字段包括正常转发normal、定向到某交换机端口output:port、丢弃drop、更改源目的mac地址mod_dl_src/mod_dl_dst等,一条流规则可有多个动作,动作执行按指定的先后顺序依次完成。

##### 结果

### 第二题


##### 分析具体的openflow1.0协议

#### 1.Hello


##### 控制器与交换机之间的OpenFlow协议是应用于TCP传输层上,所以解析应用层。他们首先发送hello消息,建立初始化连接
##### 1.Version:OpenFlow版本,低位为版本号
##### 2.Type:OpenFlow消息类型
##### 3.Length:消息总长度,包含头部
##### 4.Xid:事件ID,同一件事件的ID号一致。如feature_request和对应的feature_reply就使用同一个Transaction id,但是两个hello消息的Transaction id并不相同,不过据两个id一般是两个相邻的数字。并且packet_in的transaction id都为0。

#### 2.Feature


##### 会话一建立,控制器就会向交换机发送一个ofpt_feature_request消息,该消息只有of包头,如下所示。交换机会回复一条ofpt_feature_reply消息
##### ofpt_feature_request如图:


##### ofpt_feature_replyt如图:


##### 1.datapath_id : 数据通道独一无二的标识符,低48位是一个MAC地址,而高16位是自定义的。例如,用高16位代表VLAN ID区别一个物理交换机中的多个虚拟交换机
##### 2.n_buffers : 一次最多缓存的数据包数量
##### 3.n_tables : 表示交换机支持的流表数量。而每个流表可以设置不同的通配符和不同数量的流表项。控制器和交换机第一次通信的时候,控制器会从feature_reply消息中找出交换机支持多少流表,如果控制器还想了解大小、类型和流表查询的顺序,就发送一个ofpst_table stats请求,交换机必须按照数据包遍历流表的顺序把这些流表回复给控制器,并且精确匹配流表排在通配流表前
##### 4.capabilities : 所支持的功能
##### 5.actions : 该bitmask表示交换机所支持的actions,“required”action必须支持,vendor action不应该通过该bitmask显示,actions根据ofp_action_type的值决定需要左移几位。
##### 6.ports[] : 以数组的形式罗列出该系统中支持OpenFlow的物理端口。数据长度可以根据OpenFlow头部中的length推测出来

#### 3.Packet_in
当交换机碰到新数据包不知道如何处理,或者action要求发送给控制器,那么交换机就会用packet_in消息发送给控制器。一般将数据包缓存在交换机中,将有效的数据包信息(默认的128字节,如果原因是 “send to controller” action,那么长度由action_out的max_len决定;如果是原因table miss,那么长度由set_config消息中的miss_send_len决定。)和缓存id发送给控制器,不过,如果交换机不支持缓存或者内存用光了,那么就把整个数据包放在数据部分发给控制器,并且缓存id为-1

##### packet_in消息如下

##### total_len : 整个数据帧的长度
##### in_port : 接收数据帧的端口
##### reason : 将数据包发送给控制器的原因,一般有俩原因,一是没有匹配到流表项,二是动作要求发给控制器

#### 4.Packet_out

##### Packet_out如图:


当控制器希望交换机发送某个数据包,就使用packet_out消息

#### 参考链接
#### 1.流表相关 - <a href = 'http://www.sdnlab.com/15119.html'>http://www.sdnlab.com/15119.html<a/>
#### 2.openflow协议分析 - <a href = 'http://www.jianshu.com/p/e660508f1c5d'>http://www.jianshu.com/p/e660508f1c5d<a/>


原文地址:https://www.cnblogs.com/UNWILL2LOSE/p/6756088.html