openvswitch group hash实现代码分析

news2024/11/25 22:54:22

代码分析

ovs版本是2.11.0,linux版本是linux-3.10.0-693.21.1.el7。

只拿ovs实现的group hash和dp_hash举例分析代码,通过一个点一个功能切入代码,漫无目的看代码是很难看懂的,必须带着一个疑问看代码,点多了全面开花,从点到面,慢慢就搞定代码了。

代码分析的场景就是一个虚拟机中curl一个vip。

ovs都说首包从datapath上送到vswitchd那就找找vswitchd从哪开始处理首包的。

main
 └─bridge_run
    └─bridge_reconfigure
       └─ofproto_create
          └─construct
             └─open_dpif_backer
                ├─udpif_create
                |   └─dpif_register_upcall_cb//kernel为NULL,用于DPDK
                ├─udpif_set_threads
                |  └─dpif_handlers_set
                └─udpif_start_threads
                   └─udpif_upcall_handler
                      ├─dpif_recv
                      |  └─dpif_netlink_recv
                      |     └─dpif_netlink_recv__
                      |        └─parse_odp_packet
                      └─recv_upcalls

vswitchd启动时创建了udpif_start_threads几个thread,这几个thread循环调用recv_upcalls处理上送的首包。

再找datapath首包是在什么地方上送的。

#linux kernel datapath
ovs_vport_receive
  ├─ovs_flow_key_extract
  |   └─key_extract
  └─ovs_dp_process_packet
      ├─if ovs_flow_tbl_lookup_stats
      |   └─ovs_dp_upcall
      |      └─queue_userspace_packet
      |          └─ovs_nla_put_key
      |              └─__ovs_nla_put_key
      └─else ovs_execute_actions
          ├─case OVS_ACTION_ATTR_OUTPUT
          └─do_output
              └─ovs_vport_send

首包来了先从skb上ovs_flow_key_extract生成flow key,再根据key查找 表ovs_flow_tbl_lookup_stats,查找不到,那就上送vswitchd。

vswitchd收到开始处理,包来的ofport是知道,这个ofport在哪个桥上是知道的,那就从这个桥的table 0开始查找,匹配上了就执行动作,如果碰到goto或者resubmit那么就换个table继续查找,如果碰到normal或者output patch port,那么就换桥了,现在假如到了br-tun桥了,继续从table 0开始查找,最后到了table 20,动作是group:1001,要执行pick_select_group。

如果是hash,找到bucket,然后xlate_group_bucket,安装流表,下发datapath执行动作。

如果是dp_hash,此时flow中在hash值为空,找不到bucket,找不到就触发ctx_trigger_recirculate_with_hash,来了一次freezing,而finish_freezing中给datapath下的消息中添加了两个动作OVS_ACTION_ATTR_HASH和OVS_ACTION_ATTR_RECIRC,安装一条流,这给条是这样的:

ufid:f4352588-1396-47a7-aff7-98ce54931e72, recirc_id(0),dp_hash(0/0),skb_priority(0/0),in_port(tap240cf299-12),skb_mark(0/0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),eth(src=fa:16:3e:e5:cb:19,dst=fa:16:3e:ec:85:20),eth_type(0x0800),ipv4(src=0.0.0.0/0.0.0.0,dst=0.0.0.0/0.0.0.0,proto=0/0,tos=0/0,ttl=0/0,frag=no), packets:9, bytes:978, used:1.972s, flags:P., dp:ovs, actions:push_vlan(vid=30,pcp=0),hash(l4(0)),recirc(0x5a6)

包又下给了datapath。

