Linux网络路由表处理及钩子(Iptables and Ebtables)

网络处理过程



轮询和中断

设备和内核之间主要用两种技术来交换数据:
轮询和中断。
轮询: 内核不停地检测设备是不是有数据接收到。
中断: 当有事件发生时,设备驱动程序指示设备产生中断

帧接收和发送

/net/core/dev.c




协议处理机(Protocol Handler)

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

sk_buff结构

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

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



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



packet_type结构

struct packet_type { 
                unsigned short type;    //协议类型:ETH_P_IP, ETH_P_ARP……
                 struct net_device *dev; 
                 int (*func) (struct sk_buff *, struct net_device *, struct packet_type *);    //回调函数指针,协议处理机 (protocol handler)
                 void *af_packet_priv; 
                 struct list_head *list; 
}; 

注册协议处理机

主要调用dev_add_packet函数来实现。本例示范如何注册IP协议处理机ip_rcv.

static struct packet_type ip_packet_type = 

            .type = _ _constant_htons(ETH_P_IP), 
            .func = ip_rcv, 


int ip_rcv(struct sk_buff *buf, struct net_device *nd, struct packet_type *pt)
{
}

 void _ _init ip_init(void) 
 { 
               dev_add_pack(&ip_packet_type); 
              ... 
 } 

协议定义

ETH_P_IP                 0x0800     ip_rcv 
ETH_P_X25              0x0805     X25_lap_receive_frame
ETH_P_ARP             0x0806     arp_rcv
ETH_P_BPQ             0x08FF     bpq_rcv
ETH_P_DNA_RT      0x6003     dn_route_rcv
ETH_P_RARP           0x8035     ic_rarp_recv 
ETH_P_8021Q          0x8100      vlan_skb_rcv
ETH_P_IPX              0x8137       ipx_rcv
ETH_P_IPV6            0x86DD      ipv6_rcv
ETH_P_PPP_DISC 
ETH_P_PPP_SES     0x8863 
                                   0x8864     pppoe_disc_rcvpppoe_rcv

网络路由表及过滤器(Iptables/Netfilter)

Netfilter: 在协议栈不同点的一系列钩子
Iptables: 用户空间控制工具,可以添加/删除/修改Netfilter钩子和规则


内核模块可以在以上任何一点(1~5)注册钩子来监听数据包。
表类型是*filter *nat *mangle。
可以注册以下动作:



Netfilter钩子

本例示范如何在ip_rcv函数中注册钩子ip_rcv_finish。
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
        NF_HOOK_THRESH(pf,hook, skb, indev, outdev, okfn, INT_MIN)

#define NF_HOOK_THRESH(pf, hook, &(skb), indev, outdev, okfn, thresh)
        ({int __ret;
        if ((__ret = nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, INT_MIN,     
                      cond))==1),
            __ret = okfn(skb);
            __ret;})
static inline nf_hook_thresh(int pf, unsigned int hook, struct sk_buff **pskb, 
                struct net_device *indev,
                struct net_device *outdev,
                int (*okfn)(struct sk_buff *),   
                                                int thresh,
                int cond)
{
                nf_hook_slow(....);
}

ip_rcv_finish(...)
{
}

ip_rcv(…)
{
    …
    NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish)   
    …
}

下面是具体处理流程:




链路层处理

桥接

桥接处理过程如下:


Ebtables

Ebtables: 可以在桥接内核模块不同点上注册一系列钩子。原型如下:
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值