Linux kernel中網路裝置的管理

2022-04-30 16:00:21 字數 2524 閱讀 9522

kernel中使用net_device結構來描述網路裝置,這個結構是網路驅動及介面層中最重要的結構。該結構不僅描述了介面方面的資訊,還包括硬體資訊,致使該結構很大很複雜。通過這個結構,核心在底層的網路驅動和網路層之間構建了乙個網路介面核心層(這個叫法引自《tcp遷移報告》),這個中間層類似於檔案子系統的vfs。這樣底層的驅動程式就不需要過多地關注上層的網路協議,只需要通過核心提供的網路介面核心層就可以很方便將和網路層進行資料的互動。而網路層在向下傳送資料時,只需要通過核心提供的這個中間層進行互動即可,不需要關心底層究竟是什麼型別的網絡卡。

推薦閱讀:

linux kernel網路部分**剖析

1、註冊網路裝置

網路裝置通常在核心啟動時或者插拔網路裝置時註冊,由網路裝置驅動負責。網路裝置驅動會首先根據自己的網絡卡型別呼叫相應的分配net_device結構的函式(例如乙太網網絡卡可以呼叫alloc_etherdev(),當然也可以直接呼叫alloc_netdev()),然後初始化網絡卡相關的成員,最後呼叫register_netdev()來完成網路裝置的註冊。每個網路裝置在系統中都要有乙個唯一的名稱,通常以網絡卡型別的乙個縮寫為字首,後面跟著數字,例如,eth1就是乙個乙太網卡。register_netdev()是對register_netdevice()的包裝函式。在呼叫register_netdev()註冊裝置時,如果指定的名稱中包含%d格式串(只支援%d),核心會選擇乙個適當的數字來替換格式化串,真正的註冊工作由register_netdevice()來完成。

在呼叫register_netdevice()之前,必須要先呼叫rtnl_lock()獲取rtnl_mutex互斥鎖,任何網路配置資訊改變時都要首先獲取rtnl_mutex互斥鎖。註冊過程如下所示:

net_device結構的netdev_ops由驅動程式初始化,儲存的是裝置相關的操作。如果設定了初始化函式,則通過ndo_init成員來進行裝置相關的初始化操作

dev_valid_name()用來檢查裝置名是否為空或者包含不合法的字元(例如『/』、空白字元),並不會檢查名稱是否衝突。

dev_new_index()為裝置分配乙個可用的索引號,用來標識裝置,索引號由乙個32位計數器(dev_new_index()中定義的靜態變數)產生,每當乙個新的裝置新增到系統中時,計數器都會加1,然後檢查該索引號是否已經使用,如果可用,則返回,否則繼續加1.

在檢查完合法性後,會呼叫dev_name_hash()找到在dev_name_head雜湊表(網路命名空間net結構中的成員)中的槽位,即衝突鍊錶的頭,然後在這個衝突鍊錶中查詢是否已存在相同名稱的裝置。如果找到相同的,則返回錯誤,終止註冊過程。

接下來是是對裝置的特性進行檢查,看是否衝突,並進行調整。

netdev_register_kobject()用來在sysfs中建立跟裝置關聯的項,網路裝置的索引號以及狀態資訊可以通過/sys/class/net/eth0(eth0為裝置名,不同裝置名稱不同)目錄下的項來檢視。

在完成上述的操作後,核心會呼叫list_netdevice()將裝置新增到網路命名空間中的dev_base_head鍊錶、dev_name_head和dev_index_head雜湊表中,最後傳送netdev_register訊息到netdev_chain通知鏈上,通知對裝置註冊感興趣的核心元件。

註冊到系統中的所有網路裝置都會新增到dev_base_head鍊錶、dev_name_head和dev_index_head雜湊表中,其中dev_list按照fifo順序新增,加入name_hlist雜湊表是根據名稱計算出的雜湊值新增,加入index_hlist雜湊表是根據裝置索引號計算的雜湊值新增。它們的關係如下所示:

有了dev_name_head和dev_index_head雜湊表,可以分別通過dev_get_by_name()和dev_get_by_index()來根據裝置名稱或索引來獲取網路裝置。

2、啟用網路裝置

裝置註冊後即可使用,但必須在使用者或使用者空間應用程式開啟後才能收發資料。因為註冊到系統中的網路裝置,其初始狀態是關閉的,此時不能傳送資料。使用者可以通過"ifconfig 裝置名 up"命令來啟用,該命令(ioctl()的siocsifflags命令)通過dev_change_flags()呼叫dev_open()來啟用網路裝置。

啟用網路裝置後,會設定iff_up標誌,如果該標誌已經設定,則不用再繼續操作,直接返回。如果裝置被掛起(休眠狀態,電源管理相關)或已經移除,則不能啟用,返回enodev錯誤。

裝置的啟用主要是呼叫驅動提供的ndo_open介面(儲存在net_device結構的netdev_ops成員上)來完成的,除此之外,在開啟之前會給netdev_chain通知鏈上傳送netdev_pre_up訊息。開啟成功後會給netdev_chain通知鏈上傳送netdev_up訊息。

啟用流程如下所示:

python中網路程式設計

1.使用socket 面向連線tcp 伺服器端 user bin env python from socket import from time import ctime host localhost port 5000 bufsiz 1024 addr host,port udpsersock s...

linux中網路的管理

1.ipv4 2進製32位 10進製 172.25.0.10 255.255.255.0 172.25.0.10 ip位址 255.255.255.0 子網掩碼 子網掩碼255位對應的ip位為網路位 子網掩碼0對應的ip位為主機位 圖形化 1.圖形介面 2.文字化圖形 nmtui 命令 ifconf...

Caffe中網路的繪製

1 安裝graphviz sudo apt get install graphviz 依賴庫2 安裝pydot sudo pip install pydot3 使用命令列進行網路的繪製 第乙個引數是caffe檔案中python資料夾下的draw net.py檔案 第乙個引數 網路模型的prototx...