vpp之feature机制介绍

网上看了别人写的feature机制介绍,感觉一头雾水,果然要想理解还是要自己通过代码

下面谈谈我对feature机制的理解,主要还是介绍我使用feature的经验

在了解feature之前,需要先明白vpp的node是如何工作的

创建一个plugins 名字为testdual

通过node.c文件可以看到,该插件注册了一个node

.n_next_nodes的值表示当前节点的下一个节点有多少个

.next_nodes表示下一个节点的候选项

接着分析数据包在node.c里面是如何转发数据包的

vpp里面通过这种赋值的方式设置数据包转发的下一个节点,这里在VPPnode节点分析里写的很清楚,建议看明白

上面这种属于vpp在初始化的时候会根据注册节点的说明给节点之间的关系建立连接,属于静态的

既然是静态的,就表示node之间的连接是固定,不够灵活,为了解决node节点的灵活穿插,引入了feature机制

当然从思想上也很好理解,数据包是在内存池里的,node使用的只是指向数据包的指针,数据包在不同node之间转发本质上也是把数据包的指针存放到不同node的frame里,无论是feature还是直接在注册node时指定下一个node本质上都是记录下当前node的下一个node有哪些候选项

下面来看看feature机制如何实现的

1.首先提出一个问题,上面注册的node只表明了下一个node是什么,那么它的上一个node是谁呢?

在生成的代码 testdual.c 中

 这里是注册了一个feature

.arc_name表示该feature属于哪个arc,arc的概念相当于一个group,里面有多个feature

.node_name表示该feature控制的node

.runs_before表示testdual这个node的优先级比ethernet-input高

另外还有个.runs_after 表示比某个node优先级低,为什么要有优先级后面讲

这里来看一下testdual节点未enable时device-input节点的下一个节点有哪些

device-input表示数据包收到后起始node

可以看到图中没有testdual节点

接着enable testdual节点

可以的看到testdual被加入到了device-input节点后面

2.vpp是怎么实现把testdual加入到device-input节点后面的?

前面已经提到注册了feature

我们来看看 testdual enable-disable local0这个命令做了什么

调用了testdual_enable_disable_command_fn函数

可以看出通过vnet_feature_enable_disable函数把上面注册的feature使能,testdual节点才会挂载到device-input节点后面去

3.vnet_feature_enable_disable函数做了什么?

函数第一个参数是arc的name,第二个参数是node的name,第三个参数是网卡的index,第四个参数是enable or disable

通过这个函数控制feature是否生效

这里为什么要有sw_if_index呢?

feature机制有些特殊,假如有两个网卡A和B,如果feature只enable了网卡A,那么B网卡收的包不会根据feature机制进行

device-input明明是node的name这里为什么是arc的name?

通过vpp源码src/vnet/devices/devices.c

arc也是需要创建的,同时需要指明起始node和终止node

4.feature为什么要指明顺序?

feature注册里面为什么会有.runs_before和.runs_after

我们再创建一个插件testqs,同时把它也enable

可以看到testdual和testqs节点都在device-input 

问题来了,如果数据包到达device-input节点,那么它是转发给testdual节点呢还是testqs节点呢

这里就牵涉到同一个arc中feature的优先级了

我们可以通过命令 show features verbose看看

可以看出 在arc device-input中,testqs的优先级比testdual优先级高

如果我想testdual在testqs前面怎么办呢

修改代码,在testdual feature的注册中修改为

 可以看到

 当然也可以在testqs节点注册feature的地方改

关于feature的排序问题,通过before和after把同一个arc内的feature按照自己想要的顺序依次排列,再通过show features verbose查看是否跟预期一致

5.如何把testdual节点变成feature节点

这里会有疑惑,这个问题是什么意思

上面虽然注册了feature,也通过命令把testdual节点添加到了device-input节点后面,但是如果添加一个节点testqs通过feature把testqs排在testdual节点后面,经过测试会发现数据包走到testdual节点后仍然送到了interface-output节点,而不是testqs节点

这里涉及到了feature机制的本质,feature本质上是在原来静态连接node的关系下,把feature注册的那个节点根据排序添加到某个节点的后面,但是代码中转发数据包的逻辑并没有改变

查看testdual/node.c文件

代码中的逻辑仍然是把数据包送到interface_output节点

那么如何把testdual变成feature节点呢

只需要修改代码为(这里用testqs代码举例说明,testdual生成的代码改起来不好解释)

原来的代码是

只需要把代码改造为

vnet_feature_next_u16函数的意思是获取数据包下一个feature node的index

这样数据包就可以灵活的根据feature转发到指定的节点

下面介绍一下feature到底改变了什么

原本testdual节点的下一个节点只有interface-output节点

testqs feature enable以后等价于

虽然没有直接写出testdual后面跟testqs节点,但是作用确实如此,vnet_feature_next_u16函数获取的next_index就是TESTDUAL_NEXT_TESTQS的值

相比较于原来静态的node连接方式,feature disable以后testdual节点后面就没有testqs节点了

额外补充一点

vpp提供了函数也可以实现feature这种灵活控制的节点

模板就是这样的,通过vlib_node_add_next函数可以把某个node添加到另一个node的后面

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值