专栏首页SDNLABSDN开发笔记(七):L2switch源码分析(上)

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链接。

private void processHost(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node node,
            NodeConnector nodeConnector,
            Addresses addrs) {
        List<Host> hostsToMod = new ArrayList<>();
        List<Host> hostsToRem = new ArrayList<>();
        List<Link> linksToRem = new ArrayList<>();
        List<Link> linksToAdd = new ArrayList<>();
        synchronized (hosts) {
            log.trace("Processing nodeConnector " + nodeConnector.getId().toString());
            HostId hId = Host.createHostId(addrs);
            if (hId != null) {
                if (isNodeConnectorInternal(nodeConnector)) {
                    log.trace("NodeConnector is internal " + nodeConnector.getId().toString());
                    removeNodeConnectorFromHost(hostsToMod, hostsToRem, nodeConnector);
                    hosts.removeAll(hostsToRem);
                    hosts.putAll(hostsToMod);
                } else {
                    log.trace("NodeConnector is NOT internal " + nodeConnector.getId().toString());
                    //新建主机节点
                    Host host = new Host(addrs, nodeConnector);
                    if (hosts.containsKey(host.getId())) {
                        hosts.get(host.getId()).mergeHostWith(host);
                    } else {
                        hosts.put(host.getId(), host);
                    }
                   //创建主机与交换机的连接
                    List<Link> newLinks = hosts.get(host.getId()).createLinks(node);
                    if (newLinks != null) {
                        linksToAdd.addAll(newLinks);
                    }
                    //保存主机节点信息
                    hosts.submit(host.getId());
                }
            }
        }
        //保存link信息
        writeDatatoMDSAL(linksToAdd, linksToRem);
}

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

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

本文分享自微信公众号 - SDNLAB(SDNLAB),作者:陈明莉

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-12-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SDN实战团分享(十三):SDN测量的研究尝试

    各位前辈,大神好!我是张鹏飞,现在上海交大博士生在读,来自OMNILab。我的主要研究兴趣是SDN 网络测量和分析,今天厚着脸皮分享下我们在SDN测量方面的一些...

    SDNLAB
  • Netvirt之流表分析(一):Netvirt介绍

    1. 架构 最近在看ODL的netvirt项目,netvirt是一个完整的网络虚拟机化解决方案,几乎可以实现neutron的所有功能,包括FWaaS,VPNaa...

    SDNLAB
  • SDN网络与传统网络对比

    SDN相比传统网络具有很多优点,比如控制与转发分离,这种思想打破了传统设备供应商的绑定,提高了新业务的部署速度,可以从整个网络层面对流量进行优化等等。在SDN网...

    SDNLAB
  • 速读原著-TCP/IP(ICMP:Internet控制报文协议)

    I C M P经常被认为是 I P层的一个组成部分。它传递差错报文以及其他需要注意的信息。I C M P报文通常被I P层或更高层协议( T C P或U D P...

    cwl_java
  • 计算机网络学习记录(不断更新)

    平时TTL减为0时最后一个经手的路由器会返回TTL-Exceeded报文,到目的主机后由于端口大于30000,会返回Port-Unreachable报文,这样就...

    xiaoxi666
  • 计算机网络之网络安全基础-消息完整性与数字签名

    (1). 发送方对报文m应用散列函数, 得到固定长度的散列码, 获得报文摘要h, 将扩展报文(m,h)发送给接收方;

    越陌度阡
  • 速读原著-TCP/IP(拥塞举例)

    现在观察一下数据报文段的传输过程。图 2 1 - 6显示了报文段中数据的起始序号与该报文段发送时间的对比图。它提供了一种较好的数据传输的可视化方法。通常代表数据...

    cwl_java
  • 智能汽车安全入门|世界智能驾驶挑战赛总结

    这两天参加了世界智能汽车挑战赛,比赛使用了visual threat的汽车仿真设备。不过这个文章题目起的有些夸张,准确的说应该是CAN总线安全学习入门

    物联网安全小编
  • 速读原著-TCP/IP(时间戳选项)

    时间戳选项使发送方在每个报文段中放置一个时间戳值。接收方在确认中返回这个数值,从而允许发送方为每一个收到的 A C K计算RT T(我们必须说“每一个收到的 A...

    cwl_java
  • 世界智能驾驶挑战赛信息安全组——新人扫盲

    0x00前言 感谢天津市人民政府与国家发展和改革委员会、科学技术部、工业和信息化部、国家互联网信息办公室、中国科学院、中国工程院、中国汽车技术研究中心、XCT...

    ChaMd5安全团队

扫码关注云+社区

领取腾讯云代金券