vpp flowprobe
介紹
flowprobe plugin是vpp源碼自帶的插件,主要功能是flow信息上報,與vpp中的ipfix。
簡單的配置
set ipfix exporter collector 10.87.45.7 src 10.248.161.144 template-interval 50 port 4739 path-mtu 1450
配置flow_report_process(PROCESS類型的node),設置上報消息的目的地址,源地址,端口號,mtu等
flowprobe params record l3 active 5 passive 120
flowprobe params record <[l2] [l3] [l4]> [active <timer> passive <timer>]
配置flowprobe節點參數
flowprobe feature add-del eth0 ip4
在接口上使能這個feature
測試抓包結果:
模板上報
flow信息上報
每個flow中的信息和模板中的一致
遇到的問題以及關鍵點分析
1、數據包起始位和預期不一致
背景:
該plugin注冊在ip4-output或者interface-output arc中(取決于是l2探測還是l3 l4探測),只是上報tx方向的流量,想rx和tx的流量都上報
方法:
將該上報flow node注冊在ip4-unicast arc中
預期結果:
rx和tx方向的流量都會上報
現象:
仍然是只有tx方向的流量
問題原因
add_to_flow_record_state 這個函數。無論是設置l2、l3還是l4級別的探測,都會調用這個函數,這個函數有一處代碼
ethernet_header_t *eth = vlib_buffer_get_current (b);
因為這個node本來是放在tx方向的,所以當數據包到達這個node的時候,vlib_buffer_get_current(b)獲取到的是以太頭部。如果把這個node放在ip4-input之后,vlib_buffer_get_current(b)獲取到的是ip頭部,這樣就會導致內容獲取失敗,因此rx方向的流量無法上報。
解決方法
1、如果放在device-input中呢?
也有問題,這個flowprobe node的下一跳是ip4-lookup,如果放在了device-input,就會走不到ip4-input節點中去,也就會造成數據包到不了我們的業務處理節點
2、對node的處理邏輯做一些改動
如何判斷vlib_buffer_get_current(b)得到的是以太頭還是ip頭?
是判斷上一個節點還是判斷 vlib_buffer_get_current獲取到的內容?
node如果獲取上一個節點的name信息?
3、新注冊一個節點,放在ip4-input或者ip4-local之后,原來的節點保持不變
好處:可以針對當前的業務,對模板做一些裁剪和增加
壞處:代碼量有點大,rx和tx方向的模板不一致,對控制層解析也會造成困擾
4、新寫節點+修改原有節點
對原有節點的模板進行適應業務的修改,但是代碼改動量有點大
2、上報時間不固定的問題
現象:
設置了active time,抓包發現并不是以active time為頻率進行上報
問題原因:
走讀代碼發現active只是其中一個判斷條件,根據這些flow信息組裝成的包,總長度不超過預設的1450,仍然不會上報。如果是真是網絡環境,應該還是會接近active time的頻率上報。源代碼這么設計的好處就是可以減少上報的數據量,減輕控制層的壓力,但是缺點就是如果長時間flow信息單一,會造成上報不及時。目前的處理機制是提供一個possive timer,如果這個定時器觸發,會強制發送flow上報信息。
3、ipfix-exporter起到什么作用?
在源碼/src/vnet/ipfix-export中,定義了一個PROCESS類型的節點
VLIB_REGISTER_NODE (flow_report_process_node) = { .function = flow_report_process, .type = VLIB_NODE_TYPE_PROCESS, .name = "flow-report-process", };
這個節點有什么作用?
目前來看,這個節點的作用在于模板的上報。可以配置多個模板信息,模板由flowprobe提供。
當設置的上報模板定時器觸發,就會發送一個模板信息,與此同時,也會調用flowprobe的回調安徽省農戶,刷新flowprobe節點的數據緩存,上報flow信息。
4、node分析
flowprobe一共有5個node
flowprobe-ip4
flowprobe-ip6
flowprobe-l2
flowprobe-walker
flowprobe-timer-process
前三個都是internal類型的節點,這三個節點的入口函數是一樣的,對報文頭進行解封裝,然后查找/創建flowprobe entry,判斷是否應該上報flow信息
flowprobe-walker是input-interrupt類型的節點,負責possive timer超時處理。
flow-timer-process是process類型的節點,但是這個節點有些疑問。在其入口函數中的while(1)死循環中,沒有喚醒函數,而是通過vlib_process_suspend暫時掛起一段時間,所以這個節點只需要接收一次事件觸發就可以。這個事件是在配置tx interface able/disable的時候觸發的。這個節點的作用就是在每次掛起之前,向每個worker線程的flowprobe-walker發送interrupt信號
flowprobe-walker節點會遍歷當前線程超時的定時器(在創建每個flowprobe entry的時候,entry的索引值就是在fm->pool_per_worker[my_cpu_number]這個數組中的位置,由定時器模塊在定時器超時調用回調函數時會把這個索引填入fm->expired_passive_per_worker數組中)。根據這些信息,flowprobe-walker節點就會把所有超時的entry轉換為flow信息進行上報
5、ipfix
RFC7011
6、api文件定義的值和代碼中用到的值不一致
在api文件中,設置flowprobe feature add-del infname l2 | ip4 | ip6 命令中,l2的宏定義值是2,ip4宏定義值是1,ip6宏定義值是。在代碼中
flowprobe_tx_interface_add_del_feature
這個函數l2的宏定義值是2,ip4宏定義值是0,ip6宏定義值是1.
7、l2_ip4 / l2_ip6是什么作用
在配置中,是沒有這兩個配置參數的,如果
flowprobe params record l3 active 5 passive 120
flowprobe feature add-del eth0 l2
如果flowprobe params record設置l3,flowprobe feature設置l2,這種情況下,就會上報兩個template,既會上報l2+ip4的流信息,也會上報l2+ip6的流信息。
8、設置參數組合
record l2,l3,l4,l2&l3,l2&l4,l3&l4,l2&l3&l4
probe l2,ip4,ip6
record可以混合設置,probe不可以混合設置
which L2 L2 L2 IP4 IP4 L2 L2 L2 L2
record L2 L3 L4 L2 L3 L2L3 L2L3L4 L3L4 L2L4
T L2 L2L3 L2L4 L2 L3 L2 + L2L3 L2+L2L3L4 L2L3L4 L2+L2L4
which IP4 IP4 IP4 IP4 IP4
record L2L3 L2L3L4 L3L4 L2L4 L4
T L2L3 L2L3L4 L3L4 L2L3L4 L4
9、active timer和passive timer是什么作用?
active timer:
如果設置為0,每收到一個包,就會用fm->stateless_entry[my_cpu_number]作為新建的flowprobe entry,然后把這個entry填入flow信息上報報文,flow信息上報報文中的flow信息,packets的數量始終為1.這里會有一個問題,那就是報文duration字段,start為1970,end為當前時間,所以這個字段是不可信的。flowprobe-timer-process節點將不會觸發,flowprobe-walker也不會觸發。
如果設置為n,那么在某個flow的第一個報文到來時,會用flowprobe_create創建一個entry(也就是在fm->pool_per_worker[my_cup_number]數組里分配一個entry)。在0到n這個時間段內,如果有相同的flow到來,則更新entry即可。超過n,再把entry填入flow信息上報報文。這里會有一個問題,如果在n時間段之前來了一些報文,在n超時很長一段時間都沒有這個flow的報文到來,這就會造成上報不及時。這個問題會由possive timer來解決。但是如果在active timer到possive timer之間該flow的報文到來,就會導致上報不及時。
暫時無法在飛書文檔外展示此內容
passive timer:
如果設置為0,那么flowprobe entry就不會設置過期時間。
如果設置為n,那么active timer必須要小于n。每個flowprobe entry的過期時間為n,到了過期時間,將會由flowprobe-walker節點進行處理。
| active timer | 0 | n | n |
| passive timer | any | 0 | m |
| 無需考慮passive timer的值。上報即時,但是上報報文太多。 | entry無過期時間,會造成entry長時間無法更新,不建議這種配置 | 推薦這種配置,不會造成太多上報報文,在最長m時間內,entry一定會填入報文中 |
方案設計
1、vpp:
a、新增一個節點,
負責處理ip4-input/ip4-local節點之后的數據。模板信息參照flowprobe的l3探測。flowprobe節點保持不變。數據上報采用網絡包上報。
好處:對原有flowprobe插件不做任何改動(測試時發現原有插件的api文件定義的宏值和代碼中的宏值不一致,這個需要修改,cli方式沒有這個問題),新增節點代碼可以放在srou plugin中,隔離性較好。
壞處:新增節點的函數基本和flowprobe plugin的節點處理函數一致,代碼重復不夠精簡。
b、不新增節點
修改原有節點代碼,將原有節點在ip4-unicast arc中注冊一次,根據vlib_buffer_t的輔助信息判斷當前節點是在ip4-input之后還是在output之后。
壞處:要修改flowprobe plugin的代碼,不同節點走相同的處理函數,代碼可讀性差
好處:代碼修改量小
2、edge-controller如何對ipfix功能進行配置
采用api方式,edge-controller通過ipfix以及flowprobe提供的api接口對功能進行配置。
3、如何上報給edge-controller
a、api機制
現有代碼并沒有實現這個機制,需要開發。
b、網絡包方式
這個是vpp現有代碼實現的方式,通過配置遠端ip,通過發送網絡包進行上報。
vpp的地址和edge-controller的地址是一樣的,所以如果上報flow的報文src ip和dst ip一樣,ip4-local節點會校驗失敗。如果dst ip不是本機地址,那么報文就不會punt。src ip設置成127.0.0.1可以解決這個問題。
flowprobe創建flow entry的同時,會創建這個entry的定時器,時長為passive的值。定時器超時后會將entry index傳給定時器系統。
在定時器系統的回調函數會遍歷超時的定時器傳進來的index,然后放入fm->expired_passive_per_worker[thread_index]
這個定時器是不會停止的,即便是已經將entry填入message中,只會將entry的packet count置位0,不會停止這個定時器。在flowprobe-walker節點(此節點運行在worker線程中)中會不停的遍歷超時entry,如果packet count大于0,則把這個entry填入message中。
在disable flowprobe feature中,如何處置未填入message中的entry以及如何處置message len小于path mtu而未發送出去的message中呢?
處理disable消息的函數運行在main線程中。
目前來看,vpp只支持一個domain id,值為1。src port和dst port都是4739
flow_report stream設計的很奇怪
添加stream是找到domain id為-1的值,如果沒找到,就重新申請一塊內存。
查找的入參是domain id和src port,找到domain id和src port都匹配的stream。
刪除stream,實際上不是刪除這塊內存,而是將這個stream的domain id設置為-1.
在發送message的過程中,需要用到stream,但是,查找是檢索第一個domain id為1的stream。所以即便是添加了多個stream,也只會用到一個。
不僅如此,也沒有考慮到線程沖突。stream的增刪改查都是在main線程中進行,使用是在worker線程中。
總結
以上是生活随笔為你收集整理的vpp flowprobe的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 杜比音效卡刷包android 7.0,杜
- 下一篇: 可调电阻封装图_干货!17种元器件PCB