OpenvSwitch系列之flow_mod

2023-10-20 12:50
文章标签 mod 系列 flow openvswitch

本文主要是介绍OpenvSwitch系列之flow_mod,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近两周一直在研究flow_mod这个消息,flow_mod这个消息是openflow中最重要的消息,没有之一,所以花在它的时间上比较多,而且里面涉及的内容也比较复杂。社区有一篇博文对我帮助还是很大。因此这边可能和他的文章有一部分冲突,但是对于学习和总结无所谓啦!!

我们在上一篇中有介绍了,OpenvSwitch是如何进行不同openflow协议版本的控制的,也知道了入口函数是handle_openflow__,本文的主题是flow_mod消息,因此我们直接进入flow_mod处理函数。

众所周知,flow_mod是用于下发流表的。可以简单理解为一个flow_mod就是就是一个流表项。如果有谁不是很了解flow_mod,请自行阅读openflow协议。

通过入口函数openflow_handle__可以知道flow_mod处理函数是,为了描述相对清晰,我会在代码中直接进行注释,除了需要特别指出或者着重描写才在博文中单独写出来。

上面是flow_mod函数处理框架,下面我们进行逐个分析,我们进行分析时候会结构flow_mod消息,因此有具体的消息内容,我们在分析代码的时候不至于那么抽象。

下面报文就是我抓取的,比较有针对性,控制器下发的流表是从host1到host2,出端口是交换机的2。具体报文和网络拓扑如下:


注:红色线就是打通的通道。
由于函数ofputil_decode_flow_mod相对较长,因此采用分段描述,层层深入方式进行剖析。

上面内容相对简单,也不用多说些。下面是我们进行着重分析的。由于我们基于openflow1.3进行连接的,因此raw实际值是OFPRAW_OFPT11_FLOW_MOD。(opeflow1.1之后版本flow_mod没有变化。)在这里就有if-else判断,所以我们会着重分析if分支。
一般情况下,flow_mod消息主要是由openflow固定字段,match字段,instruction字段(可以没有),然而match字段中可以包含多个oxm字段(可以没有oxm),instruction字段中可以包含多个action字段。其中oxm格式是TLV(Type-Length-Value)。针对上面的报文来说,oxm有两个,action只有一个。所以我们能够预测if分支中主要是针对这些字段进行解析。

以上就是flow_mod解析函数大体框架,下面我们来看一下match、instruction这两个解析函数。首先我们来看一下函数调用关系图:

根据关系图,从函数3、函数4内容都比较短小,函数也比较容易理解,我们从函数5开始进行分析,分析如下:

在介绍nx_pull_raw函数之前,我们先看来看一下这个全局数组const struct mf_field mf_fields[MFF_N_IDS](在文件meta-flow.c),这个数组在下面的函数会用到mf_from_nxm_header。所先把分析一下。

这个虽然数组很长,但是里面的注释对于理解还是有帮助的,数组中是按照网络层次进行划分的,主要是metadata, L2, L2 .5,L3, L4, L5。也就是说根据报文中match字段可得出位于数组的哪层。例如上面报文,是针对物理地址(源/宿mac)那么我们可以推断出是位于数组的L2,如下面代码所示:

我们来看一下蓝色字体,这个宏定义
枚举:

通过上面代码罗列可得知,OXM_HEADER是用于构造报文OXM头部的宏,而OXM是以TLV格式进行封装的。针对上面报文和宏定义就有如下对应(图片蓝色下划线):

经过函数nxm_do_init处理,会把这个数组中成员挂在全局变量all_fields,这个变量是一个hmap结构,至于这里具体存储关系是怎么关联的,这里不进行详细解析(可以参考函数nxm_do_init)。如果有不理解hmap的网友可以去看一下我之前文章。下面我们继续分析nx_pull_raw函数。

上面分析比较混乱,这里进行一下总结:
1、通过上面这个函数处理(核心代码是for循环),就会把报文中两个oxm字段解析成功并且保存在入参match里面。
2、我们知道oxm表现形式是一个tlv格式,OpenvSwitch会把value字段赋值到match结构体中的,struct flow(flow.h)结构体。flow这个结构体和mf_fields是有关联关系的。
3、通过上面解析后,flow中字段数据时这样的(实际内存中没有冒号):
flow.dl_dst[6] = 00:00:00:00:00:02
flow.dl_src[6] = 00:00:00:00:00:01
其他字段是默认值,大部分是0。

