本文主要講解了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的抽象,所有我們在設計系統的時候,是不是可以對各個模塊有個良好統一的接口抽象,決定了我們的系統是否可以在未來更長的時間裏良好的進行特性的擴展
希望大家批評指正