導航:首頁 > 源碼編譯 > dpdk2011應用程序編譯

dpdk2011應用程序編譯

發布時間:2023-06-02 16:43:45

Ⅰ dpdk-pktgen簡單使用

這一步之前,DPDK環境已塔好,pktgen已編譯成功,網卡已綁定成功等一系列初始化工作已完成。

命令行參數:-P 和 -m 這兩個參數是必要的!

./app/build/pktgen [EAL options] -- \

                            [-h] [-P] [-G] [-T] [-f cmd_file] \

                            [-l log_file] [-s P:PCAP_file] [-m ]

  -s P:  file    PCAP packet stream file, 'P' is the port number  -f filename  Command file (.pkt) to execute or a Lua script (.lua) file 

-l          filename  Write log to filename 寫日誌

-P         Enable PROMISCUOUS mode on all ports 開啟混雜模式,必須要的參數 

-g          address  Optional IP address and port number default is (localhost:0x5606)

If -g is used that enable socket support as a server application

-G          Enable socket support using default server values localhost:0x5606 

-N          Enable NUMA support 

-T          Enable the color output 輸出顏色 

--crc-strip  Strip CRC on all ports

-h Display the help information

參數中,最復雜的是 -m <string>

-m  <string> 配置埠到邏輯核的映射關系,使用類似BNF類語法.映射的邏輯核要與 [EAL options]中的邏輯核要一致。

如下,也可以用 {} 來代替 [].

[EAL options]里的參數與DPDK基本一樣,主要是配置邏輯核掩碼和內存通道數。這里不詳解。以上是命令行參數,下面介紹運漏姿行時參數。

詳細可參考官網中的資料: pktgen運行時參數

Pktgen:/> help #有幫助提示

這里只介紹最常用的命嫌銀令,最常用的配置就是MAC,IPv4|IPv6|ARP,TCP|UDP|ICMP,SPORT|DPORT,PROTO,SEQ等

這些配置可以用 set命令來完成。

除了set命令,常用的還有顯示主頁面,page 0  | page main

載入和保存 .lua腳本的配置信息  load | save <path-to-file>

啟動/結束發包:start | stop <portlist>.

其實不用刻意去記命令怎麼使用,按兩次Tab鍵會有命令使用的提示。我現在用的是版本是3.1.2,最新版已到了3.5.0,所以一些配置命令會有些不一樣,比如配置ip時,<portlist>的順序就不一樣。以上配置是基於最新版來的,如果在實際中發現按上面的命令不對,請先確認是否為最新版.其實只要大致記住一些命令就行,實際使用時可以按兩次Tab鍵就會有提示,也可以把配置保存成.lua文件,下一次運行時候,直接載入就不用再配置了。由於對lua腳本不太熟,關於lua腳本的使用,等使用熟悉了再來深入討論一些功能。最後,放一張運行時候的圖來壓壓驚。。。芹搜宴

運行命令:./app/app/x86_64-native-linuxapp-gcc/pktgen -l 1-4 -n 4 -- -P -T -m "[1:2].0,[3:4].1"

祝大家生活愉快。

Ⅱ dpdk源碼中未定義的宏是如何在編譯時期生成的

它不可能「生成」,磨輪還是需要你指定的,具體對於這些宏如虛肢何指定 要看它編譯命令,但是一般編譯器可以通過編譯環境、差游世命令行參數等方式來定義宏

Ⅲ DPDK PKTGEN使用

PKTGEN有兩種形式,一種是直接由linux系統自帶的內核模塊進行發包(也就是略過協議棧,直接控制發包),另一種是依賴於dpdk的pktgen也就是本文主要講的,需要進行稍微復雜的編譯

modprobe pktgen
在/proc/net/pktgen看到以下文件:
kpktgend_0 kpktgend_1 kpktgend_2 kpktgend_3 pgctrl
其中kpktgen_*的多少是根據你的CPU的個數決定的,如我的機子的CPU數目為4,則有四個此文件皮宴。
通卜跡過命令cat /proc/net/pktgen/pgctrl可以型握並查看pktgen的版本等信息:

