打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Linux内核对三层协议的管理

本文主要讲解了Linux内核对三层协议的管理,使用的内核的版本是2.6.32.27

为了方便理解,本文采用整体流程图加伪代码的方式从内核高层面上梳理了Linux内核对三层协议的管理,希望可以对大家有所帮助。阅读本文章假设大家对C语言有了一定的了解


三层管理的整体结构图



伪代码和实例

  1. /*协议类型标识符*/  
  2. #define ETH_P_LOOP  0x0060      /* Ethernet Loopback packet */   
  3. #define ETH_P_PUP   0x0200      /* Xerox PUP packet     */   
  4. #define ETH_P_PUPAT 0x0201      /* Xerox PUP Addr Trans packet  */   
  5. #define ETH_P_IP    0x0800      /* Internet Protocol packet */   
  6. #define ETH_P_X25   0x0805      /* CCITT X.25           */   
  7. #define ETH_P_ARP   0x0806      /* Address Resolution packet    */   
  8.   
  9.   
  10. /*每个协议处理都会注册一套这样的结构*/  
  11. struct packet_type {  
  12.     __be16          type;   /* 标明协议的类型 ,当配置为ETH_P_ALL的时候,会放入ptype_all接受所有协议的报文,否则具体的协议会放入ptype_base中*/  
  13.     struct net_device   *dev;   /* NULL 就是收集所有设备的该协议包 ,否则收集指定网络设备的 */  
  14.     int         (*func) (struct sk_buff *,  
  15.                      struct net_device *,  
  16.                      struct packet_type *,  
  17.                      struct net_device *);  /*协议工作的起始点*/  
  18.     void            *af_packet_priv; /*私有数据内容*/  
  19.     struct list_head    list;  
  20. };  
  21.   
  22.   
  23. static struct packet_type ip_packet_type __read_mostly = {  
  24.     .type = cpu_to_be16(ETH_P_IP),  
  25.     .func = ip_rcv,  
  26.     .gso_send_check = inet_gso_send_check,  
  27.     .gso_segment = inet_gso_segment,  
  28.     .gro_receive = inet_gro_receive,  
  29.     .gro_complete = inet_gro_complete,  
  30. };  
  31. static int __init inet_init(void)  
  32. {  
  33.     dev_add_pack(&ip_packet_type); /*使用dev_add_pack将协议结构注册到系统中*/  
  34. }  
  35.   
  36. void dev_add_pack(struct packet_type *pt)  
  37. {  
  38.     /*ETH_P_ALL的放入ptype_all中,其他具体类型的放入ptype_base哈希桶中*/  
  39.     if (pt->type == htons(ETH_P_ALL))  
  40.         list_add_rcu(&pt->list, &ptype_all);  
  41.     else {  
  42.         hash = ntohs(pt->type) & PTYPE_HASH_MASK;  
  43.         list_add_rcu(&pt->list, &ptype_base[hash]);  
  44.     }  
  45.       
  46. }  
  47.   
  48.   
  49. static void ipv6_packet_cleanup(void)  
  50. {  
  51.     dev_remove_pack(&ipv6_packet_type); /*使用dev_remove_pack从协议中注销相应的协议*/  
  52. }  
  53.   
  54. void dev_remove_pack(struct packet_type *pt)  
  55. {  
  56.     /*删除指定的协议处理类型*/  
  57.     __dev_remove_pack(pt);  
  58.     {  
  59.         /*找到所属管理组*/  
  60.         if (pt->type == htons(ETH_P_ALL))  
  61.             head = &ptype_all;  
  62.         else  
  63.             head = &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK];  
  64.       
  65.         /*删除对应的协议类型*/  
  66.         list_for_each_entry(pt1, head, list) {  
  67.             if (pt == pt1) {  
  68.                 list_del_rcu(&pt->list);  
  69.                 goto out;  
  70.             }  
  71.         }  
  72.     }  
  73. }  

通过上面的讲解,可以看出LInux对所有的协议都是基于组件性质进行灵活配置,大大提高了系统的可扩展性。其关键在于成功的提取了struct packet_type的抽象,所有我们在设计系统的时候,是不是可以对各个模块有个良好统一的接口抽象,决定了我们的系统是否可以在未来更长的时间里良好的进行特性的扩展

希望大家批评指正



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
ptype_base和ptype_all理解,netid_receive_skb()函数注解
一个险恶bug的深入分析
rcu学习心得
为何不将仅仅路过的数据包导入本地协议栈呢
TCP/IP协议栈初始化流程
Android socket创建、绑定流程分析(二)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服