一个在线看Linux源码的网站http://lxr.free-electrons.com,需要翻墙
第二章 关键数据结构
本章讲述以下两个重要数据结构:
struct sk_buff:存储所有网络分层的包头、有效载荷,其他内部信息
struct net_device:网络设备的通用数据结构
sk_buff
布局:
书上sk_buff 写到的对分层头的设计是以union形式来表示,这是Linux 2.6.24之前的方式
/* Transport layer header */
union
{
struct tcphdr *th;
struct udphdr *uh;
struct icmphdr *icmph;
struct igmphdr *igmph;
struct iphdr *ipiph;
struct spxhdr *spxh;
unsigned char *raw;
} h;
/* Network layer header */
union
{
struct iphdr *iph;
struct ipv6hdr *ipv6h;
struct arphdr *arph;
struct ipxhdr *ipxh;
unsigned char *raw;
} nh;
/* Link layer header */
union
{
struct ethhdr *ethernet;
unsigned char *raw;
} mac;
Linux 2.6.24后,这个分层的指针精简为了
#ifdef NET_SKBUFF_DATA_USES_OFFSET
typedef unsigned int sk_buff_data_t;
#else
typedef unsigned char *sk_buff_data_t;
#endif
......
sk_buff_data_t transport_header;
sk_buff_data_t network_header;
sk_buff_data_t mac_header;
L2到L3时报头指针变化:
管理函数:有很多名称类似do_something和__do_somthing,第一个是包裹函数,增加额外检查或者上锁,内部的__do_something通常不会直接调用。
报文经过每一层缓冲区处理的关键函数:
skb_reserve, skb_put, skb_push, skb_pull
主要是更新:skb->data, skb->len
skb_clone只是克隆了skb_buff的结构,指向相同的缓存,缓存保存了引用计数。
skb_copy是完全拷贝缓存。
sk_buff的队列管理要注意上spin_lock锁以保证原子操作。
net_device
包括真实设备和虚拟设备(VLAN或聚合口)
全局变量dev_base列表存储了所有设备的net_device,
每个net_device有唯一的ID。
混杂模式promiscuous mode:设备接收所有封包。
设备的统计数据存在于设备的驱动内,net_device结构只保存一个priv指针指向该数据结构,有线和无线设备关键字段有区别。
来源:oschina
链接:https://my.oschina.net/u/1862101/blog/288498