RYU功能开发(一)从simple switch开始

2023-05-16

        对于任意一款控制器,想要快速了解其开发机制,从转发模块入手无疑是最佳的学习方式。RYU通过App的形式提供了一系列功能模块,其中包括使用了OpenFlow作为控制协议的二层交换机控制模块simple_switch_13.py。

        想要理解simple switch的控制逻辑,首先要掌握传统网络下二层交换机的转发学习表工作原理。

        对于每个二层交换机,都会维护一个mac地址表,用于记录mac地址和物理端口的映射关系。默认状态下,mac地址表为空,当交换机在端口A收到一个数据帧时,首先检查帧头中的源mac地址(mac_src),记录mac_src到端口A的映射关系,表示交换机可以通过端口A找到mac_src对应的主机。对于帧头中的目的mac地址(mac_dst),如果没有记录mac_dst与端口的映射关系,则会通过广播的方式将数据帧转发出去。

        假如每个交换机都通过一个唯一的switch_id来标识,那么对于整个二层网络,我们可以得到一个由(switch_id,mac)到端口号(port_num)的映射表。实例:如果存在映射关系(sw1,mac1)→(port_1),那么当sw1收到目的mac地址为mac1的数据帧时,交换机将会从port_1把数据帧转发出去。simple switch模块的核心就是实现了上述映射表的记录,记录在mac_to_port字典中。

        switch_feature_handler函数:

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        match = parser.OFPMatch()
        actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                          ofproto.OFPCML_NO_BUFFER)]
        self.add_flow(datapath, 0, match, actions)

        该函数用于对交换机配置table-miss流表项,实现交换机初始化,table-miss流表项匹配所有数据包,优先级为0,交换机会将匹配到table-miss流表项的数据包发送给控制器,形成packet_in事件。代码中,OFPMatch和OFPActionOutput对应了OpenFlow交换机流表规定的匹配字段和指定端口转发的动作字段,具体实现详见ofproto_v1_3_parser.py

        add_flow函数:

    def add_flow(self, datapath, priority, match, actions, buffer_id=None):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                             actions)]
        if buffer_id:
            mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id,
                                    priority=priority, match=match,
                                    instructions=inst)
        else:
            mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
                                    match=match, instructions=inst)
        datapath.send_msg(mod)

        通过向交换机发送flow_mod消息配置流表。其中datapath表示交换机实例,priority是优先级,注意flow_mod消息中hard_timeout和idle_timeout缺省值为0,表示流表永久存活,可以自行设置其他整数值来为流表项设置生存时间,单位是秒。

        packet_in_handler函数:

    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def _packet_in_handler(self, ev):
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']                # 从in_port得到的该数据帧
        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0] # 获取二层帧头

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            return
        dst = eth.dst
        src = eth.src
        dpid = datapath.id                            # 交换机的id
        self.mac_to_port.setdefault(dpid, {})         # 数据结构格式:{dpid: {mac: port}}
        self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)
        self.mac_to_port[dpid][src] = in_port         # 记录映射信息

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]    # 查找目的mac对应的端口号
        else:
            out_port = ofproto.OFPP_FLOOD             # 如果没有找到,则广播

        actions = [parser.OFPActionOutput(out_port)]

        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=dst, eth_src=src)
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                return
            else:
                self.add_flow(datapath, 1, match, actions)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
                                  in_port=in_port, actions=actions, data=data)
        datapath.send_msg(out)

        packet_in_handler函数通过@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)标签来注册对packet_in事件的监听。对于SDN控制器应用来说,packet_in是最常见的程序入口,通过解析包头字段,获取地址、端口号、包类型等信息。simple_switch的packet_in_handler函数中解析了以太网帧头,得到了源、目的mac地址,记录交换机id、源mac地址到收包端口号。如果交换机记录了到目的mac地址的端口映射,则从对应端口转发出去,否则指定转发端口为FLOOD。

 

有关buffer_id:

Packetin消息:用于标记缓存在交换机中的数据报文id,如报文被action上送到控制器中maxlen字段或者table_miss消息限制长度,而通过bufferid将报文缓存在交换机中,以便被另外两种消息来调用;

Packetout消息:用于控制器将原先buffer在交换机中的报文,通过Packetout个形式从交换机的某个物理口送出去;

Flowmod消息:如果flowmod中带有bufferid,那么说明这个flowmod需要做两件事情,第一是正常下发一条flow,其次是把交换机中先前buffer的那个数据报文,Packetout到table来匹配一次下的这条flow;注意以上两个指令都是通过这个带有bufferid的消息执行的,不需要控制器另外下packet_out消息,这种设计思路是非常巧妙的。

 

大家如果有希望了解的控制器源码,欢迎在评论区进行推荐。

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

RYU功能开发(一)从simple switch开始 的相关文章

  • Windows下安装Redis7.0.8

    目录 一 下载二 解压三 启动服务四 客户端连接测试五 把 redis 安装到服务1 安装2 启动服务3 停止服务4 卸载服务 一 下载 官网上没有 windows 版本的 redis 下载 xff0c 需要到 github 下载 xff1
  • 若依微服务版之集成Mybatis-Plus和Lombok

    目录 一 修改根目录 pom xml二 修改 ruoyi common core 的 pom xml三 去掉 nacos 配置文件中的 mybatis 配置 xff0c 添加 mybatis plus 配置四 添加配置类并注入五 注入类六
  • Windows下安装JDK

    目录 一 下载二 安装三 设置环境变量1 新增环境变量 JAVA HOME2 新增环境变量 CLASS PATH3 环境变量 PATH 添加变量值 四 验证 一 下载 下载链接 xff1a https www oracle com java
  • CentOS7下安装superset

    目录 一 前言二 安装 Miniconda1 下载2 安装3 加载环境变量配置文件4 取消激活 base 环境 三 创建 Python3 9 环境1 配置 conda 国内镜像2 创建 superset 环境并指定 Python3 93 激
  • Java--a++与 ++a 与 a=a+1 与a+=1

    a 43 43 等效 a 61 a 43 1 43 43 a 等效 a 43 61 1 计算顺序的区别 xff1a a 43 43 是先参加程序的运行再 43 1 xff0c 而 43 43 a则是先 43 1再参加程序的运行 举例 xff
  • 数据仓库系列文章二:浅谈企业数据仓库总线矩阵

    Kinball在 数据仓库工具箱 一书中 xff0c 详细阐述维度建模思想 xff0c 并给出维度建模的众多实践 维度建模的核心内容和建设过程在实践中已经被大家所熟知 xff0c 网上教程也很多 xff0c 本文不做赘述 本文重点谈一谈企业
  • Java中 List、Set、Map 之间的区别

    小博此篇记录了开发过程中常用的几种集合详解 xff0c 三者的区别对比均从IDEA相关层次图里面所得知 xff0c 基于JDK8 xff0c 如有错误欢迎批评指正 List 列表 List的元素以线性方式存储 xff0c 可以存放重复对象
  • DuiLib介绍及其消息处理剖析

    DirectUI技术 DirectUI意为直接在父窗口上绘图 Paint on parent dc directly 即子窗口不以窗口句柄的形式创建 windowless xff0c 只是逻辑上的窗口 xff0c 绘制在父窗口之上 微软的
  • xargs命令

    原作者地址 xff1a https www cnblogs com chyingp p linux command xargs html 感谢原作者 Linux基础 xff1a xargs命令 简介 xargs可以将输入内容 xff08 通
  • 为何HBase速度很快?

    为何HBase速度很快 xff1f HBase能提供实时计算服务主要原因是由其架构和底层的数据结构决定的 xff0c 即由LSM Tree Log Structured Merge Tree 43 HTable region分区 43 Ca
  • VirtualBox虚拟机不能ping通宿主机的解决方法

    解决VirtualBox虚拟机不能ping通宿主机的问题 问题描述 在VirtualBox虚拟中 xff0c 无法ping通宿主机 xff0c 宿主机可以ping通虚拟机 虚拟机的网络已经设置为 桥接网卡 xff0c 也可以正常上网 问题原
  • CMake 使用方法 & CMakeList.txt

    cmake 简介 CMake是一个跨平台的安装 编译 工具 可以用简单的语句来描述所有平台的安装 编译过程 他能够输出各种各样的makefile或者project文件 能测试编译器所支持的C 43 43 特性 类似UNIX下的automak
  • Hadoop安装目录

    root software hadoop 2 6 0 cdh5 15 1 etc hadoop 第一步骤 vi core site xml lt configuration gt lt property gt lt name gt fs d
  • 前端之浏览器

    你会不会和我一样 xff0c 开发了N年 xff0c 真要讲起浏览器 xff0c 发现自己一无所知 常用那几种浏览器测试 xff1f IE Safari Chrome Mozilla Firefox Opera 主流浏览器的内核有哪些 xf
  • Navicat远程连接Linux环境下MySQL(错误error:1045/1251/2003(10038)/2059)解决方案

    Navicat远程连接Linux环境下MySQL 错误error 1045 1251 2003 10038 2059 解决方案 心路历程 因为之后要学习有关数据库开发的课程 xff0c 我们需要部署云服务器并添加mysql功能 xff0c
  • MAX30102 血氧调试笔记

    一 血氧测量原理 1 1 PPG波形介绍 血氧饱和度 xff08 英语 xff1a Oxygen saturation xff09 xff0c 或称血氧浓度 xff0c 是指血中氧饱和血红蛋白相对于总血红蛋白 xff08 不饱和 43 饱和
  • HBase - Filter - 过滤器的介绍以及使用 | 那伊抹微笑

    博文作者 xff1a 那伊抹微笑 csdn 博客地址 xff1a http blog csdn net u012185296 itdog8 地址链接 http www itdog8 com thread 214 1 1 html 博文标题
  • sphereface:deep hypersphere embedding for face recognition

    SphereFace算法详解 AI之路 CSDN博客 sphereface 论文 xff1a SphereFace Deep Hypersphere Embedding for Face Recognition 论文链接 xff1a htt
  • python中的isdigit( )的使用

    python中的isdigit 函数是检测输入字符串是否只由数字组成 第三个例子既包含数字 xff0c 也包含字符串的话 xff0c 返回的也是一个False的布尔值 举例 xff1a
  • Debian没有sudo怎么办

    和Ubuntu不同 xff0c sudo命令在原始的Debian系统中时没有的 xff0c 需要额外安装 sudo apt get install sudo 编辑配置文件 xff0c 增加一个可以使用sudo命令的用户名 UserName

