tft每日頭條

 > 生活

 > 基于linux的網絡配置

基于linux的網絡配置

生活 更新时间:2024-10-01 12:50:26

Preface

Linux内核對網絡驅動程序使用統一的接口,并且對于網絡設備采用面向對象的思想設計。

Linux内核采用分層結構處理網絡數據包。分層結構與網絡協議的結構匹配,既能簡化數據包處理流程,又便于擴展和維護。

一、内核網絡結構

在Linux内核中,對網絡部分按照網絡協議層、網絡設備層、設備驅動功能層和網絡媒介層的分層體系設計。

網絡驅動功能層主要通過網絡驅動程序實現。

在Linux内核,所有的網絡設備都被抽象為一個接口處理,該接口提供了所有的網絡操作。

net_device結構表示網絡設備在内核中的情況,也就是網絡設備接口。網絡設備接口既包括軟件虛拟的網絡設備接口,如環路設備,也包括了網絡硬件設備,如以太網卡。

Linux内核有一個dev_base的全局指針,指向一個設備鍊表,包括了系統内的所有網絡設備。該設備鍊表每個節點是一個網絡設備。

在net_device結構中提供了許多供系統訪問和協議層調用的設備方法,包括初始化、打開關閉設備、數據包發送和接收等。

二、與網絡有關的數據結構

内核對網絡數據包的處理都是基于sk_buff結構的,該結構是内核網絡部分最重要的數據結構。

網絡協議棧中各層協議都可以通過對該結構的操作實現本層協議數據的添加或者删除。使用sk_buff結構避免了網絡協議棧各層來回複制數據導緻的效率低下。

基于linux的網絡配置(網絡設備驅動開發網絡分層結構)1

sk_buff結構可以分為兩個部分,一部分是存儲數據包緩存,在圖中表示為PackertData,另一部分是由一組用于内核管理的指針組成。

sk_buff管理的指針最主要的是下面4個:

head指向數據緩沖(PackertData)的内核首地址;

data指向當前數據包的地址;

tail指向當前數據包的地址;

end 指向數據緩沖的内核尾部。

數據包的大小在内核網絡協議棧的處理過程中會發生改變,因此data和tail指針也會不斷變化,而head和tail指針是不會發生改變的。

對于一個TCP數據包為例,sk_buff還提供了幾個指針直接指向各層協議頭。mac指針指向數據的mac頭;nh指針指向網絡協議頭,一般是IP協議頭;h指向傳輸層協議頭,在本例中是TCP協議頭。

對各層設置指針的是方便了協議棧對數據包的處理。

三、net_device結構

在linux中使用struct net_device結構體來描述每一個網絡設備。同時這個用來刻畫網絡設備的struct net_device結構體包含的字段非常的多,以至于内核的開發者都覺得在現在的linux内核中,這個struct net_device是一個大的錯誤。在本篇文章中,隻介紹struct net_device中的一些字段,其他的字段在以後使用的時候再說。

#define IFNAMSIZ 32 struct net_device { //用于存放網絡設備的設備名稱; char name[IFNAMSIZ]; //網絡設備的别名; char *ifalias; //網絡設備的接口索引值,獨一無二的網絡設備标識符; int ifindex; //這個字段用于構建網絡設備名的哈希散列表,而struct net中的 //name_hlist就指向每個哈希散列表的鍊表頭; struct hlist_node name_hlist; //用于構建網絡設備的接口索引值哈希散列表,在struct net中的 //index_hlist用于指向接口索引值哈希散列表的鍊表頭; struct hlist_node index_hlist; //用于将每一個網絡設備加入到一個網絡命名空間中的網絡設備雙鍊表中 struct list_head dev_list; //網絡設備接口的标識符,其狀态類型被定義在<linux/if.h>之中; unsigned int flags; //網絡設備接口的标識符,但對用戶空間不可見; unsigned short priv_flags; //接口硬件類型,在<if_arp.h>中定義了每一個接口硬件類型; unsigned short type; //網絡設備接口的最大傳輸單元; unsigned mtu; //硬件接口頭長度; unsigned short hard_header_len; //網絡設備接口的MAC地址; unsigned char *dev_addr; //網絡設備接口的單播模式 int uc_promisc; //網絡設備接口的混雜模式; unsigned int promiscuity; //網絡設備接口的全組播模式; unsigend int allmulti; //secondary unicast mac address struct netdev_hw_addr_list uc; //list of device hw address; struct netdev_hw_addr_list dev_addrs; //hw broadcast address; unsigned char broadcast[MAX_ADDR_LEN]; //multicast mac address; struct dev_addr_list *mac_list; //網絡設備接口的數據包接收隊列; struct netdev_queue rx_queue; //網絡設備接口的數據包發送隊列; struct netdev_queue *tx; //Number of TX queues allocated at alloc_netdev_mq() time unsigned int num_tx_queues; //Number of TX queues currently active in device; unsigned int real_num_tx_queues; //Max frame per queue allowned; unsigned long tx_queue_len; //網絡設備接口的狀态; unsigned long state; //網絡設備接口的統計情況; struct net_device_state states; //用于執行網絡設備所在的命名空間; struct net *nd_net; }

