ONOS源码笔记--机制

2023-05-16

app注册

private ApplicationId appId;

    appId = coreService .registerApplication("org.onosproject.fwd");
    //注册应用,一般在activate函数中完成

拓扑监听器

//自定义拓扑监听器,覆盖event函数,具体功能可自己实现,这里是避免路由黑洞
private class InternalTopologyListener implements TopologyListener {
    @Override
    public void event(TopologyEvent event) {
        List< Event> reasons = event.reasons();
        if (reasons != null) {
            reasons.forEach(re -> {
                if (re instanceof LinkEvent) {
                    LinkEvent le = (LinkEvent) re;
                    if (le .type() == LinkEvent.Type.LINK_REMOVED) {
                        fixBlackhole( le.subject().src());
                    }
                }
            });
        }
    }
}

private final TopologyListener topologyListener = new InternalTopologyListener();
//定义一个拓扑监听器

    topologyService.addListener( topologyListener);
    //添加监听器,般在activate函数中完成

设备监听器

/**
 * Listener to Device Event and OVSDB connection.
 * 这段代码来自github,供参考。网址:https://github.com/MaoJianwei/ONOS_OVS_Manager_Bootcamp2016
 */
private class InnerDeviceListener implements DeviceListener {
    @Override
    public void event(DeviceEvent event) {

        if (!event.type().equals(DeviceEvent.Type.DEVICE_ADDED)) {
            return;
        }

        Device device = event.subject();

        if (device.type() == Device.Type.CONTROLLER) {
            dealController(device.id());
        } else {
            dealSwitch(device.id());
        }
    }

    /**
     * Catch the new OVSDB connection.
     * @param deviceId : The OVSDB connection ID.
     */
    private void dealController(DeviceId deviceId) {
        controllerId = deviceId;
        log.info( "controllerId is ready !!!" );
    }

    /**
     * Separate two type of switches.
     * @param deviceId : The DeviceId of target device.
     */
    private void dealSwitch(DeviceId deviceId) {
        String datapathId = deviceId.toString().split( ":")[1];
        if (Integer.valueOf(datapathId) > CORE_DEVICEID_CARDINALITY) {
            dealCoreSwitch(deviceId);
        } else {
            dealAccessSwitch(deviceId);
        }
    }

    /**
     * Add specific ForwardingObject to CORE switch.
     * @param deviceId : The DeviceId of target device.
     */
    private void dealCoreSwitch(DeviceId deviceId) {
        TrafficSelector.Builder trafficSelectorBuilder0 = DefaultTrafficSelector.builder();
        trafficSelectorBuilder0.matchEthType(EthType.EtherType.IPV4.ethType().toShort())
                .matchIPDst(IpPrefix.valueOf( "192.168.1.1/28"))
                .matchIPSrc(IpPrefix.valueOf( "1.2.3.4/32"));

        TrafficTreatment.Builder trafficTreatmentBuilder0 = DefaultTrafficTreatment.builder();
        trafficTreatmentBuilder0.setEthDst(MacAddress.BROADCAST).transition(1);

        addForward(deviceId, BOTH_TABLE_PRIORITY,
                   trafficSelectorBuilder0.build(), trafficTreatmentBuilder0.build());
    }

    /**
     * Add specific ForwardingObject to ACCESS switch.
     * @param deviceId : The DeviceId of target device.
     */
    private void dealAccessSwitch(DeviceId deviceId) {
        TrafficSelector.Builder trafficSelectorBuilder0 = DefaultTrafficSelector.builder();
        trafficSelectorBuilder0.matchEthType(EthType.EtherType.IPV4.ethType().toShort())
                .matchIPSrc(IpPrefix.valueOf( "10.0.0.0/24"));

        TrafficTreatment.Builder trafficTreatmentBuilder0 = DefaultTrafficTreatment.builder();
        trafficTreatmentBuilder0.setEthDst(MacAddress.BROADCAST).transition(1);

        addForward(deviceId, BOTH_TABLE_PRIORITY,
                   trafficSelectorBuilder0.build(), trafficTreatmentBuilder0.build());


        TrafficSelector.Builder trafficSelectorBuilder1 = DefaultTrafficSelector.builder();
        trafficSelectorBuilder1.matchEthDst(MacAddress.BROADCAST);

        TrafficTreatment.Builder trafficTreatmentBuilder1 = DefaultTrafficTreatment.builder();
        trafficTreatmentBuilder1.drop();

        addForward(deviceId, BOTH_TABLE_PRIORITY,
                   trafficSelectorBuilder1.build(), trafficTreatmentBuilder1.build());
    }

