网络处理过程
轮询和中断
设备和内核之间主要用两种技术来交换数据:轮询和中断。
轮询: 内核不停地检测设备是不是有数据接收到。
中断: 当有事件发生时,设备驱动程序指示设备产生中断
帧接收和发送
/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_rcvETH_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)