【转】PF_RING学习笔记
轉(zhuǎn)自:Qt迭代器(Java類型和STL類型)詳解
1、PF_RING簡介
PF_RING是Luca研究出來的基于Linux內(nèi)核級的高效數(shù)據(jù)包捕獲技術(shù)。簡單來說PF_RING 是一個(gè)高速數(shù)據(jù)包捕獲庫,通過它可以實(shí)現(xiàn)將通用 PC 計(jì)算機(jī)變成一個(gè)有效且便宜的網(wǎng)絡(luò)測量工具箱,進(jìn)行數(shù)據(jù)包和現(xiàn)網(wǎng)流量的分析和操作。同時(shí)支持調(diào)用用戶級別的API來創(chuàng)建更有效的應(yīng)用程序。
?
屏幕快照 2016-12-15 下午5.15.29.png
2、PF_RING的優(yōu)點(diǎn)
現(xiàn)在我們知道PF_RING是擁有一套完整開發(fā)接口的高速數(shù)據(jù)包捕捉庫,與我們熟知的libpcap十分相似,但其性能要優(yōu)于libpcap。關(guān)于libpcap的實(shí)現(xiàn)機(jī)制可以參考libpcap實(shí)現(xiàn)機(jī)制及接口函數(shù)
問題
- 在傳統(tǒng)數(shù)據(jù)包捕獲的過程中, CPU的多數(shù)時(shí)間都被用在把網(wǎng)卡接收到的數(shù)據(jù)包經(jīng)過內(nèi)核的數(shù)據(jù)結(jié)構(gòu)隊(duì)列發(fā)送到用戶空間的過程中。也就是說是從網(wǎng)卡-->內(nèi)核, 再從內(nèi)核-->用戶空間,這兩個(gè)步驟,花去了大量CPU時(shí)間,從而導(dǎo)致沒有其他時(shí)間用來進(jìn)行數(shù)據(jù)包的進(jìn)一步處理。
在傳輸過程中sk_buff結(jié)構(gòu)的多次拷貝,以及涉及用戶空間和內(nèi)核空間的反復(fù)系統(tǒng)調(diào)用極大的限制了接收報(bào)文的效率,尤其是對小報(bào)文的接收影響更為明顯。
解決方案
** PF_RING提出的核心解決方案便是減少報(bào)文在傳輸過程中的拷貝次數(shù)**。由下圖我們可以直觀的看到不同技術(shù)下對數(shù)據(jù)拷貝的優(yōu)化是不同的。接下來將圍繞這張圖的實(shí)現(xiàn)路徑解釋PF_RING和PF_RING ZC庫的實(shí)現(xiàn)機(jī)制。
?
libpcap、PF_RING、PF_RING ZC方案對比
網(wǎng)卡接收報(bào)文的前面的流程就是libpcap實(shí)現(xiàn)機(jī)制及接口函數(shù)中講解的NAPI,主要的不同體現(xiàn)在報(bào)文在內(nèi)核空間與用戶空間的傳遞。
PF_RING noZC
1、PF_RING socket 針對輪詢機(jī)制的不足,在輪詢機(jī)制的基礎(chǔ)上提出一種新的包捕獲套接字模型,基于環(huán)形緩沖區(qū)的新的套接字 PF_RING
2、每創(chuàng)建一個(gè)PF _RING套接字便分配一個(gè)環(huán)形緩沖區(qū),當(dāng)這個(gè)套接字結(jié)束時(shí)釋放這個(gè)緩沖區(qū)
3、PF_RING套接字綁定到某一網(wǎng)卡上時(shí),這個(gè)網(wǎng)卡在套接字結(jié)束之前處于制度狀態(tài),當(dāng)數(shù)據(jù)包到達(dá)網(wǎng)卡時(shí),將其放入到環(huán)形緩沖區(qū)。如果緩沖區(qū)已經(jīng)滿,則將其丟棄。
4、用戶空間可以直接訪問這個(gè)環(huán)形緩沖區(qū)中的數(shù)據(jù)
5、當(dāng)有新的數(shù)據(jù)包到來的時(shí)候,可以直接覆蓋掉已經(jīng)被用戶空間讀取過的那個(gè)數(shù)據(jù)包的空間
?
環(huán)形緩沖區(qū)示意圖
PF_RING ZC
- PF_RING ZC 實(shí)現(xiàn)了PF_RING? DNA(Direct NIC Access 直接網(wǎng)卡訪問)技術(shù)。是一種映射網(wǎng)卡內(nèi)存和寄存器到用戶態(tài)的方法。
- 因此除了由網(wǎng)卡的網(wǎng)絡(luò)處理單元完成DMA傳輸之外,沒有任何額外的數(shù)據(jù)包復(fù)制,進(jìn)一步節(jié)省了一次數(shù)據(jù)拷貝操作
- 這將性能更好,因?yàn)镃PU周期的僅用于操作數(shù)據(jù)包,而不是把數(shù)據(jù)包從網(wǎng)卡挪走。
-
其缺點(diǎn)是,只有一個(gè)應(yīng)用可以在某個(gè)時(shí)間打開DMA ring(請注意,現(xiàn)在的網(wǎng)卡可以具有多個(gè)RX / TX隊(duì)列,從而就可以在每個(gè)隊(duì)列上同時(shí)一個(gè)應(yīng)用程序),換而言之,用戶態(tài)的多個(gè)應(yīng)用需要彼此溝通才能分發(fā)數(shù)據(jù)包。
PE_RING ZC
?
用戶空間創(chuàng)建PF_RING套接字時(shí)
fd = socket(PF_RING, SOCK_RAW, htons(ETH_P_ALL));和基于PF_PACKET套接字的libpcap不同的是,PF_RING機(jī)制更為靈活:
- 1.PF_RING采用mmap的方式將網(wǎng)絡(luò)裸數(shù)據(jù)放在一個(gè)用戶態(tài)可以直接access的地方,而不是通過socket read/write機(jī)制的內(nèi)存拷貝;
- 2.PF_RING支持下面1到3三種方式將裸數(shù)據(jù)放到mmap到用戶態(tài)的環(huán)形緩沖區(qū)以及4的DNA方式:
- 1.按照PACKET套接字的方式從netif_receive_skb函數(shù)中抓取數(shù)據(jù)包,這是一種和PACKET套接字兼容的方式,所不同的是數(shù)據(jù)包不再通過socket IO進(jìn)入用戶態(tài),而是通過mmap;(transparent_mode 0)
- 2.直接在NAPI層次將數(shù)據(jù)包置入到所謂的環(huán)形緩沖區(qū),同時(shí)NAPI Polling到skb對列,對于這兩個(gè)路徑中的第一個(gè)而言,這是一種比2.1介紹的方式更加有效的方式,因?yàn)闇p少了數(shù)據(jù)包在內(nèi)核路徑的處理長度,但是要求網(wǎng)卡支持NAPI以及PF_RING接口(一般而言,NAPI會(huì)將數(shù)據(jù)包Polling到一個(gè)skb隊(duì)列)。(transparent_mode 1)
- 3.和2相同,只是不再執(zhí)行NAPI Polling。這就意味著,數(shù)據(jù)包將不會(huì)進(jìn)入內(nèi)核,而是直接被mmap到了用戶態(tài),這特別適合于用戶態(tài)的完全處理而不僅僅是網(wǎng)絡(luò)審計(jì),既然內(nèi)核不需要處理網(wǎng)絡(luò)數(shù)據(jù)了,那么CPU將被節(jié)省下來用于用戶態(tài)的網(wǎng)絡(luò)處理。這可能會(huì)將內(nèi)核串行的網(wǎng)絡(luò)處理變?yōu)橛脩魬B(tài)并行的處理。(transparent_mode 2)
- 4.這是一種更猛的方式,喚作DNA支持的模式,直接繞過內(nèi)核協(xié)議棧的所有路徑,也就是說直接在網(wǎng)卡的芯片中將數(shù)據(jù)包傳輸?shù)?DMA的方式)所謂環(huán)形緩沖區(qū),內(nèi)核將看不到任何數(shù)據(jù)包,這種方式和Intel的萬兆猛卡結(jié)合將是多么令人激動(dòng)的事啊;(DNA技術(shù))
?
E33B49AA-8CBA-4146-9AB7-A38EB076B11B.png
以上便是我們在文檔中見到的transparent_mode。對于transparent_mode為0的情況,內(nèi)核會(huì)通過net_if_recv_skb回調(diào)packet_rcv函數(shù)實(shí)現(xiàn)數(shù)據(jù)接收,所以當(dāng)向系統(tǒng)內(nèi)核插入PF_RING模塊時(shí)在內(nèi)核注冊了packet_rcv鉤子函數(shù),使用通用的網(wǎng)卡驅(qū)動(dòng)便可以實(shí)現(xiàn)向PF_RING傳遞報(bào)文。而對于transparent_mode為1和2的模式,則是需要使用PF_RING特殊定制的網(wǎng)卡驅(qū)動(dòng),并在網(wǎng)卡驅(qū)動(dòng)中直接調(diào)用注冊的包處理函數(shù),將報(bào)文傳遞給PF_RING。
?
屏幕快照 2016-12-16 下午4.02.38.png
transparent_mode是對skb_ring_handler之前的包處理路徑進(jìn)行優(yōu)化,
quick_mode是對skb_ring_handler之后的包處理過程進(jìn)行優(yōu)化
?
?
quick_mode
?
屏幕快照 2016-12-15 下午3.06.52.png
PF_RING的背后
很多人都只是認(rèn)為PF_RING只是一個(gè)高性能的抓包機(jī)制,提供本機(jī)的數(shù)據(jù)包鏡像分析,實(shí)現(xiàn)網(wǎng)絡(luò)審計(jì),這只是按照傳統(tǒng)的思路來解釋的。更進(jìn)一步,PF_RING機(jī)制顛覆了網(wǎng)絡(luò)中間節(jié)點(diǎn)解釋數(shù)據(jù)包的方式。按照傳統(tǒng)的觀念,中間網(wǎng)絡(luò)節(jié)點(diǎn)只能按照協(xié)議棧的層次一層一層地解析數(shù)據(jù)包,所謂路由器是三層設(shè)備,交換機(jī)是二層設(shè)備,防火墻分為二層防火墻和三層防火墻...使用PF_RING的設(shè)備,它可以將數(shù)據(jù)包直接從網(wǎng)卡的芯片DMA到你機(jī)器上的內(nèi)存,僅此而已,然后你通過一個(gè)應(yīng)用程序而不是內(nèi)核協(xié)議棧來處理數(shù)據(jù)包,至于說你的應(yīng)用程序怎么處置數(shù)據(jù)包,我來列舉幾個(gè):
1.深度解析數(shù)據(jù)包,按照各種你可以想到的粒度來解析會(huì)話,然后記錄審計(jì)信息;
2.提供高性能的入侵檢測功能;
3.轉(zhuǎn)發(fā)數(shù)據(jù)包,按照路由器的方式。但是不再僅僅通過查詢路由表的方式進(jìn)行IP路由,而是可以通過各種各樣的方式,轉(zhuǎn)發(fā)表完全由你自己定義,比如實(shí)現(xiàn)一個(gè)通用的SDN流表;
4.根據(jù)上面第2點(diǎn)的含義,你可以決定哪些包被丟棄,這就是一個(gè)高性能的防火墻。
相比協(xié)議棧的串行解決方案,使用PF_RING是一個(gè)更加高效的方案,不但高效,而且靈活。如果你擁有多核心的處理器,你甚至可以可以在用戶態(tài)并行處理數(shù)據(jù)包的各個(gè)層信息
PF_RING API
作者:shaarawy18
鏈接:https://www.jianshu.com/p/6d3f3cdc2411
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
?
總結(jié)
以上是生活随笔為你收集整理的【转】PF_RING学习笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 买积存金好还是如意金好?看完就明白了!
- 下一篇: 浦发信用卡可以交水费吗 浦发信用卡怎么交