    /**
     * Utility method to add ForwardingObjective.
     * @param deviceId : The DeviceId of target device.
     * @param priority : Priority of ForwardingObjective.
     * @param selector : Match fields.
     * @param treatment : Instructions.
     */
    private void addForward(DeviceId deviceId, int priority, TrafficSelector selector, TrafficTreatment treatment) {

        ForwardingObjective.Builder forwardingObjectiveBuilder = DefaultForwardingObjective.builder();
        forwardingObjectiveBuilder
                .withFlag(ForwardingObjective.Flag.SPECIFIC)
                .withTreatment(treatment)
                .withSelector(selector)
                .withPriority(priority)
                .fromApp(applicationId)
                .makePermanent();

        flowObjectiveService.forward(deviceId, forwardingObjectiveBuilder.add());
    }
}


private InnerDeviceListener innerDeviceListener;
innerDeviceListener = new InnerDeviceListener();

deviceService.addListener(innerDeviceListener);//一般放在activate中

包处理器

/**
 * Packet processor responsible for forwarding packets along their paths.
 * 主要为process函数,处理的是一个PacketContext,在开发自己的应用时对于包的处理
 * 可以从这段代码中得到启发。
 */
private class ReactivePacketProcessor implements PacketProcessor {

    @Override
    public void process (PacketContext context ) {
        // Stop processing if the packet has been handled, since we
        // can't do any more to it.

        if (context .isHandled()) {
            return;
        }

        InboundPacket pkt = context .inPacket();
        Ethernet ethPkt = pkt .parsed();

        if (ethPkt == null) {
            return;
        }

        // Bail if this is deemed to be a control packet.
        if (isControlPacket(ethPkt )) {
            return;
        }

        // Skip IPv6 multicast packet when IPv6 forward is disabled.
        if (!ipv6Forwarding && isIpv6Multicast(ethPkt)) {
            return;
        }

        HostId id = HostId. hostId(ethPkt.getDestinationMAC());

        // Do not process link-local addresses in any way.
        if (id .mac().isLinkLocal()) {
            return;
        }

        // Do not process IPv4 multicast packets, let mfwd handle them
        if (ignoreIpv4McastPackets && ethPkt.getEtherType() == Ethernet.TYPE_IPV4 ) {
            if (id .mac().isMulticast()) {
                return;
            }
        }

        // Do we know who this is for? If not, flood and bail.
        Host dst = hostService .getHost(id);
        if (dst == null) {
            flood( context);
            return;
        }

        // Are we on an edge switch that our destination is on? If so,
        // simply forward out to the destination and bail.
        if (pkt.receivedFrom().deviceId().equals(dst .location().deviceId())) {
            if (!context.inPacket().receivedFrom().port().equals(dst.location().port())) {
                installRule( context, dst .location().port());
            }
            return;
        }

        // Otherwise, get a set of paths that lead from here to the
        // destination edge switch.
        Set<Path> paths =
                topologyService.getPaths(topologyService .currentTopology(),
                                         pkt.receivedFrom().deviceId(),
                                         dst.location().deviceId());
        if (paths .isEmpty()) {
            // If there are no paths, flood and bail.
            flood( context);
            return;
        }

        // Otherwise, pick a path that does not lead back to where we
        // came from; if no such path, flood and bail.
        Path path = pickForwardPathIfPossible(paths , pkt.receivedFrom().port());
        if (path == null) {
            log.warn("Don't know where to go from here {} for {} -> {}",
                     pkt.receivedFrom(), ethPkt .getSourceMAC(), ethPkt.getDestinationMAC());
            flood( context);
            return;
        }

        // Otherwise forward and be done with it.
        installRule( context, path .src().port());
    }

}

