struct net_device 是 Linux 核心網路子系統中最核心的數據結構,每個網絡接口(物理/虛擬)在核心中均對應一個實例。本文基於 Linux 2.6.21 內核,系統梳理其字段佈局、功能分類與關鍵語義。
struct net_device {
char name[IFNAMSIZ]; // 設備名稱(如 "eth0")
unsigned long mem_end; // 共享內存結束地址
unsigned long mem_start; // 共享內存起始地址
unsigned long base_addr; // I/O 基地址
unsigned int irq; // 中斷號
unsigned char if_port; // 多端口選擇
unsigned char dma; // DMA 通道
unsigned long state; // 設備狀態標記位
struct net_device *next; // 全域鏈表指針
// ...
}
int ifindex; // 核心分配的全域唯一索引
int iflink; // 邏輯鏈路索引(主從設備場景)
struct net_device *next_sched; // 調度鏈表指針
struct net_device_stats* (*get_stats)(struct net_device *dev);
struct iw_statistics* (*get_wireless_stats)(struct net_device *dev);
struct iw_handler_def *wireless_handlers;
struct ethtool_ops *ethtool_ops;
unsigned long trans_start; // 最後發送時間
unsigned long last_rx; // 最後接收時間
unsigned short flags; // 接口標記(IFF_UP, IFF_RUNNING...)
unsigned short gflags; // 全域標記
unsigned short priv_flags; // 內核私有標記(如 IFF_EBRIDGE)
unsigned short unused_alignment_fixer; // 對齊填充
unsigned mtu; // 最大傳輸單元
unsigned short type; // 硬件類型(ARPHRD_ETHER 等)
unsigned short hard_header_len; // 硬件頭部長度
void *priv; // 私有數據指針(舊版本,現用 netdev_priv)
// 主從設備關係(Bonding、Bridge)
struct net_device *master; // 主設備指針
unsigned char broadcast[MAX_ADDR_LEN]; // 廣播地址
unsigned char dev_addr[MAX_ADDR_LEN]; // 設備 MAC 地址
unsigned char addr_len; // 地址長度
struct dev_mc_list *mc_list; // 多播地址鏈表
int mc_count; // 多播數量
int promiscuity; // 混雜模式引用計數
int allmulti; // 接收所有多播計數
int watchdog_timeo;
struct timer_list watchdog_timer;
void *atalk_ptr; // AppleTalk
void *ip_ptr; // IPv4
void *dn_ptr; // DECnet
void *ip6_ptr; // IPv6
void *ec_ptr; // Econet
void *ax25_ptr; // AX.25
struct list_head poll_list; // NAPI 輪詢鏈表
int quota; // 輪詢配額
int weight; // 輪詢權重
struct Qdisc *qdisc; // 發送佇列規程
struct Qdisc *qdisc_sleeping; // 睡眠態 qdisc
struct Qdisc *qdisc_ingress; // 入向 qdisc
struct list_head qdisc_list; // 多佇列鏈表
unsigned long tx_queue_len; // 發送佇列長度
spinlock_t ingress_lock; // 入向同步鎖
spinlock_t xmit_lock; // 發送同步鎖
int xmit_lock_owner; // 持有發送鎖的 CPU ID
spinlock_t queue_lock; // 佇列操作鎖
atomic_t refcnt; // 引用計數
struct list_head todo_list; // 延遲操作列表
struct hlist_node name_hlist; // 名稱哈希表節點
struct hlist_node index_hlist; // 索引哈希表節點
| 字段 | 語義 | 典型操作 |
|---|---|---|
flags | 用戶可見接口標記 | IFF_UP、IFF_BROADCAST、IFF_MULTICAST、IFF_PROMISC |
priv_flags | 內核私有標記 | IFF_EBRIDGE、IFF_BONDING、IFF_VLAN_CHALLENGED |
features | 硬件卸載能力 | NETIF_F_SG、NETIF_F_IP_CSUM、NETIF_F_HW_VLAN_TX、NETIF_F_GSO |
mtu | 最大傳輸單元 | 以太網默認 1500,Jumbo Frame 9000 |
qdisc | 發送流控規程 | pfifo_fast(默認)、htb、fq_codel |
xmit_lock | 發送並發保護 | 單 CPU 併發發送保護,dev_queue_xmit 中加鎖 |
refcnt | 引用計數 | dev_hold/dev_put 管理生命週期 |
現代驅動不再使用 dev->priv,而是通過 alloc_netdev(sizeof(struct priv), ...) 在 net_device 結構體後分配私有區域:
static inline void *netdev_priv(const struct net_device *dev)
{
return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
}
驅動定義 struct nic { ... },通過 nic = netdev_priv(dev) 訪問。
net_device 結構體是一個「巨型」聚合體,涵蓋了設備標識、硬件屬性、協議族綁定、流控調度、並發控制、生命週期管理等所有維度。理解其字段佈局與語義,是進行網路驅動開發、虛擬網絡實現、流量控制調優的必修課。