recv_upcalls
 ├─odp_flow_key_to_flow
 ├─upcall_receive
 |  └─xlate_lookup
 |     └─xlate_lookup_ofproto_
 ├─process_upcall
 | └─upcall_xlate
 |   ├─xlate_in_init
 |   ├─xlate_actions
 |   |  ├─rule_dpif_lookup_from_table
 |   |  |  └─rule_dpif_lookup_in_table
 |   |  ├─rule_get_actions
 |   |  └─do_xlate_actions
 |   |     ├─freeze_unroll_actions
 |   |     |  └─freeze_put_unroll_xlate
 |   |     ├─xlate_group_action
 |   |     |  ├─pick_select_group//报文第一次找不到bucket
 |   |     |  |  └─pick_dp_hash_select_group
 |   |     |  |     └─ctx_trigger_recirculate_with_hash
 |   |     |  └─xlate_group_bucket//第二次找到bucket才执行这里
 |   |     |     ├─ofpacts_execute_action_set
 |   |     |     └─do_xlate_actions//相当于递归了
 |   |     └─finish_freezing//报文第一次来执行这里
 |   |        ├─xlate_commit_actions
 |   |        |  └─commit_odp_actions
 |   |        └─finish_freezing__
 |   |           ├─recirc_alloc_id_ctx
 |   |           ├─把OVS_ACTION_ATTR_HASH和OVS_ACTION_ATTR_RECIRC下给datapath 
 |   |           └─ctx_cancel_freeze
 |   └─ukey_create_from_upcall
 └─handle_upcalls
    └─dpif_operate
       ├─ukey_install
       └─dpif_operate//给datapath安装流表和把skb发回内核
          ├─if dpif_netlink_operate
          └─else dpif_execute_with_help
             └─odp_execute_actions
                ├─计算hash
                └─dpif_execute_helper_cb
                   └─dpif_operate         

继续看datapath接着怎么处理,匹配上刚才看的那条流了,计算hash值,执行recirc,又重头开始了,key要找不到了,再上送vswitchd。

ovs_packet_cmd_execute
  ├─ovs_flow_key_extract_userspace
  ├─ovs_nla_copy_actions
  └─ovs_execute_actions
     └─do_execute_actions
         ├─case OVS_ACTION_ATTR_HASH
         |   └─execute_hash
         |       └─skb_get_hash
         |           └─__skb_get_hash
         └─case OVS_ACTION_ATTR_RECIRC
             └─ovs_dp_process_packet

vswitchd重复刚才的处理,这次key中多了个hash值,终于找到bucket了,又下了一条流,包再下发给datapath。

ufid:ee6e45b0-4e62-43e9-8a6c-87573ece1cc7, recirc_id(0x5a6),dp_hash(0x9/0xf),skb_priority(0/0),in_port(tap240cf299-12),skb_mark(0),ct_state(0/0),ct_zone(0/0),ct_mark(0/0),ct_label(0/0),eth(src=00:00:00:00:00:00/00:00:00:00:00:00,dst=00:00:00:00:00:00/00:00:00:00:00:00),eth_type(0x8100),vlan(vid=30,pcp=0),encap(eth_type(0x0800),ipv4(src=0.0.0.0/0.0.0.0,dst=0.0.0.0/0.0.0.0,proto=0/0,tos=0/0x3,ttl=0/0,frag=no)), packets:7, bytes:816, used:1.971s, flags:P., dp:ovs, actions:set(tunnel(tun_id=0x3e8,src=10.145.69.26,dst=10.162.143.7,ttl=64,tp_dst=4789,flags(df|key))),pop_vlan,vxlan_sys_4789

这次datapath成功匹配上了,执行ovs_execute_actions中的OVS_ACTION_ATTR_OUTPUT,最终调用到ovs_vport_send就发送出去了,ovs vxlan实现留下次代码分析再写,最近一个任务就是测试和分析ovs vxlan和物理交换机vxlan性能对比。

几个回合之后没包需要再传输了,刚才安装的datapath flow需要老化,老化又就是怎么实现的。

udpif_start_threads
  └─udpif_revalidator
     ├─revalidate
     |   ├─dpif_flow_dump_next
     |   ├─udpif_get_n_flows
     |   ├─delete_op_init__
     |   └─push_dp_ops
     └─revalidator_sweep

问题

测试hash没有问题,但测试dp_hash时偶尔会出问题,tcp三次握手,syn包发送给了dpvs节点6,dpvs节点6给回复syn+ack,接着ack包居然发送给了dpvs节点7,后面就是两方不断重传,终于有一次push+ack发送到了dpvs节点6,后面又搞给了dpvs节点7,乱套了。

vswitchd的log中出现了两个hash时,并且recircid也在变,recirc_id再变说明datapath流表老化,流中的报文又重新upcall到用户态了。