private ReactivePacketProcessor processor = new ReactivePacketProcessor();
//Packet processor responsible for forwarding packets along their paths.
//负责数据包在特定路径上转发的数据包处理器

    packetService.addProcessor(processor , PacketProcessor.director(2));
    //添加包处理器,一般放在activate函数中

流表下发与删除过程

   /*
   * 制定流表规则,比较重要的部分有两个:
   * 一个是selector,用来指定源目的 ip,源目的mac,源目的port
   * 另一个treatment,用来说明怎么处理包,丢弃还是转发,从哪儿转发
   * 再有就是确定优先级,然后发到哪个设备上 
   */
   private void installRule(TrafficSelector selector, TrafficTreatment treatment , DeviceId deviceId, int priority ){

        ForwardingObjective.Builder forwardingObjectiveBuilder = DefaultForwardingObjective.builder();
         forwardingObjectiveBuilder
                    .withFlag(ForwardingObjective.Flag. VERSATILE)
                    .withSelector( selector)
                    .withTreatment( treatment)
                    .withPriority( priority)
                    .makePermanent()
                    .fromApp( appId);
         flowObjectiveService.forward(deviceId , forwardingObjectiveBuilder .add());
  }

   //流表下发测试函数,当前拓扑中的交换机都发一遍
   private void testInstallRules(){

         src_ip_0 = 10;
         src_ip_1 = 0;
         src_ip_2 = 0;
         src_ip_3 = 1;
         des_ip_0 =10;
         des_ip_1 = 0;
         des_ip_2 = 0;
         des_ip_3 = 2;
         src_port = 8011;
         des_port = 8012;

         byte[] ip = {(byte) src_ip_0, (byte )src_ip_1 , (byte) src_ip_2, (byte)src_ip_3 };
        IpAddress src_ip = IpAddress.valueOf(IpAddress.Version. INET, ip);
        Host src_host = getHostByIp(src_ip );

         byte[] ips = {(byte) des_ip_0, (byte )des_ip_1 , (byte)des_ip_2 , (byte) des_ip_3};
        IpAddress des_ip = IpAddress.valueOf(IpAddress.Version. INET, ips);
        Host des_host = getHostByIp(des_ip );

        MacAddress src_mac = src_host .mac();
        MacAddress des_mac = des_host .mac();

        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
        TrafficSelector selector = selectorBuilder.matchEthSrc(src_mac )
                    .matchEthDst( des_mac)
                    .matchEthType(Ethernet. TYPE_IPV4)
                    .matchIPSrc(Ip4Prefix. valueOf(src_ip, Ip4Prefix.MAX_MASK_LENGTH ))
                    .matchIPDst(Ip4Prefix. valueOf(des_ip, Ip4Prefix.MAX_MASK_LENGTH ))
                    .matchIPProtocol(org.onlab.packet.IPv4. PROTOCOL_UDP)
                    .matchTcpSrc(TpPort. tpPort(src_port))
                    .matchTcpDst(TpPort. tpPort(des_port))
                    .build();
        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                    .setEthDst( des_mac)
                    .build();

        Iterator<Device> devices = deviceService.getDevices(Type.SWITCH).iterator();
         while(devices .hasNext()){
              Device device = devices .next();
              DeviceId deviceId = device .id();
               //log.info(deviceId.toString());
              installRule( selector, treatment , deviceId , 10);
        }
  }

   // 删除流表