註:也有使用insmod的,和modprobe的區別是:比如需要安裝b模塊,但是b依賴於a模塊,因此使用insmod安裝就需要先安裝a模塊再安裝b模塊;如果使用modprobe的話,就可以直接安裝b模塊,默認將安裝a模塊
基本上設置完成後就可以進行測試,要查看是否有流量,可以使用ifstat,tcpmp工具查看,使用應用層的抓包工具是無法看到的

關鍵參數介紹

參數中,最復雜的是 -m <string>
-m <string> 配置埠到邏輯核的映射關系,使用類似BNF類語法.映射的邏輯核要與 [EAL options]中的邏輯核要一致。

運行命令 ./app/x86_64-native-linuxapp-gcc/pktgen -l 0-2 -n 3 -- -P -m "[1].0, [2].1"

官方的default.cfg內容如下:

需要修改的地方有三處:

修改完後即可執行。

圖中port1和port2已經有明顯區別,收包數相差100個包
用pkggen再發1000個包

Ⅳ DPDK ACL演算法介紹

DPDK提供了三種classify演算法:最長匹配LPM、精確匹配(Exact Match)和通配符匹配(ACL)。

其中的ACL演算法,本質是步長為8的Multi-Bit Trie,即每次可匹配一個位元組。一般來說步長為n時,Trie中每個節點的出邊為2^n,但DPDK在生成run-time structures時,採用DFA/QRANGE/SINGLE這幾種不同的方式進行數據結構的壓縮,有效去除了冗餘的出邊。本文將為大家介紹ACL演算法的基本原理,主要內容包括:trie樹的構造、運行時的node array生成和匹配原理。對於ACL介面的使用,參考DPDK的官方文檔即可。

ACL規則主要面向的是IP流量中的五元組信息,即IP/PORT/PROTO,演算法在這個基礎上進行了抽象,提供了三種類型的匹配區域:

熟悉這三種類型的使用後,完全可以用它們去匹配網路報文的其它區域,甚至將其應用到其它場景中。

具體來說,rte_acl_field_def有5個成員:type、size、field_index、input_index、offset。
如果要深入理解演算法,可以思考這幾個欄位的意義,或者換個角度來看:

對於規則的定義,要注意如下兩點:

比如定義了5個field,那麼請給出每一個的具體定義:

像field[1]中IP和mask都為0,表示匹配所有的IP地址;field[3]中range由0到65535,表示匹配所有。類似這樣的全匹配一定要顯示的定義出來,因為如果不明確定義,這些欄位的值取決於編譯器的,最後編譯的ACL規則很可能與原有設想存在偏差。

如果在規則中,對於某個field不進行限制,對於不同type的field,規則書寫時有一定差異:
對於BITMASK和MASK類型,全0代表匹配所有,如上例中的field[0]、field[1];
對於RANGE,則按照上述field[3]中的形式定義。

規則定義好後,會轉換為trie樹並最終合並到一起。
實際處理過程中,build_trie函數會自底向上的將rule中的每個field轉換為node,然後將這些node合並生成這條rule的trie,最後將這個trie與已有的trie進行merge,最終生成整個rule set的trie。

tire由node組成,其主要數據成員如下:

node中values成員用於記錄匹配信息,ptrs則用於描述node的出邊,用於指向轉換後的node。

values採用bitmap進行壓縮,其數據結構為struct rte_acl_bitset values; 一個byte取值范圍是[0,255],可通過256個bit位來進行對應,並實現byte值的快速查找:即通過第x位的bit值是否為1來判斷是否包含數值x(0 <= x < 256)。

num_ptrs用於描述出邊數目,ptrs即為實際的出邊,它記錄了其匹配值values和匹配後的節點指針。
match_flag和mrt則用於記錄匹配結果,trie樹中葉子節點一定是記錄匹配結果的節點。

trie樹其詳細結構比較復雜,這里將其結構進行簡化,如下所示:

