linux内核数据包转发流程(一):网络设备驱动
【版权声明:转载请保留出处:blog.csdn.net/gentleliu。邮箱:shallnew*163.com】
网卡驱动为每一个新的接口在一个全局的网络设备列表里插入一个数据结构.每一个接口由一个结构 net_device 项来描写叙述, 它在 <linux/netdevice.h> 里定义。该结构必须动态分配。
进行这样的分配的内核函数是 alloc_netdev, 它有下列原型:
struct net_device *alloc_netdev(int sizeof_priv, const char *name, void (*setup)(struct net_device *));
sizeof_priv 是驱动的的"私有数据"区的大小;name 是这个接口的名子;这个名子能够有一个 printf 风格的 %d 在里面. 内核用下一个可用的接口号来替换这个 %d。setup 是一个初始化函数的指针, 被调用来设置 net_device 结构的剩余部分。
网络子系统为各种接口提供了一些帮助函数, 包裹着 alloc_netdev。最通用的是 alloc_etherdev, 定义在 <linux/etherdevice.h>,还有其它网络设备接口,如alloc_fcdev ( 定义在 <linux/fcdevice.h> ) 为 fiber-channel 设备, alloc_fddidev (<linux/fddidevice.h>) 为 FDDI 设备, 或者 aloc_trdev (<linux/trdevice.h>) 为令牌环设备。
alloc_etherdev函数原型为:
struct net_device *alloc_etherdev(int sizeof_priv);
当中sizeof_priv 是驱动的的"私有数据"区的大小;这个函数分配一个网络设备使用 eth%d 作为參数 name. 它提供了自己的初始化函数 ( ether_setup )来设置几个 net_device 字段, 使用对以太网设备合适的值。 因此, 没有驱动提供的初始化函数给 alloc_etherdev;
他自己提供的初始化函数ether_setup为:
/**
* ether_setup - setup Ethernet network device
* @dev: network device
* Fill in the fields of the device structure with Ethernet-generic values.
*/
void ether_setup(struct net_device *dev)
{
dev->header_ops = ð_header_ops;
dev->type = ARPHRD_ETHER;
dev->hard_header_len = ETH_HLEN;
dev->mtu = ETH_DATA_LEN;
dev->addr_len = ETH_ALEN;
dev->tx_queue_len = 1000; /* Ethernet wants good queues */
dev->flags = IFF_BROADCAST|IFF_MULTICAST; memset(dev->broadcast, 0xFF, ETH_ALEN); }
EXPORT_SYMBOL(ether_setup);
实际上该函数也是不过负责了一些以太网范围中的缺省值而已。一般alloc_netdev函数提供的setup函数也会调用该函数来设置这些缺省值。
事实上无论使用alloc_netdev函数还是alloc_etherdev函数都不只设置这些缺省值就够了。
既然是编写网络设备驱动,就要完毕网卡的基本功能:收发数据包,统计网卡数据等,所以一般还要设置该结构体里面的这些功能函数指针,而这些函数正是网络设备驱动须要实现的基本功能。所以假设使用函数alloc_netdev分配空间,那么setup函数一般实现为:
{
ether_setup(dev); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
dev->netdev_ops = &xxx_netdev_ops;
#else
dev->open = xxx_open;
dev->stop = xxx_stop;
dev->hard_start_xmit = xxx_tx;
dev->get_stats = xxx_stats;
// dev->change_mtu = xxx_change_mtu;
...
#endif
}
假设使用alloc_etherdev函数分配,那么在该函数之后还须要作例如以下设置:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
dev->netdev_ops = &xxx_netdev_ops;
#else
dev->open = xxx_open;
dev->stop = xxx_stop;
dev->hard_start_xmit = xxx_tx;
dev->get_stats = xxx_stats;
// dev->change_mtu = xxx_change_mtu;
...
#endif
事实上二者的区别就是alloc_etherdev函数默认自己主动调用ether_setup函数而且自己主动分配一个网络设备使用 eth%d 作为參数 name,而函数alloc_netdev须要自己传入參数来设置这些项而已。
net_device 结构初始化之后, 传递这个结构给 register_netdev函数完毕注冊。
然后你必需要做的就是实现之前注冊的那些函数,收发函数的具体分析会在后面具体解说。
linux内核数据包转发流程(一):网络设备驱动的更多相关文章
- linux内核数据包转发流程(三)网卡帧接收分析
[版权声明:转载请保留出处:blog.csdn.net/gentleliu.邮箱:shallnew*163.com] 每一个cpu都有队列来处理接收到的帧,都有其数据结构来处理入口和出口流量,因此,不 ...
- linux内核数据包转发流程(二):中断
[版权声明:转载请保留出处:blog.csdn.net/gentleliu.邮箱:shallnew*163.com] 内核在处理2层数据包之前,必须先处理中断系统.设立中断系统,才有可能每秒处理成千的 ...
- Linux内核数据包的发送传输
本文主要讲解了Linux内核数据包的传输流程,使用的内核的版本是2.6.32.27 为了方便理解,本文采用整体流程图加伪代码的方式从内核高层面上梳理了二层数据包发送传输的流程,希望可以对大家有所帮助. ...
- [Docker]Docker与Linux ip_forward数据包转发
背景 今天在一台新虚拟机上需要临时启动一个consul服务,安装Docker后使用docker启动,但是在执行启动命令后发现docker有一个警告: WARNING: IPv4 forwarding ...
- Linux内核二层数据包接收流程
本文主要讲解了Linux内核二层数据包接收流程,使用的内核的版本是2.6.32.27 为了方便理解,本文采用整体流程图加伪代码的方式从内核高层面上梳理了二层数据包接收的流程,希望可以对大家有所帮助.阅 ...
- LINUX下的远端主机登入 校园网络注册 网络数据包转发和捕获
第一部分:LINUX 下的远端主机登入和校园网注册 校园网内目的主机远程管理登入程序 本程序为校园网内远程登入,管理功能,该程序分服务器端和客户端两部分:服务器端为remote_server_udp. ...
- Linux内核网络数据包处理流程
Linux内核网络数据包处理流程 from kernel-4.9: 0. Linux内核网络数据包处理流程 - 网络硬件 网卡工作在物理层和数据链路层,主要由PHY/MAC芯片.Tx/Rx FIFO. ...
- linux 内核网络数据包接收流程
转:https://segmentfault.com/a/1190000008836467 本文将介绍在Linux系统中,数据包是如何一步一步从网卡传到进程手中的. 如果英文没有问题,强烈建议阅读后面 ...
- Linux内核网络报文简单流程
转:http://blog.csdn.net/adamska0104/article/details/45397177 Linux内核网络报文简单流程2014-08-12 10:05:09 分类: L ...
随机推荐
- 怎么区分MSSQL中nvarchar和varchar的区别?
怎么区分MSSQL中nvarchar和varchar的区别呢?下面两段代码可以帮你看到他们的区别. declare @s Nvarchar(10) set @s='那么相当于abcd可以存储多少个汉字 ...
- Jenkins+Ant+Git+Jmeter实现持续集成
个人记录: 基本的配置与Jenkins+Ant+SVN+Jmeter实现持续集成的配置一样,主要在Jenkins的配置上的区别会有所不同 安装的插件: enkins安装好之后,需要为其安装gitlab ...
- CCF CSP 201312-4 有趣的数
CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201312-4 有趣的数 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0 ...
- javascript json字符串转json对象方法
/* * @method 将拼接好字符串格式的json 转成json对象 * @param jsonData param fomart: * var jsonData = "{name1:' ...
- Deepin Linux安装MySQL方法
sudo apt-get install mysql-server apt-get install mysql-client sudo apt-get install libmysqlclient-d ...
- 使用linux mysql客户端建立表时遇到格式解析的问题
发现在notepad++写好的建表脚本,粘贴到linux客户端后,执行时总是报我的脚本有问题. 我看了又看,发现建表脚本本身是没有问题,问题出在"Tab"键上和注释上边了. 解决办 ...
- R语言实战(六)重抽样与自助法
本文对应<R语言实战>第12章:重抽样与自助法 之前学习的基本统计分析.回归分析.方差分析,是假定观测数据抽样自正态分布或者其他性质较好的理论分布,进而进行的假设检验和总体参数的置信区间估 ...
- Python并发编程-协程实现socketserver
#server.py from gevent import monkey;monkey.patch_all() import socket import gevent sk = socket.sock ...
- Android IntentService
IntentService简要分析 IntentService 继承自 android.app.Service.内部实现极其简单. 首先在 onCreate()中去开启了一个 HandlerThrea ...
- Python 递归删除非空目录(包括子目录以及文件)
Python的OS模块自带rmdir和removedirs函数用于删除目录,但是两者都不能删除非空目录,以下代码定义了一个函数 remove_dir 用于删除非空目录. #作者官网 http://ww ...