随机推荐

  • ES6——给对象部署Iterator接口

    Iterator接口的目的就是为所有数据结构提供一种统一访问的机制 xff0c 用for of 实现 一个数据结构只要有Symbol iterator属性 xff0c 就可以认为是 可遍历的 原型部署了Iterator接口的数据结构有三种
  • 我还在坚持的道路上

    高考 xff0c 一个似乎已经久远的经历但却又有一种恍如昨日的感觉 记得那年 2012年 xff0c 考完最后一场 xff0c 下着大暴雨 xff0c 那一刻有一种终于解放的窃喜但内心又憋着无形的鸭梨 xff0c 不知道最后结果会怎样 不过
  • CodeBlocks的下载安装、配置、简单编程

    IDE简介 http www baidu com s wd 61 codeblocks xff0c 这里只是介绍Windows平台下的 IDE 环境配置 CodeBlocks的下载 安装 配置 xff1a 下载 xff1a http www
  • 四、安装cuDNN,caffe和openCV

    一 安装cuDNN 1 下载cudnn 可以注册再下载 不过有点麻烦 官网https developer nvidia com cudnn 或者百度云下载http pan baidu com s 1hrAMHko 2 安装 tar span
  • 网络爬虫(三)------宽度优先爬虫(一个的基础,简单但是很重要哦)

    在实际项目中 xff0c 我们使用爬虫遍历互联网 xff0c 把网络中相关的网页全部抓取过来 xff0c 这也体现了爬虫的特点 爬虫爬行的过程是这样子的 xff1a 互联网中每一个页面看作是一个节点 xff0c 页面中的链接可以看成图的有向
  • Win10+Ubuntu双系统修复Ubuntu系统引导

    这两天笔者安装win10 43 ubuntu16 04双系统 xff0c 因为网络上能找到大量的资料 xff0c 安装过程此处就不多讲 因为笔者电脑是华硕主板 xff0c bios默认设置为安全启动 xff0c 笔者猜测会阻止加载ubunt
  • 全面分析 Spring 的编程式事务管理及声明式事务管理

    关于本教程 本教程将深入讲解 Spring 简单而强大的事务管理功能 xff0c 包括编程式事务和声明式事务 通过对本教程的学习 xff0c 您将能够理解 Spring 事务管理的本质 xff0c 并灵活运用之 先决条件 本教程假定您已经掌
  • classpath*作用

    classpath It refers to a list of resources and loads all such files present in the classpath and list can be empty and i
  • java 8 根据map 字段值 去重

    java 8 根据map 字段值 去重 span class token class name List span span class token generics span class token punctuation lt span
  • java 8 去重

    span class token comment 取差集 span span class token class name List span span class token generics span class token punct
  • 解读程序员的武侠世界,顶级程序员是内外兼修的大侠,那么你呢?

    在漫天的星河中 xff0c 有这样一颗星 xff0c 他朴实无华 xff0c 却又熠熠生辉 xff0c 照亮了无数人的人生 他就是金庸先生 随着一代大侠的驾鹤西去 xff0c 飞雪连天射白鹿 xff0c 笑书神侠倚碧鸳 xff0c 成为绝响
  • Eclipse使用入门教程

    Eclipse使用入门教程 说起java的IDE xff0c 朗朗上口的无非是Eclipse了 xff0c 假若能熟练Eclipse xff0c 对于我们编写java程序会起到事半功倍的效果 xff0c 大大提高我们工作效率 因此本篇博文
  • Win7 + Ubuntu16.04 双系统安装

    之前安装win7 43 Ubuntu14 04双系统 xff0c 后来换成win10用了一段时间后觉得有些卡 xff0c 而且装双系统装了几次都成功 xff0c 所以又换回了win7系统 xff0c 并重新安装了win7 43 Ubuntu
  • 双系统Ubuntu 引导修复(Boot Repair)

    安装完双系统 xff0c 如果在使用过程中不小心删除了Ubuntu引导向 xff0c 则会导致开机后无法选择进入Ubuntu系统 或者当我们重装了windows系统后 xff0c 也会发现原来的Ubuntu引导不见了 xff0c 当出现这两
  • 数据库为何要有复合主键(多主键)

    最近学习一点数据库的基本知识 xff0c 被一个问题困惑了许久 xff1a 主键是唯一的索引 xff0c 那么为何一个表可以创建多个主键呢 xff1f 其实 主键是唯一的索引 这话有点歧义的 举个例子 xff0c 我们在表中创建了一个ID字
  • @JSONField 注解详解和应用

    讲到 64 JSONField 注解 xff0c 就不得不提到Alibaba 开源的fasejson fastjson是目前java语言中最快的json库 xff0c 比自称最快的jackson速度要快 xff0c 第三方独立测试结果看这里
  • 外部访问docker容器(docker run -p/-P 指令)

    容器中可以运行一些网络应用 xff0c 要让外部也可以访问这些应用 xff0c 可以通过 P xff08 大写 xff09 或 p xff08 小写 xff09 参数来指定端口映射 xff08 1 xff09 当使用 P 标记时 xff0c
  • 解决Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题

    LocalDate LocalTime LocalDateTime 是Java 8开始提供的时间日期API xff0c 主要用来优化Java 8以前对于时间日期的处理操作 然而 xff0c 我们在使用Spring Boot或使用Spring
  • gcc 编译选项

    原来 Os相当于 O2 5 是使用了所有 O2的优化选项 xff0c 但又不缩减代码尺寸的方法 ffunction sections fdata sections Place each function or data item into
  • RYU功能开发(一)从simple switch开始

    对于任意一款控制器 xff0c 想要快速了解其开发机制 xff0c 从转发模块入手无疑是最佳的学习方式 RYU通过App的形式提供了一系列功能模块 xff0c 其中包括使用了OpenFlow作为控制协议的二层交换机控制模块simple sw