DPDK Sample Applications User Guides(14)內核NIC接口示例應用程序 KNI

官方文檔查看地址:
http://doc.dpdk.org/guides/sample_app_ug/kernel_nic_interface.html
PDF下載地址:
https://www.intel.com/content/www/us/en/embedded/technology/packet-processing/dpdk/dpdk-sample-applications-user-guide.html

本篇難度係數:
翻譯:☆☆☆☆☆
理解:★★☆☆☆

14.內核NIC接口示例應用程序
內核NIC接口(KNI)是一種DPDK控制平面解決方案,允許用戶空間應用程序與內核網絡堆棧交換數據包。爲實現此目的,DPDK用戶空間應用程序使用IOCTL調用來請求在Linux *內核中創建KNI虛擬設備。IOCTL調用提供接口信息和DPDK的物理地址空間,由KNI內核可加載模塊重新映射到內核地址空間,該模塊將信息保存到虛擬設備上下文。DPDK爲每個分配的設備創建用於數據包入口和出口到內核模塊的FIFO隊列。

KNI內核可加載模塊是標準網絡驅動程序,在接收到IOCTL調用後,訪問DPDK的FIFO隊列以從/向DPDK用戶空間應用程序接收/發送數據包。FIFO隊列包含指向DPDK中數據包的指針。這個:

  • 提供更快的機制來與內核網絡堆棧連接並消除系統調用
  • 使用標準Linux *用戶空間網絡工具(tcpdump,ftp等)爲DPDK提供便利
  • 消除對數據包的copy_to_user和copy_from_user操作。

內核NIC接口示例應用程序是一個簡單的示例,演示如何使用DPDK創建數據包通過Linux *內核的路徑。這是通過爲每個DPDK端口創建一個或多個內核網絡設備來完成的。該應用程序允許使用標準Linux工具(ethtool,ifconfig,tcpdump)與DPDK端口以及DPDK應用程序和Linux *內核之間的數據包交換。

內核NIC接口示例應用程序要求將KNI內核模塊rte_kni加載到內核中。有關加載內核模塊的更多信息,請參閱 內核NIC接口rte_kni

14.1 概述
內核NIC接口示例應用程序kni爲每個物理NIC端口分配一個或多個KNI接口。對於每個物理NIC端口, kni在用戶空間中使用兩個DPDK線程; 一個線程從端口讀取並寫入相應的KNI接口,另一個線程從KNI接口讀取並將未修改的數據寫入物理NIC端口。

建議爲每個物理網卡端口配置一個KNI接口。應用程序可以爲每個物理NIC端口配置多個KNI接口以進行性能測試,或者可以在將來與VMDq支持一起使用。

通過內核NIC接口應用程序的數據包流如下圖所示。
在這裏插入圖片描述
圖14.1 內核NIC應用程序包流

如果使用-m命令行標誌啓用鏈接監視,則會啓動一個額外的pthread,它將檢查每個物理NIC端口的鏈接狀態,並將更新相應KNI接口的運營商狀態以匹配物理NIC端口的狀態。這意味着當以太網鏈路斷開時,KNI接口將自動禁用,並在以太網鏈路啓動時啓用。

如果啓用了鏈接監視,rte_kni則應加載內核模塊,以便將默認運營商狀態設置爲off。這確保了KNI接口時,纔會啓用後, 相應的NIC端口的以太網鏈路已達到銜接狀態。

如果未啓用鏈接監視,rte_kni則應加載內核模塊,並將默認運營商狀態 設置爲on。這在 啓用KNI接口時將KNI接口的載波狀態設置爲on,而不考慮相應NIC端口的實際鏈路狀態。這對於在環回模式下進行測試很有用,其中NIC端口可能沒有物理連接到任何東西。

14.2 編譯應用程序
要編譯示例應用程序,請參閱編譯示例應用程序(http://doc.dpdk.org/guides/sample_app_ug/compiling.html)。

該應用程序位於examples/kni子目錄中。

注意
此應用程序僅用作Linux。

14.3 運行kni示例應用程序
kni示例應用程序需要大量的命令行選項:

KNI [EAL選項]  -  -p PORTMASK --config = “(端口,lcore_rx,lcore_tx [,lcore_kthread,...])[,(端口,lcore_rx,lcore_tx [,lcore_kthread,...])]”[ -P] [-m]

例如:

  • -p PORTMASK
    要配置的端口的十六進制位掩碼。

  • --config="(port,lcore_rx,lcore_tx[,lcore_kthread,...])[,(port,lcore_rx,lcore_tx[,lcore_kthread,...])]"
    決定Rx和Tx DPDK任務的哪些核心,以及(可選)KNI內核線程爲每個物理端口綁定的內核。

  • -P
    可選標誌,用於將所有端口設置爲混雜模式,以便無論數據包的以太網MAC目標地址如何都可以接收數據包。如果沒有此選項,則只接受以太網MAC目標地址設置爲端口以太網地址的數據包。

  • -m
    可選標誌,用於監視和更新以太網載波狀態。設置此選項後,將啓動一個線程,該線程將定期檢查物理以太網端口的以太網鏈路狀態,並設置相應KNI網絡接口的載波狀態以匹配它。這意味着當以太網鏈路關閉時,KNI接口將自動禁用,並在以太網鏈路啓動時啓用。

有關運行應用程序和環境抽象層(EAL)選項的一般信息,請參閱“ DPDK入門指南”。

EAL選項的-c coremask-l corelist參數必須包含lcore_rx和lcore_tx爲每個端口指定的lcore,但不需要包含lcore_kthread指定的lcore,因爲這些核心用於將內核線程固定在rte_kni內核模塊中。

--config參數必須包含一組(port,lcore_rx,lcore_tx,[lcore_kthread,…])值,用於-p PORTMASK參數中指定的每個物理端口。

可選的lcore_kthreadlcore ID參數--config可以爲每個物理端口指定零,一次或多次。

如果沒有指定lcore_kthread的lcore ID ,則將爲物理端口創建一個KNI接口port,並且KNI內核線程將沒有特定的核心關聯。

如果爲其指定了一個或多個lcore ID lcore_kthread,則將爲指定的每個lcore ID創建一個KNI接口,該接口綁定到物理端口 port。如果rte_kni內核模塊以多內核線程模式加載,則將爲每個KNI接口創建一個內核線程並綁定到指定的內核。如果rte_kni 內核模塊以單內核線程 模式加載,則只爲所有KNI接口啓動一個內核線程。內核線程將綁定到lcore_kthread指定的第一個lcore ID。

14.3.1 示例配置
以下命令將首先以多內核線程模式加載rte_kni內核模塊 。在kni 隨後的應用程序使用兩個端口開始; 端口0使用lcore 4作爲Rx任務,lcore 6作爲Tx任務,並將創建單個KNI接口 vEth0_0,內核線程綁定到lcore 8.端口1使用lcore 5作爲Rx任務,lcore 7作爲Tx任務,並將vEth1_0使用綁定到lcore 9的內核線程創建單個KNI接口。

# rmmod rte_kni
# insmod kmod/rte_kni.ko kthread_mode=multiple
# ./build/kni -l 4-7 -n 4 -- -P -p 0x3 -m --config="(0,4,6,8),(1,5,7,9)"

以下示例完全相同,只是每個物理端口指定了一個額外的lcore_kthread核心。在這種情況下,kni將創建四個KNI接口:vEth0_0/ vEth0_1綁定到物理端口0和 vEth1_0/ vEth1_1綁定到物理端口1。

每個接口的內核線程將綁定如下:

  • vEth0_0 - 綁定到lcore 8號。
  • vEth0_1 - 綁定到lcore 10號。
  • vEth1_0 - 綁定到lcore 9號。
  • vEth1_1 - 綁定到lcore 11號
# rmmod rte_kni
# insmod kmod/rte_kni.ko kthread_mode=multiple
# ./build/kni -l 4-7 -n 4 -- -P -p 0x3 -m --config="(0,4,6,8,10),(1,5,7,9,11)"

下面的示例可用於測試kni測試應用程序和rte_kni內核模塊之間的接口。
在本例中,rte_kni內核模塊以單內核線程模式加載,啓用了環回模式,並將默認載波狀態設置爲on,以便使用KNI接口時不必連接相應的物理NIC端口。
爲端口0創建一個KNI接口vEth0_0,爲端口1創建一個KNI接口vEth1_0。
由於rte_kni是在“單內核線程”模式下加載的,所以一個內核線程被綁定到lcore 8。

由於沒有使用物理NIC端口,可以通過不向kni指定-m標誌來禁用鏈路監控:

# rmmod rte_kni
# insmod kmod/rte_kni.ko lo_mode=lo_mode_fifo carrier=on
# ./build/kni -l 4-7 -n 4 -- -P -p 0x3 --config="(0,4,6,8),(1,5,7,9)"

14.4 KNI操作
一旦啓動kni應用程序,用戶可以使用普通的Linux命令,好像他們是任何其它Linux的網絡界面來管理KNI接口。

啓用KNI接口並分配IP地址:

# ifconfig vEth0_0 192.168.0.1

顯示KNI接口配置和統計信息:

# ifconfig vEth0_0

用戶還可以通過向kni 應用程序發送USR1和USR2信號來檢查和重置應用程序內的數據包統計信息:

# 打印統計
# kill -SIGUSR1 `pidof kni`

# 清除統計
# kill -SIGUSR2 `pidof kni`

轉儲網絡流量:

# tcpdump -i vEth0_0

普通的Linux命令也可用於更改與KNI接口對應的物理網卡使用的MAC地址和MTU大小。但是,如果爲物理端口配置了多個KNI接口,則這些命令僅適用於該端口的第一個KNI接口。

更改MAC地址:

# ifconfig vEth0_0 hw ether 0C:01:02:03:04:08

更改MTU大小:

#ifconfig vEth0_0 MTU 1450

如果編譯DPDK CONFIG_RTE_KNI_KMOD_ETHTOOL=y並使用Intel NIC,則用戶可以在KNI接口上使用ethtool,就像它是普通的Linux內核接口一樣。

顯示NIC寄存器:

# ethtool -d vEth0_0

關閉kni應用程序後,將從Linux內核中刪除所有KNI接口。

14.5 說明
以下部分提供了一些代碼說明。

14.5.1 初始化
mbuf池,驅動程序和隊列的設置類似於L2轉發示例應用程序(在實際和虛擬化環境中)中完成的設置。此外,根據命令行參數爲每個配置的端口分配一個或多個內核NIC接口。

用於爲特定端口分配內核NIC接口的代碼位於函數kni_alloc中。

此示例應用程序獨有的初始化過程中的另一個步驟是每個端口與RX,TX和內核線程的lcores的關聯。

  • 一個lcore從端口讀取並寫入相關的一個或多個KNI設備
  • 從一個或多個KNI設備讀取並寫入端口的另一個核心
  • 用於逐個固定內核線程的其他lcores

這是通過使用kni_port_params_array[]由端口ID索引的數組來完成的。代碼在函數parse_config中。

14.5.2 數據包轉發
初始化步驟完成後,將在每個lcore上運行main_loop()函數。此函數首先針對用戶提供的lcore_rx和lcore_tx檢查lcore_id,以查看此lcore是讀取內核NIC接口還是寫入內核NIC接口。

對於從NIC端口讀取並寫入內核NIC接口(kni_ingress)的情況,數據包接收與L2轉發示例應用程序中的相同(請參閱接收,處理和傳輸數據包(http://doc.dpdk.org/guides/sample_app_ug/l2_forward_real_virtual.html#l2-fwd-app-rx-tx-packets))。通過將mbuf發送到內核NIC接口來完成數據包傳輸rte_kni_tx_burst()。在內核成功複製mbuf後,KNI庫自動釋放mbuf。

對於從內核NIC接口讀取並寫入物理NIC端口(kni_egress)的另一種情況,通過從內核NIC接口讀取mbuf來檢索數據包rte_kni_rx_burst()。數據包傳輸與L2轉發示例應用程序中的相同(請參閱接收,處理和傳輸數據包)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章