vpp之浅谈插件和使用
vpp版本
笔者这里使用的vpp版本是最新git下来的,show version信息如下
DBGvpp# show version
vpp v19.04-rc0~531-g537e85d built by ych on localhost.localdomain at Wed Mar 27 10:17:26 CST 2019
插件介绍
vpp的软件框架主要分为四个层面:
top ├──Plugins 包含越来越丰富的数据平面插件集,可以认为每一个插件是一个小型的应用app
│ │
│ ├──VNET 与VPP的网络接口(第2,3和4层)协同工作,执行会话和流量管理,并与设备和数据控制平面配合使用
│ │
│ ├──VLIB 矢量处理库。vlib层还处理各种应用程序管理功能:缓冲区,内存和图形节点管理,维护和导出计数器,线程管理,数据包跟踪。Vlib实现调试CLI(命令行界面)
│ │
bottom └──VPP Infra VPP基础设施层,包含核心库源代码。该层执行内存函数,与向量和环一起使用,在哈希表中执行键查找,并与定时器一起用于调度图节点
每一个插件在vpp里面有不同的node构成,每一个node主要分为以下四种类型:
VLIB_NODE_TYPE_INTERNAL
内部节点,最典型的节点接收缓冲向量,执行操作。vpp大部分节点是这个角色,主要对数据流做内部处理,比如ip4-input-no-checksum/ip4-icmp-input等内部功能节点VLIB_NODE_TYPE_INPUT
输入节点,通常是设备输入节点。从零开始创建框架并分派到内部节点(internal), 比如dpdk-input/af-packet-input节点,
input节点收包模式分为轮询和中断两种模式vlib_node_state_t.VLIB_NODE_TYPE_PRE_INPUT
输入节点前处理的节点,暂时在vpp里面没用用到VLIB_NODE_TYPE_PROCESS
线程节点,和线程一样,可以可以暂停、等待事件、恢复,不同于pthread_thread,他是基于setjump/longjump实现的弦程.
等待一个事件:always_inline f64 vlib_process_wait_for_event_or_clock (vlib_main_t * vm, f64 dt)
发送一个事件: always_inline void vlib_process_signal_event (vlib_main_t * vm, uword node_index, uword type_opaque, uword data)
注册节点
- 注册一个输入节点
VLIB_REGISTER_NODE (dpdk_input_node) = {.type = VLIB_NODE_TYPE_INPUT,.name = "dpdk-input",.sibling_of = "device-input",/* Will be enabled if/when hardware is detected. */.state = VLIB_NODE_STATE_DISABLED,.format_buffer = format_ethernet_header_with_length,.format_trace = format_dpdk_rx_trace,.n_errors = DPDK_N_ERROR,.error_strings = dpdk_error_strings,
};
- 注册一个内部结点
VLIB_REGISTER_NODE (myplugin_node) =
{.name = "myplugin",.vector_size = sizeof (u32),.format_trace = format_myplugin_trace,.type = VLIB_NODE_TYPE_INTERNAL,.n_errors = ARRAY_LEN(myplugin_error_strings),.error_strings = myplugin_error_strings,.n_next_nodes = MYPLUGIN_N_NEXT,/* edit / add dispositions here */.next_nodes = {[MYPLUGIN_NEXT_INTERFACE_OUTPUT] = "interface-output",},
};
- 注册一个线程节点
VLIB_REGISTER_NODE (myplugin_periodic_node) =
{.function = myplugin_periodic_process,.type = VLIB_NODE_TYPE_PROCESS,.name = "myplugin-periodic-process",
};
创建一个插件基本框架
在最新的版本,vpp提供了一个创建插件的脚本,直接使用这个脚本就可以创建我们需要的插件基本框架
如果自己系统没有安装emacs,需要安装一下,否则脚本运行会失败,我自己的系统是centos,所以需要安装
sudo yum install -y emacs
需要提供两个设置:
- 插件的名字
- 调度类型,有双单环路对还是四单环路对
下面是具体命令:
$ cd ./src/plugins
$ ../../extras/emacs/make-plugin.sh
<snip>
Loading /scratch/vpp-docs/extras/emacs/tunnel-c-skel.el (source)...
Loading /scratch/vpp-docs/extras/emacs/tunnel-decap-skel.el (source)...
Loading /scratch/vpp-docs/extras/emacs/tunnel-encap-skel.el (source)...
Loading /scratch/vpp-docs/extras/emacs/tunnel-h-skel.el (source)...
Loading /scratch/vpp-docs/extras/emacs/elog-4-int-skel.el (source)...
Loading /scratch/vpp-docs/extras/emacs/elog-4-int-track-skel.el (source)...
Loading /scratch/vpp-docs/extras/emacs/elog-enum-skel.el (source)...
Loading /scratch/vpp-docs/extras/emacs/elog-one-datum-skel.el (source)...
Plugin name: myplugin
Dispatch type [dual or qs]: dual
(Shell command succeeded with no output)OK...
调度类型暂时我还不太清楚有多大差异,暂时选择dual模式,后面自己根据自己业务,对插件做相关的修改就行。
生成出来的文件:
$ cd ./myplugin
$ ls
CMakeLists.txt myplugin.c myplugin_periodic.c setup.pg
myplugin_all_api_h.h myplugin.h myplugin_test.c
myplugin.api myplugin_msg_enum.h node.c
编译插件
$ cd <top-of-workspace>
$ make rebuild [or rebuild-release]
验证插件是否正常
$ cd <top-of-workspace>
$ make run
<snip>
load_one_plugin:189: Loaded plugin: myplugin_plugin.so (myplugin description goes here)
<snip>
load_one_vat_plugin:67: Loaded plugin: myplugin_test_plugin.so
<snip>
DBGvpp#
如果上面有显示自己插件的信息,表示你提供的插件功能基本完备,能正常加载使用了.
测试插件
默认创建的插件已经实现了以下功能:
- 注册了process节点,监听插件是否工作的事件(MYPLUGIN_EVENT_PERIODIC_ENABLE_DISABLE),
通过命令行来触发(VLIB_CLI_COMMAND (myplugin_enable_disable_command, static))这个事件。
使用这里enable了,该插件才会work。 - 注册了内部节点,让其在ethernet-input节点运行之前运行
VLIB_REGISTER_NODE (myplugin_node) =
{.name = "myplugin",.vector_size = sizeof (u32),.format_trace = format_myplugin_trace,.type = VLIB_NODE_TYPE_INTERNAL,.n_errors = ARRAY_LEN(myplugin_error_strings),.error_strings = myplugin_error_strings,.n_next_nodes = MYPLUGIN_N_NEXT,/* edit / add dispositions here */.next_nodes = {[MYPLUGIN_NEXT_INTERFACE_OUTPUT] = "interface-output",},
};VNET_FEATURE_INIT (myplugin, static) =
{.arc_name = "device-input",.node_name = "myplugin",.runs_before = VNET_FEATURES ("ethernet-input"),
};
- 在内部节点的实现函数里面(VLIB_NODE_FN (myplugin_node)),主要实现功能是对input节点收进来的报文,做一个src dst mac交换,然后源端口发送出去。
ok,到此为止我们知道这个模板插件能做的事情了,下面我们测试一下,我们结合前面的vpp+dpdk环境,测试一下这个模型。
测试
- 将dpdk网口up起来
set int state eth0 up - 开启网口的混杂模式
set int promiscuous on eth0 - 使能我们的插件
myplugin enable-disable eth0 - dpdk网口对端发包
- 预期结果
在发送侧:每发送一个报文,能在本端口收到一个src mac和dst mac交换的报文.
在vpp测,可以看到网口收发包统计和trace信息:
00:01:24:063351: dpdk-inputeth0 rx queue 0, tid=233990336buffer 0x13b1d4: current data 0, length 554, buffer-pool 1, ref-count 1, totlen-nifb 0, trace 0x0ext-hdr-valid l4-cksum-computed l4-cksum-correct PKT MBUF: port 0, nb_segs 1, pkt_len 554buf_len 2176, data_len 554, ol_flags 0x182, data_off 128, phys_addr 0x4ec7580packet_type 0x211 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0rss 0x54078cbc fdir.hi 0x0 fdir.lo 0x54078cbcPacket Offload FlagsPKT_RX_RSS_HASH (0x0002) RX packet with RSS hash resultPKT_RX_IP_CKSUM_GOOD (0x0080) IP cksum of RX pkt. is validPKT_RX_L4_CKSUM_GOOD (0x0100) L4 cksum of RX pkt. is validPacket TypesRTE_PTYPE_L2_ETHER (0x0001) Ethernet packetRTE_PTYPE_L3_IPV4 (0x0010) IPv4 packet without extension headersRTE_PTYPE_L4_UDP (0x0200) UDP packetIP4: 00:12:34:56:78:9a -> 00:11:22:33:44:55UDP: 1.1.1.2 -> 2.2.2.2tos 0x00, ttl 64, length 540, checksum 0x72cafragment id 0x0001UDP: 521 -> 521length 520, checksum 0x9c70
00:01:24:063375: mypluginMYPLUGIN: sw_if_index 1, next index 0, tid=233990336new src 00:11:22:33:44:55 -> new dst 00:12:34:56:78:9a
00:01:24:063434: eth0-outputeth0 l4-cksum-computed l4-cksum-correct IP4: 00:11:22:33:44:55 -> 00:12:34:56:78:9aUDP: 1.1.1.2 -> 2.2.2.2tos 0x00, ttl 64, length 540, checksum 0x72cafragment id 0x0001UDP: 521 -> 521length 520, checksum 0x9c70
00:01:24:063442: eth0-txeth0 tx queue 1buffer 0x13b1d4: current data 0, length 554, buffer-pool 1, ref-count 1, totlen-nifb 0, trace 0x0ext-hdr-valid l4-cksum-computed l4-cksum-correct PKT MBUF: port 0, nb_segs 1, pkt_len 554buf_len 2176, data_len 554, ol_flags 0x182, data_off 128, phys_addr 0x4ec7580packet_type 0x211 l2_len 0 l3_len 0 outer_l2_len 0 outer_l3_len 0rss 0x54078cbc fdir.hi 0x0 fdir.lo 0x54078cbcPacket Offload FlagsPKT_RX_RSS_HASH (0x0002) RX packet with RSS hash resultPKT_RX_IP_CKSUM_GOOD (0x0080) IP cksum of RX pkt. is validPKT_RX_L4_CKSUM_GOOD (0x0100) L4 cksum of RX pkt. is validPacket TypesRTE_PTYPE_L2_ETHER (0x0001) Ethernet packetRTE_PTYPE_L3_IPV4 (0x0010) IPv4 packet without extension headersRTE_PTYPE_L4_UDP (0x0200) UDP packetIP4: 00:11:22:33:44:55 -> 00:12:34:56:78:9aUDP: 1.1.1.2 -> 2.2.2.2tos 0x00, ttl 64, length 540, checksum 0x72cafragment id 0x0001UDP: 521 -> 521length 520, checksum 0x9c70
vpp之浅谈插件和使用相关推荐
- 【呆子化雨】浅谈Discuz插件开发-邮件验证提醒插件
插件功能介绍: 这是一款提醒用户验证邮箱的插件,主要是当未验证邮箱的用户访问论坛时,会自动弹出提示框,提醒用户验证邮箱,后台可以设置弹出提示后,是否自动对该用户发送验证邮箱的邮件,设置是否发送邮件后根 ...
- 浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除
浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除 MyBatis-Plus官方文档连接 什么是MyBatis-Plus 请点击上面官方文档查看 代码演示:代码注释为功能详细解释 数 ...
- 浅谈 MySQL 新的身份验证插件 caching_sha2_password
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 介绍 从 MySQL 8.0.4 开始,MySQL ...
- java 中的单元测试_浅谈Java 中的单元测试
单元测试编写 Junit 单元测试框架 对于Java语言而言,其单元测试框架,有Junit和TestNG这两种, 下面是一个典型的JUnit测试类的结构 package com.example.dem ...
- 形态学滤波:腐蚀与膨胀(浅谈)
形态学滤波:腐蚀与膨胀(浅谈) 一 关于二值化.膨胀.腐蚀以及拟合椭圆中心的代码如下** 二 关于腐蚀和膨胀,在此做一些浅显的总结. 三 对于上述代码中所生成的图片,进行一些说明. 四 接下来谈谈自己 ...
- html4与html5效果,浅谈HTML5与HTML4的10个关键区别
HTML5是HTML标准的下一个版本.越来越多的程序员开始HTML5来构建网站.如果你同时使用HTML4和HTML5的话,你会发现用HTML5从头构建,比从HTML4迁移到HTML5要方便很多.虽然H ...
- 浅谈Django的中间件与Python的装饰器
浅谈Django的中间件 与Python的装饰器 一.原理 1.装饰器是Python的一种语法应用,利用闭包的原理去更改一个函数的功能,即让一个函数执行之前先到另外一个函数中执行其他需求语句,在执行该 ...
- 页面显示 amp html6,浅谈HTML5 amp;amp; CSS3的新交互特性
本文标题的这副图片,是用Phosotshop制作的.但是,在搜索引擎中你却无法搜索到它,搜索引擎还没有强大到能够识别图片里面的文字.并且由于图片的体积不算太小,可能网速慢的网友在浏览的时候不得不耐心的 ...
- 浅谈Service Mesh体系中的Envoy
摘要: 提到Envoy就不得不提Service Mesh,说到Service Mesh就一定要谈及微服务了,那么我们就先放下Envoy,简单了解下微服务.Service Mesh以及Envoy在Ser ...
最新文章
- 【问题收录】Ubuntu14.04连接两个双显示器失败的解决方案
- 怎么用Windows 2008配置DHCP中继?
- 科学家研发多模态生物识别系统,基于脑纹独特性来防范身份欺骗
- 北斗导航 | PPP-RTK技术研究进展与试验验证(第十一届中国卫星导航年会报告)
- 汇编访问计算机端口,汇编总结(2):中断、端口、直接定址表
- Kotlin实战指南十三:协程
- linux之NTP服务
- Android—APT实践
- 自动挡轿车等红灯时,是挂D挡踩刹车好还是挂N挡好呢?
- 记录——《C Primer Plus (第五版)》第十一章编程练习第四题
- mac简体拼音打出来是英文_mac怎样打出拼音 - 卡饭网
- 有关GUASS高斯数据库的语法汇总(获取字符串字节数等)
- waylandweston
- 文人和书生 摘自《明朝那些事儿》
- matlab已知滤波器参数,求频响
- 【商品架构day2】一个商品的领域模型长什么样子 - 淘宝十多年前的认知
- html td 水平居中,html元素水平居中的几种方法
- 转: 大年三十整理的asp.net资料!(经典)
- 【LeetCode】1710.卡车上的最大单元数
- pandas操作1(读csv不要索引/写csv不要索引/删除有空值行/按时间排序)
热门文章
- 五德凤雏-集成微模块史上最强大的逐浪CMS v8.5.0正式发布
- 【TextView】Android TextView显示省略号的问题(关于TextView maxLength 和maxEms的学习)
- 《我是一只IT小小鸟》读后感,献给要正在找工作的有缘朋友
- Hexo界面美化_实用插件配置
- Java 实习要掌握的知识
- 网页导航栏设计方法和技巧
- vue+Element做表格的批量增加
- 怎样压缩PDF文件体积?
- 介绍一款搜索引擎(Magi):也就比百度好用一丢丢
- 有一个网页地址, 比如百度主页: https://www.baidu.com/ 如何得到它的内容?