美文网首页
如何写一个floodlight模块

如何写一个floodlight模块

作者: ae9e2d371f0c | 来源:发表于2017-04-06 16:16 被阅读248次

    [译]如何写一个floodlight模块

    目标

    这里完成一个floodligth模块,这个模块可以监听新的MAC地址,并且打印出新的MAC地址以及发现这些MAC地址的交换机的DPID信息.

    事前准备

    • 已经装好floodlight,并且把floodlight导入到eclipse中
    • 已经安装了mininet或者是物理ovs交换机

    创建一个listener

    在eclipse中增加一个类

    1. 在eclipse项目中增加一个package,叫做net.floodlightcontroller.mactracker
    2. 在这个package下增加一个类,叫做MACTracker
    3. MACTracker需要实现IOFMessageListener, IFloodlightModule两个接口,创建好MACTracker类之后,我们在eclipse中会得到如下代码:
    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;
        }
     
    }
    

    设置模块的依赖和初始化函数

    下面往MACTracker这个类中增加三个成员变量,如下

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

    为了监听OpenFlow消息,所以需要一个FloodlightProvider(IFloodlightProviderService class)对象.
    为了保存当前发现的mac地址,需要一个set对象来保存mac地址。
    为了显示日志信息,打印mac地址以及交换机的信息,所以需要要给Logger对象
    下面我们在getModuleDependencies函数中告诉floodlight,我们需要依赖那些模块。代码如下:

    @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函数在startup函数之前被调用。init函数的作用是加载依赖项以及初始化成员变量。如下:

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

    处理Packet-In消息

    下面来实现基本监听功能。首先在startUp函数中注册PACKET_IN消息的处理,负责处理的对象就是this,也就是MacTracerk。这边在startUp中,可以保证所有的依赖项都已经加载完毕。

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

    对与这个OFMessage监听器,我们也给他起个名字,覆盖父类的getName函数,如下:

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

    下面来实现具体的处理逻辑

    
    @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;
        }
    

    处理完成之后,为了让后续的流程可以继续处理OFMessage,我们需要return一个Command.CONTINUE;

    注册模块

    1. 首先告诉floodlight我们的模块存在
      修改src/main/resources/META-INF/services/net.floodlightcontroller.core.modul文件,在结尾增加包名net.floodlightcontroller.mactracker.MACTracker。如图

      Paste_Image.png
    2. 告诉floodlight启动的时候,把我们的模块启动起来。修改src/main/resources/floodlightdefault.properties,增加类名net.floodlightcontroller.mactracker.MACTracker,如图所示:

      Paste_Image.png

    这样新的模块就已经完成。

    把mininet连接到floodlight上

    1. 启动floodlight
    2. 启动mininetsudo mn --controller=remote,ip=127.0.0.1,port=6653.执行pingall,在eclipse控制台中可以看到打印的信息,如图:
    Paste_Image.png

    相关文章

      网友评论

          本文标题:如何写一个floodlight模块

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