美文网首页
Floodlight开发——怎样写一个floodlight模块

Floodlight开发——怎样写一个floodlight模块

作者: 空明俗人 | 来源:发表于2016-07-25 16:48 被阅读0次

    一 前提

    我们将编写一个简单的Floodlight模块,用来检测在网络中新的、未被发现的MAC地址,并记录被检测到的MAC地址和交换机。

    二 创建监听器

    2.1在Eclipse中添加类

    a). 将“floodlight”项目导入Eclipse中,并在包管理器中展开,然后找到
    “src/main/java”目录。
    b). 右键单击“src/main/java”目录,选择“New / Class”.
    c). 在“Package”框中输入“net.floodlightcontroller.mactracker”。
    d). 在“Name”框中输入“MACTracker”。
    e). 接下来找到“Interface”那一栏,点击旁边的“Add...”按钮。
    f). 添加“IOFMessageListener”和“IFloodlightModule”,点击“OK”按钮。
    g). 点击对话框上的“Finish”按钮。

    最后你会得到一个类,如下所示:

    package net.floodlightcontroller.mactracker;
    
    import java.util.Collection;
    import java.util.Map;
     
    import org.projectfloodlight.openflow.protocol.OFMessage;
    import org.projectfloodlight.openflow.protocol.OFType;
    import org.projectfloodlight.openflow.types.MacAddress;
     
    import net.floodlightcontroller.core.FloodlightContext;
    import net.floodlightcontroller.core.IOFMessageListener;
    import net.floodlightcontroller.core.IOFSwitch;
    import net.floodlightcontroller.core.module.FloodlightModuleContext;
    import net.floodlightcontroller.core.module.FloodlightModuleException;
    import net.floodlightcontroller.core.module.IFloodlightModule;
    import net.floodlightcontroller.core.module.IFloodlightService;
     
    public class MACTracker implements IOFMessageListener, IFloodlightModule {
     
        @Override
        public String getName() {
            // TODO Auto-generated method stub
            return null;
        }
     
        @Override
        public boolean isCallbackOrderingPrereq(OFType type, String name) {
            // TODO Auto-generated method stub
            return false;
        }
     
        @Override
        public boolean isCallbackOrderingPostreq(OFType type, String name) {
            // TODO Auto-generated method stub
            return false;
        }
     
        @Override
        public Collection<Class<? extends IFloodlightService>> getModuleServices() {
            // TODO Auto-generated method stub
            return null;
        }
     
        @Override
        public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
            // TODO Auto-generated method stub
            return null;
        }
     
        @Override
        public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
            // TODO Auto-generated method stub
            return null;
        }
     
        @Override
        public void init(FloodlightModuleContext context)
                throws FloodlightModuleException {
            // TODO Auto-generated method stub
     
        }
     
        @Override
        public void startUp(FloodlightModuleContext context) {
            // TODO Auto-generated method stub
     
        }
     
        @Override
        public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
            // TODO Auto-generated method stub
            return null;
        }
     
    }
    

    2.2 设置模块的依赖关系和初始化

    在开始前,我们需要引入一些依赖包。使用像eclipse一样的工具可以很方便的添加,如果你没有使用eclipse,只需要将下面的代码添加到类的前面。

    import net.floodlightcontroller.core.IFloodlightProviderService;
    import java.util.ArrayList;
    import java.util.concurrent.ConcurrentSkipListSet;
    import java.util.Set;
    import net.floodlightcontroller.packet.Ethernet;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    

    现在,我们有了类的框架,我们还需要实现相关的功能才能使得模块能够被加载。首先,我们添加一些在类中需要的成员变量。因为要监听OpenFLow的消息,我们需要用FloodlightProvider(IFloodlightProviderService类)注册信息,我们也需要一个Set集合来存储被检测到的MAC地址,最后,我们使用一个日志类logger打印出被检测出的信息。

    protected IFloodlightProviderService floodlightProvider;
    protected Set<Long> macAddresses;
    protected static Logger logger;
    

    我们需要将其连接到模块加载系统。通过修改getModuleDependencies() 方法告诉模块加载器它与该类的依赖关系。

    @Override
    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
        Collection<Class<? extends IFloodlightService>> l =
            new ArrayList<Class<? extends IFloodlightService>>();
        l.add(IFloodlightProviderService.class);
        return l;
    }
    

    现在我们开始写模块的初始化方法init(),init()会在控制器启动过程的早期被调用——它主要用来加载相关依赖和初始化数据结构。

    @Override
    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
        floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
        macAddresses = new ConcurrentSkipListSet<Long>();
        logger = LoggerFactory.getLogger(MACTracker.class);
    }
    

    2.3 处理Packet-In消息

    接下来实现基本的监听器。我们将在startUp()方法中注册PACKET_IN消息。在这里,我们确保其他被依赖的模块已经被初始化。

    @Override
    public void startUp(FloodlightModuleContext context) {
        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
    }
    

    我们也必须在OFMessage消息监听器中设置一个ID,这可以在getName()方法中实现。

    @Override
    public String getName() {
        return MACTracker.class.getSimpleName();
    }
    

    现在我们来定义我们想要的对PACKET_IN消息的处理行为。注意,为了使PACKET_IN
    消息在后面可以继续被其他相关消息处理程序处理,我们需要返回Command.CONTINUE。

    @Override
       public net.floodlightcontroller.core.IListener.Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
            Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
                              IFloodlightProviderService.CONTEXT_PI_PAYLOAD)
            Long sourceMACHash = eth.getSourceMACAddress().getLong();
            if (!macAddresses.contains(sourceMACHash)) {
                macAddresses.add(sourceMACHash);
                logger.info("MAC Address: {} seen on switch: {}",
                        eth.getSourceMACAddress().toString(),
                        sw.getId().toString());
            }
            return Command.CONTINUE;
        }
    

    2.4 注册模块

    我们已经基本完成了模块的编写工作,现在我们只需要告诉Floodlight在启动的时候加载本模块。首先,我们必须告诉加载器本模块的存在,这需要在文件src/main/resources/META-INF/services/
    net.floodlightcontroller.core.module.IFloodlightModule 中添加一行模块的全名。打开该文件,然后在下面添加一行:

    net.floodlightcontroller.mactracker.MACTracker
    

    接下来需要让模块被加载。我们可以在Floodlight模块配置文件中添加MACTracker模块,这个默认的文件在src/main/resources/floodlightdefault.properties。它的key值是floodlight.modules,value是一个将模块名用逗号分割的列表。

    floodlight.modules = <leave the default list of modules in place>, net.floodlightcontroller.mactracker.MACTracker
    

    最后运行控制器,右键Main.java文件,选择"Run As... / Java Application"。

    三 检验模块功能

    3.1 建立网络拓扑

    打开mininet虚拟机,输入命令

    sudo mn --topo single,3 --controller=remote,ip=<你本机的ip地址>,port=6653 --switch ovsk,protocols=OpenFlow13
    

    结果如下图所示:

    3.2 查看floodlight输出结果

    在Eclipse的控制台输出信息里,查找MACTracker,可以看到如下信息,可以看到网络中新接入设备的MAC地址和相关交换机


    相关文章

      网友评论

          本文标题:Floodlight开发——怎样写一个floodlight模块

          本文链接:https://www.haomeiwen.com/subject/hecgjttx.html