加入收藏 | 设为首页 | 会员中心 | 我要投稿 辽源站长网 (https://www.0437zz.com/)- 云专线、云连接、智能数据、边缘计算、数据安全!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核--网络栈实现分析(二)--数据包的传递过程--转

发布时间:2021-01-24 11:33:52 所属栏目:Linux 来源:网络整理
导读:转载地址 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的”(上)“,”(下)“表示分析过程基于数据包的传递方向:”(上)“表示分析是从底层向上分析、”(下)“表示分析是从上向下分析。 ?上篇: 上一篇博文中我们从宏观上分析了Linux内核
副标题[/!--empirenews.page--]


转载地址

作者:闫明

本文分析基于Linux Kernel 1.2.13

注:标题中的”(上)“,”(下)“表示分析过程基于数据包的传递方向:”(上)“表示分析是从底层向上分析、”(下)“表示分析是从上向下分析。

?上篇:

上一篇博文中我们从宏观上分析了Linux内核中网络栈的初始化过程,这里我们再从宏观上分析一下一个数据包在各网络层的传递的过程。

我们知道网络的OSI模型和TCP/IP模型层次结构如下:

Linux内核--网络栈实现分析(二)--数据包的传递过程--转

上文中我们看到了网络栈的层次结构:

Linux内核--网络栈实现分析(二)--数据包的传递过程--转

我们就从最底层开始追溯一个数据包的传递流程。

1、网络接口层

* 硬件监听物理介质,进行数据的接收,当接收的数据填满了缓冲区,硬件就会产生中断,中断产生后,系统会转向中断服务子程序。

* 在中断服务子程序中,数据会从硬件的缓冲区复制到内核的空间缓冲区,并包装成一个数据结构(sk_buff),然后调用对驱动层的接口函数netif_rx()将数据包发送给链路层。该函数的实现在net/inet/dev.c中,(在整个网络栈实现中dev.c文件的作用重大,它衔接了其下的驱动层和其上的网络层,可以称它为链路层模块的实现)

该函数的实现如下:

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;copy

?
  1. ?
  2. ?
  3. ?
  4. ??
  5. {??
  6. ??
  7. ?
  8. ?
  9. ????skb->sk?=?NULL;??
  10. free?=?1;??
  11. ????(skb->stamp.tv_sec==0)??
  12. stamp?=?xtime;??
  13. ??
  14. ?
  15. ??
  16. ????????dropping?=?0;??
  17. ?300)??
  18. ????????dropping?=?1;??
  19. ?????(dropping)???
  20. ????????kfree_skb(skb,?FREE_READ);??
  21. ????}??
  22. ?????
  23. ??
  24. ????IS_SKB(skb);??
  25. ????skb_queue_tail(&backlog,skb);??
  26. ????
  27. ?
  28. ??
  29. ????mark_bh(NET_BH);??
  30. }??

该函数中用到了bootom half技术,该技术的原理是将中断处理程序人为的分为两部分,上半部分是实时性要求较高的任务,后半部分可以稍后完成,这样就可以节省中断程序的处理时间。可整体的提高系统的性能。该技术将会在后续的博文中详细分析。

我们从上一篇分析中知道,在网络栈初始化的时候,已经将NET的下半部分执行函数定义成了net_bh(在socket.c文件中1375行左右)

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;copy

?

* 函数net_bh的实现在net/inet/dev.c中

<div class="dp-highlighter bg_cpp">
<div class="bar">
<div class="tools">
[cpp]?<a class="ViewSource" title="view plain" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423"&gt;copy

?
  1. ?
  2. ?
  3. ?
  4. ???
  5. {??
  6. ?????packet_type?*ptype;??
  7. ????unsigned??type;??
  8. ?????
  9. ??
  10. ?????(set_bit(1,?(*)&in_bh))??
  11. ??
  12. ?
  13. ?
  14. ??
  15. ????
  16. ?
  17. ?
  18. ??
  19. ??????
  20. ?
  21. ???????
  22. ????{??
  23. ?
  24. ????????backlog_size--;??
  25. ????????sti();??
  26. ????????????
  27. ?
  28. ?
  29. ??
  30. h.raw?=?skb->data?+?skb->dev->hard_header_len;??
  31. ????????skb->len?-=?skb->dev->hard_header_len;??
  32. ????????????
  33. ?
  34. ?
  35. ?
  36. ?
  37. ??????????
  38. dev->type_trans(skb,?skb->dev);??
  39. ??
  40. ?
  41. ?
  42. ?
  43. ?
  44. ?
  45. ????????pt_prev?=?NULL;??
  46. next)???
  47. ????????{??
  48. ?????????????((ptype->type?==?type?||?ptype->type?==?htons(ETH_P_ALL))?&&?(!ptype->dev?||?ptype->dev==skb->dev))??
  49. ?????????????????
  50. ?
  51. ????????????????(pt_prev)??
  52. ?????????????????????sk_buff?*skb2;??
  53. ????????????????????skb2=skb_clone(skb,?GFP_ATOMIC);??
  54. ?????????????????????
  55. ?
  56. ??
  57. ????????????????????????pt_prev->func(skb2,?skb->dev,?pt_prev);??
  58. ??????????????????????????????????????????????
  59. ??????????????????
  60. ????????????}??
  61. ??????????
  62. ?
  63. ??
  64. ????????????pt_prev->func(skb,?pt_prev);??
  65. ?
  66. ???????
  67. ????????????kfree_skb(skb,?FREE_WRITE);??
  68. ?????????
  69. ?
  70. ??
  71. ????????dev_transmit();??
  72. ????}?????
  73. ?????
  74. ??
  75. ????in_bh?=?0;??
  76. ??????
  77. ?
  78. ???????
  79. }??

2、网络层* 就以IP数据包为例来说明,那么从链路层向网络层传递时将调用ip_rcv函数。该函数完成本层的处理后会根据IP首部中使用的传输层协议来调用相应协议的处理函数。

UDP对应udp_rcv、TCP对应tcp_rcv、ICMP对应icmp_rcv、IGMP对应igmp_rcv(虽然这里的ICMP,IGMP一般成为网络层协议,但是实际上他们都封装在IP协议里面,作为传输层对待)

这个函数比较复杂,后续会详细分析。这里粘贴一下,让我们对整体了解更清楚

(编辑:辽源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读