vpp插件介绍之创建插件

vpp通过插件的方式可以方便的在原有框架基础上扩展新的功能

vpp提供了脚本可以自动创建插件

1.安装emacs

一般安装vpp时就安装了

yum install emacs

2.切换至插件目录

cd vpp/src/plugins

3.执行脚本

../../extras/emacs/make-plugin.sh

这里先设置插件名字,然后选择插件的类型

插件有两个类型 dual 和 qs

dual和qs只在node.c文件上有差异,dual一般应用于二层网络,里面添加了对mac的处理,qs一般是三层网络,里面只有数据包的处理

两种模板转发数据包的方式有点差异,dual适合转发到多个节点,qs适合转发到下一个节点,vpp中node节点的转发基本上都是这两种方式,具体的分析将会在后面文章中介绍

即使有差异也不要紧,因为两种方式只是插件的模板,还要根据具体需求对代码进行修改

4.插件的目录结构

这里以dual类型的插件为例,qs类型生成的文件是一样的,只是node.c中的代码有些差异

如图所示,脚本生成的插件都是这么几个文件

CMakeLists.txt是编译文件,最终生成两个动态库,一个是给vpp用,另一个是给vat用;另外还会生成一些代码放在vpp/build-root/build-vpp_debug-native/vpp目录下

node.c是该插件作为节点,主要负责数据包经过该节点的处理

testdual.api是定义vat需要的数据结构

testdual.c主要负责binary api和cli处理

testdual.h主要负责声明和定义节点需要的全局变量

testdual_periodic.c应该是跟事件触发相关,一直没用到

testdual_test.c是vat与vpp通信的接口,会集成到vpp_api_test程序里去

5.使用插件

在vpp目录下执行 make build 即可编译插件,目前插件只能enable-disable,没有太大意义,如下图所示

后面将会对插件代码进行更进一步分析

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用VPP进行收包发包的插件示例: 1. 接收插件示例: ``` #include <vlib/vlib.h> static uword my_input_node (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { u32 n_left_from, * from, * to_next; my_input_next_t next_index; my_input_trace_t * t; vnet_main_t * vnm = vnet_get_main(); from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; next_index = node->cached_next_index; while (n_left_from > 0) { u32 n_left_to_next; vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) { u32 bi0; vlib_buffer_t * b0; u32 next0; bi0 = from[0]; from += 1; n_left_from -= 1; to_next[0] = bi0; to_next += 1; n_left_to_next -= 1; b0 = vlib_get_buffer (vm, bi0); t = vlib_add_trace (vm, node, b0, sizeof (*t)); t->sw_if_index = vnet_buffer(b0)->sw_if_index[VLIB_RX]; next0 = MY_INPUT_NEXT_NORMAL; vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi0, next0); } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } return frame->n_vectors; } ``` 2. 发送插件示例: ``` #include <vnet/vnet.h> #include <vnet/ip/ip.h> static u32 my_output_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { u32 n_left_from, * from; u32 n_left_to_next, * to_next; my_output_next_t next_index; u32 pkts_sent = 0; vlib_frame_t *f; u32 thread_index = vm->thread_index; from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; next_index = node->cached_next_index; while (n_left_from > 0) { u32 n_left_to_next; vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); while (n_left_from > 0 && n_left_to_next > 0) { u32 bi0; vlib_buffer_t * b0; u32 next0 = 0; u32 error0 = 0; u32 sw_if_index0; bi0 = from[0]; from += 1; n_left_from -= 1; to_next[0] = bi0; to_next += 1; n_left_to_next -= 1; b0 = vlib_get_buffer (vm, bi0); sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_TX]; vlib_buffer_advance (b0, -sizeof (ethernet_header_t)); ethernet_header_t *eth = vlib_buffer_get_current (b0); eth->type = clib_host_to_net_u16 (ETHERNET_TYPE_IP4); if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) { my_output_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); tr->sw_if_index = sw_if_index0; tr->next_index = next0; } vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi0, next0); pkts_sent++; } vlib_put_next_frame (vm, node, next_index, n_left_to_next); } vlib_node_increment_counter (vm, my_output_node.index, MY_OUTPUT_ERROR_TX, pkts_sent); return frame->n_vectors; } ``` 这里仅是简单的示例,实际使用中需要根据具体需求进行修改和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值