網路接收流程描述

2021-06-16 07:27:14 字數 2536 閱讀 9756

在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乙個支點,它可以撬動整個數字邏輯。給我一根槓桿我就能撬動地球 是古希臘數學家 物理學家阿基公尺德說的,這句話是阿基公尺德的經典語錄,這句話還被翻譯為 給我乙個...