下面的這幅圖用于展示linux内核如何利用struct net和struct net_device來構成一個網絡命名空間:

基于linux的網絡配置(網絡設備驅動開發網絡分層結構)2

詳細免費視頻資料關注 後台私信;資料;兩個字可以免費視頻領取 文檔 各大廠面試題 資料内容包括:C/C ,Linux,golang,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,嵌入式 等

基于linux的網絡配置(網絡設備驅動開發網絡分層結構)3

四、數據包接收流程

在Linux内核中,一個網絡數據包從網卡接收到用戶空間需要經過鍊路層、傳輸層和socket的處理,最終到達用戶空

1、數據包到達網卡設備

2、收到數據後網卡根據設置的hash規則(多隊列網卡),決定将數據放到哪個ring buffer,然後通過DMA将數據放到内存,也就是網卡的ring buffer中

3、設備産生硬件中斷,根據網卡設置的中斷綁核通知對應CPU處理數據報文

4、對應CPU執行網絡設備注冊的中斷處理函數,響應硬中斷,将該設備添加到CPU輪詢設備隊列中,關閉網絡設備中斷響應,并喚醒軟中斷處理

5、系統根據RPS和RFS的設置,确定軟中斷在哪個CPU執行,對應CPU的NAPI軟中斷處理例程從CPU的輪詢隊列中按額度從ring buffer中poll數據報文skb并遞交上層協議棧處理,收完報文後,恢複網卡設備中斷響應

6、協議棧處理報文

7、報文遞交至應用程序socket的receive buffers中

基于linux的網絡配置(網絡設備驅動開發網絡分層結構)4

詳細免費視頻資料關注 後台私信;資料;兩個字可以免費視頻領取 文檔 各大廠面試題 資料内容包括:C/C ,Linux,golang,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,嵌入式 等

五、數據包發送流程

以UDP數據包發送流程為例,在DM9000網卡上如何發送一個數據包。

基于linux的網絡配置(網絡設備驅動開發網絡分層結構)5

當用戶空間的應用程序通過 socket函數 sento()發送一個UDP數據後,會調用内核空間的 sock_writev()函數,然後通過 sock_sendmsg()函數處理。sock_sendmsg()函數調用 inet_sendmsg()函數處理,inet_sendmsg()函數會把要發送的數據交給傳輸層的 udp_sendmsg()函數處理。

udp_sendmsg()函數在數據前加入UDP頭,然後把數據交給 ip_build_xmit()函數處理,該函數根據 socket提供的目的 IP和端口信息構造IP頭,然後調用 output_maybe_reroute()函數處理。out_maybe_reroute()函數檢查數據包是否需要經過路由,最後交給 ip_output()函數寫入到發送隊列,寫入完成後由 ip_finish_output()函數處理後續工作。

鍊路層的 dev_queue_xmit()函數處理發送隊列,調用 DM9000網卡的發送數據包函數 dm9000_xmit()發送數據包,發送完畢後,調用 dm9000_xmit_done函數處理發送結果。

總結:更多免費視頻教程文檔資料免費領取後台私信【資料】自行獲取。,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved