Windows XP Windows 7 Windows 2003 Windows Vista Windows教程綜合 Linux 系統教程
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟件教程
 Windows教程網 >> Linux系統教程 >> Linux教程 >> linux協議棧之網橋實現

linux協議棧之網橋實現

日期:2017/2/7 14:39:47      編輯:Linux教程
 

概述了數據在網卡驅動上的處理,接著數據包的流程繼續往下走。網卡驅動的最後一個函數是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代表的函數是什麼呢?網橋的數據處理框架又是什麼樣的呢?呵呵。這就是今天所要分析的問題了。
 

Copyright © Windows教程網 All Rights Reserved