| 副标题[/!--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协议里面,作为传输层对待) 这个函数比较复杂,后续会详细分析。这里粘贴一下,让我们对整体了解更清楚 (编辑:鹰潭站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |