ONOS-ifwd-app源码分析总结

2023-05-16

ONOS-ifwd源码分析,参考资料:https://www.sdnlab.com/10297.html
在之前的文章中,介绍了ONOS-sample-apps的获取,但是将其生成的oar文件导入到ONOS-2.0及其以上版本的时候,是不能够运行的,本文在参考了一些资料的基础上,解决ifwd模块对ONOS版本的不兼容问题,并且对ifwd的源码进行分析学习。

1.源码的修改

1.将import里面的apache服务修改成osgi组件,如下

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;

将以上代码修改为

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;

2.修改Reference服务的关键字参数,将

 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected TopologyService topologyService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PacketService packetService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected HostService hostService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected FlowRuleService flowRuleService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected StatisticStore statisticStore;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected FlowObjectiveService flowObjectiveService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

修改为:


    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected TopologyService topologyService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected PacketService packetService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected IntentService intentService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected HostService hostService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected FlowRuleService flowRuleService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected FlowObjectiveService flowObjectiveService;

2.POM文件的修改

由于ifwd模块在拉取下来的时候,pom文件的onos版本是1.8.0版本的,以及依赖也有一些缺失。可以直接粘贴复制我修改后的pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright 2014-2016 Open Networking Foundation
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~     http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.onosproject</groupId>
        <artifactId>onos-dependencies</artifactId>
        <version>1.8.0</version>
        <relativePath/><!-- parent is remote -->
    </parent>

    <artifactId>onos-app-ifwd</artifactId>
    <version>1.8.0-SNAPSHOT</version>
    <packaging>bundle</packaging>

    <description>Reactive forwarding application using intent service (experimental)</description>

    <properties>
        <onos.version>2.0.0</onos.version>
        <onos.app.name>org.onosproject.ifwd</onos.app.name>
        <onos.app.origin>ON.Lab</onos.app.origin>
        <onos.app.title>Reactive Forwarding App (Intent)</onos.app.title>
        <onos.app.category>Traffic Steering</onos.app.category>
        <onos.app.url>http://onosproject.org</onos.app.url>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.onosproject</groupId>
            <artifactId>onos-api</artifactId>
            <version>${onos.version}</version>
        </dependency>

        <dependency>
            <groupId>org.onosproject</groupId>
            <artifactId>onos-core-common</artifactId>
            <version>${parent.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.scr.annotations</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
     
            </plugin>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-scr-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.onosproject</groupId>
                <artifactId>onos-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3.ifwd模块的运行测试

在IDEA执行mvn clean compile,mvn install,然后在ONOS-WEB-UI界面上将对应的oar模块导入,启动openflow模块,然后启动Mininet进行连通性测试。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

4.ifwd源码分析

1.Karaf技术相关解析:由于ONOS控制器是使用Karaf技术的,而在ifwd模块中,会使用到Karaf加载模块。下面对源码中Karaf组件加载的关键字进行说明。

Component(immediate = true) – 声明一个类作为组件激活,并且强制立即激活
Activate – 标记一个方法作为组件启动时调用
Deactivate – 标记一个方法作为组件关闭时调用
Reference(Cardinality = ReferenceCardinality.MANDATORY_UNARY) – 标记一个服务作为一个应用程序的依赖,并且在该应用程序启动之前,需要这样服务的一个实例被提前加载。

更多信息:http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/scr-annotations.html。

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected TopologyService topologyService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected PacketService packetService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected IntentService intentService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected HostService hostService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected FlowRuleService flowRuleService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected FlowObjectiveService flowObjectiveService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected PortStatisticsService portStatisticsService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected LinkService linkService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected DeviceService deviceService;

对于上面的源码,翻译过来就是在运作ifwd的其他代码的时候,Karaf会先激活并且调用ONOS的核心服务,拓扑服务,包服务,意图网络服务,主机服务,流表规则服务,流对象服务,端口服务,链路服务,设备服务。

private ApplicationId appId;

由于应用程序在使用ONOS提供服务的时候,都需要有一个application ID,因此要定义一个appId,后面注册的时候使用。

private ReactivePacketProcessor processor = new ReactivePacketProcessor();

这里新建了一个包处理对象,用于后面对接受报文的处理。

private static final int DROP_RULE_TIMEOUT = 300;

private static final EnumSet<IntentState> WITHDRAWN_STATES = EnumSet.of(IntentState.WITHDRAWN,
                                                                            IntentState.WITHDRAWING,
                                                                            IntentState.WITHDRAW_REQ);

这里定义了流表的持续时间,以及一个枚举,用于说明IntenState的状态
IntentState:表示一个意图在其生命周期当中可能达到的状态
IntentState.WITHDRAWN:表示这个意图成功被撤回
IntentState.WITHDRAWING:表示这个意图正在被撤回
IntentState.WITHDRAW_REQ:表示一个应用程序请求撤回一个意图

    @Activate
    public void activate() {
        appId = coreService.registerApplication("org.onosproject.ifwd");

        packetService.addProcessor(processor, PacketProcessor.director(2));

        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
        selector.matchEthType(Ethernet.TYPE_IPV4);
        packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);

        log.info("Started");
    }

标记该代码块在组件启动时要先调用,向核心服务注册一个ApplicationId,决定包处理器的优先级,新建一个流选择处理器,并且指定处理的包的IP类型为IPV4。最后是调用packetService.requestPackets方法,输出对应的参数。
这样子,在该模块启动的时候,当接受到包的时候,就能够根据我们设定好的方法进行报文的处理。

    @Deactivate
    public void deactivate() {
        packetService.removeProcessor(processor);
        processor = null;
        log.info("Stopped");
    }

标记该代码块在该组件关闭的时候调同。主要完成的工作是将包处理器移除并且置空。

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

            HostId srcId = HostId.hostId(ethPkt.getSourceMAC());
            HostId dstId = HostId.hostId(ethPkt.getDestinationMAC());

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

            // Otherwise forward and be done with it.
            setUpConnectivity(context, srcId, dstId);
            forwardPacketToDst(context, dst);


        }
    }

在该代码块,对包处理器进行覆写,以定义我们想要的包转发行为。
一、定义处理方法,需要输入数据包作为参数:
1.判断该包是否已经被处理,若已被处理,则返回
2.将正在处理的入站数据包传递给pkt
3.用以太类型的ethPkt接收入站数据包的解析类型
4.如果该包的解析类型为空,则返回
5.获取该包的源MAC地址,目的MAC地址
6.根据目的MAC地址,在拓扑上精准确定目的主机,若目的主机为空,则调用flood方法,对包进行洪泛
7.目的主机不为空,调用setUpConnectivity方法,在目的节点与源节点之间建立连接
8.调用forwardPacketToDst方法,对包进行转发

    private void flood(PacketContext context) {
        if (topologyService.isBroadcastPoint(topologyService.currentTopology(),
                                             context.inPacket().receivedFrom())) {
            packetOut(context, PortNumber.FLOOD);
        } else {
            context.block();
        }
    }

    // Sends a packet out the specified port.
    private void packetOut(PacketContext context, PortNumber portNumber) {
        context.treatmentBuilder().setOutput(portNumber);
        context.send();
    }

下面对flood方法及其需要用到的方法packetOut进行学习分析
flood方法,需要输入的参数是PacketContext
1.判断设备上的端口是否为收到该包的端口,如果不是的话,调用packetOut方法
2.若设备上的端口是收到该包的端口,阻塞该端口
packetOut方法,需要输入的参数是PacketContext,PortNumber
1.新建一个流量处理生成器,再输入对应的端口参数
2.发送该包

