Linux协议栈(3)——接收流程及函数

本章来看下,数据是如何从网络中接收并最后到达应用程序的。

网络层将数据链路层提供的帧组成数据包,包中封装有网络层包头,其中含有逻辑地址信息。

1.1.1.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)。

1.1.1.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函数进行组播路由的查找。

1.1.1.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队列的。

1.1.1.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 方法。

如下图:


更多相关文章

  1. Linux C 字符串输入函数 gets()、fgets()、scanf() 详解
  2. Linux中mprotect()函数的用法
  3. mysql数据库忘记ROOT密码时的解决办法
  4. Oracle:从SQL文件批量导入数据
  5. 无法从SQLite数据库获取最后一行
  6. Java数据持久层框架 MyBatis之API学习七(动态 SQL详解)
  7. 当 IDENTITY_INSERT 设置为 OFF 时,不能为表 'tb_MyInvoices&
  8. sql2008中如何收缩数据库日志文件
  9. pl/sql数据插入出现中文乱码问题

随机推荐

  1. 你应该要理解的java并发关键字volatile
  2. android通过服务实现消息推送
  3. 一个同步工具类CyclicBarrier的详解(干货
  4. java中一个重要的原子类AtomicInteger详
  5. Docker Swarm 下搭建 MongoDB 分片+副本+
  6. 微服务初级设计指南
  7. 基于角色的访问控制
  8. java并发编程CAS机制原理分析
  9. HTTPS 项目实战指南
  10. 基于数据的访问控制