struct net_device网络设备结构体详解
轉自:http://blog.csdn.net/viewsky11/article/details/53046787
在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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
下面的這幅圖用于展示linux內核如何利用struct net和struct net_device來構成一個網絡命名空間:
1.分配一個網絡設備函數,即分配一個struct net_device結構體:alloc_netdev(sizeof_priv, name, setup);
這個alloc_netdev()函數本質上是一個宏定義:
#define alloc_netdev(sizeof_priv, name, setup)
alloc_netdev_mq(sizeof_priv, name, setup, 1)
struct net_device *alloc_netdev_mq(int sizeof_priv,
const char *name, void(*setup)(struct net_device*),
unsigned int queue_count)
EXPORT_SYMBOL(alloc_netdev_mq)
1
2
3
4
5
6
7
8
參數介紹:
- sizeof_priv:為分配給網絡設備私有空間的大小;
- name :網絡設備的名稱;
- setup:對分配的網絡設備進行初始化的回調函數;
- queue_count:分配給網絡設備的子隊列數;
struct net_device *alloc_netdev_mq( int sizeof_priv, const char *name,
void (*setup)( struct net_device *), unsigned int queue_count )
{
struct net_device *dev ;
struct netdev_queue *tx ;
int alloc_size ;
alloc_size = sizeof(struct net_device);
dev = kzalloc(alloc_size, GFP_KERNEL);
tx = kcalloc(queue_count, sizeof(struct netdev_queue), GFP_KERNEL);
dev_addr_init(dev);//對struct net_device中的dev_addrs成員進行初始化;
dev_unicast_init(dev); //對struct net_device中的uc成員進行初始化;
dev_net_set(dev, &init_net);//對網絡設備的命名空間進行初始化,默認為init_net;
dev->_tx = tx ;//設置網絡設備的發送隊列;
dev->num_tx_queues = queue_count ;
dev->real_num_tx_queues = queue_count ;
netdev_init_queues(dev);//對struct net_device中的rx_queue成員進行初始化;
setup(dev); //對struct net_device結構體進行初始化;
strcpy(dev->name, name);//設置網路設備的設備名稱;
}
EXPORT_SYMBOL(alloc_netdev_mq);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2.釋放一個網絡設備:
void free_netdev(struct net_device *dev);
EXPORT_SYMBOL(free_netdev);
1
2
3
3.注冊一個網絡設備,只有對一個網絡設備進行注冊以后,這個網絡設備才會在內核中起作用:
int register_netdev(struct net_device *dev)
EXPORT_SYMBOL(register_netdev);
1
2
3
返回值:
- 0:表示注冊成功;
- a negative errno code :表示注冊失敗;
int register_netdev(struct net_device *dev)
{
struct hlist_head *head;
struct hlist_node *p;
int ret;
struct net *net = dev_net(dev); // 獲取網絡設備所在的命名空間;
rtnl_lock();//獲取rtnl信號量;
if(!dev_valid_name(dev->name)) //判斷網絡設備的設備名是否有效;
{}
dev->ifindex = dev_new_index(net); //從網絡設備所在的命名空間中找到一個全局唯一的網絡
//接口索引值;
dev->iflink = dev->ifindex ;
//用于判斷網絡命名空間中是否有相同名字的網絡設備存在;
head = dev_name_hash(net, dev->name);
hlist_for_each(p,head)
{
struct net_device *d = hlist_entry(p, struct net_device, name_hlist);
if(!strncmp(d->name, dev->name, 32))
{
ret = -EEXIST ;
}
}
set_bit(__LINK_STATE_PRESENT, &dev->state);//設置網絡設備的狀態;
list_netdevice(dev); //將網絡設備叫入到相應的命名空間之中;
}
EXPORT_SYMBOL(register_netdev);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
3.注銷一個網絡設備結構體:
void unregister_netdev(struct net_device *dev);
EXPORT_SYMBOL(unregister_netdev);
1
2
3
4.設置一個網絡設備的MAC地址:
int dev_set_mac_address(struct net_device *dev,
struct sockaddr *sa);
EXPORT_SYMBOL(dev_set_mac_address);
1
2
3
4
5.設置一個網絡設備的最大傳輸單元:
int dev_set_mtu(struct net_device *dev, int new_mtu);
EXPORT_SYMBOL(dev_set_mtu);
1
2
3
6.改變一個網絡設備的flag標識符:
int dev_change_flags(struct net_device *dev, unsigend flags);
EXPORT_SYMBOL(dev_change_flags);
1
2
3
7.獲取一個網絡設備的flag標識符:
unsigned dev_get_flags(struct net_device *dev);
EXPORT_SYMBOL(dev_get_flags);
1
2
3
8.給網絡設備添加一個單播MAC地址,當網絡設備在發送單播時使用單播MAC地址
int dev_unicast_add(struct net_device *dev, void *addr);
EXPORT_SYMBOL(dev_unicast_add);
1
2
3
9.刪除網絡設備中的單播MAC地址:
int dev_unicast_delete(struct net_device *dev, void *addr);
EXPORT_SYMBOL(dev_unicast_delete);
1
2
3
10.給網絡設備添加一個設備地址:
int dev_addr_add(struct net_device *dev, unsigned char *addr,
unsigned char addr_type)
EXPORT_SYMBOL(dev_addr_add);
addr_type : address type;
1
2
3
4
5
11.刪除網絡設備中的一個設備地址:
int dev_addr_del(struct net_device *dev, unsigend char *addr,
unsigned char addr_type);
EXPORT_SYMBOL(dev_addr_del);
1
2
3
4
12.設置網絡設備的接口為混雜模式:
int dev_set_promiscuity(struct net_device *dev, int inc);
EXPORT_SYMBOL(dev_set_promiscuity);
1
2
3
當 inc > 0 將網絡設備設置為混雜模式;
當 inc = 0 將網絡設備設置為正常模式;
當 inc < 0 將去掉網絡設備的混雜模式;
13.設置網絡設備的接口為allmulticast模式:
int dev_set_allmulti(struct net_device *dev, int inc);
EXPORT_SYMBOL(dev_set_allmulti);
inc 含義同上;
1
2
3
4
14.在給一個網絡設備的設備名稱進行賦值時,先要檢測這個名字是否有效:
int dev_valid_name(const char *name);
EXPORT_SYMBOL(dev_valid_name);
1
2
3
返回:
1 :表示有效;
0 :表示無效;
15.通過設備的MAC地址以及設備類型來獲取網絡設備的設備結構體:
struct net_device *dev_getbyhwaddr(struct net *net,
unsigned short type, char *hwaddr);
EXPORT_SYMBOL(dev_getbyhwaddr);
1
2
3
4
net : 網絡命名空間;
type: media type of device;
hwaddr:hardware address;
通過memcmp(dev->dev_addr, hwaddr, dev->addr_len)來實現;
16.通過網絡設備的接口索引值來獲取網絡設備結構體:
struct net_device *dev_get_by_index(struct net *net, int ifindex);
EXPORT_SYMBOL(dev_get_by_index);
1
2
3
17.通過網絡設備的設備名來獲取網絡設備結構體:
struct net_device *dev_get_by_name(struct net *net, const char *name);
EXPORT_SYMBOL(dev_get_by_name);
1
2
3
以上所介紹的所有函數位于/net/core/dev.c之中;
本文轉載自http://weiguozhihui.blog.51cto.com/3060615/1584894
總結
以上是生活随笔為你收集整理的struct net_device网络设备结构体详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js -- 时间转年月日
- 下一篇: CSS单行、多行文本溢出显示省略号(……