setUpConnectivity利用了ONOS-intent-framework,具体的学习分析以及心得在后面跟大家分享。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ONOS-ifwd-app源码分析总结 的相关文章

  • 高德地图绘制标记点,点击弹出弹框进入第三方地图软件

    需求 根据经纬度绘制标记点 点击标记点弹出弹框和底部按钮 点击顶部弹框进入二级界面 点击底部按钮弹出第三方地图软件选择页 实现跨进程跳转 效果图 项目是公司项目 只放出重要部分代码 final Marker marker1 aMap add
  • 如何申请安卓证书,申请安卓证书的流程是什么?

    用HBuilderX打包安卓正式app时 我们需要使用自有证书 安卓证书是免费申请的 虽然HBuilderX有申请教程 为了自己后期使用方便 今天给大家分享下详细的申请教程 HBuilderX的文档 https ask dcloud net
  • Android App软件框架搭建

    1 App软件框架搭建 1 0软件基本架构 1 1创建MainActivity并设置布局文件 布局文件如下
  • APP移动应用测试策略与工具思维导图

    2张图构建移动应用测试知识体系 1 APP移动测试策略 2 移动测试常用工具 目前觉得好用的 因还有其它事 故这里不再啰嗦 想要听我啰嗦的 改天书里见
  • iOS开发实战之app获取通讯录(iOS 9)

    在做通讯类APP的时候 时常会访问到手机的通讯录 来获取联系人的各种属性 那么本文就来讨论一下怎么获取通讯录 注意 iOS 9 版本上可以行 其他版本未试 第一步 先导入系统库 Contacts framework 然后在 h上导入头文件
  • 手机串口终端

    手机串口终端 做嵌入式开发的小伙伴永远离不开串口 想想一下 假设你需要进行现场调试 但是身边没有电脑 或者其他特殊环境不方便用电脑 或者就是单纯的懒得用电脑 该怎么办 这就是我碰到的场景 而且不止一次 说多了都是泪 别问 这种情况你就只能把
  • Poppuwindow的简单使用

    继 DialogFragment的简单使用 之后 我们再来试试 Poppuwindow 的简单使用 切记 本篇博客只能保证你入门哦 适合小白学习 效果展示 1 几个常用的构造方法 public PopupWindow Context con
  • Android APP 与STM32无线环境控制系统

    本系统为安卓APP的环境参数远程监控系统 以STM32F103单片机作为本设计的中控中心 结合物联网技术 以Android智能手机作为远程控制的客户端 通过8266 WiFi模块实现环境监控系统硬件与Android手机的交互 环境参数的反馈
  • Android 开发中ScrollView无法上下滚动

    本节目录 问题 解决办法 问题 因项目需要做一个App出来 所以最近在学Android Studio开发 但是我在利用ScrollView实现内容上下滚动的时候出现了一个问题 就是无法将超出页面的内容进行上下滑动 设计UI界面如下 这里的T
  • App6种常见的数据加载设计

    设计师在进行APP设计的设计时 往往会更加专注于界面长什么样 界面和界面之间怎么跳转 给予用户什么样的操作反馈 却偏偏特别容易忽略掉一个比较重要的环节 就是APP数据加载中的设计 所以会导致我们看到的APP 往往有着华丽的启动界面 然后就是
  • 安卓图片浏览app,应付期末考试的(附下载链接)

    安卓图片浏览app 一个简单的安卓app 采用andstudio开发 有注册登录功能 可以搜索详细情况请看应用截图所示 下载链接 https download csdn net download weixin 43474701 850717
  • APPCAN + wampserver 实现简单的个人登录功能

    开发背景 Appcan wampserver 其中wampserver主要用于提供本地服务器和数据库 这是软件开发工程这门课中的一个大作业 需要实现 1 首页 index html 首页包含 滚动图片 新闻列表和导航栏 首页内容通过Requ
  • 关于as遇到的Enable "Android Support" Plugin错误问题

    元旦休息了3天 17年第一天上班打开as就遇到了这个facets cannot be loaded you can mark them as ignored to suppress this error错误问题 蛋疼得很 当然既然遇到了 就
  • 惊呆了!女儿拿着小天才电话手表,问我Android启动流程!

    首先 new一个女儿 var mDdaughter new 女儿 6岁 漂亮可爱 健康乖巧 最喜欢玩小天才电话手表和她的爸爸 好了 女儿有了 有一天 女儿问我 爸爸爸爸 你说我玩的这个小天才电话手表怎么这么厉害 随便点一下这个小图片 这个应
  • chromecast 协议_Chromecast和Android TV有什么区别?

    chromecast 协议 Google isn t particularly known for its clear branding This is certainly the case when it comes to Chromec
  • uniapp打包app后,ios端微信登录报错,login:fail [:-1]未能完成操作。(PGWXAPI错误-1。)

    报错内容 errMsg login fail 1 未能完成操作 PGWXAPI错误 1 errCode 100 code 100 报错原因 在manifest json文件 视图模式里面只有appid和 ios平台通用链接两个配置 需要在m
  • Android Studio 中Gradle Build时报错:请求的操作无法在使用用户映射区域打开的文件上

    今天在运行Android项目 Android Studio 中Gradle Build时报错 请求的操作无法在使用用户映射区域打开的文件上执行 1 问题描述 Error java io FileNotFoundException F And
  • APP、软件版本号的命名规范与原则

    APP 软件版本号的命名规范与原则 为了在软件产品生命周期中更好的沟通和标记 我们应该对APP 软件的版本号命名的规范和原则有一定的了解 1 APP 软件的版本阶段 Alpha版 也叫 版 此版本主要是以实现软件功能为主 通常只在软件开发者
  • [2024]基于springboot的租房(房屋租赁)小程序设计

    目录 一 整体目录 示范 文档含项目技术介绍 E R图 数据字典 项目功能介绍与截图等 二 运行截图 三 代码部分 示范 四 数据库表 示范 数据库表有注释 可以导出数据字典及更新数据库时间 欢迎交流学习 五 主要技术介绍 六 项目调试学习
  • java.lang.NoSuchFieldError:DEF_CONTENT_CHARSET

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

随机推荐