本文主要讲解了Linux内核对三层协议的管理,使用的内核的版本是2.6.32.27
为了方便理解,本文采用整体流程图加伪代码的方式从内核高层面上梳理了Linux内核对三层协议的管理,希望可以对大家有所帮助。阅读本文章假设大家对C语言有了一定的了解
三层管理的整体结构图
伪代码和实例
/*协议类型标识符*/
#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
#define ETH_P_X25 0x0805 /* CCITT X.25 */
#define ETH_P_ARP 0x0806 /* Address Resolution packet */
/*每个协议处理都会注册一套这样的结构*/
struct packet_type {
__be16 type; /* 标明协议的类型 ,当配置为ETH_P_ALL的时候,会放入ptype_all接受所有协议的报文,否则具体的协议会放入ptype_base中*/
struct net_device *dev; /* NULL 就是收集所有设备的该协议包 ,否则收集指定网络设备的 */
int (*func) (struct sk_buff *,
struct net_device *,
struct packet_type *,
struct net_device *); /*协议工作的起始点*/
void *af_packet_priv; /*私有数据内容*/
struct list_head list;
};
static struct packet_type ip_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_IP),
.func = ip_rcv,
.gso_send_check = inet_gso_send_check,
.gso_segment = inet_gso_segment,
.gro_receive = inet_gro_receive,
.gro_complete = inet_gro_complete,
};
static int __init inet_init(void)
{
dev_add_pack(&ip_packet_type); /*使用dev_add_pack将协议结构注册到系统中*/
}
void dev_add_pack(struct packet_type *pt)
{
/*ETH_P_ALL的放入ptype_all中,其他具体类型的放入ptype_base哈希桶中*/
if (pt->type == htons(ETH_P_ALL))
list_add_rcu(&pt->list, &ptype_all);
else {
hash = ntohs(pt->type) & PTYPE_HASH_MASK;
list_add_rcu(&pt->list, &ptype_base[hash]);
}
}
static void ipv6_packet_cleanup(void)
{
dev_remove_pack(&ipv6_packet_type); /*使用dev_remove_pack从协议中注销相应的协议*/
}
void dev_remove_pack(struct packet_type *pt)
{
/*删除指定的协议处理类型*/
__dev_remove_pack(pt);
{
/*找到所属管理组*/
if (pt->type == htons(ETH_P_ALL))
head = &ptype_all;
else
head = &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK];
/*删除对应的协议类型*/
list_for_each_entry(pt1, head, list) {
if (pt == pt1) {
list_del_rcu(&pt->list);
goto out;
}
}
}
}
通过上面的讲解,可以看出LInux对所有的协议都是基于组件性质进行灵活配置,大大提高了系统的可扩展性。其关键在于成功的提取了struct packet_type的抽象,所有我们在设计系统的时候,是不是可以对各个模块有个良好统一的接口抽象,决定了我们的系统是否可以在未来更长的时间里良好的进行特性的扩展
希望大家批评指正