当前位置: 首页 > news >正文

六、vpp 流表+负载均衡

草稿!!!

vpp node其实就是三个部分
1、plugin init
2、set command
3、function 实现功能,比如这里的流表

今天我们再用VPP实现一个流表的功能

一、流表

1.1流表----plugin init

VLIB_REGISTER_NODE 注册流表节点

// 注册流表节点
VLIB_REGISTER_NODE(flowtable_node) = {.function = flowtable_getinfo, // 节点处理函数.name = "flow-table", // 节点名称.vector_size = sizeof(u32), // 向量大小.format_trace = format_flowtable_getinfo, // 跟踪格式函数.type = VLIB_NODE_TYPE_INTERNAL, // 节点类型为内部节点.n_errors = FLOWTABLE_N_ERROR, // 错误数目.error_strings = flowtable_error_strings, // 错误字符串数组.n_next_nodes = FT_NEXT_N_NEXT, // 下一个节点数目.next_nodes = {[FT_NEXT_IP4] = "ip4-lookup",[FT_NEXT_DROP] = "error-drop",[FT_NEXT_ETHERNET_INPUT] = "ethernet-input",[FT_NEXT_LOAD_BALANCER] = "load-balance",[FT_NEXT_INTERFACE_OUTPUT] = "interface-output",} // 下一个节点的映射
};// 注册插件
VLIB_PLUGIN_REGISTER() = {.version = "1.0", // 插件版本.description = "sample of flowtable", // 插件描述
};

1.2 流表-----command 解析

接收到命令后,调用注册好的回调函数flowtable_command_enable_fn,最后会通过VPP自带的vnet_hw_interface_rx_redirect_to_node函数将硬件接口的接收流量重定向到指定节点,这里就是我们的流表节点

// 启用或禁用流表功能,将硬件接口的接收流量重定向到指定节点
int flowtable_enable(flowtable_main_t *fm,u32 sw_if_index,int enable){// 如果启用,获取流表节点的索引;如果禁用,则设置索引为无效值u32 node_index = enable ? flowtable_node.index : ~0;printf("debug:[%s:%s:%d] node_index:%d\n", __FILE__, __func__, __LINE__, flowtable_node.index);// 调用 VPP 的函数,将硬件接口的接收流量重定向到指定节点return vnet_hw_interface_rx_redirect_to_node(fm->vnet_main,sw_if_index,node_index);
}static clib_error_t * flowtable_command_enable_fn(struct vlib_main_t *vm,unformat_input_t *input,struct vlib_cli_command_t *cmd){// 获取与流表相关的主数据结构flowtable_main_t * fm = &flowtable_main;u32 sw_if_index = ~0;// 初始化接口索引为无效值int enable_disable = 1;// 初始化启用/禁用标志为启用// 解析命令行输入,直到输入结束while(unformat_check_input(input) != UNFORMAT_END_OF_INPUT){// 如果输入中包含 "disable" 参数,则禁用流表功能if(unformat(input,"disable")){enable_disable = 0;}// 如果输入中包含接口索引,则解析并存储在 sw_if_index 中else if (unformat(input,"%U",unformat_vnet_sw_interface,fm->vnet_main,&sw_if_index)){}elsebreak;}// 如果没有指定接口索引,则返回错误if(sw_if_index == ~0){return clib_error_return(0,"No Interface specified");}// 调用流表启用/禁用函数int rv = flowtable_enable(fm,sw_if_index,enable_disable);if(rv){if(rv == VNET_API_ERROR_INVALID_SW_IF_INDEX){return clib_error_return(0,"Invalid interface");}else if(rv == VNET_API_ERROR_UNIMPLEMENTED){return clib_error_return(0,"Device driver doesn't support redirection");}else{return clib_error_return(0,"flowtable_enable_disable returned %d\n",rv);}}return 0;
}//命令行启动、关闭流表功能
VLIB_CLI_COMMAND(flowtable_interface_enable_disable_command) = {.path = "flowtable",.short_help = "flowtable <interface> [disable]",.function = flowtable_command_enable_fn, //对应的flowtable命令行回调函数
};

1.3 流表------function

经过上面,这是当网卡接收到数据,就会传到我们指定的流表功能函数进行处理

static uword flowtable_getinfo(struct vlib_main_t *vm,struct vlib_node_runtime_t *node,struct vlib_frame_t *frame){u32 n_left_from, *from,*to_next;u32 next_index = node->cached_next_index;printf("flowtable_getinfo cached_next_index: %u\n", next_index);from = vlib_frame_vector_args(frame);//获取指向帧向量数据的指针,即第一个数据包的地址n_left_from = frame->n_vectors;	// 获取向量数量,即有多少个数据包while(n_left_from > 0){u32 n_left_to_next;/*获取下一个节点的帧和向量,然后vlib_put_next_frame将当前节点处理的数据包添加到这个帧中,以便后续的节点可以处理这些数据包,最开始这里是获取的第一帧,一帧里面有多个vlib_buffer可以看做为二维数组*/vlib_get_next_frame(vm,node,next_index,to_next,n_left_to_next);/*n_left_to_next 是当前帧中剩余的空闲槽位数量,当值为0后,需要vlib_put_next_frame获取一个新的帧来继续传递数据包*/while(n_left_from > 0 && n_left_to_next > 0){vlib_buffer_t *b0;u32 bi0,next0 = 0;bi0 = to_next[0] = from[0];from += 1;to_next += 1;n_left_to_next -= 1;n_left_from -= 1;//它将 DPDK 的 rte_mbuf 转换为 VPP 的 vlib_buffer_t,vlib_buffer_t里面有多个rte_mbuf(数据包)b0 = vlib_get_buffer(vm,bi0);//取出当前需要处理的数据包ip4_header_t *ip0 = vlib_buffer_get_current(b0);ip4_address_t ip_src = ip0->src_address;ip4_address_t ip_dst = ip0->dst_address;//获取处理的数据包所到达的接口的软件索引,并将其存储在变量 sw_if_index0 中u32 sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];//对每个数据包打印其源ip及目的ipstruct in_addr addr;addr.s_addr = ip_src.as_u32;printf("sw_if_index0: %d, ip_src: %s ", sw_if_index0, inet_ntoa(addr));addr.s_addr = ip_dst.as_u32;printf(" ip_dst: %s \n", inet_ntoa(addr));/*将当前处理的缓冲区 bi0 传递到下一个节点,同时更新 to_next 数组、n_left_to_next 计数和下一个节点的下一个节点索引 next0。这样,数据包将会在当前节点处理后传递到下一个节点进行进一步处理*/vlib_validate_buffer_enqueue_x1(vm,node,next_index,to_next,n_left_to_next,bi0,next0);}/*vlib_get_next_frame获取下一个节点的帧和向量,然后vlib_put_next_frame将当前节点处理的数据包添加到这个帧中,		以便后续的节点可以处理这些数据包*/vlib_put_next_frame(vm,node,next_index,n_left_to_next);}return frame->n_vectors; //这里决定接下来继续走哪一个node
}

这里的function函数有个返回值,根据返回值决定下一个节点走哪里
flowtable_getinfo这里处理函数返回2 ,则下一步走这个节点[FT_NEXT_ETHERNET_INPUT] = “ethernet-input”,
在这里插入图片描述

浅谈node

在一些系统中,节点的执行顺序可能是在程序初始化的时候静态确定的,特别是在构建数据处理流水线时。这种情况下,节点的顺序是在配置或初始化阶段定义的,然后在整个程序运行期间保持不变。

然而,在某些系统中,特别是对于一些灵活的数据流框架,节点的执行顺序可能是在程序运行时动态决定的。这可以通过某种策略或运行时的条件来调整节点的执行顺序,以适应实时需求或系统的动态变化。

总的来说,节点的执行顺序是取决于应用程序设计和需求的。一些系统更倾向于静态的、在初始化时确定的执行顺序,而其他系统则更注重在运行时根据动态需求来调整节点的执行顺序

在许多系统中,插件和节点的初始化顺序通常是通过配置文件、命令行参数或其他配置机制来确定的。这些配置通常在应用程序启动时被解析,并在初始化过程中用于指导插件和节点的加载和初始化。

以下是一些可能的方式来决定插件和节点的顺序:

配置文件: 应用程序可能会有一个配置文件,其中包含有关插件和节点的信息,包括它们的加载顺序。在应用程序启动时,解析配置文件并按照其中定义的顺序加载插件和节点。

命令行参数: 应用程序可能允许通过命令行参数来指定插件和节点的加载顺序。例如,通过在启动命令中指定参数来控制加载的插件和它们的顺序。

硬编码: 在某些情况下,加载顺序可能是硬编码在应用程序的源代码中的,即在代码中明确指定加载和初始化的顺序。

依赖关系: 插件和节点之间可能存在依赖关系,系统可以根据这些依赖关系来确定加载和初始化的顺序。例如,某个插件可能依赖于另一个插件的某些功能,因此必须在其之前加载。

具体的实现方式取决于系统的设计和开发者的选择。在某些情况下,可能会结合使用上述多种机制来达到更大的灵活性。

相关文章:

六、vpp 流表+负载均衡

