VPP Features Arc
  Pq37jUF4UeqZ 2023年11月02日 46 0

Author basilguo@163.com

Date Aug. 09, 2023

Description VPP Feature Arcs.

1. 环境

在介绍VPP的Feature Arcs之前,需要简要介绍下VLIB。如果有不当之处,还请参考官网VLIB文档

1.1. 版本

$ sudo vppctl # 或者make run
DBGvpp# show version
vpp v23.06-release built by XXX on XXX at 2023-08-02T07:37:51

$ lsb_release -r
Release:        20.04

2. VLIB (Vector Processing Library)

VLIB源码文件位于:${VPP_HOME}/src/{vlib, vlibapi, vlibmemory}目录。提供向量处理支持,例如图节点调度、可靠性多播、多任务线程轻量级协作,CLI,.dll支持,物理内存和Linux epoll支持。

VPP VLIB提供的处理数据包的方式是构造无环有向图处理方式。所以添加新的feature,就是向图中添加新的node节点,合理的选择节点的添加位置,就能实现想要的功能。

一个路由器或者交换机具备很多L2-L4层的功能,这也是VPP能通过graph nodes提供的。不过已有的nodes可能无法提供你需要的功能,这时候就需要添加新的feature了。

feature arc并没有严格的定义,它就是现有VPP图的一个子图,包含了你需要的节点nodes。由于是有向图,所以就需要定义从哪里开始,到哪里结束。一般这些严格的首尾节点都是定义好了的,例如device-input、interface-output以及error-drop,从名字也能看出来些端倪。

所以实际上添加新的feature arc,就变成了如何确定添加到的位置,以及如何添加。如何添加的问题,其实就是写一个新的Plugin,可以参考VPP 插件分析与开发 ,其中需要:

  1. 注册插件
  2. 入口init函数
  3. 节点注册以及feature挂载位置
  4. CLI命令行注册(可选,默认开启情况下)
  5. 在配置文件中的配置(可选,可以参考hicn

在创建了插件之后,node.c中插件注册了一个node,指定该node名称以及后续node。

VLIB_REGISTER_NODE (sample_node) =
{
  .name = "sample",
  .vector_size = sizeof (u32),
  .format_trace = format_sample_trace,
  .type = VLIB_NODE_TYPE_INTERNAL,

  .n_errors = ARRAY_LEN(sample_error_strings),
  .error_strings = sample_error_strings,

  .n_next_nodes = SAMPLE_N_NEXT,    // enum中最后一个,表示的该节点后续节点候选项个数

  /* edit / add dispositions here */
  .next_nodes = {                   // 后续节点候选项
    [SAMPLE_NEXT_INTERFACE_OUTPUT] = "interface-output",
  },
};

node.c还指定了该node要处理函数的逻辑,有两种方式来指定,一种是在注册node的时候使用.function = function_name,一种是使用宏VLIB_NODE_FN (sample_node),其中参数sample_nodeVLIB_REGISTER_NODE宏中参数对应即可。

3. VPP Fearture Arcs

VPP的Feature就是有序的图节点集合(子有向图嘛)。分为两种,一种是需要接口使能,一种是系统使能。就是是否指定使能接口的区别。

Feature arcs中的node是独立的,没有耦合性的,相互之间不知道彼此存在,需要coder去做“next feature node”的指定。

3.1. 添加新的feature arc

VNET_FEATURE_ARC_INIT (ip4_unicast, static) =
{
  .arc_name = "ip4-unicast",
  .start_nodes = VNET_FEATURES ("ip4-input", "ip4-input-no-checksum"),
  .last_in_arc = "ip4-lookup",
  .arc_index_ptr = &ip4_main.lookup_main.ucast_feature_arc_index,
};

这里只是个例子,ip4-unicast已经存在于VPP中了,初始化的内容包括arc名称、起始结束node名字以及arc_index指针。会以链表形式挂接到全局变量extern vnet_feature_main_t feature_main 的next_arc上。

通过show feature verbose可以查看该feature arc以及内部的feature。如果需要添加自己的arc,倒是可以查看一下源代码如何添加feature arc。

DBGvpp# show features verbose
...
[15] ip4-unicast:
  [ 0]: ip4-rx-urpf-loose
  [ 1]: ip4-rx-urpf-strict
  [ 2]: svs-ip4
  [ 3]: srv6-t-m-gtp4-dt
  [ 4]: srv6-t-m-gtp4-d
  [ 5]: srv6-as4-rewrite
  [ 6]: srv6-ad4-flow-rewrite
  [ 7]: srv6-ad4-rewrite
  [ 8]: snort-enq
  [ 9]: ip4-sv-reassembly-feature
  [10]: pnat-input
  [11]: plugin_sample
...

3.2. 添加新的feature

VNET_FEATURE_INIT (mactime, static) =
{
  .arc_name = "ip4-input",       // arc的名称,挂载位置
  .node_name = "plugin_sample",
  .runs_before = VNET_FEATURES ("ip4-lookup"),
};

主要完成feature挂载的arc名称,node节点名称,以及运行当前feature的之前或者之后的node节点。可以通过show features verbose查看挂载位置。还可以查看该节点的一些信息。

DBGvpp# show node plugin_sample
node plugin_sample, type internal, state active, index 77
  node function variants:
    default only

  next nodes:
    next-index  node-index               Node               Vectors
         0          643               ip4-lookup               0
         1          698               error-drop               0

  known previous nodes:
    none

当然在VNET_FEATURE_INIT的时候,还可以指定.runs_after,这样也就能确定previous nodes了。不过我这里就不修改不演示了。

3.3. 启用/关闭feature

vnet_feature_enable_disable ("device-input", /* arc name */
                         "plugin_sample",      /* feature name */
                         sw_if_index,    /* Interface sw_if_index */
                         enable_disable, /* 1 => enable */
                         0 /* (void *) feature_configuration */,
                         0 /* feature_configuration_nbytes */);

sw_if_index = 0,那么就会作为系统使能的方式启用、关闭。

4. 参考

  1. VPP VLIB文档
  2. VPP Feature Arcs
  3. vpp--arc_feature学习以ipv4单播为例
  4. vpp之feature机制介绍
  5. VPP之插件框架分析
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
Pq37jUF4UeqZ