数据帧收发主要函数及netdevice 结构Word下载.docx
- 文档编号:18754785
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:21
- 大小:216.15KB
数据帧收发主要函数及netdevice 结构Word下载.docx
《数据帧收发主要函数及netdevice 结构Word下载.docx》由会员分享,可在线阅读,更多相关《数据帧收发主要函数及netdevice 结构Word下载.docx(21页珍藏版)》请在冰豆网上搜索。
unsigned
long
flags
;
/*ifnetpollwantsit,pretendweneversawit*/
if
(netpoll_rx
(skb
))
return
NET_RX_DROP;
(!
skb->
tstamp
.tv64
)//得到帧接收的时间
net_timestamp(skb);
/*
*Thecodeisrearrangedsothatthepathisthemost
*shortwhenCPUiscongested,butisstilloperating.
*/
local_irq_save(flags);
queue
=
&
__get_cpu_var
(softnet_data
);
//获取当前CPU的softnet_data数据
__get_cpu_var(netdev_rx_stat
).total
++;
//当前CPU接收的帧数+1
(queue->
input_pkt_queue
.qlen
<
netdev_max_backlog){
//监测设备是否还有空间来存储帧,如果空间已满,表示网络阻塞严重,则返回一个错误,此后cpu将丢掉再来的帧。
){
enqueue:
//将该帧加入到softnet_data队列
__skb_queue_tail(&
->
input_pkt_queue,
skb);
local_irq_restore(flags);
NET_RX_SUCCESS;
}
//当队列是空的时候,表明这个队列并没有被软中断所schedule,因此我们需要将此队列加入到软中断的处理链表中。
可以看到加入的正好是backlog,由于调用netif_rx的是非napi的驱动,因此backlog就是初始化时的process_backlog函数。
napi_schedule(&
backlog);
goto
enqueue;
).dropped
kfree_skb(skb);
//上面代码中用到一个关键的数据结构softnet_data,在网卡收发数据的时候,需要维护一个缓冲区队列,来缓存可能存在的突发数据,在协议栈中用一个队列层来表示该缓冲区,队列层位于数据链路层和网络层之间。
softnet_data就是数据链路层中的数据结构,它是一个Per-CPU变量,每个CPU都有一个
/**
netif_receive_skb-processreceivebufferfromnetwork
buffertoprocess
netif_receive_skb()isthemainreceivedataprocessingfunction.
Italwayssucceeds.Thebuffermaybedroppedduringprocessing
forcongestioncontrolorbytheprotocollayers.
Thisfunctionmayonlybecalledfromsoftirqcontextandinterrupts
shouldbeenabled.
Returnvalues(usuallyignored):
NET_RX_SUCCESS:
nocongestion
NET_RX_DROP:
packetwasdropped
//netif_receive_skb是对于netif_rx的NAPI对等函数;
它递交一个报文给内核.当一个NAPI兼容的驱动已耗尽接收报文的供应,它应当重开中断,并且调用netif_rx_complete(现在是
__napi_complete())来停止轮询.
netif_receive_skb(
packet_type
ptype,*pt_prev
net_device
orig_dev;
master;
null_or_orig;
null_or_bond;
ret
__be16type;
)
(vlan_tx_tag_present
)
vlan_hwaccel_do_receive(skb))
/*ifwe'
vegottenherethroughNAPI,checknetpoll*/
(netpoll_receive_skb
skb_iif
skb
dev->
ifindex;
//记录帧的入口
null_or_orig
NULL;
orig_dev
dev;
master
ACCESS_ONCE
(orig_dev
master);
(master){
(skb_bond_should_drop
/*deliveronlyexactmatch*/
else
dev
skb_reset_network_header(skb);
skb_reset_transport_header(skb);
mac_len
network_header
mac_header
pt_prev
rcu_read_lock();
#ifdefCONFIG_NET_CLS_ACT
(skb->
tc_verd
TC_NCLS){
CLR_TC_NCLS(
ncls;
#endif
//处理ptype_all上所有的packet_type->
func(),这里先提一下Linux是根据packet_type通过
dev_add_pack()函数来注册相应的处理函数,后面会讲如何注册,每种包对应哪个处理函数
//
staticstructlist_headptype_all__read_mostly;
list_for_each_entry_rcu(ptype,
ptype_all
list
(ptype->
==
||
ptype->
||
orig_dev){
(pt_prev)
deliver_skb
//调用相应的包处理函数
ptype;
handle_ing
out;
ncls:
//若编译内核时选上BRIDGE,下面会执行网桥模块
handle_bridge
//编译内核时选上MAC_VLAN模块,下面才会执行
handle_macvlan
*MakesureframesreceivedonVLANinterfacesstackedon
*bondinginterfacesstillmaketheirwaytoanybasebonding
*devicethatmayhaveregisteredforaspecificptype.
The
*handlermayhavetoadjustskb->
devandorig_dev.
null_or_bond
((skb->
priv_flags
IFF_802_1Q_VLAN)
(vlan_dev_real_dev(
dev)->
IFF_BONDING)){
vlan_dev_real_dev
dev);
//最后type=skb->
protocol;
&
ptype_base[ntohs(type)&
15]处理ptype_base[ntohs(type)&
15]上的所有的packet_type->
func(),根据第二层不同协议来进入不同的钩子函数,重要的有:
ip_rcv(),arp_rcv()
type
protocol
list_for_each_entry_rcu(ptype,
ptype_base[ntohs
(type
)&
PTYPE_HASH_MASK],
list){
(ptype
null_or_bond)){
(pt_prev){
func(
skb,
dev,
}
else
/*Jamal,nowyouwillnotabletoescapeexplaining
*mehowyouweregoingtousethis.:
-)
out:
rcu_read_unlock();
ret;
dev_queue_xmit-transmitabuffer
buffertotransmit
Queueabufferfortransmissiontoanetworkdevice.Thecallermust
havesetthedeviceandpriorityandbuiltthebufferbeforecalling
thisfunction.Thefunctioncanbecalledfromaninterrupt.
Anegativeerrnocodeisreturnedonafailure.Asuccessdoesnot
guaranteetheframewillbetransmittedasitmaybedroppeddue
tocongestionortrafficshaping.
*-----------------------------------------------------------------------------------
Inoticethismethodcanalsoreturnerrorsfromthequeuedisciplines,
includingNET_XMIT_DROP,whichisapositivevalue.
So,errorscanalso
bepositive.
Regardlessofthereturnvalue,theskbisconsumed,soitiscurrently
difficulttoretryasendtothismethod.
(Youcanbumptherefcount
beforesendingtoholdareferenceforretryifyouarecareful.)
Whencallingthismethod,interruptsMUSTbeenabled.
Thisisbecause
theBHenablecodemusthaveIRQsenabledsothatitwillnotdeadlock.
--BLG
dev_queue_xmit(
netdev_queue
txq;
Qdisc
q;
rc
=-
ENOMEM;
/*GSOwillhandlethefollowingemulationsdirectly.*/
(netif_needs_gso
(dev
))//如果是GSO数据包,且设备支持GSO数据包的处理
gso;
/*Convertapagedskbtolinear,ifrequired*/
(skb_needs_linearize
__skb_linearize(skb))
out_kfree_skb;
/*Ifpacketisnotchecksummedanddevicedoesnotsupport
*checksummingforthisprotocol,completechecksumminghere.
ip_summed
CHECKSUM_PARTIAL){
skb_set_transport_header(skb,
csum_start
-
skb_headroom(skb));
dev_can_checksum
skb_checksum_help(skb))
gso:
/*Disablesoftirqsforvariouslocksbelow.Also
*stopspreemptionforRCU.
rcu_read_lock_bh();
txq
dev_pick_tx
q
rcu_dereference_bh(txq->
qdisc
SET_TC_AT(
AT_EGRESS
(q->
enqueue
__dev_xmit_skb
/*Thedevicehasnoqueue.Commoncaseforsoftwaredevices:
loopback,allthesortsoftunnels...
Really,itisunlikelythatnetif_tx_lockprotectionisnecessary
here.
(f.e.loopbackandIPtunnelsarecleanignoringstatistics
counters.)
However,itispossible,thattheyrelyonprotection
madebyushere.
Checkthisandshotthelock.Itisnotpronefromdeadlocks.
Eithershotnoqueueqdisc,itisevensimpler8)
(dev->
flag
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据帧收发主要函数及netdevice 结构 数据 收发 主要 函数 netdevice
![提示](https://static.bdocx.com/images/bang_tan.gif)