副标题[/!--empirenews.page--]
转载地址
作者:闫明
本文分析基于Linux Kernel 1.2.13
注:标题中的”(上)“,”(下)“表示分析过程基于数据包的传递方向:”(上)“表示分析是从底层向上分析、”(下)“表示分析是从上向下分析。
?上篇:
上一篇博文中我们从宏观上分析了Linux内核中网络栈的初始化过程,这里我们再从宏观上分析一下一个数据包在各网络层的传递的过程。
我们知道网络的OSI模型和TCP/IP模型层次结构如下:

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

我们就从最底层开始追溯一个数据包的传递流程。
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">view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423">copy
?
- ?
-
- ?
-
- ?
-
- ??
-
- {??
-
- ??
-
- ?
-
- ?
-
- ????skb->sk?=?NULL;??
- free?=?1;??
- ????(skb->stamp.tv_sec==0)??
- stamp?=?xtime;??
- ??
-
- ?
-
- ??
-
- ????????dropping?=?0;??
- ?300)??
- ????????dropping?=?1;??
-
- ?????(dropping)???
-
- ????????kfree_skb(skb,?FREE_READ);??
-
- ????}??
-
- ?????
-
- ??
-
- ????IS_SKB(skb);??
-
- ????skb_queue_tail(&backlog,skb);??
-
- ????
-
- ?
-
- ??
-
- ????mark_bh(NET_BH);??
-
- }??
该函数中用到了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">view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423">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">view plain<a class="CopyToClipboard" title="copy" href="http://blog.csdn.net/geekcome/article/details/7492423">copy
?
- ?
-
- ?
-
- ?
-
- ???
-
- {??
-
- ?????packet_type?*ptype;??
-
- ????unsigned??type;??
-
- ?????
-
- ??
-
- ?????(set_bit(1,?(*)&in_bh))??
-
- ??
-
- ?
-
- ?
-
- ??
-
- ????
-
- ?
-
- ?
-
- ??
-
- ??????
-
- ?
-
- ???????
-
- ????{??
-
- ?
-
- ????????backlog_size--;??
-
- ????????sti();??
-
- ????????????
-
- ?
-
- ?
-
- ??
- h.raw?=?skb->data?+?skb->dev->hard_header_len;??
- ????????skb->len?-=?skb->dev->hard_header_len;??
-
- ????????????
-
- ?
-
- ?
-
- ?
-
- ?
-
- ??????????
- dev->type_trans(skb,?skb->dev);??
- ??
-
- ?
-
- ?
-
- ?
-
- ?
-
- ?
-
- ????????pt_prev?=?NULL;??
- next)???
- ????????{??
-
- ?????????????((ptype->type?==?type?||?ptype->type?==?htons(ETH_P_ALL))?&&?(!ptype->dev?||?ptype->dev==skb->dev))??
-
- ?????????????????
-
- ?
-
- ????????????????(pt_prev)??
-
- ?????????????????????sk_buff?*skb2;??
-
- ????????????????????skb2=skb_clone(skb,?GFP_ATOMIC);??
-
- ?????????????????????
-
- ?
-
- ??
-
- ????????????????????????pt_prev->func(skb2,?skb->dev,?pt_prev);??
-
- ??????????????????????????????????????????????
-
- ??????????????????
-
- ????????????}??
-
- ??????????
-
- ?
-
- ??
-
- ????????????pt_prev->func(skb,?pt_prev);??
-
- ?
-
- ???????
-
- ????????????kfree_skb(skb,?FREE_WRITE);??
-
- ?????????
-
- ?
-
- ??
-
- ????????dev_transmit();??
-
- ????}?????
-
- ?????
-
- ??
-
- ????in_bh?=?0;??
-
- ??????
-
- ?
-
- ???????
-
- }??
2、网络层* 就以IP数据包为例来说明,那么从链路层向网络层传递时将调用ip_rcv函数。该函数完成本层的处理后会根据IP首部中使用的传输层协议来调用相应协议的处理函数。
UDP对应udp_rcv、TCP对应tcp_rcv、ICMP对应icmp_rcv、IGMP对应igmp_rcv(虽然这里的ICMP,IGMP一般成为网络层协议,但是实际上他们都封装在IP协议里面,作为传输层对待)
这个函数比较复杂,后续会详细分析。这里粘贴一下,让我们对整体了解更清楚
(编辑:淮北站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|