Linux內核網絡報文簡單流程


轉:http://blog.csdn.net/adamska0104/article/details/45397177

Linux內核網絡報文簡單流程 2014-08-12 10:05:09

分類: Linux

linux下的網卡驅動中通常會提供類似XXX_rx的接收函數

該函數處理與具體硬件相關的寄存器操作

包括中斷檢查,數據狀態檢查,錯誤檢查等

在確認有數據抵達后讀取數據或從DMA的接收環中獲取數據地址

XXX_rx函數以skb為元數據結構組織報文數據

隨后調用內核接口函數netif_rx或netif_receive_skb

這里會涉及到軟中斷的處理,NAPI的接收方式

但是最后都會走netif_receive_skb函數

 

現在內核中使用了RPS機制

將報文分散到各個cpu的接收隊列中進行負載均衡處理

在netif_receive_skb函數中進行了封裝

 

真正的數據處理從__netif_receive_skb_core函數開始

現在可以將該函數視為協議棧的入口函數

首先進行skb中報文頭元數據的調整

如果是vlan報文則先從數據中提取至vlan_tci字段

將vlan標簽的4個字節從數據移除

即在調用deliver_skb向上層傳遞報文數據時不含vlan標簽

 

ptype_all鏈表的處理主要用於抓包

在應用程序中注冊PF_PACKET族ETH_P_ALL的socket便可以得到所有的輸入報文

也可以用於實現自定義的協議類型報文收發

隨后內核會丟棄無法識別的報文

也可以在內核模塊中使用dev_add_pack向ptype_all注冊自定義的處理函數

 

如果接口上配置了輸入流控

則根據具體的隊列和分類規則決定繼續處理或丟棄報文

 

對於vlan數據報文

將skb記錄的輸入接口修改為vlan虛接口

比如使用vconfig配置的eth0.100虛接口

再重復上述處理

 

內核提供了netdev_rx_handler_register接口函數向接口注冊rx_handler

比如為網橋下的接口注冊br_handle_frame函數

為bonding接口注冊bond_handle_frame函數

這相對於老式的網橋處理更靈活

有了這個機制也可以在模塊中自行注冊處理函數

 

網橋的處理包括向上層提交和轉發

發往本地的報文會修改入接口為網橋虛接口如br0

調用netif_receive_skb重新進入協議棧處理

對於上層協議棧見到的只有橋虛接口

需要轉發的報文根據轉發表進行單播或廣播發送

netfilter在網橋的處理路徑中從br_handle_frame到br_dev_queue_push_xmit設置了5個hook點

根據nf_call_iptables的配置還會經過NFPROTO_IPV4的hook點等

內核注冊的由br_nf_ops數組中定義

可在模塊中自行向NFPROTO_BRIDGE族的幾個hook點注冊函數

ebtables在netfilter框架NFPROTO_BRIDGE中實現了橋二層過濾機制

配合應用程序ebtables可在橋下自定義相關規則

 

處理完接口上的rx_handler后便根據具體的3層協議類型在ptype_base中尋找處理函數

比如ETH_P_IP則調用ip_rcv,ETH_P_IPV6則調用ipv6_rcv

這些函數都由dev_add_pack注冊

可在模塊中自定義協議類型處理函數

如果重復定義相同協議的處理函數則要注意報文的修改對后續流程的影響

 

IP報文進入ip_rcv后進行簡單的檢查便進入路由選擇

根據路由查找結果調用ip_local_deliver向上層提交或調用ip_forward進行轉發

向上層提交前會進行IP分片的重組

在ip_local_deliver_finish中會根據報文中4層協議類型調用對應的處理函數

處理函數由接口函數inet_add_protocol注冊

針對TCP或UDP進行不同處理,最后喚醒應用程序接收數據

向外發送和轉發數據經由ip_output函數

包括IP的分片,ARP學習,MAC地址的修改或填充等

netfilter在從ip_rcv到ip_output間設置了5個hook點

向各個點的鏈表中注冊處理函數或使用iptables工具自定義規則

實現報文處理的行為控制

 

報文的發送最后匯聚到隊列發送函數dev_queue_xmit

在接口up的時候dev_activate會創建默認的隊列規則

這里也涉及到接口驅動初始化的時候軟件多隊列與硬件多隊列

配合tc工具可以在報文發送前進行流量控制等

 

最終報文發送到dev_hard_start_xmit調用接口注冊的動作函數ndo_start_xmit

發送前會檢查ptype_all鏈表,支持抓包處理等

如果是虛擬接口則通常調用其對應物理接口的發送函數

到這里內核對報文的控制便結束了

根據不同網卡驅動的實現,操作寄存器等由物理層將數據發送出去

 

整個調用鏈相對較長

每個點都包含大量的細節

主線都是圍繞元數據結構skb的處理

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM