概述了數據在網卡驅動上的處理,接著數據包的流程繼續往下走。網卡驅動的最後一個函數是netif_receive_skb.就從它說起。
為了簡單起見,去掉了裡面預編譯代碼
int netif_receive_skb(struct sk_buff *skb) (net/core/dev.c)
{
struct packet_type *ptype, *pt_prev;
int ret = NET_RX_DROP;
unsigned short type;
//打上接收的時間戳
if (!skb->stamp.tv_sec)
net_timestamp(&skb->stamp);
//如果存在dev->master。則更新相應指針
skb_bond(skb);
//更新CPU的接收統計數據
__get_cpu_var(netdev_rx_stat).total++;
skb->h.raw = skb->nh.raw = skb->data;
skb->mac_len = skb->nh.raw - skb->mac.raw;
pt_prev = NULL;
rcu_read_lock();
//處理所有協議的模塊
list_for_each_entry_rcu(ptype, &ptype_all, list) {
if (!ptype->dev || ptype->dev == skb->dev) {
if (pt_prev)
ret = deliver_skb(skb, pt_prev);
pt_prev = ptype;
}
}
//分片處理
handle_diverter(skb);
//網橋處理
if (handle_bridge(&skb, &pt_prev, &ret))
goto out;
type = skb->protocol;
//為協議調用相應模塊處理。
list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
if (ptype->type == type &&
(!ptype->dev || ptype->dev == skb->dev)) {
if (pt_prev)
ret = deliver_skb(skb, pt_prev);
pt_prev = ptype;
}
}
if (pt_prev) {
ret = pt_prev->func(skb, skb->dev, pt_prev);
} else {
kfree_skb(skb);
/* Jamal, now you will not able to escape explaining
* me how you were going to use this. :-)
*/
ret = NET_RX_DROP;
}
out:
rcu_read_unlock();
return ret;
}
此函數主要完成了分片重組,網橋處理,根據不同協議調用不同的傳輸層處理模塊。本節的重點是概述linux的網橋實現與處理。傳輸層協議分層將在後續章節陸續給出。進入網橋處理代碼:
#if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE) (net/core/dev.c)
int (*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff **pskb);
static __inline__ int handle_bridge(struct sk_buff **pskb,
struct packet_type **pt_prev, int *ret)
{
struct net_bridge_port *port;
//回環接口?非以太網接口?
if ((*pskb)->pkt_type == PACKET_LOOPBACK ||
(port = rcu_dereference((*pskb)->dev->br_port)) == NULL)
return 0;
if (*pt_prev) {
*ret = deliver_skb(*pskb, *pt_prev);
*pt_prev = NULL;
}
// br_handle_frame_hook是一個全局的函數指針
return br_handle_frame_hook(port, pskb);
}
#else
#define handle_bridge(skb, pt_prev, ret) (0)
#endif
從此可以看出。如果編譯的時候選擇了網橋模式,則會進入網橋的處理模塊了,否則,只是一個空函數,直接返回。br_handle_frame_hook代表的函數是什麼呢?網橋的數據處理框架又是什麼樣的呢?呵呵。這就是今天所要分析的問題了。