PHP
首页 | 下载 | 博客 | 链接

区域

工具

查看代码的工具推荐用Eclipse Platform,将includes文件路径设置好以后,查找原型/函数/结构相当方便,如果怕麻烦,lxr也是个不错的选择,比如lxr.linux.no


相关链接

启动中的ipvs
运行中的ipvs
ipvs的调度
ipvs的数据报转送

ipvs的hash算法
数据包结构/操作分析
[转]ipvs基本原理/框架


资源链接

netfilter官方指南(中文)
ipvs官方网站(中文)
developerWorks-cluster(中文)


说明

文章中出现的内核代码版本是linux-2.6.26,为了保证行号的一致性,中文的注释没有插入回车/换行符.可能会显得有些紧巴巴的.
由于个人能力有限,网站内容存在许多错误和不足,希望读者能踊跃给予批评指正或建议. 本人联系方式:yubo@yubo.org

数据包结构/操作分析

以下是sk_buff类型的定义

include/linux/skbuff.h

  1.  struct sk_buff {
  2.   /* These two members must be first. */
  3.   struct sk_buff *next; //下一个socket buff的指针
  4.   struct sk_buff *prev; //上一个socket buff的指针
  5.  
  6.   struct sock *sk; //自己拥有的socket连接(只有连接是和本地进程通讯时才有,如果是转发的连接,指针为NULL)
  7.   ktime_t tstamp; //到达时间
  8.   struct net_device *dev; //到达/离开时使用的网络设备
  9.  
  10.   union { //此报文的路由,路由确定后赋此值
  11.   struct dst_entry *dst;
  12.   struct rtable *rtable;
  13.   };
  14.   struct sec_path *sp;
  15.  
  16.   /*
  17.   * This is the control buffer. It is free to use for every
  18.   * layer. Please put your private variables there. If you
  19.   * want to keep them across layers you have to do a skb_clone()
  20.   * first. This is owned by whoever has the skb queued ATM.
  21.   */
  22.   char cb[48]; //用于在协议栈之间传递参数,参数内容的涵义由使用它的函数确定
  23.  
  24.   unsigned int len, //此报文的长度,这是指网络报文在不同协议层中的长度,包括头部和数据。在协议栈的不同层,这个长度是不同的
  25.   data_len; //数据长度
  26.   __u16 mac_len, //链路层头部的长度
  27.   hdr_len; //对cloned的skb能够写入的头部长度
  28.   union {
  29.   __wsum csum;
  30.   struct {
  31.   __u16 csum_start;
  32.   __u16 csum_offset;
  33.   };
  34.   };
  35.   __u32 priority;
  36.   __u8 local_df:1,
  37.   cloned:1,
  38.   ip_summed:2,
  39.   nohdr:1,
  40.   nfctinfo:3;
  41.   __u8 pkt_type:3,
  42.   fclone:2,
  43.   ipvs_property:1,
  44.   peeked:1,
  45.   nf_trace:1;
  46.   __be16 protocol;
  47.  
  48.   void (*destructor)(struct sk_buff *skb);
  49.  #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
  50.   struct nf_conntrack *nfct;
  51.   struct sk_buff *nfct_reasm;
  52.  #endif
  53.  #ifdef CONFIG_BRIDGE_NETFILTER
  54.   struct nf_bridge_info *nf_bridge;
  55.  #endif
  56.  
  57.   int iif;
  58.  #ifdef CONFIG_NETDEVICES_MULTIQUEUE
  59.   __u16 queue_mapping;
  60.  #endif
  61.  #ifdef CONFIG_NET_SCHED
  62.   __u16 tc_index; /* traffic control index */
  63.  #ifdef CONFIG_NET_CLS_ACT
  64.   __u16 tc_verd; /* traffic control verdict */
  65.  #endif
  66.  #endif
  67.  #ifdef CONFIG_IPV6_NDISC_NODETYPE
  68.   __u8 ndisc_nodetype:2;
  69.  #endif
  70.   /* 14 bit hole */
  71.  
  72.  #ifdef CONFIG_NET_DMA
  73.   dma_cookie_t dma_cookie;
  74.  #endif
  75.  #ifdef CONFIG_NETWORK_SECMARK
  76.   __u32 secmark;
  77.  #endif
  78.  
  79.   __u32 mark; //标记,在ipvs中作为fwmark(防火墙标记)使用
  80.  
  81.   sk_buff_data_t transport_header; //传输层头部指针的偏移量(如果设置了NET_SKBUFF_DATA_USES_OFFSET,则为指针)
  82.   sk_buff_data_t network_header; //网络层头部指针
  83.   sk_buff_data_t mac_header; //链路层头部指针
  84.   /* These elements must be at the end, see alloc_skb() for details. */
  85.   sk_buff_data_t tail;
  86.   sk_buff_data_t end;
  87.   unsigned char *head, //buffer的头部指针,以上的所有偏移量都是以这个指针为基础
  88.   *data; //数据起始位置
  89.   unsigned int truesize; //此报文存储区的长度,这个长度是16字节对齐的,一般要比报文的长度大。
  90.   atomic_t users; //这个socket的引用数,工作方式类似于文件系统的硬链接的引用数.比如clone了一次,连接数就+1
  91.  };

网络层头部结构iphdr

include/linux/ip.h

  1.  struct iphdr {
  2.  #if defined(__LITTLE_ENDIAN_BITFIELD)
  3.   __u8 ihl:4,
  4.   version:4;
  5.  #elif defined (__BIG_ENDIAN_BITFIELD)
  6.   __u8 version:4,
  7.   ihl:4;
  8.  #else
  9.  #error "Please fix <asm/byteorder.h>"
  10.  #endif
  11.   __u8 tos;
  12.   __be16 tot_len;
  13.   __be16 id;
  14.   __be16 frag_off;
  15.   __u8 ttl;
  16.   __u8 protocol;
  17.   __sum16 check;
  18.   __be32 saddr;
  19.   __be32 daddr;
  20.   /*The options start here. */
  21.  };

传输层头部结构tcphdr

include/linux/tcp.h

  1.  struct tcphdr {
  2.   __be16 source;
  3.   __be16 dest;
  4.   __be32 seq;
  5.   __be32 ack_seq;
  6.  #if defined(__LITTLE_ENDIAN_BITFIELD)
  7.   __u16 res1:4,
  8.   doff:4,
  9.   fin:1,
  10.   syn:1,
  11.   rst:1,
  12.   psh:1,
  13.   ack:1,
  14.   urg:1,
  15.   ece:1,
  16.   cwr:1;
  17.  #elif defined(__BIG_ENDIAN_BITFIELD)
  18.   __u16 doff:4,
  19.   res1:4,
  20.   cwr:1,
  21.   ece:1,
  22.   urg:1,
  23.   ack:1,
  24.   psh:1,
  25.   rst:1,
  26.   syn:1,
  27.   fin:1;
  28.  #else
  29.  #error "Adjust your <asm/byteorder.h> defines"
  30.  #endif
  31.   __be16 window;
  32.   __sum16 check;
  33.   __be16 urg_ptr;
  34.  };

传输层头部结构udphdr

include/linux/udp.h

  1.  struct udphdr {
  2.   __be16 source;
  3.   __be16 dest;
  4.   __be16 len;
  5.   __sum16 check;
  6.  };

icmphdr

include/linux/icmp.h

  1.  struct icmphdr {
  2.   __u8 type;
  3.   __u8 code;
  4.   __sum16 checksum;
  5.   union {
  6.   struct {
  7.   __be16 id;
  8.   __be16 sequence;
  9.   } echo;
  10.   __be32 gateway;
  11.   struct {
  12.   __be16 __unused;
  13.   __be16 mtu;
  14.   } frag;
  15.   } un;
  16.  };

链路层帧格式

前导码
8 bytes
目的mac地址
6 bytes
源mac地址
6 bytes
帧类型
2 bytes
帧数据
46~1500 bytes
crc校验
4 bytes

网络层数据包格式

4 bits 4 bits 8 bits 3 bits 13 bits
Version IHL Type of Service Total Length
Identification Flags Fragmentation Offset
Time To Live Protocol Header Checksum
Source Address
Destination Address
Options Padding
Data

传输层数据报文格式

4 bits 6 bits 6 bits 16 bits
Source Port Destination Port
Sequence Number
Acknowledge Number
Data
Offset
Reserved Code Window
Ckecksum Urgent Pointer
Options Padding
Data
 
Done in 0.110696792603 seconds