<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    海闊天空

    I'm on my way!
    隨筆 - 17, 文章 - 69, 評(píng)論 - 21, 引用 - 0
    數(shù)據(jù)加載中……

    Linux (2.6.24.4)網(wǎng)卡接收數(shù)據(jù)包的流程

    2.6.24.4內(nèi)核網(wǎng)絡(luò)接收數(shù)據(jù)包分析
    瀚海書(shū)香
    在2.6.24.4中所有的網(wǎng)卡,不管是否支持napi,都是通過(guò)struct napi_struct結(jié)構(gòu)進(jìn)行。所有我們先說(shuō)一下這個(gè)結(jié)構(gòu)。
    struct napi_struct{
       struct list_head poll_list;
       unsigned long state;
       int weight;
       int (*poll)(struct napi_struct *,int);
    }
    對(duì)應(yīng)支持napi的網(wǎng)卡,自己填充這個(gè)結(jié)構(gòu)體;而非napi網(wǎng)卡,則使用per cpu的softnet_data>backlog,這個(gè)結(jié)構(gòu)的初始化在net_dev_init()中完成。
    我們先說(shuō)一下非napi機(jī)制的網(wǎng)卡:
        網(wǎng)卡接收到數(shù)據(jù)包后dma到內(nèi)核空間,然后調(diào)用netif_rx()將數(shù)據(jù)包掛接到softnet_data>input_pkt_queue中, 如果backlog這個(gè)napi_struct沒(méi)有被調(diào)度,則napi_schedule(&backlog).napi_schedule() 會(huì)將backlog的poll_list掛接到softnet_data->poll_list上,同時(shí)出發(fā)軟中斷NET_RX_SOFTIRQ。 NET_RX_SOFTIRQ軟中斷,調(diào)用相應(yīng)的函數(shù)net_rx_action()。
    對(duì)應(yīng)napi機(jī)制的網(wǎng)卡:
         網(wǎng)卡初始化是會(huì)自己初始化一個(gè)自己的數(shù)據(jù)包接收隊(duì)列,當(dāng)有數(shù)據(jù)包到達(dá)時(shí),將數(shù)據(jù)包dma到自己的數(shù)據(jù)包隊(duì)列中,如果自己的napi沒(méi)有調(diào)度,則 napi_schedule(mynapi),這里的mynapi是網(wǎng)卡自己的napi_struct.napi_schedule()會(huì)將網(wǎng)卡自己的 poll_list掛接到softnet_data->poll_list上,同時(shí)出發(fā)軟中斷NET_RX_SOFTIRQ。 NET_RX_SOFTIRQ軟中斷,調(diào)用相應(yīng)的函數(shù)net_rx_action()。
     
    net_rx_action():
        首先獲取softnet_data->poll_list,通過(guò)遍歷poll_list,獲取每個(gè)poll_list對(duì)應(yīng)的napi_struct 結(jié)構(gòu)(container_of實(shí)現(xiàn)),然后根據(jù)napi_struct的weight調(diào)用poll函數(shù),如果是非napi網(wǎng)卡,這里的 napi_struct是backlog,所以poll函數(shù)就是process_backlog;如果是napi的網(wǎng)卡,則會(huì)使自己的poll函數(shù)。
    napi網(wǎng)卡的poll函數(shù)就是從自己數(shù)據(jù)包隊(duì)列中dequeue出一個(gè)skb,然后調(diào)用netif_receive_skb().
    非napi的process_backlog會(huì)獲取softnet_data->input_pkt_queue,然后對(duì)隊(duì)列input_pkt_queue進(jìn)行dequeue操作,獲得一個(gè)skb,之后調(diào)用netif_receive_skb(skb)。
    netif_receive_skb():
        對(duì)skb做一些準(zhǔn)備工作,例如設(shè)置mac_len等,調(diào)用deliver_skb()給所有的注冊(cè)ptype_all類(lèi)型的協(xié)議處理handle,然后是 網(wǎng)橋和VLAN的處理,之后會(huì)給注冊(cè)的相應(yīng)協(xié)議的ptype_base的handle。這里假設(shè)是ip協(xié)議,則會(huì)調(diào)用相應(yīng)的ip協(xié)議handle的處理函 數(shù)ip_rcv。
    ip_rcv():
        對(duì)skb做一些檢查工作,如果skb->users!=1,則clone一個(gè)skb,之后會(huì)轉(zhuǎn)入netfilter的 NF_IP_PRE_ROUTING的hook點(diǎn),調(diào)用所有在該點(diǎn)注冊(cè)的hook函數(shù)。比如說(shuō)如果開(kāi)啟了conntrack,則會(huì)在這里進(jìn)行數(shù)據(jù)包重組。 之后調(diào)用ip_rcv_finish().
    ip_rcv_finish():
        首先調(diào)用ip_route_input()決定數(shù)據(jù)包的路由,初始化skb->dst,調(diào)用dst_input(skb).
    dst_input():
        實(shí)際上是調(diào)用skb->dst->input(skb),對(duì)應(yīng)input的初始化在route.c中。如果是發(fā)往本地的數(shù)據(jù)包 dst->input=ip_local_deliver;如果是轉(zhuǎn)發(fā)的數(shù)據(jù)包dst->input=ip_forward;
    本地流程:
    ip_local_deliver():
        首先是對(duì)分片的數(shù)據(jù)包重組,會(huì)轉(zhuǎn)入netfilter的NF_IP_LOCAL_IN的hook點(diǎn),調(diào)用所有在該點(diǎn)注冊(cè)的hook函數(shù)。之后會(huì)調(diào)用ip_local_deliver_finish(),之后就到第四層了。
    轉(zhuǎn)發(fā)流程:
    ip_forward():
        做一些源路由等方面的檢查后,會(huì)轉(zhuǎn)入netfilter的NF_IP_FORWARD的hook點(diǎn),調(diào)用所有在該點(diǎn)注冊(cè)的hook函數(shù)。之后會(huì)調(diào)用ip_forward_finish().
    ip_forward_finish():
        調(diào)用dst_output().
    dst_output():
        skb->dst->output(skb).一般output=ip_output.
    ip_output():
        設(shè)置skb的dev為發(fā)包的dev,同時(shí)設(shè)置skb->protocol,會(huì)轉(zhuǎn)入netfilter的NF_IP_POST_ROUTING的hook點(diǎn),調(diào)用所有在該點(diǎn)注冊(cè)的hook函數(shù)。之后會(huì)調(diào)用ip_finish_output().
    ip_finish_output():
        檢查一下數(shù)據(jù)包是否需要分片,如果需要分片,則進(jìn)行ip_fragement(),之后調(diào)用ip_finish_output2().
    ip_finish_output2():
        根據(jù)neighbour,調(diào)用dst->neighbour->output.
    到這為止,數(shù)據(jù)包會(huì)經(jīng)過(guò)dev_queue_xmit放入dev的qdisc中。之后就是流控出隊(duì)列。

    出處:http://pengliang.cublog.cn

    posted on 2009-12-02 13:32 石頭@ 閱讀(2597) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Tcp/Ip

    主站蜘蛛池模板: 亚洲精品中文字幕麻豆| 亚洲sss综合天堂久久久| 国产精品白浆在线观看免费| 亚洲精品人成电影网| 日韩免费无砖专区2020狼| 国产一级高青免费| 亚洲AV无码一区二区三区在线| 成年女人色毛片免费看| 深夜福利在线免费观看| 亚洲人成依人成综合网| 国产免费看插插插视频| 一区二区三区福利视频免费观看| 国产成人精品日本亚洲专| 激情综合色五月丁香六月亚洲| 最近最新高清免费中文字幕| 国产亚洲美女精品久久久久| 久久久久久亚洲精品中文字幕| 在线观看免费精品国产| 久9这里精品免费视频| 亚洲AV无码一区二区三区网址| 亚洲一区二区女搞男| 成人毛片免费观看视频大全| 国产午夜精品久久久久免费视| 亚洲大尺度无码无码专线一区| 亚洲四虎永久在线播放| www亚洲精品少妇裸乳一区二区| 18勿入网站免费永久| 成人无码精品1区2区3区免费看| 亚洲精品无码专区在线播放| 亚洲第一精品在线视频| 亚洲精品tv久久久久久久久久| 国产免费看JIZZ视频| 午夜免费啪视频在线观看 | 中文字幕亚洲日韩无线码| 免费观看美女用震蛋喷水的视频| 久久99精品免费一区二区| 久久综合亚洲色hezyo| 亚洲国产精品张柏芝在线观看| 国产精品亚洲片在线| 亚洲国产精品一区二区第一页免| 免费一本色道久久一区|