网卡接收数据的关键过程

2024-04-17 04:52

本文主要是介绍网卡接收数据的关键过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

网卡接收数据的关键过程

    • 网卡中断处理
    • 网络软中断处理
    • 协议栈处理
    • 传输层处理

Linux内核tracers的实现原理与应用
前年ftrace for io /去年ftrace for mm/今年ftrace for network.今年ftrace也被深度定制加强。

在这篇文章中,我们将深入探讨网卡接收数据的完整过程,了解数据是如何从网卡到达应用程序的。我们将使用Linux内核源代码来分析这一过程:

网卡中断处理

当网卡接收到数据时,会触发一个中断,内核将调用相应的中断处理函数。对于virtio网卡,中断处理函数为vring_interrupt():

vring_interrupt()skb_recv_done()napi_schedule_prep() virtqueue_disable_cb() // disable virtnet interrupt__napi_schedule(); // start network softirq

napi_schedule_prep()函数中,会先禁用virtnet中断,然后通过__napi_schedule()函数启动网络软中断。

bool napi_schedule_prep(struct napi_struct *n)
{unsigned long new, val = READ_ONCE(n->state);do {if (unlikely(val & NAPIF_STATE_DISABLE))return false;new = val | NAPIF_STATE_SCHED;new |= (val & NAPIF_STATE_SCHED) / NAPIF_STATE_SCHED * // 如果state还在sched状态,也设置missNAPIF_STATE_MISSED;} while (!try_cmpxchg(&n->state, &val, new)); // state至少也设置为sched状态return !(val & NAPIF_STATE_SCHED);        // 驱动会判断如果state不是sched状态,则开启napi模式
}

网络软中断处理

网络软中断处理函数为net_rx_action(),它会调用__napi_poll()函数来轮询virtnet设备:

__do_softirq()net_rx_action()__napi_poll()virtnet_poll() // virtnet poll__napi_alloc_skb() // allocate skbnapi_gro_receive() // GRO 

virtnet_poll()函数中,会分配skb缓冲区,并通过napi_gro_receive()函数进行GRO(Generic Receive Offload)处理。

当轮询完成后,会调用virtqueue_napi_complete()函数完成napi过程:

virtnet_poll() // virtnet poll prepare to completevirtqueue_napi_complete()virtqueue_enable_cb_prepare() // 开启virtnet interrupt

协议栈处理

napi_complete_done()函数中,会调用gro_normal_list()函数将接收到的数据包交给协议栈处理:

napi_complete_done()gro_normal_list()netif_receive_skb_list_internal()ip_rcv()

对于IP数据包,会调用ip_rcv()函数进行处理:

static struct packet_type ip_packet_type __read_mostly = {.type = cpu_to_be16(ETH_P_IP),.func = ip_rcv,.list_func = ip_list_rcv,
};
#define ETH_P_IP        0x0800          /* Internet Protocol packet */

ip_rcv()函数中,会根据路由表查找结果,确定是将数据包交给本地接收还是进行转发:

ip_rcv()fib_table_lookup()struct rtable *rth = rt_dst_alloc()rth->dst.input = ip_local_deliver/ip_forwardrth->dst->dev = nhc->nhc_dev; // 从路由表确定接收或者转发网络设备dst->ops = ops;

传输层处理

对于本地接收的数据包,会根据传输层协议(TCP或UDP)进行相应的处理:

static const struct net_protocol tcp_protocol = {.handler        =       tcp_v4_rcv,.err_handler    =       tcp_v4_err,.no_policy      =       1,   .icmp_strict_tag_validation = 1, 
};static const struct net_protocol udp_protocol = {.handler =      udp_rcv,.err_handler =  udp_err,.no_policy =    1,   
};ip_local_deliver() // ip_forwardip_local_deliver_finiship_hdr(skb)->protocol   // <<< tcp/udptcp_v4_rcv() / udp_rcv() // by tcp/udp protocol

至此,数据包就从网卡接收,经过协议栈处理,最终到达应用程序。(以上函数流程都来自ftrace工具)

Linux内核tracers的实现原理与应用

–JeffXie

这篇关于网卡接收数据的关键过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/910826

相关文章

最新版IDEA配置 Tomcat的详细过程

《最新版IDEA配置Tomcat的详细过程》本文介绍如何在IDEA中配置Tomcat服务器,并创建Web项目,首先检查Tomcat是否安装完成,然后在IDEA中创建Web项目并添加Web结构,接着,... 目录配置tomcat第一步,先给项目添加Web结构查看端口号配置tomcat    先检查自己的to

SpringBoot集成SOL链的详细过程

《SpringBoot集成SOL链的详细过程》Solanaj是一个用于与Solana区块链交互的Java库,它为Java开发者提供了一套功能丰富的API,使得在Java环境中可以轻松构建与Solana... 目录一、什么是solanaj?二、Pom依赖三、主要类3.1 RpcClient3.2 Public

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

SpringBoot整合kaptcha验证码过程(复制粘贴即可用)

《SpringBoot整合kaptcha验证码过程(复制粘贴即可用)》本文介绍了如何在SpringBoot项目中整合Kaptcha验证码实现,通过配置和编写相应的Controller、工具类以及前端页... 目录SpringBoot整合kaptcha验证码程序目录参考有两种方式在springboot中使用k

SpringBoot整合InfluxDB的详细过程

《SpringBoot整合InfluxDB的详细过程》InfluxDB是一个开源的时间序列数据库,由Go语言编写,适用于存储和查询按时间顺序产生的数据,它具有高效的数据存储和查询机制,支持高并发写入和... 目录一、简单介绍InfluxDB是什么?1、主要特点2、应用场景二、使用步骤1、集成原生的Influ

SpringBoot实现websocket服务端及客户端的详细过程

《SpringBoot实现websocket服务端及客户端的详细过程》文章介绍了WebSocket通信过程、服务端和客户端的实现,以及可能遇到的问题及解决方案,感兴趣的朋友一起看看吧... 目录一、WebSocket通信过程二、服务端实现1.pom文件添加依赖2.启用Springboot对WebSocket

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

作业提交过程之HDFSMapReduce

作业提交全过程详解 (1)作业提交 第1步:Client调用job.waitForCompletion方法,向整个集群提交MapReduce作业。 第2步:Client向RM申请一个作业id。 第3步:RM给Client返回该job资源的提交路径和作业id。 第4步:Client提交jar包、切片信息和配置文件到指定的资源提交路径。 第5步:Client提交完资源后,向RM申请运行MrAp

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

Solr 使用Facet分组过程中与分词的矛盾解决办法

对于一般查询而言  ,  分词和存储都是必要的  .  比如  CPU  类型  ”Intel  酷睿  2  双核  P7570”,  拆分成  ”Intel”,”  酷睿  ”,”P7570”  这样一些关键字并分别索引  ,  可能提供更好的搜索体验  .  但是如果将  CPU  作为 Facet  字段  ,  最好不进行分词  .  这样就造成了矛盾  ,  解决方法