ImageVerifierCode 换一换
格式:DOCX , 页数:21 ,大小:216.15KB ,
资源ID:5767732      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5767732.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(数据帧收发主要函数及netdevice 结构.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

数据帧收发主要函数及netdevice 结构.docx

1、数据帧收发主要函数及netdevice 结构*netif_rx-post buffer to the network code*skb: buffer to post*This function receives a packet from a device driver and queues it for*the upper (protocol) levels to process. It always succeeds. The buffer*may be dropped during processing for congestion control or by the*protocol

2、 layers.*return values:*NET_RX_SUCCESS(no congestion)*NET_RX_DROP (packet was dropped)*/intnetif_rx(structsk_buff*skb)structsoftnet_data*queue;unsignedlongflags;/* if netpoll wants it, pretend we never saw it */if(netpoll_rx(skb)returnNET_RX_DROP;if(!skb-tstamp.tv64) /得到帧接收的时间net_timestamp(skb);/* *

3、 The code is rearranged so that the path is the most * short when CPU is congested, but is still operating. */local_irq_save(flags);queue=&_get_cpu_var(softnet_data);/获取当前CPU的 softnet_data 数据 _get_cpu_var(netdev_rx_stat).total+;/当前CPU接收的帧数+1if(queue-input_pkt_queue.qleninput_pkt_queue.qlen) enqueue:

4、 /将该帧加入到softnet_data队列 _skb_queue_tail(&queue-input_pkt_queue,skb);local_irq_restore(flags);returnNET_RX_SUCCESS;/当队列是空的时候,表明这个队列并没有被软中断所schedule,因此我们需要将此队列加入到软中断的处理链表中。可以看到加入的正好是backlog,由于调用netif_rx的是非napi的驱动,因此backlog就是初始化时的process_backlog函数。napi_schedule(&queue-backlog);gotoenqueue;_get_cpu_var(n

5、etdev_rx_stat).dropped+;local_irq_restore(flags);kfree_skb(skb);returnNET_RX_DROP;/ 上面代码中用到一个关键的数据结构 softnet_data ,在网卡收发数据的时候,需要维护一个缓冲区队列,来缓存可能存在的突发数据,在协议栈中用一个队列层来表示该缓冲区,队列层位于数据链路层和网络层之间。softnet_data 就是数据链路层中的数据结构,它是一个Per-CPU变量,每个CPU都有一个/*netif_receive_skb - process receive buffer from network*skb:

6、buffer to process*netif_receive_skb() is the main receive data processing function.*It always succeeds. The buffer may be dropped during processing*for congestion control or by the protocol layers.*This function may only be called from softirq context and interrupts*should be enabled.*Return values

7、(usually ignored):*NET_RX_SUCCESS: no congestion*NET_RX_DROP: packet was dropped*/netif_receive_skb 是对于 netif_rx 的 NAPI 对等函数; 它递交一个报文给内核. 当一个 NAPI 兼容的驱动已耗尽接收报文的供应, 它应当重开中断, 并且调用 netif_rx_complete(现在是_napi_complete() 来停止轮询.intnetif_receive_skb(structsk_buff*skb)structpacket_type*ptype, *pt_prev;struc

8、tnet_device*orig_dev;structnet_device*master;structnet_device*null_or_orig;structnet_device*null_or_bond;intret=NET_RX_DROP;_be16 type;if(!skb-tstamp.tv64)net_timestamp(skb);if(vlan_tx_tag_present(skb)&vlan_hwaccel_do_receive(skb)returnNET_RX_SUCCESS;/* if weve gotten here through NAPI, check netpol

9、l */if(netpoll_receive_skb(skb)returnNET_RX_DROP;if(!skb-skb_iif)skb-skb_iif=skb-dev-ifindex;/ 记录帧的入口null_or_orig=NULL;orig_dev=skb-dev;master=ACCESS_ONCE(orig_dev-master);if(master) if(skb_bond_should_drop(skb,master)null_or_orig=orig_dev;/* deliver only exact match */elseskb-dev=master;_get_cpu_va

10、r(netdev_rx_stat).total+;skb_reset_network_header(skb);skb_reset_transport_header(skb);skb-mac_len=skb-network_header-skb-mac_header;pt_prev=NULL;rcu_read_lock();#ifdef CONFIG_NET_CLS_ACTif(skb-tc_verd&TC_NCLS) skb-tc_verd=CLR_TC_NCLS(skb-tc_verd);gotoncls;#endif /处理 ptype_all 上所有的 packet_type-func(

11、) ,这里先提一下Linux 是根据packet_type 通过dev_add_pack() 函数来注册相应的处理函数,后面会讲如何注册,每种包对应哪个处理函数 /static struct list_head ptype_all _read_mostly; list_for_each_entry_rcu(ptype,&ptype_all,list) if(ptype-dev=null_or_orig|ptype-dev=skb-dev|ptype-dev=orig_dev) if(pt_prev)ret=deliver_skb(skb,pt_prev,orig_dev);/调用相应的包处理函

12、数pt_prev=ptype;#ifdef CONFIG_NET_CLS_ACTskb=handle_ing(skb,&pt_prev,&ret,orig_dev);if(!skb)gotoout;ncls:#endif /若编译内核时选上BRIDGE,下面会执行网桥模块skb=handle_bridge(skb,&pt_prev,&ret,orig_dev);if(!skb)gotoout; /编译内核时选上MAC_VLAN模块,下面才会执行skb=handle_macvlan(skb,&pt_prev,&ret,orig_dev);if(!skb)gotoout;/* * Make sur

13、e frames received on VLAN interfaces stacked on * bonding interfaces still make their way to any base bonding * device that may have registered for a specific ptype. The * handler may have to adjust skb-dev and orig_dev. */null_or_bond=NULL;if(skb-dev-priv_flags&IFF_802_1Q_VLAN)&(vlan_dev_real_dev(s

14、kb-dev)-priv_flags&IFF_BONDING) null_or_bond=vlan_dev_real_dev(skb-dev);/最后 type = skb-protocol; &ptype_basentohs(type)&15处理ptype_basentohs(type)&15上的所有的 packet_type-func(),根据第二层不同协议来进入不同的钩子函数,重要的有:ip_rcv(), arp_rcv()type=skb-protocol;list_for_each_entry_rcu(ptype,&ptype_basentohs(type) &PTYPE_HASH_

15、MASK,list) if(ptype-type=type&(ptype-dev=null_or_orig|ptype-dev=skb-dev|ptype-dev=orig_dev|ptype-dev=null_or_bond) if(pt_prev)ret=deliver_skb(skb,pt_prev,orig_dev);pt_prev=ptype;if(pt_prev) ret=pt_prev-func(skb,skb-dev,pt_prev,orig_dev);elsekfree_skb(skb);/* Jamal, now you will not able to escape ex

16、plaining * me how you were going to use this. :-) */ret=NET_RX_DROP;out:rcu_read_unlock();returnret;/*dev_queue_xmit - transmit a buffer*skb: buffer to transmit*Queue a buffer for transmission to a network device. The caller must*have set the device and priority and built the buffer before calling*t

17、his function. The function can be called from an interrupt.*A negative errno code is returned on a failure. A success does not*guarantee the frame will be transmitted as it may be dropped due*to congestion or traffic shaping.* -* I notice this method can also return errors from the queue disciplines

18、,* including NET_XMIT_DROP, which is a positive value. So, errors can also* be positive.* Regardless of the return value, the skb is consumed, so it is currently* difficult to retry a send to this method. (You can bump the ref count* before sending to hold a reference for retry if you are careful.)*

19、 When calling this method, interrupts MUST be enabled. This is because* the BH enable code must have IRQs enabled so that it will not deadlock.* -BLG*/intdev_queue_xmit(structsk_buff*skb)structnet_device*dev=skb-dev;structnetdev_queue*txq;structQdisc*q;intrc= -ENOMEM;/* GSO will handle the following

20、 emulations directly. */if(netif_needs_gso(dev,skb)/如果是GSO数据包,且设备支持GSO数据包的处理gotogso;/* Convert a paged skb to linear, if required */if(skb_needs_linearize(skb,dev)&_skb_linearize(skb)gotoout_kfree_skb;/* If packet is not checksummed and device does not support * checksumming for this protocol, compl

21、ete checksumming here. */if(skb-ip_summed=CHECKSUM_PARTIAL) skb_set_transport_header(skb,skb-csum_start-skb_headroom(skb);if(!dev_can_checksum(dev,skb)&skb_checksum_help(skb)gotoout_kfree_skb;gso:/* Disable soft irqs for various locks below. Also * stops preemption for RCU. */rcu_read_lock_bh();txq=

22、dev_pick_tx(dev,skb);q=rcu_dereference_bh(txq-qdisc);#ifdef CONFIG_NET_CLS_ACTskb-tc_verd=SET_TC_AT(skb-tc_verd,AT_EGRESS);#endifif(q-enqueue) rc=_dev_xmit_skb(skb,q,dev,txq);gotoout;/* The device has no queue. Common case for software devices: loopback, all the sorts of tunnels. Really, it is unlik

23、ely that netif_tx_lock protection is necessary here. (f.e. loopback and IP tunnels are clean ignoring statistics counters.) However, it is possible, that they rely on protection made by us here. Check this and shot the lock. It is not prone from deadlocks. Either shot noqueue qdisc, it is even simpler 8) */if(dev-flag

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1