OpenDaylight与Mininet应用实战之三层转发机制四
本文属于该专题中的进阶篇,主要讲解ODL应用不同网段的三层数据转发机制,在OpenDaylight与Mininet应用实战之流表操作(三)中会涉及到相同网段的二层数据通信,此是在(三)的基础上更加了解ODL的功能应用。学习本文前,可先熟悉本专题前面两篇文章。
1 自定义创建SDN网络拓扑
在验证中我用Mininet创建了如下的网络拓扑结构,1台ODL控制器(0.1版本),2台交换机,每台交换机分别连接2台主机,即共4台主机,这些主机分别属于2个不同的网段,交换机与控制器之间采用OpenFlow协议。拓扑结构及网段分配如图1所示:
图1 拓扑结构
1.1 编写生产拓扑脚本
首先测试网络的拓扑结构由Python脚本生成,可将配置文件保存于虚拟机/mininet/custom目录下的topo-2sw_2host.py文件内:
"""Custom topology example
Two directly connected switches plus two hosts for each switch:
host1 --- switch1 --- switch2 --- host3
| |
| |
host2 host4
"""
from mininet.topo import Topo
class MyTopo( Topo ):
"Simple topology example."
def __init__( self ):
"Create custom topo."
# Initialize topology
Topo.__init__( self )
# Add hosts and switches
Host1 = self.addHost( 'h1' )
Host2 = self.addHost( 'h2' )
Host3 = self.addHost( 'h3' )
Host4 = self.addHost( 'h4' )
Switch1 = self.addSwitch( 's1' )
Switch2 = self.addSwitch( 's2' )
# Add links
self.addLink( Host1, Switch1 )
self.addLink( Host2, Switch1 )
self.addLink( Switch1, Switch2 )
self.addLink( Switch2, Host3 )
self.addLink( Switch2, Host4 )
topos = { 'mytopo': ( lambda: MyTopo() ) }
1.2 启动测试环境
启动测试环境,使用以下命令生成测试拓扑结构:
sudo mn --custom ~/mininet/custom/topo-2sw_2host.py --topo mytopo --controller=remote,ip=192.168.5.203,port=6633
通过启动抓包软件WireShark(或sudo tcpdump -i any ip host 192.168.5.203 -w ./odl.tcpdump.pcap)可以看到交换机与ODL控制器的通信过程,具体详情可看上一章节OpenDaylight与Mininet应用实战之OpenFlow1.0协议分析(二)。生成拓扑后,将OpenDaylight连接至Mininet作为交换机的控制器控制主机通信。
1.3 ODL配置三层网关地址
生成网络拓扑后,须在ODL控制器界面上为每个三层网段设置一个网关地址,将交换机的端口与三层网关相关联。即将SW5的1号(连接h1)和SW6的1号口(连接h3)分别与网关10.0.0.254关联,将SW5的2号(连接h2)和SW6的2号口(连接h4)分别与网关20.0.0.254关联,如下图2所示。这一过程好比在SDN内划分了不同的三层网段,并将设备物理接口与三层对应,与以太网划分VLAN和增加三层虚接口的过程相类似。
图2 ODL Web界面交换机端口与三层网关相关联
然后对各个Host的主机IP地址、子网掩码和默认网关进行逐一设置,在Mininet提示符下如下设置:
mininet> h1 ifconfig h1-eth0 10.0.0.1 netmask 255.0.0.0
mininet> h3 ifconfig h3-eth0 10.0.0.3 netmask 255.0.0.0
mininet> h2 ifconfig h2-eth0 20.0.0.1 netmask 255.0.0.0
mininet> h4 ifconfig h4-eth0 20.0.0.2 netmask 255.0.0.0
mininet> h1 route add default gw 10.0.0.254
mininet> h3 route add default gw 10.0.0.254
mininet> h2 route add default gw 20.0.0.254
mininet> h4 route add default gw 20.0.0.254
2 SDN网络三层转发机制
测试SDN控制器ODL如何实现两个不同网段主机之间的数据转发通信。
2.1 通信结果显示
在mininet>终端使用xterm h1 h2 h3 h4命令,显示4个主机的界面,在4个主机中对其他三个主机进行ping操作,同时使用Wireshark抓包,4个主机间都能ping通,h1、h4结果显示如下图3、图4:
图3 h1窗口
图4 h4窗口
对于三层转发,主机首先会判断目的IP与自己不在同一网段内,须解析网关的MAC地址,将数据包发向默认网关。
(1)h1发出 ARP,请求网关10.0.0.254的MAC。SW5不知如何处理,将其通过OF协议发送到ODL控制器。ODL上配置了网关地址10.0.0.254,它以自己的MAC地址回应ARP消息,并指示SW5交换机将ARP响应发送到与h1相连的端口。同时ODL控制器知道了h1的存在,通过路径计算,得到每一台交换机去往10.0.0.1的路径,并通过OF Flow Modify将流表推送到每一台交换机上。
(2)主机h1收到网关的ARP消息,构造ICMP PING Request数据包,其中源和目的MAC分别为h1和网关10.0.0.254的MAC,源和目的IP分别为h1和h4的IP,此包发向SW5。SW5没有关于到达20.0.0.2的流表,将缓存这个数据包。同时SW5也会将该包通过OF协议发送到ODL控制器,ODL发现该包要去向20.0.0.2,而此目的主机位置未知。
(3)ODL控制器会要求每一台交换机对应20.0.0.0/8网段的非SW互联端口发出ARP消息来请求20.0.0.2的MAC地址,其中ARP的源IP为20.0.0.0/8网段的网关20.0.0.254。
(4)只有h4(20.0.0.2)才会响应ARP,它将ARP Response发送到SW6。SW6不知如何处理,将ARP封装在OF协议中发送到ODL控制器。ODL控制器接到这个ARP响应,同时得到h4的位置是处于SW6的某个端口。ODL控制器通过路径计算,得到每一台交换机去往20.0.0.2的流表,并通过OF Flow Modify消息推送流表到每一台交换机上,对20.0.0.2目的地址的流表下发如图5所示。
图5 对20.0.0.2目的地址的流表下发
(5)SW5在装载流表后向正确的端口上转发之前缓存的ICMP数据包, SW6也可顺利转发。SW6还会将ICMP包的目的MAC地址修改为h4的MAC,以确保主机正确接收。对于主机相邻的交换机不仅要指该主机所对应流的出端口,还需要对目的MAC地址进行改写以匹配主机MAC,因此下发的流表内有2个动作(Action),对于二层转发亦然。
(6)此时h4会收到ICMP Request,它发现是不同网段主机发出的ICMP请求,因此仍要通过ARP解析出自己的默认网关。此请求发送到SW6后仍要通过OF协议转发到ODL控制器,ODL控制器用自己的MAC进行响应,然后通过OF协议发往SW6,并最终发送到h4。
(7)主机h4收到ARP后可构造ICMP PING Response,其中源和目的MAC分别为h4和网关20.0.0.254的MAC,源和目的IP分别为h4和h1的IP。此包发向SW6,然后经过SW5,同样SW5在将其转发到目的端口前会将目的MAC地址修改为h1的MAC。这样h1和h4之间的通道被完全打通,进行通信。
整个流程图如下图6所示:
图6 ODL SDN三层转发机制流程
当网络的所有主机都完成一次通信后,ODL感知到所有网络节点的状态。通过控制器提供的界面,可以看到网络的可视化视图(http://192.168.5.203:8080),与我们之前给出的网络拓扑一致,如下图7所示。
图7 ODL控制界面显示SDN网络拓扑
观察一下各交换机上的流表,可见每个交换机装载了正确的流表。随后交换机将定期向ODL控制器汇报流的状态,如匹配流的数量,转发的字节数量、生存时间等。这些流和它们的状态在ODL Web控制台上都可以看到,如下图8、图9所示:
图8 SW5转发流表信息
图9 SW6转发流表信息
3 总结
通过本文的实践操作,对ODL的三层数据转发机制进行分析学习,对OF协议也有了更为透彻地了解,且ODL不同网段的主机通信实验更熟悉。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 微软自家沙盒 Sandbox公布
- php DES加密算法实例分析
- php提供实现反射的方法和实例代码
- PHP实现批量修改文件名的方法示例
- Linux VPS快速下载Bilibili视频脚本 ,支持1080P/720P/360P等格式
- PHP递归统计系统中代码行数
- PHP切割整数工具类似微信红包金额分配的思路详解
- php写入文件不覆盖的实例讲解
- php解决crontab定时任务不能写入文件问题的方法分析
- Laravel项目中timeAgo字段语言转换的改善方法示例
- php生成微信红包数组的方法
- 解决php写入数据库乱码的问题
- php写入txt乱码的解决方法
- PHP实现的AES 128位加密算法示例
- php写入mysql中文乱码的实例解决方法