草稿&#xff01;&#xff01;&#xff01; vpp node其实就是三个部分 1、plugin init 2、set command 3、function 实现功能&#xff0c;比如这里的流表 今天我们再用VPP实现一个流表的功能 一、流表 1.1流表----plugin init VLIB_REGISTER_NODE 注册流表节点 // 注册流…...

word已排序好的参考文献,插入新的参考文献,序号更新

原排序好的文献序号。 现在在3号后面插入一个新文献。4&#xff0c;5号应该成为5&#xff0c;6 这时在3号后面&#xff0c;回车&#xff0c;就会自动的增长。如下图&#xff1a; 但是如果手滑&#xff0c;把[4]删除了如何排序&#xff1f;&#xff1f; 如下图&#xff1a; …...

二叉树的顺序存储——堆——初识堆排序

前面我们学过可以把完全二叉树存入到顺序表中&#xff0c;然后利用完全二叉树的情缘关系&#xff0c;就可以通过数组下标来联系。 但是并不是把二叉树存入到数组中就是堆了&#xff0c;要看原原来的二叉树是否满足&#xff1a;所有的父都小于等于子&#xff0c;或者所有的父都…...

CYEZ 模拟赛 9

A a ⊥ b ⇒ a − b ⊥ a b (1) a \perp b \Rightarrow a-b \perp ab \tag {1} a⊥b⇒a−b⊥ab(1) 证明&#xff1a; gcd ⁡ ( a , b ) gcd ⁡ ( b , a − b ) \gcd(a,b) \gcd(b, a-b) gcd(a,b)gcd(b,a−b)&#xff0c;故 a − b ⊥ b a - b \perp b a−b⊥b&#xff0c;同…...

typescript: Builder Pattern

