Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6940067
  • 博文数量: 701
  • 博客积分: 10821
  • 博客等级: 上将
  • 技术积分: 12021
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-02 10:41
个人简介

中科院架构师,专注企业数字化各个方面,MES/ERP/CRM/OA、物联网、传感器、大数据、ML、AI、云计算openstack、Linux、SpringCloud。

文章分类

全部博文(701)

分类: 服务器与存储

2015-12-23 17:49:52

原文链接:

最近在研究openvswitch,文章不错,找时间实践一把。
SDN网络的一大特点就是资源由控制器集中管理,控制器管理网络,最基本的当然需要知道网络的拓扑,而网络拓扑可能时时发生变化,所以控制器需要时 时监测,对于整个网络来说,控制器担负了太多的计算任务,所以如果能够帮助控制器减压,则会提高整个网络的性能。本篇文章将以ryu控制器为例,首先介绍 传统网络和现在SDN网络的拓扑发现原理,然后介绍改进算法,最后讲解改写后的代码逻辑。

一. LLDP拓扑发现原理

传统网络中的链路发现协议为LLDP(Link Layer Discovery Protocol),LLDP允许局域网中的结点告诉其他结点他自己的capabilities和neighbours。在传统以太网交换机中,交换机从 自己的每个端口发送LLDP数据包,这个数据包不会被其他交换机转发,寿命只有一跳,LLDP负载被封装在以太网帧中,结构如下图,其中深灰色的即为 LLDP负载,Chassis ID TLV, Port ID TLV和Time to live TLV三个是强制字段,分别代表交换机标识符(在局域网中是独一无二的),端口号和TTL。这个数据发出并被邻居结点收到之后进行解析,就可以知道这条链 路的源目的交换机以及源目的接口。

二. ryu拓扑发现原理

OpenFlow的官方没有规定标准的拓扑发现方法,现在的OFDP(OpenFlow Discovery Protocol)利用的仍然是传统网络中的链路发现协议LLDP,接下来介绍ryu如何利用LLDP发现拓扑,假设现在有两个OpenFlow交换机连 接在控制器上,如下图,简述拓扑发现步骤(以S1作为主体,S2的类似):

1. SDN控制器构造PacketOut消息向S1的三个端口分别发送上图所示的LLDP数据包,其中将Chassis ID TLV和Port ID TLV分别置为S1的dpid和端口号;

2. 控制器向交换机S1中下发流表,流表规则为:将从Controller端口收到的LLDP数据包从他的对应端口发送出去;

3. 控制器向交换机S2中下发流表,流表规则为:将从非Controller接收到LLDP数据包发送给控制器;

4. 控制器通过解析LLDP数据包,得到链路的源交换机,源接口,通过收到的PacketIn消息知道目的交换机和目的接口;

现在的ryu发现拓扑是对整个数据平面的所有交换机的所有端口发送PacketOut数据包,对于Fattree等网络来说,端口的数量是交换机数 量的k倍,因此导致了很多资源的消耗,所以是否可以对这个拓扑发现的机制进行改进,让发送的PacketOut消息和交换机的数量相同?

三. 改进后的ryu拓扑发现机理

为了实现上面所提到的改进目标,需要将LLDP负载中的Port ID TLV进行改进,或者有其他的域和Port ID TLV一一映射也可以,这里提供一种解决办法,在LLDP数据包从交换机端口转发出去的时候,将这个以太网数据包的源MAC地址替换成为这个端口的MAC 地址,而控制器在早先的配置阶段已经获得了关于交换机的端口的所有信息,所以对控制器来说,MAC地址和交换机的端口号是一一对应的,下面详细讲述改进方 案。

1. 更新控制器的LLDP PacketOut消息数量,由一个端口一个,改为一个交换机一个PacketOut消息,LLDP数据包负载中的域Port ID TLV值置为零;

2. 控制器向流表下发一条规则:所有从端口Controller接收到的LLDP数据包,依次将其源MAC地址置为端口MAC地址,然后从相应的端口转发出去;

3. 更新控制器的PacketIn消息处理机制,根据LLDP数据包的来源,可以得到目的交换机,目的端口,通过解析LLDP数据包,得到源MAC和源交换机,通过源MAC地址查找对应的端口号;

4. 由于是修改的代码,所以不要忘了删除原来的以端口主导的相关代码。

四. 代码分析

首选需要添加的一些变量和类

* SwitchData类:包含了时间戳以及交换机所包含的LLDP数据

* SwitchDataState:类似于PortDataState类,继承自字典,保存从Switch类到SwitchData类的映射,维护了一个类似双向链表的数据结构

接着简述修改的核心代码,对应上面第三部分提到的四点

1. 更新控制器的LLDP PacketOut消息数量,由一个端口一个,改为一个交换机一个PacketOut消息,LLDP数据包负载中的域Port ID TLV值置为零;

2.控制器向流表下发一条规则:所有从端口Controller接收到的LLDP数据包,依次将其源MAC地址置为端口MAC地址,然后从相应的端口转发出去;

3.更新控制器的PacketIn消息处理机制,根据LLDP数据包的来源,可以得到目的交换机,目的端口,通过解析LLDP数据包,得到源MAC和源交换机,通过源MAC地址查找对应的端口号;

4.由于是修改的代码,所以不要忘了删除原来的以端口主导的相关代码。

完整的代码见

五. 实验验证

用Mininet建立一个二层二叉树,s3作为根节点分别连接s1和s2。如下图:

写个简单的ryu应用来调用拓扑发现模块提供的API接口,应用为topo_learner.py,代码见

用wireshark抓取OpenFlow和LLDP数据包来进行验证

首先抓取交换机对控制器的响应消息,查看交换机的端口以及对应的MAC地址,从解析可以看到这是s3交换机,拥有四个端口(分别连接控制 器,s1,s2,h3),下图是截取到的一个LLDP数据包,可以看出图中蓝色背景的LLDP的数据包的源MAC地址是s3交换机的3端口的MAC地址, 说明前面的代码修改成功。

参考论文:

阅读(3747) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~