linux内核网络协议栈--接收流程及函数(九)
本章来看下,数据是如何从网络中接收并最后到达应用程序的。
网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息。
1、链路层
包到达机器的物理网卡时候触发一个中断,并将通过DMA传送到位于 linux kernel 内存中的rx_ring。
中断处理程序分配 skb_buff 数据结构,并将接收到的数据帧从网络适配器I/O端口拷贝到skb_buff 缓冲区中,并设置 skb_buff 相应的参数,这些参数将被上层的网络协议使用,例如skb->protocol;
然后发出一个软中断(NET_RX_SOFTIRQ,该变量定义在include/linux/interrupt.h 文件中),通知内核接收到新的数据帧。
进入软中断处理流程,调用 net_rx_action 函数。包从 rx_ring 中被删除,进入 netif _receive_skb 处理流程。
netif_receive_skb根据注册在全局数组 ptype_all 和 ptype_base 里的网络层数据报类型,把数据报递交给不同的网络层协议的接收函数(INET域中主要是ip_rcv和arp_rcv)。
2、网络层
网络IP层的入口函数在ip_rcv函数。
ip_rcv函数调用第三层协议的接收函数处理该skb包,进入第三层网络层处理。
该函数首先会做包括checksum在内的各种检查,如果需要的话会做 IP defragment(分片合并),最终到达 ip_rcv_finish 函数。
ip_rcv_finish 函数会调用ip_router_input函数,进入路由处理环节。会调用 ip_route_input 来更新路由,然后查找 route,决定该会被发到本机还是会被转发还是丢弃:
如果发到本机的话,调用 ip_local_deliver 函数,可能会做 de-fragment(合并多个包),并调用ip_local_deliver_finish。最后调用下一层接口,包括 tcp_v4_rcv (TCP), udp_rcv (UDP),icmp_rcv (ICMP),igmp_rcv(IGMP)。对于 TCP 来说,函数 tcp_v4_rcv 函数会被调用,从而处理流程进入 TCP 栈。
如果需要转发,则进入转发流程,调用 dev_queue_xmit,进入链路层处理流程。
如果不是发送到本机的话就要进行转发,则调用ip_forward转发。
如果是igmp管理数据包,则调用ip_mr_input函数进行组播路由的查找。
3、传输层
传输层 TCP 处理入口在tcp_v4_rcv函数(位于 linux/net/ipv4/tcp_ipv4.c 文件中),首先会做一些完整性检查,发现问题直接将包丢弃。
如果是tcp,则调用tcp_v4_do_rcv。
然后sk->sk_state == TCP_ESTABLISHED,调用tcp_rcv_established。
调用tcp_data_queue方法将报文放入队列中。然后用tcp_ofo_queue方法报文插入receive队列的。
4、应用层
应用调用 read 或者 recvfrom 时,该调用会被映射为/net/socket.c 中的 sys_recv 系统调用,并被转化为 sys_recvfrom 调用,然后调用 sock_recgmsg 函数。
对于 INET 类型的 socket,/net/ipv4/af_inet.c 中的 inet_recvmsg 方法会被调用,它会调用相关协议的数据接收方法。
TCP 会调用 tcp_recvmsg。该函数从 socket buffer 中拷贝数据到buffer。
UDP从用户空间可以调用三个recv()/recvfrom()/recvmsg() 中的任意一个来接收 UDP 包,这些系统调用最终都会调用内核中的 udp_recvmsg 方法。
原文链接:https://blog.csdn.net/notbaron/article/details/79597188
linux内核网络协议栈--接收流程及函数(九)相关推荐
- linux内核网络协议栈--发送流程及函数(十)
本章会一步一步的分析,在linux内核中,数据是如何从网络中接收并最后到达应用程序的. 用户数据的发送流程如下图所示,不管是tfp,telnet,http都是类似的.当然我们在使用应用的时候,根本不会 ...
- Linux内核网络协议栈流程及架构
文章目录 Linux内核网络报文处理流程 Linux内核网络协议栈架构 Linux内核网络报文处理流程 linux网络协议栈是由若干个层组成的,网络数据的处理流程主要是指在协议栈的各个层之间的传递. ...
- Linux内核网络协议栈:udp数据包发送(源码解读)
<监视和调整Linux网络协议栈:接收数据> <监控和调整Linux网络协议栈的图解指南:接收数据> <Linux网络 - 数据包的接收过程> <Linux网 ...
- 深入浅出Linux内核网络协议栈|结构sk_buff|Iptables|Netfilter丨内核源码丨驱动开发丨内核开发丨C/C++Linux服务器开发
深入浅出Linux内核网络协议栈 视频讲解如下,点击观看: 深入浅出Linux内核网络协议栈|结构sk C/C++Linux服务器开发高级架构师知识点精彩内容包括:C/C++,Linux,Nginx, ...
- linux内核网络协议栈--数据接收流程图(五)
各层主要函数以及位置功能说明: 1)sock_read:初始化msghdr{}的结构类型变量msg,并且将需要接收的数据存放的地址传给msg.msg_iov->iov_base. net/soc ...
- linux内核网络协议栈--linux网络设备理解(十三)
网络层次 linux网络设备驱动与字符设备和块设备有很大的不同. 字符设备和块设备对应/dev下的一个设备文件.而网络设备不存在这样的设备文件.网络设备使用套接字socket访问,虽然也使用read, ...
- Linux 内核网络协议栈运行原理
封装:当应用程序用 TCP 协议传送数据时,数据首先进入内核网络协议栈中,然后逐一通过 TCP/IP 协议族的每层直到被当作一串比特流送入网络.对于每一层而言,对收到的数据都会封装相应的协议首部信息( ...
- linux内核网络协议栈--数据包的接收过程(二十)
本文将介绍在Linux系统中,数据包是如何一步一步从网卡传到进程手中的. 本文只讨论以太网的物理网卡,不涉及虚拟设备,并且以一个UDP包的接收过程作为示例. 本示例里列出的函数调用关系来自于kerne ...
- linux内核网络协议栈--数据包的接收过程(二十二)
与其说这篇文章分析了网卡驱动中中数据包的接收,还不如说基于Kernel:2.6.12,以e100为例,对网卡驱动编写的一个说明.当然,对数据包的接收说的很清楚. 一.从网卡说起 这并非是一个网卡驱动分 ...
最新文章
- ESP32-CAM教程一:网页上显示摄像头数据
- IOS Animation-CAShapeLayer、UIBezierPath与Animation的结合
- 网站建设中关于eclipse启动参数的优化
- node.js中对Event Loop事件循环的理解
- 1.2开发文档简读,了解全貌.mp4
- 分享百度文库提交成功的八大因素
- bzoj 1419: Red is good
- java shutdowninput,java中socket.shutdownOutput()使用后如果还想用输出流怎么办
- UnicodeDecodeError: 'gbk' codec can't decode byte 0xb1 in position 5: illegal multibyte sequence
- 实操:SparrowRecsys的首次运行
- c++ 设计一个立方体的类,求出立方体的面积和体积
- 5G应用加速落地,酷雷曼VR直播应时而生。
- 轻松制作 Notion 风格的头像 - Notion Avatar Maker
- recordcount=-1的原因以及解决方法
- SIM卡中ICCID标识与IMSI的区别
- SpringCloud-25-Gateway:动态路由、过滤器使用
- 简单了解计算机组成原理 -- CPU与操作系统
- 怎么调整gif表情包的比例?
- 什么是软件测试,软件测试究竟是做什么的
- 销售人员的优势和动力
热门文章
- python自学多久可以找到工作-自学Python的高效方法,学Python多久能找到工作?
- python怎么下载-如何下载python包
- python爬虫教程pdf-Python 爬虫:把廖雪峰教程转换成 PDF 电子书
- python小程序源代码-Python小项目:开发一个动态时钟小程序(附源码)
- 从小白到精通python要多久-小白学Python需要多久?老男孩Python培训教程
- python订单详细教程-Python抓取订单页面
- python 命令行参数-python实现读取命令行参数的方法
- python基础知识整理-python基础知识整理——容器
- yolov5 v3.0训练出现KeyError错误
- python读取 .mat 文件(matlab文件)