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网络设备结构体详解的更多相关文章
- NetBios 的结构体详解
[NetBios 的结构体详解] NetBIOS是早期的局域网传输协议. 1.结构体. 2.命令 NetBIOS命令的使用方式有两种,即等待和非等待(或称为同步与异步)方式. 如果命令码的高阶位是0时 ...
- struct socket结构体详解
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://weiguozhihui.blog.51cto.com/3060615/15852 ...
- Linux下DIR,dirent,stat等结构体详解
摘自:http://www.liweifan.com/2012/05/13/linux-system-function-files-operation/ 最近在看Linux下文件操作相关章节,遇到了这 ...
- Linux进程描述符task_struct结构体详解--Linux进程的管理与调度(一)【转】
Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程,这个结构体包含了一个进程所需的所有信息.它定义在include/linux/sched.h文件中. 谈到task_str ...
- Linux下DIR,dirent,stat等结构体详解(转)
最近在看Linux下文件操作相关章节,遇到了这么几个结构体,被搞的晕乎乎的,今日有空,仔细研究了一下,受益匪浅. 首先说说DIR这一结构体,以下为DIR结构体的定义: struct __dirstre ...
- I2C初始化结构体详解
typedef struct { uint32_t I2C_ClockSpeed; /*设置SCL时钟频,此值不低于40000*/ uint16_t I2C_Mode; /* 指定工作模式,可选I2C ...
- CEF CefSettings 结构体 详解
1. single_process: 设置为ture时,browser和render使用同一个进程.Chromium 不正是支持此运行模式,并且不如默认的多进程稳定. 2. no_sandbox: 沙 ...
- struct termios结构体详解
一.数据成员 termios 函数族提供了一个常规的终端接口,用于控制非同步通信端口. 这个结构包含了至少下列成员:tcflag_t c_iflag; /* 输入模式 */tcflag_t ...
- 【USB】struct usb_device_id 结构体详解
struct usb_device_id { /* which fields to match against? */ __u16 match_flags; //说明使用哪种匹配方式 /* Used ...
随机推荐
- CMT跟踪算法学习笔记(一)
关于这个算法,已经有网友写出笔记. 这位网友用画图的方式总结出了算法的各个流程,并总结了源码中的各个类:http://blog.csdn.net/roamer_nuptgczx/article/det ...
- laravel 辅助函数
数组&对象 1.array_divide() array_divide 函数返回两个数组,一个包含原始数组的健,另一个包含原始数组的值 [$keys, $values] = array_div ...
- 【BZOJ】4292: [PA2015]Równanie
题解 \(f(n)\)的取值范围最多\(9^2 * 18\) 直接枚举判断就好 代码 #include <bits/stdc++.h> #define fi first #define s ...
- 【LOJ】#2550. 「JSOI2018」机器人
题解 我不会打表找规律啊QAQ 规律就是 对于\(n = m\)我们每一条左下到右上的对角线上的点的走法都是一样的且每n步一个轮重复 对于\(n != m\)我们找到最大公约数\(d\),在每个\(d ...
- maven打包时包含本地jar
项目中需要使用maven的打包工具,生成zip压缩包,使用的插件是assembly-plugin.因为一些特殊的原因,需要使用一些本地的jar进行依赖,加载外部jar后编码过程中没有任何问题,但是打包 ...
- 使用HttpServlet简单实例
使用HttpServlet简单实例 package com.kettas.servlet ; import javax.servlet.* ; import javax.servlet.http.* ...
- 每日踩坑 2018-01-09 WebAPI会如何面对URL中的空串string参数?
这个问题是我的同事问我的,可能有点 low 哈. 同事审查我的代码,表示应该对 URL 中的 string 参数进行一个空验证. 我倾向于认为,会无法匹配到路由方法. 然后我就写了一个Test, [H ...
- QT学习笔记9:QTableWidget的用法总结
最近用QT中表格用的比较多,使用的是QTableWidget这个控件,总结一下QTableWidget的一些相关函数. 1.将表格变为禁止编辑: tableWidget->setEditTrig ...
- BZOJ.4072.[SDOI2016]征途(DP 斜率优化)
题目链接 题目要求使得下面这个式子最小(\(\mu=\frac{\sum_{i=1}^ma_i}{m}\)是平均数,\(a_i\)为第\(i\)段的和): \[\frac{\sum_{i-1}^m(\ ...
- 在mysql中使用group by和order by取每个分组中日期最大一行数据
转载自:https://blog.csdn.net/shiyong1949/article/details/78482737 在mysql中使用group by进行分组后取某一列的最大值,我们可以直接 ...