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的后面
總結
以上是生活随笔為你收集整理的vpp之feature机制介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三菱M70M700数控系统简明调试手册
- 下一篇: WEB安全——文件上传