LINUX协议栈详解 协议处理

协议处理,主要介绍了从驱动中获取数据后,如何进行分发给不同的协议处理,包括IP协议、ARP协议等处理。

__netif_receive_skb协议处理的开始,主要的数据结构是ptype_all和ptype_base,其中ptype_all是一个链表结构,ptype_base则是一个数组,并通过hash来type来实现索引。

  1. list_for_each_entry_rcu(ptype, &ptype_all, list) {  
  2.         if (!ptype->dev || ptype->dev == skb->dev) {  
  3.             if (pt_prev)  
  4.                 ret = deliver_skb(skb, pt_prev, orig_dev);  
  5.             pt_prev = ptype;  
  6.         }  
  7.     }  
其中ptype_all通常用于例如抓包之类的数据处理,也就是不管什么数据包都会被接收。


  1. type = skb->protocol;  
  2.     list_for_each_entry_rcu(ptype,  
  3.             &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {  
  4.         if (ptype->type == type &&  
  5.             (ptype->dev == null_or_dev || ptype->dev == skb->dev ||  
  6.              ptype->dev == orig_dev)) {  
  7.             if (pt_prev)  
  8.                 ret = deliver_skb(skb, pt_prev, orig_dev);  
  9.             pt_prev = ptype;  
  10.         }  
  11.     }  
ptype_base则是通过具体的type来索引处理函数。

现在有几个问题,

1,什么时候注册的?

注册是通过dev_add_pack来实现的,

IP协议 

  1. static struct packet_type ip_packet_type __read_mostly = {  
  2.     .type = cpu_to_be16(ETH_P_IP),  
  3.     .func = ip_rcv,  
  4.     .gso_send_check = inet_gso_send_check,  
  5.     .gso_segment = inet_gso_segment,  
  6.     .gro_receive = inet_gro_receive,  
  7.     .gro_complete = inet_gro_complete,  
  8. };  

在inet_init调用dev_add_pack来注册。

ARP协议

  1. static struct packet_type arp_packet_type __read_mostly = {  
  2.     .type = cpu_to_be16(ETH_P_ARP),  
  3.     .func = arp_rcv,  
  4. };  

所有处理的协议号

  1. /* 
  2.  *  These are the defined Ethernet Protocol ID's. 
  3.  */  
  4.   
  5. #define ETH_P_LOOP  0x0060      /* Ethernet Loopback packet */  
  6. #define ETH_P_PUP   0x0200      /* Xerox PUP packet     */  
  7. #define ETH_P_PUPAT 0x0201      /* Xerox PUP Addr Trans packet  */  
  8. #define ETH_P_IP    0x0800      /* Internet Protocol packet */  
  9. #define ETH_P_X25   0x0805      /* CCITT X.25           */  
  10. #define ETH_P_ARP   0x0806      /* Address Resolution packet    */  
  11. #define ETH_P_BPQ   0x08FF      /* G8BPQ AX.25 Ethernet Packet  [ NOT AN OFFICIALLY REGISTERED ID ] */  
  12. #define ETH_P_IEEEPUP   0x0a00      /* Xerox IEEE802.3 PUP packet */  
  13. #define ETH_P_IEEEPUPAT 0x0a01      /* Xerox IEEE802.3 PUP Addr Trans packet */  
  14. #define ETH_P_DEC       0x6000          /* DEC Assigned proto           */  
  15. #define ETH_P_DNA_DL    0x6001          /* DEC DNA Dump/Load            */  
  16. #define ETH_P_DNA_RC    0x6002          /* DEC DNA Remote Console       */  
  17. #define ETH_P_DNA_RT    0x6003          /* DEC DNA Routing              */  
  18. #define ETH_P_LAT       0x6004          /* DEC LAT                      */  
  19. #define ETH_P_DIAG      0x6005          /* DEC Diagnostics              */  
  20. #define ETH_P_CUST      0x6006          /* DEC Customer use             */  
  21. #define ETH_P_SCA       0x6007          /* DEC Systems Comms Arch       */  
  22. #define ETH_P_TEB   0x6558      /* Trans Ether Bridging     */  
  23. #define ETH_P_RARP      0x8035      /* Reverse Addr Res packet  */  
  24. #define ETH_P_ATALK 0x809B      /* Appletalk DDP        */  
  25. #define ETH_P_AARP  0x80F3      /* Appletalk AARP       */  
  26. #define ETH_P_8021Q 0x8100          /* 802.1Q VLAN Extended Header  */  
  27. #define ETH_P_IPX   0x8137      /* IPX over DIX         */  
  28. #define ETH_P_IPV6  0x86DD      /* IPv6 over bluebook       */  
  29. #define ETH_P_PAUSE 0x8808      /* IEEE Pause frames. See 802.3 31B */  
  30. #define ETH_P_SLOW  0x8809      /* Slow Protocol. See 802.3ad 43B */  
  31. #define ETH_P_WCCP  0x883E      /* Web-cache coordination protocol  
  32.                      * defined in draft-wilson-wrec-wccp-v2-00.txt */  
  33. #define ETH_P_PPP_DISC  0x8863      /* PPPoE discovery messages     */  
  34. #define ETH_P_PPP_SES   0x8864      /* PPPoE session messages   */  
  35. #define ETH_P_MPLS_UC   0x8847      /* MPLS Unicast traffic     */  
  36. #define ETH_P_MPLS_MC   0x8848      /* MPLS Multicast traffic   */  
  37. #define ETH_P_ATMMPOA   0x884c      /* MultiProtocol Over ATM   */  
  38. #define ETH_P_LINK_CTL  0x886c      /* HPNA, wlan link local tunnel */  
  39. #define ETH_P_ATMFATE   0x8884      /* Frame-based ATM Transport  
  40.                      * over Ethernet  
  41.                      */  
  42. #define ETH_P_PAE   0x888E      /* Port Access Entity (IEEE 802.1X) */  
  43. #define ETH_P_AOE   0x88A2      /* ATA over Ethernet        */  
  44. #define ETH_P_TIPC  0x88CA      /* TIPC             */  
  45. #define ETH_P_1588  0x88F7      /* IEEE 1588 Timesync */  
  46. #define ETH_P_FCOE  0x8906      /* Fibre Channel over Ethernet  */  
  47. #define ETH_P_FIP   0x8914      /* FCoE Initialization Protocol */  
  48. #define ETH_P_EDSA  0xDADA      /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */  
  49.   
  50. /* 
  51.  *  Non DIX types. Won't clash for 1500 types. 
  52.  */  
  53.   
  54. #define ETH_P_802_3 0x0001      /* Dummy type for 802.3 frames  */  
  55. #define ETH_P_AX25  0x0002      /* Dummy protocol id for AX.25  */  
  56. #define ETH_P_ALL   0x0003      /* Every packet (be careful!!!) */  
  57. #define ETH_P_802_2 0x0004      /* 802.2 frames         */  
  58. #define ETH_P_SNAP  0x0005      /* Internal only        */  
  59. #define ETH_P_DDCMP     0x0006          /* DEC DDCMP: Internal only     */  
  60. #define ETH_P_WAN_PPP   0x0007          /* Dummy type for WAN PPP frames*/  
  61. #define ETH_P_PPP_MP    0x0008          /* Dummy type for PPP MP frames */  
  62. #define ETH_P_LOCALTALK 0x0009      /* Localtalk pseudo type    */  
  63. #define ETH_P_CAN   0x000C      /* Controller Area Network      */  
  64. #define ETH_P_PPPTALK   0x0010      /* Dummy type for Atalk over PPP*/  
  65. #define ETH_P_TR_802_2  0x0011      /* 802.2 frames         */  
  66. #define ETH_P_MOBITEX   0x0015      /* Mobitex (kaz@cafe.net)   */  
  67. #define ETH_P_CONTROL   0x0016      /* Card specific control frames */  
  68. #define ETH_P_IRDA  0x0017      /* Linux-IrDA           */  
  69. #define ETH_P_ECONET    0x0018      /* Acorn Econet         */  
  70. #define ETH_P_HDLC  0x0019      /* HDLC frames          */  
  71. #define ETH_P_ARCNET    0x001A      /* 1A for ArcNet :-)            */  
  72. #define ETH_P_DSA   0x001B      /* Distributed Switch Arch. */  
  73. #define ETH_P_TRAILER   0x001C      /* Trailer switch tagging   */  
  74. #define ETH_P_PHONET    0x00F5      /* Nokia Phonet frames          */  
  75. #define ETH_P_IEEE802154 0x00F6     /* IEEE802.15.4 frame       */  
  76. #define ETH_P_CAIF  0x00F7      /* ST-Ericsson CAIF protocol    */  

2,什么时候赋值skb->protocol

由驱动负责给protocol赋值,且通过eth_type_trans赋值,同时skb->pkt_type也是在这个函数中赋值的。

  1. /* Packet types */  
  2.   
  3. #define PACKET_HOST     0       /* To us        */  
  4. #define PACKET_BROADCAST    1       /* To all       */  
  5. #define PACKET_MULTICAST    2       /* To group     */  
  6. #define PACKET_OTHERHOST    3       /* To someone else  */  
  7. #define PACKET_OUTGOING     4       /* Outgoing of any type */  

到现在我们知道了协议处理过程,也就很自然的进入了具体协议等研究,例如ARP的处理,IP数据包的处理等。

后面将深入讲解IP协议、路由过程(包括策略路由)和邻居系统,整一个是同一有机体。这之前我们还会深入一些TC系统的研究,对TC的研究有助于巩固对数据包发送过程的理解;还有一个重要的是网桥的研究,网桥其实作为单独一章来讲解,并不会非常的深入,只是大体讲解网桥的过程,曾经参与过项目,将网桥和VLAN是合在一起的,具体可以参考LISA(http://lisa.mindbit.ro/)。

没有评论: