linux网络设备结构中最重要的两个数据结构struct sk_buff和struct net_device。
对于这两个结构体,要了解他们的作用是什么,以及内核何时以何种方式操作他们。
sk_buff位于网络协议接口层,用于在linux网络子系统各层次之间传递数据。定义在include/linux/skbuff.h中。
当发送数据包时,将要发送的数据存入 sk_buff中,传递给下层,通过添加相应的协议头交给网络设备发送。
当接收数据包时,想将数据保存在sk_buff中,并传递到上层,上层通过剥去协议头直至交给用户。
部分源代码:
- struct sk_buff {
- /* These two members must be first. */
- struct sk_buff *next;
- struct sk_buff *prev;
- struct net_device *dev; //处理该数据包的设备
- unsigned int len, //有效数据长度
- data_len;
- __u16 mac_len,
- hdr_len;
- sk_buff_data_t transport_header;
- sk_buff_data_t network_header;
- sk_buff_data_t mac_header;
- /* These elements must be at the end, see alloc_skb() for details. */
- sk_buff_data_t tail; //有效数据结束
- sk_buff_data_t end;
- unsigned char *head, //分配空间的开始
- *data; //有效数据开始
- unsigned int truesize;
- atomic_t users;
- }
内核对sk_buff的操作有分配、释放、变更等。
(1)分配
内核分配套接字缓冲区的函数
struct sk_buff *alloc_skb(unsigned int len,gfp_t priority);
分配一个套接字缓冲区和一个数据缓冲区,并初始化data、tail、head成员。由内核协议栈分配。
struct sk_buff *dev_alloc_skb(unsigned int len);
以GFP_ATOMIC优先级调用alloc_skb()分配。由驱动程序中收到数据分配使用。
(2)释放
void kfree_skb(struct sk_buff *skb);
内核协议栈调用。
void dev_kfree_skb(struct sk_buff *skb);
驱动程序中释放缓冲区。用于非中断缓冲区。
dev_kfree_skb_irq()用于中断上下文。
(3)变更
unsigned char *skb_put(struct sk_buff *skb,unsigned int len);
skb-->tail后移len字节。
unsigned char *skb_push(struct sk_buff *skb,unsigned int len);
skb-->data前移len字节。
net_device结构体位于网络设备接口层,用于描述一个设备。定义与include/linux/netdevice.h
内部成员包含了网络设备的属性描述和接口操作。
部分源代码:
- struct net_device {
- /*
- * This is the first field of the "visible" part of this structure
- * (i.e. as seen by users in the "Space.c" file). It is the name
- * of the interface.
- */
- char name[IFNAMSIZ];
- ...
- unsigned long mem_end; /* shared mem end */
- unsigned long mem_start; /* shared mem start */
- unsigned long base_addr; /* device I/O address */
- unsigned int irq; /* device IRQ number */
- ...
包括了对设备的操作函数打开、关闭等,具体函数实现在设备驱动程序中。
阅读(3940) | 评论(0) | 转发(7) |