1.Linux網絡子系統
Linux網絡子系統的頂部是系統調用接口層。它為用戶空間提供的應用程序提供了一種訪問內核網絡子系統的方法(socket)。位於其下面是一個協議無關層,它提供一種通用的方法來使用傳輸層協議。然後是具體協議的實現,在Linux中包括內核的協議TCP,UDP,當然還有IP。然後是設備無關層,它提供了協議與設備驅動通信的通用接口,最下面是設備的驅動程序。
設備無關接口將協議與各種網絡驅動連接在一起,這一層提供一組通用函數供底層網絡設備驅動使用,讓它們可以對高層協議棧進行操作。需要從協議層向設備發生數據,需要調用dev_queue_xmit函數,這個函數對數據進行列隊,然後交由底層驅動程序的hard_start_xmit方法最終完成傳輸。接收通常是使用netif_rx執行的。當底層設備程序接收到一個報文(發生中斷)時,就會調用netif_rx將數據上傳至設備無關層。
下圖為設備無關層到驅動層的體系結構
2.網絡設備描述(structnet_device)
每一個網絡設備都由struct net_device來描述,該結構可使用如下內核函數進行動態分配
struct net_device *alloc_net(intsizeof_priv, const char *mask, void(*setup)(struct net_deive *))
sizeof_priv是私有數據區大小;mask是設備名,setup是初始化函數,在注冊該設備時,該函數被調用。也就是net_deivce的init成員。
struct net_device *alloc_etherdev(intsizeof_priv)
這個函數和上面的函數不同之處在於內核知道會將該設備做一個以太網設備看待並做一些相關的初始化。
net_device結構可分為全局成員、硬件相關成員、接口相關成員、設備方法成員和公用成員等五個部分
主要全局成員
char name[INFAMSIZ]
設備名,如:eh%d
unsigned long state
設備狀態
unsigned long base_addr
I/O基地址
unsigned int irq
中斷號
主要設備方法有
int (*init)(struct net_device *dev)
初始化函數,該函數在register_netdev時被調用來完成對net_device結構的初始化
int (*open)(struct net_device *dev)
打開接口。ifconfig激活時,接口將被打開
int (*stop)(struct net_deivce *dev)
停止接口,ifconfig eth% down時調用
int (*hard_start_xmit)(struct sk_buf*skb,struct net_device *dev)
數據發送函數
int (*do_ioctl)(struct net_deive *dev,struct ifreq *ifr, int cmd)
處理特定於接口的ioctl命令(sock_ioctl)進行調用。
int (*set_mac_address)(struct net_device*dev, void *addr)
改變MAC地址的函數,需要硬件支持該功能。
網絡設備的注冊
網絡設備注冊方式與字符驅動不同之處在於它沒有主次設備號,並使用下面的函數注冊
int register_netdev(struct net_deivce*dev)
網絡設備的注銷
void unregister_netdev(struct net_device*dev)