Linux内核中流量控制_第1页
Linux内核中流量控制_第2页
Linux内核中流量控制_第3页
Linux内核中流量控制_第4页
Linux内核中流量控制_第5页
已阅读5页,还剩360页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、这份文件的复印件属于yfydz。它由GPL出版,可以自由复制。重印时请保持文件的完整性。严禁将其用于任何商业目的。MSN : yfydz_资料来源:1.前言linux内核为流量控制提供了相关的处理功能,相关的代码在net/sched目录中。应用层的控制是通过iproute2软件包中的tc实现的。tc和sched之间的关系就像iptables和netfilter之间的关系一样。一个是用户层接口,另一个是具体实现。对于tc的使用,可以详细了解Linux高级路由方法。本文主要分析了在内核中的具体实现。流量控制包括:流量控制算法的几

2、个部分,通常在net/sched/sch _ *中实现。默认是先进先出,这是一个典型的黑盒模式。外部只能看到两个操作,即队列进入和队列退出。流量控制结构的操作和处理;并且通过以下方式控制用户空间Rtnetlink。以下内核代码版本是。2.控制入口2.1控制条目linux流控制功能反映为网卡设备的属性,表明它是网络的最低处理部分,与上层网络协议栈:无关/* include/linux/netdevice.h */struct网络设备./*缓存行主要用于队列传输路径(qdisc)*/*设备队列锁定*/spin lock _ t queue _ lock _ _ _ _ _ cach

3、e line _ aligned _ in _ SMP。/这是发送数据时的队列处理结构Qdisc*qdisc。/网卡停止时保存网卡活动的队列处理方法结构Qdisc * qdisc _ sleeping/网卡处理的数据队列链表结构列表_headqdisc_list。/最大队列长度无符号longtx _ queue _ len/*每个队列允许的最大帧数*/*部分传输的GSO数据包。*/struct sk _ buff * gso _ skb/*入口路径同步器*/输入流量控制锁spinlock _ tingress _ lock/这是接收数据时的队列处理结构Qdisc * Qdisc _ entry

4、;.2.1.2输出流量控制当数据发送出去进行流量控制处理时,上层的所有处理都已经完成,数据包已经传送到网卡设备进行传输,与流量控制处理相关的网络数据的导出功能为dev _ queue _ xmit();如果它正在接收流量控制,则数据刚刚从网卡设备接收到,还没有提交给网络的上层进行处理。然而,网卡的输入流控制不是必需的,并且默认情况下不执行流控制。输入流控制入口函数是ing_filter()函数,由skb_receive_skb()调用。/* net/core/dev.c */int dev_queue_xmit(结构sk_buff *skb)struct net _ device * dev=

5、skb-dev;结构Qdisc * RC=-ENOMEM;./* qdisc的更新由queue_lock序列化。* Qdisc指向的结构Qdisc现在是一个*区域协调股结构-可以在不获取的情况下获取*锁(但结构可能已经过时。)的解放* qdisc将被推迟,直到它知道没有*更多参考。*如果qdisc具有入队功能,我们仍然需要*在调用队列_锁之前保持队列_锁,因为队列_锁*还序列化对设备队列的访问。*/获取网卡的qdisc指针,它不需要加锁,是每个CPU的私有数据。q=rcu _ de reference(dev-q disc);#ifdef CONFIG_NET_CLS_ACTskb-

6、TC _ verd=SET _ TC _ AT(skb-TC _ verd,AT _ EXCEPT);#endif/如果队列输入不为空,则将数据包排队/对于物理网卡设备,默认情况下使用先进先出qdisc。此成员函数不为空,仅使用逻辑网卡/只能为空如果(q-入队)/*抓取设备队列*/锁定自旋锁(开发队列锁);/dev-qdisc可以直接访问q=dev-q disc;如果(q-入队)/进入团队进行处理RC=q-入队(skb,q);/运行流量控制和队列操作qdisc _ run(dev);旋转解锁(开发队列锁定);rc=rc=NET_XMIT_BYPASS?NET _ XMIT _ SUCCESS

7、: rc出去;旋转解锁(开发队列锁定);./团队外操作静态内嵌void qdisc _ run(struct net _ device * dev)如果(!netif_queue_stopped(dev)!测试和设置位(_ _链接_状态_ QDISC _运行,开发状态)_ _ qdisc _ run(dev);/* net/sched/sch_generic.c */void _ _ qdisc _ run(struct net _ device * dev)/如果是noop_qdisc流量控制,实际上是丢包if(不太可能(dev-qdisc=noop_qdisc)出去;同时(qdisc_re

8、start(dev) 0!netif_queue_stopped(dev)/*无*/;out:清零位(_ _链接_状态_ QDISC _运行,开发状态);/*踢腿装置。请注意,该过程可以由看门狗定时器调用,因此我们这里不检查dev-tbusy标志。返回3360 0 -队列为空。0 -队列不为空,但已节流。0 -队列不为空。设备已被节流,如果开发失败!=0 .注:在本地禁用的进程队列锁定下调用。*/静态内联int qdisc_restart(结构网络_设备*开发)结构Qdisc *q=dev-qdisc .struct sk _ buff * skb/*出队数据包*/数据包出队if(skb=de

9、v-GSO _ skb)| |(skb=q-出列(q)无符号nolock=(开发特性NETIF _ F _ LLTX);dev-gso_skb=空;.2.1.3输入流控输入流控好象不是必须的,目前内核需要配置CLS法案选项才起作用:/* net/core/dev.c */int netif_receive_skb(结构sk_buff *skb).#ifdef CONFIG_NET_CLS_ACTif (pt_prev) ret=deliver_skb(skb,pt_prev,orig _ dev);pt_prev=空;/*在*/其他skb-TC _ verd=SET _ TC _ OK2 UN

10、GE(skb-TC _ verd);ret=ing _ filter(skb);if(ret=TC _ ACT _ SHOT | |(ret=TC _ ACT _ STORE)kfree _ skb(skb);出去;skb-TC _ verd=0;ncls:#endif.静态int _ filter(struct sk _ buff * skb)结构Qdisc *q .struct net _ device * dev=skb-dev;内部结果=正常;/如果网卡设备有输入流控处理if(dev-qdisc _ entry)_ _ u32 TTL=(_ _ u32)RTTL;如果(最大红色循环时间

11、)printk(KERN_WARNING Redir循环检测到丢弃数据包(%s-%)s)n ,skb-input_dev-name,skb-dev-name);返回动作镜头/设置数据包的TC参数skb-TC _ verd=SET _ TC _ RTTL(skb-TC _ verd,TTL);skb-TC _ verd=SET _ TC _ AT(skb-TC _ verd,AT _ ENTRY);自旋锁(开发入口锁);if(q=dev-qdisc _ entry)!=空)/数据入队结果=q-入队(skb,q);旋转解锁(开发入口锁定);返回结果;2.2初始化本节先跟踪一下网卡设备的qdisc指

12、针是如何被赋值的,缺省赋值为何值。在网卡设备的初始化函数register_netdevice()函数中调用dev_init_scheduler()函数对网卡设备的流控队列处理进行了初始化,也就是说每个网络网卡设备的qdisc指针都不会是空的:/* net/sched/sch_gentric.c */void dev_init_scheduler(结构网络_设备*开发)qdisc _ lock _ tree(dev);/处理发出数据的qdisc是必须的,而处理输入数据的qdisc _ entry则不是必须的/缺省情况下的qdiscdev-qd disc=noop _ qd disc .dev-q

13、d光盘_ sleeping=noop _ qd光盘;初始化_列表_标题(dev-q光盘_列表);qdisc _ unlock _ tree(dev);dev _ watchdog _ init(dev);当然noop _ qd盘中的调度是不可用的,只进行丢包处理;网卡在激活(dev_open)时会调用dev_activate()函数重新对qdisc指针赋值,但未对qdisc _ entry赋值:/* net/sched/sch_generic.c */void dev _ activate(struct net _ device * dev)/*设备没有附加排队规则;为设备创建默认设置,即pfifo_fast,哪个需要排队和noqueue_qdisc虚拟接口*/如果当前的qdisc_sleeping是noop _ qdisc,重新找一个流控操作指针i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论