在2.6.24.4中所有的網絡卡,不管是否支援napi,都是通過struct napi_struct結構進行。所有我們先說一下這個結果。
struct napi_struct
對應支援napi的網絡卡,自己填充這個結構體;而非napi網絡卡,則使用per cpu的softnet_data->backlog,這個結構的初始化在net_dev_init()中完成。
我們先說一下非napi機制的網絡卡:
網絡卡接收到資料報後dma到核心空間,然後呼叫netif_rx()將資料報掛接到softnet_data->input_pkt_queue中,如果backlog這個napi_struct沒有被排程,則napi_schedule(&backlog).
napi_schedule()會將backlog的poll_list掛接到softnet_data->poll_list上,同時觸發軟中斷net_rx_softirq。
net_rx_softirq軟中斷,呼叫相應的函式net_rx_action()。
對應napi機制的網絡卡:
網絡卡初始化是會自己初始化乙個自己的資料報接收佇列,當有資料報到達時,將資料報dma到自己的資料報佇列中,如果自己的napi沒有排程,則napi_schedule(mynapi),這裡的mynapi是網絡卡自己的napi_struct.napi_schedule()會將網絡卡自己的poll_list掛接到softnet_data->poll_list上,同時出發軟中斷net_rx_softirq。net_rx_softirq軟中斷,呼叫相應的函式net_rx_action()。
net_rx_action():
首先獲取softnet_data->poll_list,通過遍歷poll_list,獲取每個poll_list對應的napi_struct結構(container_of實現),然後根據napi_struct的weight呼叫poll函式,如果是非napi網絡卡,這裡的napi_struct是backlog,所以poll函式就是process_backlog;如果是napi的網絡卡,則會使自己的poll函式。
napi網絡卡的poll函式就是從自己資料報佇列中dequeue出乙個skb,然後呼叫netif_receive_skb().
非napi的process_backlog會獲取softnet_data->input_pkt_queue,然後對佇列input_pkt_queue進行dequeue操作,獲得乙個skb,之後呼叫netif_receive_skb(skb)。
netif_receive_skb():
對skb做一些準備工作,例如設定mac_len等,呼叫deliver_skb()給所有的註冊ptype_all型別的協議處理handle,然後是網橋和vlan的處理,之後會給註冊的相應協議的ptype_base的handle。這裡假設是ip協議,則會呼叫相應的ip協議handle的處理函式ip_rcv。
ip_rcv():
對skb做一些檢查工作後,會轉入netfilter的nf_ip_pre_routing的hook點,呼叫所有在該點註冊的hook函式。比如說如果開啟了conntrack,則會在這裡進行資料報重組。之後呼叫ip_rcv_finish().
ip_rcv_finish():
首先呼叫ip_route_input()決定資料報的路由,初始化skb->dst,呼叫dst_input(skb).
dst_input():
實際上是呼叫skb->dst->input(skb),對應input的初始化在route.c中。如果是發往本地的資料報dst->input=ip_local_deliver;如果是**的資料報dst->input=ip_forward;
本地流程:
ip_local_deliver():
首先是對分片的資料報重組,會轉入netfilter的nf_ip_local_in的hook點,呼叫所有在該點註冊的hook函式。之後會呼叫ip_local_deliver_finish(),之後就到第四層了。
**流程:
ip_forward():
做一些源路由等方面的檢查後,會轉入netfilter的nf_ip_forward的hook點,呼叫所有在該點註冊的hook函式。之後會呼叫ip_forward_finish().
ip_forward_finish():
呼叫dst_output().
dst_output():
skb->dst->output(skb).一般output=ip_output.
ip_output():
設定skb的dev為發包的dev,同時設定skb->protocol,會轉入netfilter的nf_ip_post_routing的hook點,呼叫所有在該點註冊的hook函式。之後會呼叫ip_finish_output().
ip_finish_output():
檢查一下資料報是否需要分片,如果需要分片,則進行ip_fragement(),之後呼叫ip_finish_output2().
ip_finish_output2():
根據neighbour,呼叫dst->neighbour->output.
到這為止,資料報會經過dev_queue_xmit放入dev的qdisc中。之後就是流控出佇列。
android 接收簡訊流程
簡訊來了之後framework會傳送廣播 android.provider.telephony.sms received privilegedsmsreceiver 此時,privilegedsmsreceiver會接受到該廣播,呼叫父類smsreceiver的onreceivewithprivil...
CrtmpServr 接收Http流程
最近在研究crtmpserver http部分,記錄一些基本的流程,以備查閱。首先,開啟配置指令碼crtmpserver.lua 確認指令碼中有以下內容,如果沒有需要加上。acceptors validatehandshake true default true 在瀏覽器位址列中輸入跟蹤crtmps...
(9)SPI接收verilog描述
第一,本節目錄 第二,本節引言 第三,fpga簡介 第四,verilog簡介 第五,spi接收verilog描述例項 第六,結束語。給fpga乙個支點,它可以撬動整個數字邏輯。給我一根槓桿我就能撬動地球 是古希臘數學家 物理學家阿基公尺德說的,這句話是阿基公尺德的經典語錄,這句話還被翻譯為 給我乙個...