通过上面的一系列分析,openflow中的match字段就结束了。现在我们返回到函数ofputil_decode_flow_mod中,下面应该解析instructions。

基于目前OpenvSwitch实现主要支持这6中actions,分别是:openflow1.3中meter表,openflow1.1中apply_action,openflow1.1中clear_action,openflow1.1中write_action,openflow1.1中write_metadata,openflow1.1中goto_table。针对当前的flowmod中action是apply_action,如下图所示:

在介绍函数之前,我们先来看一下函数中即将用到指针数组,const struct ofp11_instruction *insts[N_OVS_INSTRUCTIONS],通过查看宏定义可知, N_OVS_INSTRUCTIONS=6

默认指针数组中保存地址是null,经过处理后会把其中某个数组存储单元修改为有效地址。针对上面那个报文,instructions的类型是apply_actions,因此经过函数decode_openflow11_instructions会把数组下标为OVSINST_OFPIT11_APPLY_ACTIONS的值修改为有效地址(即上图中红色字体)。 

现在我们来看一下这个函数代码,下面红色字体就是那6种action:

我们现在来分析一下这两个函数:decode_openflow11_instructions(解析instructions函数)和ofpacts_from_openflow(解析actions函数)。

函数decode_openflow11_instructions主要是循环遍历,不断解析instructions,内部最终处理函数是decode_openflow11_instruction,对于这个函数,比较难看懂,主要是因为里面switch-case子句是通过宏定义的,这样不便于理解。然而我们可以借助编译器(GCC),让它帮我们展开宏定义。由于展开后代码变得非常庞大,因此我只相关代码展示出来:

我们再来看一下actions解析函数,上面已经说过了,对于openflow1.3的actions报文,最终会进入这个ofpact_from_openflow11函数,函数主体代码如下:

这篇关于OpenvSwitch系列之flow_mod的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/247205

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

GNSS CTS GNSS Start and Location Flow of Android15

目录 1. 本文概述2.CTS 测试3.Gnss Flow3.1 Gnss Start Flow3.2 Gnss Location Output Flow 1. 本文概述 本来是为了做Android 14 Gnss CTS 的相关环境的搭建和测试,然后在测试中遇到了一些问题,去寻找CTS源码(/cts/tests/tests/location/src/android/locat

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训

Java基础回顾系列-第七天-高级编程之IO

Java基础回顾系列-第七天-高级编程之IO 文件操作字节流与字符流OutputStream字节输出流FileOutputStream InputStream字节输入流FileInputStream Writer字符输出流FileWriter Reader字符输入流字节流与字符流的区别转换流InputStreamReaderOutputStreamWriter 文件复制 字符编码内存操作流(

Java基础回顾系列-第五天-高级编程之API类库

Java基础回顾系列-第五天-高级编程之API类库 Java基础类库StringBufferStringBuilderStringCharSequence接口AutoCloseable接口RuntimeSystemCleaner对象克隆 数字操作类Math数学计算类Random随机数生成类BigInteger/BigDecimal大数字操作类 日期操作类DateSimpleDateForma

Java基础回顾系列-第三天-Lambda表达式

Java基础回顾系列-第三天-Lambda表达式 Lambda表达式方法引用引用静态方法引用实例化对象的方法引用特定类型的方法引用构造方法 内建函数式接口Function基础接口DoubleToIntFunction 类型转换接口Consumer消费型函数式接口Supplier供给型函数式接口Predicate断言型函数式接口 Stream API 该篇博文需重点了解:内建函数式

Java基础回顾系列-第二天-面向对象编程

面向对象编程 Java类核心开发结构面向对象封装继承多态 抽象类abstract接口interface抽象类与接口的区别深入分析类与对象内存分析 继承extends重写(Override)与重载(Overload)重写(Override)重载(Overload)重写与重载之间的区别总结 this关键字static关键字static变量static方法static代码块 代码块String类特