&ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
if (ptype->type == type &&
(ptype->dev == null_or_orig || ptype->dev == skb->dev ||
ptype->dev == orig_dev)) {
if (pt_prev)
ret = deliver_skb(skb, pt_prev, orig_dev);
pt_prev = ptype;
}
}
struct packet_type *pt_prev,
struct net_device *orig_dev)
{
atomic_inc(&skb->users);
return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
}
{
int hash;
spin_lock_bh(&ptype_lock);
if (pt->type == htons(ETH_P_ALL)) 如果是ETH_P_ALL类型,则加入ptype_all 用于sniffer等
list_add_rcu(&pt->list, &ptype_all);
else {
hash = ntohs(pt->type) & PTYPE_HASH_MASK; 否则使用hash方式插入ptype_base中
list_add_rcu(&pt->list, &ptype_base[hash]);
}
spin_unlock_bh(&ptype_lock);
}
dev_add_pack(&pppoed_ptype); pppoed
->inet_init() /net/ipv4/af_inet.c
->dev_add_pack(&ip_packet_type);
.type = cpu_to_be16(ETH_P_IP), #define ETH_P_IP 0x0800 /* Internet Protocol packet */
.func = ip_rcv,
.gso_send_check = inet_gso_send_check,
.gso_segment = inet_gso_segment,
.gro_receive = inet_gro_receive,
.gro_complete = inet_gro_complete,
};
ip协议入口
goto drop; pkt_type表示报文类型 。PACKET_OTHERHOST表示非去往本机但是在特定模式下被接受的报文
goto inhdr_error;
goto inhdr_error;
ip_rcv_finish); 交给netfilter过滤,过滤通过则交给ip_rcv_finish处理
goto drop;
先看ip_local_deliver:
if (ip_defrag(skb, IP_DEFRAG_LOCAL_DELIVER)) 进行重组
return 0;
}
->ip_local_deliver_finish()
ipprot = rcu_dereference(inet_protos[hash]
{
int hash, ret;
hash = protocol & (MAX_INET_PROTOS - 1);
spin_lock_bh(&inet_proto_lock);
if (inet_protos[hash]) {
ret = -1;
} else {
inet_protos[hash] = prot;
ret = 0;
}
spin_unlock_bh(&inet_proto_lock);
return ret;
}
static const struct net_protocol tcp_protocol = {
.handler = tcp_v4_rcv,
.err_handler = tcp_v4_err,
.gso_send_check = tcp_v4_gso_send_check,
.gso_segment = tcp_tso_segment,
.gro_receive = tcp4_gro_receive,
.gro_complete = tcp4_gro_complete,
.no_policy = 1,
.netns_ok = 1,
};
->(!ipprot->no_policy) ipprot->no_policy如果为1,表明当前处理的协议设置了IP_SEC处理规则
->ipprot->handler(skb); .handler = tcp_v4_rcv, 若是TCP则调用该函数 数据包进入TCP协议栈继续处理