/*** file: CarBuilderts.ts* TypeScript 实体类 Model* Builder Pattern* 生成器是一种创建型设计模式&#xff0c; 使你能够分步骤创建复杂对象。* https://stackoverflow.com/questions/12827266/get-and-set-in-typescript* https://github.com/Microsoft/TypeScript/wiki/…...

WPS/word 表格跨行如何续表、和表的名称

1&#xff1a;具体操作&#xff1a; 将光标定位在跨页部分的第一行任意位置&#xff0c;按下快捷键ctrlshiftenter&#xff0c;就可以在跨页的表格上方插入空行&#xff08;在空行可以写&#xff0c;表1-3 xxxx&#xff08;续&#xff09;&#xff09; 在空行中输入…...

Python的NumPy库(一)基础用法

NumPy库并不是Python的标准库&#xff0c;但其在机器学习、大数据等很多领域有非常广泛的应用&#xff0c;NumPy本身就有比较多的内容&#xff0c;全部的学习可能涉及许多的内容&#xff0c;但我们在这里仅学习常见的使用&#xff0c;这些内容对于我们日常使用NumPy是足够的。 …...

uniapp app 导出excel 表格

直接复制运行 <template><view><button click"tableToExcel">导出一个表来看</button><view>{{ successTip }}</view></view> </template><script>export default {data() {return {successTip: }},metho…...

【RabbitMQ】常用消息模型详解

文章目录 AMQP协议的回顾RabbitMQ支持的消息模型第一种模型(直连)开发生产者开发消费者生产者、消费者开发优化API参数细节 第二种模型(work quene)开发生产者开发消费者消息自动确认机制 第三种模型(fanout)开发生产者开发消费者 第四种模型(Routing)开发生产者开发消费者 第五…...

图像拼接后丢失数据,转tiff报错rasterfile failed: an unknown

图像拼接后丢失数据 不仅是数据丢失了&#xff0c;还有个未知原因报错 部分数据存在值不存在的情况 原因 处理遥感数据很容易&#xff0c;磁盘爆满了 解决方案 清理一些无用数据&#xff0c;准备买个2T的外接硬盘用着了。 然后重新做处理...

Nginx之日志模块解读

目录 基本介绍 配置指令 access_log&#xff08;访问日志&#xff09; error_log&#xff08; 错误日志&#xff09; 基本介绍 Nginx日志主要分为两种&#xff1a;access_log(访问日志)和error_log(错误日志)。Nginx日志主要记录以下信息&#xff1a; 记录Nginx服务启动…...

latex方程组编写,一种可以保证方程编号自适应的方法

问题描述&#xff1a; 在利用latex编写方程组时&#xff0c;可以有很多种方法&#xff0c;但不总是编辑好的公式能够显示出编号&#xff0c;故提出一种有效的方程组编写方法 方法&#xff1a; \begin{equation}X_{ t1}\left \{ \begin{matrix}\frac{x_{i}}{a} \quad\quad 0&l…...

深度学习基础 2D卷积(1)

什么是2D卷积 2D参数量怎么计算 以pytorch为例子&#xff0c;2D卷积在设置的时候具有以下参数&#xff0c;具有输入通道的多少&#xff08;这个决定了卷积核的通道数量&#xff09;&#xff0c;滤波器数量&#xff0c;这个是有多少个滤波器&#xff0c;越多提取的特征就越有用…...

OpenCV DNN C++ 使用 YOLO 模型推理

OpenCV DNN C 使用 YOLO 模型推理 引言 YOLO&#xff08;You Only Look Once&#xff09;是一种流行的目标检测算法&#xff0c;因其速度快和准确度高而被广泛应用。OpenCV 的 DNN&#xff08;Deep Neural Networks&#xff09;模块为我们提供了一个简单易用的 API&#xff0…...

第八章 Linux文件系统权限

目录 8.1 文件的一般权限 1.修改文件或目录的权限---chmod命令 2.对于文件和目录&#xff0c;r&#xff0c;w&#xff0c;x有不同的作用&#xff1a; 3.修改文件或目录的所属主和组---chown,chgrp 8.2 文件和目录的特殊权限 三种通过字符描述文件权限 8.3 ACL 权限 1.A…...

XXL-JOB源码梳理——一文理清XXL-JOB实现方案

分布式定时任务调度系统 流程分析 一个分布式定时任务&#xff0c;需要具备有以下几点功能&#xff1a; 核心功能&#xff1a;定时调度、任务管理、可观测日志高可用&#xff1a;集群、分片、失败处理高性能&#xff1a;分布式锁扩展功能&#xff1a;可视化运维、多语言、任…...

java做个qq机器人

前置的条件 机器人是基于mirai框架实现的。根据官方的文档&#xff0c;建议使用openjdk11。 我这里使用的编辑工具是idea2023 在idea中新建一个maven项目&#xff0c;虽然可以使用gradle进行构建&#xff0c;不过我这里由于网络问题没有跑通。 pom.xml <dependency>&l…...

前端 | AjaxAxios模块

文章目录 1. Ajax1.1 Ajax介绍1.2 Ajax作用1.3 同步异步1.4 原生Ajax 2. Axios2.1 Axios下载2.2 Axios基本使用2.3 Axios方法 1. Ajax 1.1 Ajax介绍 Ajax: 全称&#xff08;Asynchronous JavaScript And XML&#xff09;&#xff0c;异步的JavaScript和XML。 1.2 Ajax作用 …...

高效的ProtoBuf

一、背景 Google ProtoBuf介绍 这篇文章我们讲了怎么使用ProtoBuf进行序列化&#xff0c;但ProtoBuf怎么做到最高效的&#xff0c;它的数据又是如何压缩的&#xff0c;下面先看一个例子&#xff0c;然后再讲ProtoBuf压缩机制。 二、案例 网上有各种序列化方式性能对比&#…...

删除SQL记录

删除记录的方式汇总&#xff1a; 根据条件删除&#xff1a;DELETE FROM tb_name [WHERE options] [ [ ORDER BY fields ] LIMIT n ] 全部删除&#xff08;表清空&#xff0c;包含自增计数器重置&#xff09;&#xff1a;TRUNCATE tb_namedelete和truncate的区别&#xff1a; d…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

Mysql故障排插与环境优化

前置知识点 最上层是一些客户端和连接服务&#xff0c;包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念&#xff0c;为通过安全认证接入的客户端提供线程。同样在该层上可…...

FOPLP vs CoWoS

以下是 FOPLP&#xff08;Fan-out panel-level packaging 扇出型面板级封装&#xff09;与 CoWoS&#xff08;Chip on Wafer on Substrate&#xff09;两种先进封装技术的详细对比分析&#xff0c;涵盖技术原理、性能、成本、应用场景及市场趋势等维度&#xff1a; 一、技术原…...

2025.6.9总结(利与弊)

凡事都有两面性。在大厂上班也不例外。今天找开发定位问题&#xff0c;从一个接口人不断溯源到另一个 接口人。有时候&#xff0c;不知道是谁的责任填。将工作内容分的很细&#xff0c;每个人负责其中的一小块。我清楚的意识到&#xff0c;自己就是个可以随时替换的螺丝钉&…...

20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题

20250609在荣品的PRO-RK3566开发板的Android13下解决串口可以执行命令但是脚本执行命令异常的问题 2025/6/9 20:54 缘起&#xff0c;为了跨网段推流&#xff0c;千辛万苦配置好了网络参数。 但是命令iptables -t filter -F tetherctrl_FORWARD可以在调试串口/DEBUG口正确执行。…...