China Open source community
站内导航:

 
 
 
当前位置: 首页 >> 开源操作系统 >> Linux 2.4.x 网络协议栈QoS模块(TC)的设计与实现
 

Linux 2.4.x 网络协议栈QoS模块(TC)的设计与实现

作者:祝顺民 (getmoon@163.com)      来源:     发表时间:2006-03-02     浏览次数:      字号:    

isc) { ………….. for (prio=0; prio < 3; prio++) skb_queue_purge(list+prio); /*释放3个优先级队列中的所有数据包*/ ………….. }

在数据包发送的时候会调用Qdisc->enqueue函数(在qdisc_create_dflt函数中已经将Qdisc_ops的enqueue,dequeue,requeue函数分别赋值于Qdisc分别对应的函数指针)。


int dev_queue_xmit(struct sk_buff *skb)
{
……………….
    q = dev->qdisc;
    if (q->enqueue) {
	   /* 对应于pfifo_fast_enqueue 函数*/
        int ret = q->enqueue(skb, q);
	   /*启动这个设备的发送,这里涉及到两个函数pfifo_fast_dequeue ,pfifo_fast_requeue 稍后介绍*/
        qdisc_run(dev);
        return;
    }
……………
}

入队列函数pfifo_fast_enqueue:


static int
pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc* qdisc)
{
…………..
	list = ((struct sk_buff_head*)qdisc->data) +
		prio2band[skb->priority&TC_PRIO_MAX];
		/*首先确定这个数据包的优先级,决定放入的队列*/

	if (list->qlen <= skb->dev->tx_queue_len) {
		__skb_queue_tail(list, skb);	/*将数据包放入队列的尾部*/
		qdisc->q.qlen++;
		return 0;
	}
……………..
}

在数据包放入队列之后,调用qdisc_run来发送数据包。


static inline void qdisc_run(struct net_device *dev)
{
	while (!netif_queue_stopped(dev) &&
	       qdisc_restart(dev)<0)
		/* NOTHING */;
}

在qdisc_restart函数中,首先从队列中取出一个数据包(调用函数pfifo_fast_dequeue)。然后调用网卡驱动的发送函数(dev->hard_start_xmit)发送数据包,如果发送失败,则需要将这个数据包重新压入队列(pfifo_fast_requeue),然后启动协议栈的发送软中断进行再次的发送。


static struct sk_buff *
pfifo_fast_dequeue(struct Qdisc* qdisc)
{
…………..
	for (prio = 0; prio < 3; prio++, list++) {
		skb = __skb_dequeue(list);
		if (skb) {
			qdisc->q.qlen--;
			return skb;
		}
	}
……………….
}

从dequeue函数中可以看出,pfifo的策略是:从高优先级队列中取出数据包,只有高优先级的队列为空,才会对下一优先级的队列进行处理。

requeue函数重新将数据包压入相应优先级队列的头部。


static int
pfifo_fast_requeue(struct sk_buff *skb, struct Qdisc* qdisc)
{
	struct sk_buff_head *list;

	list = ((struct sk_buff_head*)qdisc->data) +
		prio2band[skb->priority&TC_PRIO_MAX];
		/*确定相应优先级的队列*/
	__skb_queue_head(list, skb);/*将数据包压入队列的头部*/
	qdisc->q.qlen++;
	return 0;
}

总结:

QoS是当前一个非常热门的话题,几乎所有高端的网络设备都支持QoS功能,并且这个功能也是当前网络设备之间竞争的一个关键技术。Linux为了在在高端服务器能够占有一席之地,从2.2.x内核开始就支持了QoS。本文在linux 2.4.0的代码基础上对Linux如何支持QoS进行了分析。并且分析了Linux内核的缺省队列处理方法PFIFO的实现。

参考文献:

(1) linux 2.4.0 内核源代码。

作者简介:

祝顺民,网名:getmoon。目前从事防火墙开发,致力于网络的研究和开发,分析linux内核。经常出没于http://www.linuxforum.net/的内核板块。希望于爱好者们共同探讨。email:getmoon@163.com


[1] [2]

编辑 webmaster

 
 
 
评论
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •  
    中国源码网 - WWW.YUANMA.ORG - 中国开放源代码社区