上圖的trie樹有4個node,通過ptrs進行指向,values欄位為匹配值的bitmap表示,為了表述的簡潔,後續會採用simple的方式進行描述。
在trie simple中,實心節點表示匹配節點,邊上的數字代表匹配值(為便於閱讀,採用實際值而不再是bitmap形式),…代表其它匹配值。

不同type的field,轉換為node的方式會有所不同。
目前提供的3種類型:BITMASK描述一個byte的匹配,支持mask模式;MASK用於描述4個byte的匹配,支持mask模式;RANGE描述2個byte的匹配,此時mask表示上限。
field到node的轉換,見build_trie中的for循環,具體轉換函數則參考:

對於BITMASK,如{.value.u8 = 6, .mask_range.u8 = 0xff,},它最後的轉換形式如下:

構造field的node時,總會在結尾添加一個空的end節點,最後一個field除外(它是match node)。在for循環中每完成了一個field的解析後,會將其合並到root中,從而生成這個rule的trie。
合並前,也會先構造一個空的end node(見build_trie函數中,while循環下的root創建),讓它與field構成的node頭合並,因為不相交,所以merge時會將匹配信息合並到end node並釋放原有的頭,並將field鏈的end節點返回(保存到end_prev中),下次合並時,就用此end節點與新的node頭合並。
循環遍歷完所有的field後,這些node就串聯起來了,構成這個rule的trie。

對於多個rule,每次構造完成後會merge到整體的trie中。
這里詳細介紹下merge演算法原理,其實仔細閱讀acl_merge_trie函數的注釋即可。

對於node A和node B的merge, acl_merge_trie函數返回一個節點,這個節點指向它們路徑的交集。
這里給出三個例子用於展示merge前後的變化。為了減少狀態點,構造rte_acl_field_def如下:

示例1:

acl_rules[1]為trie A,acl_rules[0]對應trie B,最終trie B合並到trie A上,具體如下:

1和1』合並時,因為level為0,所以1』直接合並到1中;
4和4』合並時,因為節點無交集,所以創建新節點c1(node 4的拷貝),並將4'上的邊拷貝到c1中。

示例2,rule類別相同,但優先順序不同:

acl_rules[1]為trie A,acl_rules[0]對應trie B,最終trie B合並到trie A上,具體如下:

6和6』是match node,類別相同,且6的優先順序為2大於6』的優先順序。
6和6』合並時,直接返回6。而前面創建的新節點,如d1,已包含5』的所有邊(非ACL_INTERSECT_B),所以最終返回5,free d1。
同理依次往上回溯,a4,b3,c2,也依次被釋放,最終merge的trie即為原來的trie A。

示例3,rule類別不同,優先順序相同:

acl_rules[1]為trie A,acl_rules[0]對應trie B,最終trie B合並到trie A上,具體如下:

6和6』是match node,因為類別不同,所以最終創建了新node e1,這也導致示例3和示例2最終merge結果的不同。

合並是一個遞歸的過程,逆向思考構造過程會有助於理解演算法。另外,在build_trie之前會sort_rule,匹配范圍更大的rule會放到前面優先構造trie,個人為這樣node A包含node B的概率更大,這可能也是merge時創建的node C是A的拷貝而不是B的拷貝的原因,因為這樣出現ACL_INTERSECT_B的概率相對較低。

一些說明:

trie樹構造完成後,會將其由指針跳轉的形式轉換為等效的數組索引形式,即node array,既可讓匹配數據更緊湊,也可提高匹配演算法的效率。
採用node array的方式進行狀態點的壓縮是很常見的優化方式,比如snort裡面的ac演算法(acsmx.c):

筆者也曾經做過類似的優化,通過將出邊由指針方式修改為索引方式,整個匹配tree的內存佔用只需要原來的1/5。
將指針方式轉換為node array形式是優化的第一步,對於Next[256]出邊又可以採用多種壓縮方式,比如snort中新的ac演算法(acsmx2.c),就採用了Sparse rows和Banded rows等多種壓縮方式,但其原理是將出邊進行映射轉換,本質上還是做DFA狀態跳轉。

DPDK對邊的壓縮方式與上述類似,不過它優化的粒度更細,不同type的node有不同的壓縮方式:

