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主要分为以下四种类型:

  1. VLIB_NODE_TYPE_INTERNAL
    内部节点,最典型的节点接收缓冲向量,执行操作。vpp大部分节点是这个角色,主要对数据流做内部处理,比如ip4-input-no-checksum/ip4-icmp-input等内部功能节点

  2. VLIB_NODE_TYPE_INPUT
    输入节点,通常是设备输入节点。从零开始创建框架并分派到内部节点(internal), 比如dpdk-input/af-packet-input节点,
    input节点收包模式分为轮询和中断两种模式vlib_node_state_t.

  3. VLIB_NODE_TYPE_PRE_INPUT
    输入节点前处理的节点,暂时在vpp里面没用用到

  4. 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)

注册节点

  1. 注册一个输入节点
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,
};
  1. 注册一个内部结点
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",},
};
  1. 注册一个线程节点
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

需要提供两个设置:

  1. 插件的名字
  2. 调度类型,有双单环路对还是四单环路对
    下面是具体命令:
$ 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#

如果上面有显示自己插件的信息,表示你提供的插件功能基本完备,能正常加载使用了.

测试插件

默认创建的插件已经实现了以下功能:

  1. 注册了process节点,监听插件是否工作的事件(MYPLUGIN_EVENT_PERIODIC_ENABLE_DISABLE),
    通过命令行来触发(VLIB_CLI_COMMAND (myplugin_enable_disable_command, static))这个事件。
    使用这里enable了,该插件才会work。
  2. 注册了内部节点,让其在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"),
};
  1. 在内部节点的实现函数里面(VLIB_NODE_FN (myplugin_node)),主要实现功能是对input节点收进来的报文,做一个src dst mac交换,然后源端口发送出去。

ok,到此为止我们知道这个模板插件能做的事情了,下面我们测试一下,我们结合前面的vpp+dpdk环境,测试一下这个模型。

测试

  1. 将dpdk网口up起来
    set int state eth0 up
  2. 开启网口的混杂模式
    set int promiscuous on eth0
  3. 使能我们的插件
    myplugin enable-disable eth0
  4. dpdk网口对端发包
  5. 预期结果
    在发送侧:每发送一个报文,能在本端口收到一个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之浅谈插件和使用相关推荐

  1. 【呆子化雨】浅谈Discuz插件开发-邮件验证提醒插件

    插件功能介绍: 这是一款提醒用户验证邮箱的插件,主要是当未验证邮箱的用户访问论坛时,会自动弹出提示框,提醒用户验证邮箱,后台可以设置弹出提示后,是否自动对该用户发送验证邮箱的邮件,设置是否发送邮件后根 ...

  2. 浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除

    浅谈:MyBatis-Plus的CRUD与乐观锁,分页插件,逻辑删除 MyBatis-Plus官方文档连接 什么是MyBatis-Plus 请点击上面官方文档查看 代码演示:代码注释为功能详细解释 数 ...

  3. 浅谈 MySQL 新的身份验证插件 caching_sha2_password

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 介绍 从 MySQL 8.0.4 开始,MySQL ...

  4. java 中的单元测试_浅谈Java 中的单元测试

    单元测试编写 Junit 单元测试框架 对于Java语言而言,其单元测试框架,有Junit和TestNG这两种, 下面是一个典型的JUnit测试类的结构 package com.example.dem ...

  5. 形态学滤波:腐蚀与膨胀(浅谈)

    形态学滤波:腐蚀与膨胀(浅谈) 一 关于二值化.膨胀.腐蚀以及拟合椭圆中心的代码如下** 二 关于腐蚀和膨胀,在此做一些浅显的总结. 三 对于上述代码中所生成的图片,进行一些说明. 四 接下来谈谈自己 ...

  6. html4与html5效果,浅谈HTML5与HTML4的10个关键区别

    HTML5是HTML标准的下一个版本.越来越多的程序员开始HTML5来构建网站.如果你同时使用HTML4和HTML5的话,你会发现用HTML5从头构建,比从HTML4迁移到HTML5要方便很多.虽然H ...

  7. 浅谈Django的中间件与Python的装饰器

    浅谈Django的中间件 与Python的装饰器 一.原理 1.装饰器是Python的一种语法应用,利用闭包的原理去更改一个函数的功能,即让一个函数执行之前先到另外一个函数中执行其他需求语句,在执行该 ...

  8. 页面显示 amp html6,浅谈HTML5 amp;amp; CSS3的新交互特性

    本文标题的这副图片,是用Phosotshop制作的.但是,在搜索引擎中你却无法搜索到它,搜索引擎还没有强大到能够识别图片里面的文字.并且由于图片的体积不算太小,可能网速慢的网友在浏览的时候不得不耐心的 ...

  9. 浅谈Service Mesh体系中的Envoy

    摘要: 提到Envoy就不得不提Service Mesh,说到Service Mesh就一定要谈及微服务了,那么我们就先放下Envoy,简单了解下微服务.Service Mesh以及Envoy在Ser ...

最新文章

  1. 【问题收录】Ubuntu14.04连接两个双显示器失败的解决方案
  2. 怎么用Windows 2008配置DHCP中继?
  3. 科学家研发多模态生物识别系统,基于脑纹独特性来防范身份欺骗
  4. 北斗导航 | PPP-RTK技术研究进展与试验验证(第十一届中国卫星导航年会报告)
  5. 汇编访问计算机端口,汇编总结(2):中断、端口、直接定址表
  6. Kotlin实战指南十三:协程
  7. linux之NTP服务
  8. Android—APT实践
  9. 自动挡轿车等红灯时,是挂D挡踩刹车好还是挂N挡好呢?
  10. 记录——《C Primer Plus (第五版)》第十一章编程练习第四题
  11. mac简体拼音打出来是英文_mac怎样打出拼音 - 卡饭网
  12. 有关GUASS高斯数据库的语法汇总(获取字符串字节数等)
  13. waylandweston
  14. 文人和书生 摘自《明朝那些事儿》
  15. matlab已知滤波器参数,求频响
  16. 【商品架构day2】一个商品的领域模型长什么样子 - 淘宝十多年前的认知
  17. html td 水平居中,html元素水平居中的几种方法
  18. 转: 大年三十整理的asp.net资料!(经典)
  19. 【LeetCode】1710.卡车上的最大单元数
  20. pandas操作1(读csv不要索引/写csv不要索引/删除有空值行/按时间排序)

热门文章

  1. 五德凤雏-集成微模块史上最强大的逐浪CMS v8.5.0正式发布
  2. 【TextView】Android TextView显示省略号的问题(关于TextView maxLength 和maxEms的学习)
  3. 《我是一只IT小小鸟》读后感,献给要正在找工作的有缘朋友
  4. Hexo界面美化_实用插件配置
  5. Java 实习要掌握的知识
  6. 网页导航栏设计方法和技巧
  7. vue+Element做表格的批量增加
  8. 怎样压缩PDF文件体积?
  9. 介绍一款搜索引擎(Magi):也就比百度好用一丢丢
  10. 有一个网页地址, 比如百度主页: https://www.baidu.com/ 如何得到它的内容?