SDN开发笔记(七):L2switch源码分析(上)

前言

一般按照odl官方文档或者wiki安装L2switch组件会采用在karaf控制台上输入feature:install odl-l2switch-all命令,该命令是将L2switch组件全部安装到odl控制器,而L2switch组件包括packethandler、loopremover、l2switch-main、hosttracker、arphandler、addresstracker模块这几个,模块之间的相互依赖关系可以在features当中查看。

模块功能介绍

如上所述,L2switch组件包括packethandler、loopremover、l2switch-main、hosttracker、arphandler、addresstracker模块,各个模块先简单描述功能,后面会详细从代码上分析。

1、Packethandler :数据包处理器

Packethandler就是将openflowplugin接收到的packetin数据包解封装送到其他模块,并且按照顺序发送,是L2switch与openflowplugin的桥梁,所有的需要l2switch处理的packetin报文都会经过它处理解析,所以分析l2switch需要先从Packethandler分析。

Packethandler模块的入口在PacketHandlerModule.java的createInstance函数:

此函数当中调用了initiateDecoders函数进行初始化,其实也就是new出一些解码器对象,比如EthernetDecoder、ArpDecoder、Ipv4Decoder、Ipv6Decoder解码器。

解码器的设计是先定义一个抽象类,这样一来其他解码器只要继承该抽象类,然后做自己的具体实现就可以了。所以各个文件描述如下:

AbstractPacketDecoder.java——定义的抽象类,所有解封装器必须继承实现其中的方法。

EthernetDecoder.java——mac帧解码器类,openflowplugin接收到的报文上送至控制器,由EthernetDecoder统一mac帧解包(去掉mac帧头),再发送给对应的解码类(ARP、IPV4、IPV6)处理(此过程并不是先判断是arp还是ip报文再发送,而是发送广播notification,所有解码器都能接受到该广播,只不过解码器当中自己去判断是否是自己应该解的报文——canDecode,如果不是则不处理)。

先看EthernetDecoder以太网mac帧的解码,首先EthernetDecoder是实现PacketProcessingListener接口,当openflowplugin接收到packetIn报文时,就会发出notification出来,此时PacketProcessingListener的onPacketReceived函数就会被调用,所以所有packetIn报文都会通过onPacketReceived函数进行后续处理。

报文进入decodeAndPublish之后转到AbstractPacketDecoder抽象类当中,

然后进入decode函数,此函数是抽象函数,所以由具体类实现,比如刚刚是EthernetDecoder转进来的报文,则由EthernetDecoder解析。

解析完了之后,继续采用notification的方式发布,这样报文就经过了mac帧的解码,继续流向下一个环节。

再看IPV4解码类,注意到刚刚EthernetDecoder将报文解码之后,发出notification,而Ipv4Decoder实现了EthernetPacketListener,所以Ipv4Decoder能够收到上述通告,进入onEthernetPacketReceived函数

同理Ipv4Decoder也会跟EthernetDecoder将报文内容解析出来,并将报文以notification形式发出去。

整个Packethandler的报文处理就是这样,所以如果我们想自己定义一种新的packetin报文上送到控制器,就可以在此处按照这样的流程进行报文解析,比如思科自己的cdp报文解析。

最后归类下:
EthernetDecoder.java – 以太网帧解码类
ArpDecoder.java – arp报文解码类
Ipv4Decoder.java -- IPV4报文解码类
Ipv6Decoder.java --IPV6报文解码类

2、Addresstracker

由openflowplugin发上来的报文经过Packethandler处理之后,就会经过Addresstracker模块进行网络设备的MAC地址以及IP学习。

Addresstracker的入口在AddressTrackerModule.java文件当中的函数createInstance。

稍微解释下,AddressObservationWriter是一个公有类,在56-addresstracker.xml当中配置了observe-addresses-from节点,可以是arp、ipv4、ipv6,默认是arp,是arp则调用AddressObserverUsingArp监听arp报文,然后调用addressObservationWriter的addAddress函数添加地址(mac-ip)到md-sal的Inventory,从而触发Hosttracker的主机发现。如果发现地址是已经存在的,则通过timestampUpdateInterval来判断是否需要更新地址时间戳。

比如根据arp来学习设备地址,则进入AddressObserverUsingArp.java文件,可以看到该文件对可以监听上述的Packethandler通告,这样arp报文就流入此文件进行处理。

接收arp报文通告之后,可以根据报文的源mac、源IP等加入datastore。

进入addressObservationWriter.addAddress()函数就是MAC的学习,一般来说是主机host的MAC学习,为下面的hosttracker提供数据。

学习到了MAC之后,将该mac信息以AddressCapableNodeConnector通过Augmentation的方式merge到NodeConnector数据节点,也就是在address-tracker.yang中定义的数据节点,此时merge的数据是在inventory数据库当中。

3、Hosttracker 主机发现

随着上述的流程,当学习到主机host的mac之后,Hosttracker会将新主机以node的形式添加到network-topology当中,这样web前端就有主机节点显示出来。

Hosttracker入口在HostTrackerModule.java的createInstance函数当中,从该函数当中new出一个HostTrackerImpl对象,并注册数据监听器,主要是监听上述的NodeConnector 的AddressCapableNodeConnector数据变化。


当Addresstracker学习到主机mac之后,merge主机的AddressCapableNodeConnector到NodeConnector就会引起hostracker进入onDataChanged函数。

从而进入packetReceived函数,进而进入processHost函数。

在processHost函数当中就将主机添加到network-topology数据节点当中,并建立主机与交换机的link链接。

在hosttracker当中实现主机发现功能,只有主机主动发出报文并经过openflow交换机以packetin形式上送控制器,该报文经过packethandler处理,再到addresstracker,最后由hosttracker写入数据库,该主机节点才能显示到web的拓扑上,因此当我们采用mininet模拟一个哑铃式网络,启动网络是在web的拓扑上只能看到两台交换机,并未出现主机节点,只有pingall之后才能出现主机节点。

由于篇幅有限,下篇继续分析Loopremover、Arphandler等模块。

作者简介:鸿哥,硕士研究生,国内某通信设备公司软件研发工程师,主要从事云计算、SDN技术开发


  • 本站原创文章仅代表作者观点,不代表SDNLAB立场。所有原创内容版权均属SDNLAB,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用,转载须注明来自 SDNLAB并附上本文链接。
  • 本文链接http://www.sdnlab.com/18285.html
分享到:
相关文章
2条评论

登录后才可以评论

  1. comment reply brook_l 2016/12/25 12:06
    讲解得很到位,期待博主的后续文章!
        1楼
  2. comment reply run_earth 2017/01/02 17:03
    楼主写的不错,每期都跟你的帖子,帮助我学习SDN解答了很多疑惑。
        2楼
wellbeing 发表于16-12-21
2