相关术语 octet:网络设备和协议所能理解的最小单位,一组8个的数据位。
网络接口是第三类标准Linux设备。
系统中网络接口的角色和一个已挂载的块设备类似。网络设备必须使用特定的内核数据结构注册自身,以备与外界进行数据包交换时调用。
块设备和网络设备最重要的不同在于:块设备只响应来自内核的请求,而网络驱动程序异步地接收来自外部世界的数据包。
Linux内核中的网络子系统被设计成完全与协议无关。
网络驱动程序通常不必关心高层协议头,但是他们必须负责创建硬件层协议头。
每个接口有一个net_device结构描述,其定义在中。
1.分配net_device结构
- /**
- * alloc_netdev_mqs - allocate network device
- * @sizeof_priv: size of private data to allocate space for
- * @name: device name format string
- * @setup: callback to initialize device
- * @txqs: the number of TX subqueues to allocate
- * @rxqs: the number of RX subqueues to allocate
- *
- * Allocates a struct net_device with private data area for driver use
- * and performs basic initialization. Also allocates subquue structs
- * for each queue on the device.
- */
- struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
- void (*setup)(struct net_device *),
- unsigned int txqs, unsigned int rxqs)
2.注册net_device结构
- /**
-
* register_netdev - register a network device
-
* @dev: device to register
-
*
-
* Take a completed network device structure and add it to the kernel
-
* interfaces. A %NETDEV_REGISTER message is sent to the netdev notifier
-
* chain. 0 is returned on success. A negative errno code is returned
-
* on a failure to set up the device, or if the name is a duplicate.
-
*
-
* This is a wrapper around register_netdevice that takes the rtnl semaphore
-
* and expands the device name if you passed a format string to
-
* alloc_netdev.
-
*/
-
int register_netdev(struct net_device *dev)
需要注意的是:当调用register_netdev函数后,就可以调用驱动程序操作设备了。因此,必须在初始化一切事情后在注册。内核在ether_setup函数里为net_device结构设置了很多默认值。函数代码如下:
- /**
-
* 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);
-
-
}
这里还需要对net_device结构的一个成员---priv作进一步解释。该成员作用与字符设备驱动程序中的private_data指针的作用类似。但是privz指针是和net_device结构一起分配的,处于性能和灵活性方面的考虑,不鼓励直接访问priv成员。应当使用netdev_priv函数。比如:
- struct snull_priv *priv = netdev_priv(dev);
3.注销与释放net_device结构体
- void unregister_netdev(struct net_device *dev); //注销net_device结构体
-
void free_netdev(struct net_device *dev); //释放net_device结构体
阅读(1387) | 评论(0) | 转发(0) |