内核execute_hash->skb_get_hash调用到flow_dissector计算hash时没有用到tcp flag,hash值不会变,内核出错的概念也不大。

不断抓包观察到是重传间隔时间越来越长,终于有一次push+ack包才回到dpvs节点6上,说明是datapath流表老化了,又上用户态,难道一个hash值是用户态计算的,另一个hash值是datapath计算的,但OVS_ACTION_ATTR_HASH没有用到SLOW_ACTION,是在内核态执行的,ovs用户态代码实现太多了,难道我漏看了什么,怀疑大概率还是一个hash值是用户态计算的,另一个在内核态计算的,代码注释中说用户态OVS_ACTION_ATTR_HASH只用于bond,即使和datapath hash值不同也没有问题,可能会导致报文乱序,但交换机不在乎,但这儿的使用场景不行,包发给错的dpvs节点,dpvs节点没有session,包直接丢了,一条流只能hash到一个dpvs节点。在代码在还是没有看明白什么地方设置LOW_ACTION的。

原文链接“https://zhuanlan.zhihu.com/p/337143779” 

(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂

更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! ! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/46845.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

降低点云密度的几种方法(含python代码)

本文只是对学习过程中的点云密度降采样的几种方法做一个记录,原文参考知乎Python点云数据处理(四)点云下采样 - 知乎 (zhihu.com) 本文介绍python点云数据处理中的点云下采样算法和关键点算法以及在点云工具箱软件中的实现。由于点云的海量和无序性,直接…

Java基于springboot+vue的房屋出租租房系统 前后端分离

伴随着全球信息化发展,行行业业都与计算机技术相衔接,计算机技术普遍运用于各大行业,房屋出租管理系统便是其中一种。实施计算机系统来管理可以降低大学生租房管理的成本,使整个大学生租房的发展和服务水平有显著提升。 本论文主要…

umask 设置文件权限掩码

我们在创建文件或者目录时,看到的权限往往和我们设置的不一样,原因就在于创建文件时要受到 umask的影响。 目录 一、实际情景介绍 二、文件权限掩码 1、什么是权限掩码? 2、权限掩码的作用过程 3、设置权限掩码的两种方式 (1) umask 命…

【java基础系列】14- Java的内部类与常用类

Java的内部类与常用类 1、内部类 1.1 内部类的分类 成员内部类静态内部类局部内部类匿名内部类 1.2 什么是内部类? 概念:在一个类的内部再定义一个完整的类。特点: 编译之后可生成独立的字节码文件。内部类可直接访问外部类的私有成员&a…

【HIT-OSLAB-实验报告】

文章目录前言实验 0 环境的搭建实验原理&材料实验流程建议实验1 输出硬件参数实验内容基础知识实验代码实验结果实验2 实现系统调用实验内容whoami()评分标准基础知识实验代码实验结果实验3 进程运行轨迹的跟踪实验内容基础知识实验代码实验结果结合自己的体会 从程序设计者…

Elasticsearch

一、Spring Data 1、简介 Spring Data 是一个用于简化数据库、非关系型数据库、索引库访问,并支持云服务的开源框架。Spring Data 可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据库的访问和操作。除了 CRUD 之外&#xff…

作业-11.29

将txt中的单词转到数据库中 #include <stdio.h> #include <sqlite3.h> #include <stdlib.h> #include <string.h> void do_insert(sqlite3* db, int id, char word[], char jieshi[]); void txt_todatabase(sqlite3* db); int main(int argc, const ch…

DevExpress FMX Data Grid全面编辑和定制

DevExpress FMX Data Grid全面编辑和定制 FMX数据网格(CTP)FireMonkey(FMX)的高性能数据网格组件&#xff0c;具有集成的主细节和数据分组支持。它被优化并构建为与RAD Studio/Delphi/CBuilder一起使用。它支持Windows、Android和macOS平台。 DevExpress FMX数据网格功能强大&a…

redis介绍和理解

官网 介绍: https://www.bilibili.com/video/BV1Fd4y1T7pD/?spm_id_from333.337.search-card.all.click&vd_source4c263677a216945c0d21ca65ee15a5f9 Redis是一个key value的数据库&#xff0c;基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库。 https://ww…

【Java+LeetCode训练】binarySearch源码解析

二分搜索Arrays.binarySearch(int[] a,int key)源码分析【LeetCode】209. 长度最小的子数组解法1&#xff1a;前缀和 暴力解法解法2&#xff1a;前缀和 二分搜索序&#xff1a;使用Arrays工具类中的binarySearch方法进行二分搜索时&#xff0c;我们知道搜索成功会返回其下标&…

数字化餐饮| 刘大厨湘菜馆进杭州,开场及巅峰

盼了几年的刘大厨辣椒炒肉终于来杭州了&#xff0c;但我却没有吃到&#xff0c;小钱对雨科网说&#xff1a;驱车三十里&#xff0c;排队三小时都没吃上&#xff0c;原来他们是每天10点开始放号&#xff0c;11点开餐&#xff0c;去的晚就吃不到。 5月20日&#xff0c;刘大厨在杭…

5G无线技术基础自学系列 | 5G上行物理信道和信号

素材来源&#xff1a;《5G无线网络规划与优化》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 5G上行的物理信道包括PRACH、PUCCH、PU…

产品经理要不要考PMP?进化你能力的阶梯!(附:新版考纲及教材)

产品经理和项目经理看起来是毫不相关的两个专业&#xff0c;那么产品经理要不要考PMP呢&#xff1f;其实是非常有必要的。 以前去面试产品经理&#xff0c;HR只会问1个问题&#xff1a;会用axure吗&#xff1f;一开始对产品经理的定义就是设计产品原型的。能设计产品原型&…

【附源码】计算机毕业设计JAVA中小学教务管理平台

【附源码】计算机毕业设计JAVA中小学教务管理平台 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JAVA …

【北京迅为】RK3568开发板android11系统固件讲解

脚本里面写入这些内容&#x1f446;&#xff0c; apt-get install uuid 后面就是包名&#xff0c;比如说安装了这些内容uuid 在安装之前先执行这个命令增加下载源&#x1f447; 这里会提示&#xff0c;需要输入 回车继续&#xff0c;还是输入 Ctrl-c取消 当然要输入回车继续…

51单片机学习笔记4 新建工程及点亮LED实战

51单片机学习笔记4 新建工程及点亮LED实战一、使用keil新建工程二、项目设置1. 点击魔术棒&#xff0c;钩选Output-Create Hex File2. 设置仿真器三、编写代码1. 尝试编译代码2. 点亮LED的代码3. GPIO引脚介绍4. GPIO内部结构P0端口&#xff1a;P1 端口四、软件仿真一、使用kei…

aws cloudformation 理解自定义资源的使用

资料 AWS::CloudFormation::CustomResourcecfn-response module 自定义资源的逻辑 cloudformation只能对aws service进行部署和配置&#xff0c;但是用户可能需要使用第三方产品&#xff0c;此时需要通过自定义资源将其纳入到cloudformation的管理中。通过编写自定义逻辑&am…

为什么我们提供了新的公共镜像库

众所周知&#xff0c;建木在项目初期就已经完成了“自举”&#xff0c;就是使用建木完成自身的全部CI/CD/CO等自动化流程。 另外&#xff0c;由于建木本身和官方支持的节点都是打包为镜像发布到Docker Hub上&#xff0c;结果最近半年我们频繁碰到如下场景。 场景一 “CI服务的…

flink程序执行管理-1.13

1. 版本说明 本文档内容基于 flink-1.13.x&#xff0c;其他版本的整理&#xff0c;请查看本人博客的 flink 专栏其他文章。 2. 执行配置 StreamExecutionEnvironment 包含 ExecutionConfig 对象&#xff0c;该对象允许程序指定运行时的配置值。改变默认值可以影响所有的任务…

【Nginx 原理】进程模型、HTTP 连接建立和请求处理过程、高性能、高并发、事件处理模型、模块化体系结构

Nginx 原理 Nginx 以其高性能&#xff0c;稳定性&#xff0c;丰富的功能&#xff0c;简单的配置和低资源消耗而闻名。 Nginx进程模型 Nginx 是一个多进程的模型&#xff0c;主要分为一个 Master 进程、多个 Worker 进程。 Master 进程&#xff1a; 管理 Worker 进程。 对外…