比如在示例三中,node 1為DFA節點(根節點強制使用DFA方式),2、3、a5、b4、c3、d2為QRANGE,4、5為SINGLE,6、e1為MATCH。
2、3、a5、b4雖然在圖上僅有一條有效邊,但它不為SINGLE,因為對於無效的匹配其實也會有出邊,所以它的真實出邊數目並不唯一,只有像4、5這類全匹配節點才是真正的SINGLE節點。

在構造node array前,會調用acl_calc_counts_indices函數更新node的node type,fanout等信息。
node type依據其fanout值決定,fanout計算見acl_count_fanout函數,其原理是:

比如對於示例3中的d2節點:

fanout計算完成後,若其值為1則為SINGLE節點,(1, 5]為QRANGE節點,(5, 256]為DFA節點。
注意:對於trie樹的root節點,不論fanout值為多少,會強制將其構造為DFA節點,且其fanout值會重新計算。

type和fanout計算完成後,會統計各類節點數目,信息保存在acl_calc_counts_indices傳入的counts參數中,隨後rte_acl_gen依據這些信息將整塊的node array內存分配出來,其布局大致如下:

Data indexes中用於保存在rte_acl_field_def中定義的offset;
Results對應match node,用於保存匹配結果。
Trans table包含整個匹配過程中的跳轉點:

靜態將整塊node array分配完成後,就需要依據trie 樹的node信息填充Trans table和Results了,具體過程見acl_gen_node函數;Data indexes的填充則在acl_set_data_indexes中完成。

2.2中的內存布局大致描繪了各種類型節點的分布情況,DFAs內部由一個一個的DFA節點組成,QUADs和SINGLEs也一樣,都是由相同類型的節點構成。
對於每一個節點,其結構則類似如下形式:

DFA節點的fanout一般為4,出邊數為fanout*RTE_ACL_DFA_GR64_SIZE;(圖中畫的為fanout為4的情況,256條出邊)
QUAD節點的fanout不超過5,即為節點的出邊數不超過5;(圖中畫的為fanout為4的情況)
SINGLE節點只有一個出邊;
圖中的trans即為這個節點的出邊,它本質是一個uint64的數據結構,通過trans和input信息即可計算得到下一個節點的index,從而實現匹配跳轉。trans中不同bit位包含著豐富的信息,具體見acl.h中的說明即可。

高32位對於不同類型的節點有不同的解釋:

低32位:

在實際處理過程中,通過高32位與input_byte計算得到index,與低32位中的addr,即可快速定位到下一個trans:trans_table + (addr+index)。
這里的處理其實與傳統的DFA跳轉差別很大,傳統處理時,next = node[『input』],跳轉到下一個節點,然後採用next[『input』]進行跳轉和匹配,即使有數據結構的壓縮,跳轉目標仍是狀態點。但DPDK中,跳轉時直接採用trans_table + (addr+index),直接找到了狀態點的邊(trans),而不是到狀態點。

跳轉表具體構建時,採用acl_gen_node函數完成:

匹配的過程與跳轉表的構建其實是互為一體的,如何構建跳轉表就決定了如何進行匹配。

在2.3節,對於跳轉的形式已進行了說明,具體可閱讀rte_acl_classify_scalar函數:跳轉時直接採用trans_table + (addr+index),直接找到了狀態點的邊(trans),而不是到狀態點。

對於具體的匹配過程,還有一點需要注意,即GET_NEXT_4BYTES的使用,每次匹配時候都會去4BTYTES進行匹配,這也是為什麼定義input fields時要求4位元組連續。比如我在dpdk-dev郵件組中問的這個 問題 。

解決4位元組連續,可以通過定義相同的input_index來解決,比如像郵件中提到的設置sport/dport的input_index相同,這是因為data indexes的構造取決於input_index,見acl_build_index函數;同時field_index不同、input_index相同時可避免對field區間的優化(如果優化,將某個field去掉了,這時4位元組匹配會失效)。郵件中的問題,正是因為field[3]被優化掉後,4位元組連續匹配出現問題。

