`
网络接口
  • 浏览: 44937 次
文章分类
社区版块
存档分类
最新评论

2.6.24.4内核网络接收数据包分析

 
阅读更多

在2.6.24.4中所有的网卡,不管是否支持napi,都是通过struct napi_struct结构进行。所有我们先说一下这个结构。

struct napi_struct{

   struct list_head poll_list;

   unsigned long state;

   int weight;

   int (*poll)(struct napi_struct *,int);

}

对应支持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机制的网卡:

     网卡初始化时会自己初始化一个自己的数据包接收队列同时将这个接收代理放到poll_list中,当有数据包到达时,将数据包dma到自己的数据包队列中。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做一些检查工作,如果skb->users!=1,则clone一个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中。之后就是流控出队列。

分享到:
评论

相关推荐

    linux2.6.24.4到S3C2410的移植

    本文档主要介绍如何将Linux2.6.24.4内核移植到基于S3C2410处理器的Nano2410开发板上。 #### 二、目标硬件平台信息 **目标板(Nano2410):** - **CPU:** S3C2410X - **SDRAM:** HY57V561620 (32MB) - **FLASH:** K9F...

    tq2440 Linux 2.6.30.4内核移植1

    tq2440 Linux 2.6.30.4内核移植 tq2440 Linux 2.6.30.4内核移植

    CS8900_linux-2.6.24.4.rar_2410 cs8900_S3C2410 CS8900 _cs8900_cs8

    标题中的"CS8900_linux-2.6.24.4.rar_2410 cs8900_S3C2410 CS8900 _cs8900_cs8"指的是针对Linux内核版本2.6.24.4的CS8900网络控制器驱动程序,特别适配于S3C2410微处理器。CS8900是一款常见的以太网控制器,用于...

    linux2.6.11.12内核源码注释

    linux-2.6.11.12内核源码,带有注释,如果想学习linux内核可以参考。

    linux-2.6.8.1.tar.bz2

    linux-2.6.8.1.tar.bz2linux-2.6.8.1.tar.bz2linux-2.6.8.1.tar.bz2linux-2.6.8.1.tar.bz2linux-2.6.8.1.tar.bz2linux-2.6.8.1.tar.bz2linux-2.6.8.1.tar.bz2linux-2.6.8.1.tar.bz2linux-2.6.8.1.tar.bz2linux-2.6....

    Linux-2.6.32.2内核在mini2440上的移植

    **知识点详解:Linux-2.6.32.2内核在mini2440上的移植** 在深入探讨Linux-2.6.32.2内核如何在mini2440开发板上进行移植之前,让我们先了解几个关键概念与步骤。 ### 1. 构建自主开发环境 开发环境的搭建是任何...

    commons-lang-2.6.jar包

    commons-lang-2.6.jar包commons-lang-2.6.jar包commons-lang-2.6.jar包commons-lang-2.6.jar包commons-lang-2.6.jar包加源码

    linux-2.6.21.5源代码

    Linux 2.6.21.5内核的网络协议栈实现了TCP/IP协议族,包括网络接口层、互联网层、传输层和应用层。其中,TCP(传输控制协议)和UDP(用户数据报协议)是传输层的两个重要协议,负责可靠的数据传输和无连接的数据传输...

    2.6.15.5内核配置选项

    2.6.15.5内核配置选项包括了对处理器架构的支持(如x86、x86_64等)、设备驱动程序(如网络、存储、显卡等)、文件系统、内存管理、调度策略等多个方面。例如,对于服务器环境,可能会选择优化内存管理,增加TCP/IP...

    Linux 2.6.17.9内核文件系统调用详解

    Linux 2.6.17.9 内核文件系统调用详解 本资源主要讲述 Linux 2.6.17.9 内核版本中文件 I/O 操作的实现,包括主要的数据结构、宏定义和函数流程,并分别讲述 open、create、close、read、write、lseek 系统调用。 1...

    【干货】linux-2.6.11.12内核源代码及源码注释.zip

    在Linux-2.6.11.12版本的内核中,包含了多个关键领域的源代码和注释,这对于理解操作系统的工作原理以及进行内核级别的编程至关重要。 1. **同步机制**:在多线程环境中,同步是非常关键的,以确保数据的一致性和...

    Vagaa哇嘎画时代版 2.6.7.1(修正加速速度)

    Vagaa哇嘎画时代版 2.6.7.1(修正加速速度)Vagaa哇嘎画时代版 2.6.7.1(修正加速速度)

    PTSetupPure2.6.0.0.exe

    PTSetupPure2.6.0.0.exe

    qualcomm_mde.win.2.6_installer_2.6.1.26.zip

    标题“qualcomm_mde.win.2.6_installer_2.6.1.26.zip”指的是高通(Qualcomm)MDE(Mobile Development Environment)的Windows 2.6版本安装程序,版本号为2.6.1.26。这个压缩包文件是针对QCC3040和QCC3046芯片的TWS...

    hive-jdbc-uber-2.6.5.0-292.jar

    在实际项目中,"hive-jdbc-uber-2.6.5.0-292.jar"可以作为大数据分析工具链的一部分,与其他Java应用(如ETL工具、数据可视化工具等)集成,实现对Hive数据仓库的高效访问。尽管下载途径有限,但这个特定版本的JDBC...

    libpython2.6.so.1.0

    libpython2.6.so.1.0

    TortoiseGit-2.6.0.0-64bit+TortoiseGit-LanguagePack-2.6.0.0-64bit-zh_CN

    它的最新版本为2.6.0.0,适用于64位操作系统。这个软件包包含了两个主要的部分,分别是"TortoiseGit-2.6.0.0-64bit"和"TortoiseGit-LanguagePack-2.6.0.0-64bit-zh_CN",旨在为用户提供完整的Git功能以及中文语言...

    pdfjs-2.6.347-dist.zip

    标题 "pdfjs-2.6.347-dist.zip" 暗示这是一个PDF.js的发行版,版本号为2.6.347。"dist"通常表示这是经过编译和打包的发布版本,适合在生产环境中使用,而不是开发源码。 描述中的 "pdfjs-2.6.347-dist.zip" 与标题...

    hive-jdbc-uber-2.6.5.0-292.zip

    标题中的“hive-jdbc-uber-2.6.5.0-292.zip”指的是Hive JDBC驱动的Uber版本,版本号为2.6.5.0-292。Uber JAR是一种包含所有依赖的单一JAR文件,便于分发和使用,特别是对于连接工具如DataGrip这样的集成开发环境...

    微信电脑版 2.6.8 - WeChatSetup2.6.8.52

    微信电脑版 2.6.8 - WeChatSetup2.6.8.52

Global site tag (gtag.js) - Google Analytics