private void cleanFlowRules(SrcDstPair pair , DeviceId id) {
    log.info(">>>>>Searching for flow rules to remove from: " + id);
    log.info(">>>>>Removing flows w/ SRC=" + pair.src + ", DST=" + pair.dst );
         for (FlowEntry r : flowRuleService.getFlowEntries( id)) {


        boolean matchesSrc = false, matchesDst = false ;
        for (Instruction i : r.treatment().allInstructions()) {
            if (i .type() == Instruction.Type.OUTPUT) {
                // if the flow has matching src and dst
                for (Criterion cr : r.selector().criteria()) {
                    if (cr .type() == Criterion.Type.ETH_DST) {
                        if (((EthCriterion) cr).mac().equals(pair .dst )) {
                            matchesDst = true ;
                        }
                    } else if (cr .type() == Criterion.Type.ETH_SRC) {
                        if (((EthCriterion) cr).mac().equals(pair .src )) {
                            matchesSrc = true ;
                        }
                    }
                }
            }
        }
        if (matchesDst && matchesSrc) {
            log.info(">>>>>Removed flow rule from device: " + id);
            flowRuleService.removeFlowRules((FlowRule) r );
        }
    }

}
   //流表删除测试函数
   private void testCleanRules(){

         src_ip_0 = 10;
         src_ip_1 = 0;
         src_ip_2 = 0;
         src_ip_3 = 1;
         des_ip_0 =10;
         des_ip_1 = 0;
         des_ip_2 = 0;
         des_ip_3 = 2;
         src_port = 8013;
         des_port = 8014;

         byte[] ip = {(byte) src_ip_0, (byte )src_ip_1 , (byte) src_ip_2, (byte)src_ip_3 };
        IpAddress src_ip = IpAddress.valueOf(IpAddress.Version. INET, ip);
        Host src_host = getHostByIp(src_ip );

         byte[] ips = {(byte) des_ip_0, (byte )des_ip_1 , (byte)des_ip_2 , (byte) des_ip_3};
        IpAddress des_ip = IpAddress.valueOf(IpAddress.Version. INET, ips);
        Host des_host = getHostByIp(des_ip );

        MacAddress src_mac = src_host .mac();
        MacAddress des_mac = des_host .mac();

        Iterator<Device> devices = deviceService.getDevices(Type.SWITCH).iterator();
         while(devices .hasNext()){
              Device device = devices .next();
              DeviceId deviceId = device .id();
               //log.info(deviceId.toString());
              SrcDstPair pair = new SrcDstPair(src_mac, des_mac);
              cleanFlowRules( pair, deviceId );
        }
  }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ONOS源码笔记--机制 的相关文章

  • Ubuntu 16.04 安装onos 2.2.0

    之前使用了别人分享的安装好的p4虚拟机 xff0c 应该是这个人的 xff0c 不过我记得的是用的谷永普的 xff0c 当时还是从微云上下载的 xff0c 但是找不到了 不过无所谓 xff0c 本文不讲p4的安装 xff0c 有需要的 xf
  • 【SDN控制器分析之一】ONOS架构概述

    ONOS 设计目标 ONOS是一个采用OSGI技术来管理子项目的SDN控制器开源项目 xff0c 在最初设计时有这么几个目标是明确的 xff1a 代码模块化 xff1a 支持把新的功能作为新的独立单元引入特性可配置 xff1a 无论是在启动
  • onos实现driver的自动加载

    AbstractDriverLoader 已知driverAdminServer 根据path读取配置文件的内容 1 进入到XMLDriverLoader里 xff0c 根据XML 创建Provider gt XMLDriverLoader
  • ONOS之开放分布式SDN操作系统

    为什么80 的码农都做不了架构师 xff1f gt gt gt 关于构建ONOS xff08 开放式网络操作系统 xff09 的项目专题 xff0c 是通过性能激发创建的实验性分布式 SDN 控制平台 xff0c 满足大型运营商网络的可扩展
  • ONOS高可用性和可扩展性实现初探

    为什么80 的码农都做不了架构师 xff1f gt gt gt ONOS 的发布直面OpenDaylight 进行挑战 xff0c 直接将 SDN 领域两大阵营 xff08 运营商和设备商 xff09 的竞争瞬间升级 xff0c 之所以 O
  • ONOS意图框架

    1 意图基本概念 Intent是用于描述应用需求的不可变模型对象 xff0c ONOS核心根据其改变网络行为 在最低级别上 xff0c 可以用以下方式描述意图 即意图的组成 xff1a 1 Network Resource xff1a 一组
  • ONOS-ifwd-app源码分析总结

    ONOS ifwd源码分析 xff0c 参考资料 xff1a https www sdnlab com 10297 html 在之前的文章中 xff0c 介绍了ONOS sample apps的获取 xff0c 但是将其生成的oar文件导入
  • ONOS简介

    一 与ODL区别 ONOS与OpenDayLight 两个控制器之间的较量 ODL 立场 xff1a 设备厂商 xff1a Cisco Citrix Systems Red Hat Brocade Ericsson ClearPath HP
  • ONOS源码笔记--机制

    app注册 private ApplicationId appId appId 61 coreService registerApplication 34 org onosproject fwd 34 注册应用 xff0c 一般在activ
  • 使用ONOS的REST API来下发流表

    1 启动ONOS后 xff0c 浏览器进入doc http 10 109 247 211 8181 onos v1 docs 2 找到Flow xff0c 并打开POST 3 可以直接在这个上面编辑flow stream里面模拟GET获得的
  • 从零开始安装ubuntu18+P4+ONOS

    1 安装VMware Tools xff08 前面VM虚拟机安装Ubuntu的教程太多 xff0c 就不写了 xff09 先从虚拟机下载好 xff0c 然后将压缩包里的文件夹移动出来 xff08 可以用解压或者直接点开压缩包 xff0c 移
  • ONOS 控制器安装和app新建和编译

    1 1 ONOS 控制器编译与安装 ONOS 1 8 版本起强制使用 BUCK 构建工具 xff0c 不再使用 maven xff0c 编译和打包方式与旧版本有所区别 步骤 xff1a 配置环境 gt 下代码 gt 编译 gt 运行 配置环
  • Mininet连接ONOS的一些问题

    Mininet连接ONOS的一些问题 一 启动ONOS二 简单小问题1 Mininet创建最简拓扑后连接不上远程控制器2 Mininet创建最简拓扑后主机之间ping不通3 不启动fwd应用自己通过REST API下发流表发现两台主机间pi
  • Ubuntu Server 14.04部署ONOS

    参考官网 xff1a https wiki onosproject org display ONOS Installing 43 and 43 Running 43 ONOS 由于笔者习惯ssh xff0c ubuntu默认没有开启ssh
  • P4连接ONOS——导入ONOS虚拟机

    补充 xff1a 2020年5月11日 13点07分 近期有同学私信我安装过程中有这个报错 xff0c 如下图 根据报错信息 xff0c 似乎是下载这个包服务器501出错 xff0c 很可能是因为内网无法下载这个包 我忘记说了 xff0c
  • ONOS链路发现源码

    ONOS链路发现源码 send LLDP by ynogpu private void sendProbes Long portNumber String portDesc if context packetService 61 61 nu
  • 基于IDEA分析ONOS源码

    1 安装Java依赖 sudo apt get install software properties common y amp amp sudo add apt repository ppa webupd8team java y amp
  • HashMap底层实现原理

    HashMap HashMap 最早出现在 JDK 1 2中 底层基于散列算法实现 它是一个key value结构的容器 是一个key value的映射容器 key不重复 jdk8中的HashMap基于数组 链表 红黑树实现 不保证键值的顺
  • vue2的响应式

    结合源码分析一下vue的响应式 之前对于响应式 只是简单 很表面上的认识 知道vue的响应式主要通过Object defineProperty 方法来进行数据劫持以及发布者 订阅模式来实现的 但是如何进行数据劫持呢 发布订阅者模式又是什么呢
  • java.lang.NoSuchFieldError:DEF_CONTENT_CHARSET

    我正在尝试运行 java 程序 但收到以下运行时错误 错误如下所示 Exception in thread main java lang NoSuchFieldError DEF CONTENT CHARSET at org apache

随机推荐

  • 【HAL库】STM32+ESP8266+Onenet+MQTT,极简工程,hal库移植。

    ESP8266 43 Onenet 43 MQTT 1 导入 c h文件 xff08 不再赘述 xff0c 详细见LED部分 xff09 2 Cubemx配置3 修改 c h 文件4 测试 ESP8266通过MQTT协议连接Onenet 从
  • 【HAL库】BMP180气压传感器+STM32,hal库移植

    BMP180气压传感器 43 STM32 1 导入 c h文件 xff08 不再赘述 xff0c 详细见LED部分 xff09 2 Cubemx配置3 修改 h 文件4 测试 将BMP180从标准库移植到HAL库 模拟IIC 极简工程代码如
  • 【硬件】嵌入式板卡硬件电路设计、焊接

    文章目录 嵌入式板卡电路 框图常用焊接工具和焊接操作 框图一 元器件 有极性 1 肖特基二极管2 钽电容3 三极管4 MOS5 LED6 SMAJ5 0CA xff08 TVS管 xff09 8 SRV05 4 xff08 ESD管 xff
  • C语言中的输入输出函数

    一 字符数据输入输出函数 1 putchar xff0c 输出一个字符 include lt stdio h gt int main char cChar1 cChar2 cChar3 cChar4 cChar1 61 39 H 39 cC
  • printf的执行顺序&++i与i++的区别

    问题的由来 xff1a 在学习C语言预处理命令时看到这样一段 https www cnblogs com clover toeic p 3851102 html span class token macro property span cl
  • Traceback (most recent call last): File “/home/myp4/.local/bin/pip“, line 5, in <module> from

    https blog csdn net weixin 41135864 article details 89817343 Traceback most recent call last File home myp4 local bin pi
  • sys.stderr.write(f“ERROR: {exc}”)

    https www cjavapy com article 1701
  • 为什么PBFT需要三阶段

    首先 xff0c 第一阶段是预提议 xff08 pre prepare xff09 xff0c 这一阶段的主要原因是使用领导可以降低通信复杂度 xff0c 但是我对其没了解 xff0c 就不瞎说了 接着是提议 xff08 prepare x
  • 文件的自定义包发送接收

    需求 对一个特定的文件进行分片发送 xff0c 构造数据包 xff0c 发送数据包 xff0c 接收数据包并提取有效数据 xff0c 对数据组合还原为原文件 设计 当前 xff0c 基于socket的网络编程已成为当今不可替代的编程方法 x
  • 阿里云服务器图形化界面

    https blog csdn net qq 43264202 article details 119578968
  • 安卓开放端口

    https blog csdn net weixin 39737831 article details 109965587
  • Ubuntu14.04 支持ESM

    https discourse ubuntu com t ubuntu advantage client 21788
  • 开启关闭ICMP

    echo request http www xoxxoo com index index article id 780 html redirect https blog csdn net weixin 39684454 article de
  • AD使用技巧

    AD快捷键 快捷键要处在英文模式的情况下才可以使用 xff1a AD测量快捷键 xff1a R AD对齐快捷键 xff1a A AD切换单位快捷键 xff1a Q AD改变栅格快捷键 xff1a G AD视图配置快捷键 xff1a L AD
  • 多传感器融合框架搭建

    架构 src include apps xff1a 节点文件 front end node cpp 前端节点data pretreat node cpp 数据预处理节点back end node cpp 后端节点loop closing n
  • 多传感器融合框架-ESKF

    架构 基本同图优化框架差不多 内容简述 数据预处理节点 订阅imu原始数据 xff0c gnss原始数据 xff0c 完成数据时间戳同步 点云畸变补偿发布如下消息 畸变补偿后的点云 synced cloudgnss里程计 synced gn
  • OpenCV笔记4.3

    C 43 43 读取目录下所有文件名称 1 包含头文件 96 span class token macro property span class token directive hash span span class token dir
  • 半小时内实现Esp32-Cam模型训练和图像识别

    Esp32 Cam图像识别 一 网页显示视频流1 Linux式例程2 MicroPython式例程步骤1 下载Thonny步骤2 烧录Esp32 Cam固件步骤3 运行相应代码 3 Arduino式例程步骤1 下载Arduino步骤2 安装
  • MANIFOLD 2-G开发 之 利用ROS话题编程实现UART1串口通讯

    目录 MANIFOLD 2 G开发笔记1 项目描述2 遇到的问题3 解决方案4 示例代码5 注意事项6 资源附件6 运行与调试 MANIFOLD 2 G开发笔记 本博客内容将记录MANIFOLD 2 G 开发过程中遇到的问题及解决方案 xf
  • ONOS源码笔记--机制

    app注册 private ApplicationId appId appId 61 coreService registerApplication 34 org onosproject fwd 34 注册应用 xff0c 一般在activ