Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1777324
  • 博文数量: 272
  • 博客积分: 1272
  • 博客等级: 少尉
  • 技术积分: 1866
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-09 15:51
文章分类

全部博文(272)

文章存档

2016年(16)

2015年(28)

2014年(97)

2013年(59)

2012年(25)

2011年(47)

分类: LINUX

2015-11-04 23:47:13

帧接收和发送
/net/core/dev.c

协议处理机(Protocol Handler)
在网络的每一层,都有一个协议处理机来负责该层的通信。

sk_buff结构
协议类别: sk_buff->protocol
协议头 (ETH, IP, ARP,ICMP,TCP,UDP…..)
入口设备
出口设备
数据

netif_receive_skb函数根据sk_buff中指定的协议做出相应处理。



内核中,每种协议都由一个packet_type数据结构来描述。

packet_type结构

点击(此处)折叠或打开

  1. struct packet_type {
  2.         unsigned short type; //协议类型:ETH_P_IP, ETH_P_ARP……
  3.         struct net_device *dev;
  4.         int (*func) (struct sk_buff *, struct net_device *, struct packet_type *); //回调函数指针,协议处理机(protocol handler) 
  5.         void *af_packet_priv;
  6.         struct list_head *list;
  7. };
注册协议处理机
主要调用dev_add_packet函数来实现。本例示范如何注册IP协议处理机ip_rcv.

  1. static struct packet_type ip_packet_type =
  2. {
  3.             .type = _ _constant_htons(ETH_P_IP),
  4.             .func = ip_rcv,
  5. }

  6. int ip_rcv(struct sk_buff *buf, struct net_device *nd, struct packet_type *pt)
  7. {
  8. }

  9.  void _ _init ip_init(void)
  10.  {
  11.                dev_add_pack(&ip_packet_type);
  12.               ...
  13.  }
协议定义
  1. ETH_P_IP 0x0800 ip_rcv
  2. ETH_P_X25 0x0805 X25_lap_receive_frame
  3. ETH_P_ARP 0x0806 arp_rcv
  4. ETH_P_BPQ 0x08FF bpq_rcv
  5. ETH_P_DNA_RT 0x6003 dn_route_rcv
  6. ETH_P_RARP 0x8035 ic_rarp_recv
  7. ETH_P_8021Q 0x8100 vlan_skb_rcv
  8. ETH_P_IPX 0x8137 ipx_rcv
  9. ETH_P_IPV6 0x86DD ipv6_rcv
  10. ETH_P_PPP_DISC
  11. ETH_P_PPP_SES 0x8863 
  12. 0x8864 pppoe_disc_rcvpppoe_rcv
网络路由表及过滤器(Iptables/Netfilter)
Netfilter: 在协议栈不同点的一系列钩子
Iptables: 用户空间控制工具,可以添加/删除/修改Netfilter钩子和规则


Netfilter钩子
本例示范如何在ip_rcv函数中注册钩子ip_rcv_finish。

  1. #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
  2.         NF_HOOK_THRESH(pf,hook, skb, indev, outdev, okfn, INT_MIN)

  3. #define NF_HOOK_THRESH(pf, hook, &(skb), indev, outdev, okfn, thresh)
  4.         ({int __ret;
  5.         if ((__ret = nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, INT_MIN,
  6.                       cond))==1),
  7.             __ret = okfn(skb);
  8.             __ret;})
  9. static inline nf_hook_thresh(int pf, unsigned int hook, struct sk_buff **pskb,
  10.                 struct net_device *indev,
  11.                 struct net_device *outdev,
  12.                 int (*okfn)(struct sk_buff *),
  13.                                                 int thresh,
  14.                 int cond)
  15. {
  16.                 nf_hook_slow(....);
  17. }

  18. ip_rcv_finish(...)
  19. {
  20. }

  21. ip_rcv()
  22. {
  23.     …
  24.     NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish)
  25.     …
  26. }

下面是具体处理流程:



链路层处理
桥接
桥接处理过程如下:

Ebtables
Ebtables: 可以在桥接内核模块不同点上注册一系列钩子。原型如下:
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish)
阅读(2598) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~