在特定的場合還必須通過指定.size為32來解決,即使type類型為BITMASK,見DPDK的ACL文檔中關於 tos示例的說明 。

另外再說下field_index,前面提出一個問題:field_index是否多餘?
答案是不多餘,因為演算法中會對field進行優化,如果不指定field_index欄位,這個優化就無法進行了,具體的優化處理見acl_rule_stats函數。
優化過程中要進行input_index的判斷,這是因為相同的input_index可以有多個field,但其中只有某個field是completely wild時應避免進行優化。只有相同input_index的所有field都是completely wild時,才應該將這個field優化掉。

上面的一系列說明,都是針對GET_NEXT_4BYTES每次匹配四個位元組的匹配進行的補充說明。

匹配的具體過程,這里用圖形的方式進行簡要說明,為了能有多種類型的node,這里構造規則如下:

trie樹如下所述:

對應的node array如下圖所示:

假設輸入數據為:proto 16, ip 192.12.8.8,則transition跳轉方式如上圖紅線所示:

注意:node array中indexes、DFA0和idle省略了。

關於trie樹相關的理論知識參考 這里 。

本文主要介紹了DPDK的ACL演算法,詳細描述了如何由規則生成trie,並將trie轉換為node array的過程,在文末通過示例介紹了具體的匹配過程。文章旨在介紹ACL演算法的基本思路,希望對大家能有所幫助。

Ⅳ 編譯和運行DPDK示常式序

DPDK(Data Plane Development Kit)是數據平面開發工具包,由用於加速在各種CPU架構上運行的數據包處理的庫組成。

在Linux上部署DPDK的方法請參考:
在Linux(CentOS)上部署DPDK------命令行方式

該章節的內容參照自官網的 DPDK build sample apps

當DPDK的target環境創建好後(例如 x86_64-native-linuxapp-gcc ), x86_64-native-linuxapp-gcc 目錄中會包含編譯應用程序的庫和頭文件。

在編譯DPDK應用程序之前,首先需要指定兩個環境變數:

在DPDK的 examples 路徑下面有許多示例應用,這里以其中的 helloworld 為例進行編譯:

DPDK的 examples 路徑下面的應用均可以通過這種方式編譯,也可以直接在 examples 路徑下面運行 make ,將這些應用全都編譯好。

在運行應用程序之前,需要確保:

DPDK應用程序與DPDK target環境的環境抽象層EAL(Environmental Abstraction Layer )庫相關聯,該庫提供了一些通用於每個DPDK應用程序的選項。

EAL的詳細配置請參照: DPDK EAL參數

可按照下列參數運行 ./helloworld :

其中 -l 命令指定cpu cores list是EAL必須的配置;若沒有指定 --socket-mem ,則默認會按照預留的hugepages size來分配。

Ⅵ 在虛擬機編譯運行dpvs

修改:PKG_CONFIG_PATH應該謹唯悄是*.pc所在目錄,祥渣如下設置即可。
export PKG_CONFIG_PATH=/root/dpvs/dpdk/dpdklib/lib/x86_64-linux-gnu/pkgconfig

修改:安裝libnuma-dev即可。apt install libnuma-dev

修改:src/Makefile 中加上 -Wno-address-of-packed-member
CFLAGS += -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -Wno-address-of-packed-member -mcmodel=medium

修改:src/Makefile 中加上 -Wno-packed-not-aligned
CFLAGS += -Wall -Werror -Wstrict-prototypes -Wmissing-prototypes -Wno-address-of-packed-member -Wno-packed-not-aligned -mcmodel=medium

修改:注山困釋掉下面兩行

修改:安裝 apt-get install libpopt-dev

修改:修改dpip的makefile,添加CFLAGS += $(DEFS) -Wno-address-of-packed-member

Ⅶ DPDK編程指南(翻譯)( 三十一)

DPDK 需要一個構建系統用於編譯等操作。 本節介紹 DPDK 框架中使用的約束和機制。

這個框架有兩個使用場景:

以下提供了如何構建DPDK二進制文件。

安裝之後,將創建一個構建目錄結構。 每個構件目錄包含文件、庫和應用程序。

構建目錄特定於配置的體系結構、執行環境、工具鏈。 可以存在幾個構建目錄共享源碼,但是配置不一樣的情況。

例如,要使用配置模板 config/defconfig_x86_64-linuxapp 創建一個名為 my_sdk_build_dir 的構建目錄,我們使用如下命令:

這會創建一個新的 new my_sdk_build_dir 目錄,之後,我們可以使用如下的命令進行編譯:

相當於:

目錄 my_sdk_build_dir 的內容是:

請參閱 Development Kit Root Makefile Help 獲取更詳細的信息。

由於DPDK本質上是一個開發工具包,所以最終用戶的第一個目標就搜此是使用這個SDK創建新的應用程序。 要編譯應用程序,用戶必須設置 RTE_SDK 和 RTE_TARGET 環境變數。

對於一個新的應用程序,用戶必須創建新的 Makefile 並包含指定的 .mk 文件,如 ${RTE_SDK}/mk/rte.vars.mk 和 ${RTE_SDK}/mk/rte.app.mk。 這部分內容描述請參考 Building Your Own Application .

根據 Makefile 所選定的目標(架構、機器、執行環境、工具鏈)或環境變數,應用程序和庫將使用適當的h頭文件進行編譯,並和適當的a庫鏈接。 這些文件位於 ${RTE_SDK}/arch-machine-execenv-toolchain,由 ${RTE_BIN_SDK} 內部引用。

為了編譯應用程序猛襪,用戶只需要調用make命令。編譯結果將置於 /path/to/my_app/build 目錄。

示例應用程序在example目錄中提供。

在DPDK中,Makefiles始終遵循相同的方案:

根據Makefile最後包含的 .mk 文件,Makefile將具有不同的角色。 注意到,並不能在同一個Makefile文件中同時編譯庫和應用程序。 因此,用戶必須創建兩個獨立的Makefile文件,最好是置於兩個不同的目錄中。

無論如何,rte.vars.mk 文件必須包含用戶Makefile。

這些 Makefiles 生成一個二進制應用程序。

創建一個 .a 庫。

app/dpdk-pmdinfogen

dpdk-pmdinfogen 掃描各種總所周知的符號名稱對象文件。這些目標文件由各種宏定義,用於導出關於pmd文件的硬體支持和使用的重要信息。 例如宏定義:

創建以下的符號:

將被 dpdk-pmdinfogen 掃描。使用這個虛擬系,可以從目標文件中導出其他相關位信息,並用於產生硬體支持描述, 然後 dpdk-pmdinfogen 按照以下格式編碼成 json 格式的字元串:

然後可以通過外部工具搜索這些字元串,以確定給定庫或應用程序的硬體支持。

一些變數可以用來配置構建系統的行為。在文件 Development Kit Root Makefile Help 及 External Application/Library Makefile Help 中有描述。

這避免了根據編譯器(icc或gcc)使用不同世知迅的情況。而且,這個變數可以從命令行覆蓋,這允許繞過標志用於測試目的。

閱讀全文

與dpdk2011應用程序編譯相關的資料

熱點內容
java表格居中 瀏覽:403
能來回穿梭現代和民國的小說 瀏覽:830
法國版未刪 瀏覽:755
java中字元串輸入 瀏覽:185
可愛女友糖糖圓圓小詩 瀏覽:272
如何在雲南交投app辦etc 瀏覽:829
尺度大的男同志電影 瀏覽:925
主角為秦霄的穿越小說 瀏覽:707
大尺度床戲多的電影 瀏覽:395
台灣性電影 瀏覽:942
華為手機聊天加密軟體 瀏覽:833
台灣電影愛情片他女朋友死了 瀏覽:813
電影音樂下載 瀏覽:158
池恩瑞的作品 瀏覽:912
澳門電影免費觀看網站大全 瀏覽:243
電腦多組命令 瀏覽:806
abkdb編譯 瀏覽:710
尺度計演算法大全 瀏覽:926
單片機開發板的作用 瀏覽:331