for many environment:LINUX TC:HTB相关源码
来源:百度文库 编辑:中财网 时间:2024/03/29 13:25:02
LINUX TC:HTB相关源码 收藏
HTB(hierarchy token buffer)是linux tc(traffic control)模块中的排队队列的一种。它的配置比CBQ要简单.同时实现功能也很强大。下面,就来看看,HTB在linux中的源码。
1、 Qdisc_ops的注册
先从module_init函数看起(遵从fudan_abc的建议)static int __init htb_module_init(void){ return register_qdisc(&htb_qdisc_ops);}
上面的code会调用register_qdisc函数,将htb_qdisc_ops注册到系统中,那么htb_qdisc_ops包含了那些内容:static struct Qdisc_ops htb_qdisc_ops __read_mostly = { .cl_ops = &htb_class_ops, .id = "htb", .priv_size = sizeof(struct htb_sched), .enqueue = htb_enqueue, .dequeue = htb_dequeue, .peek = qdisc_peek_dequeued, .drop = htb_drop, .init = htb_init, .reset = htb_reset, .destroy = htb_destroy, .dump = htb_dump, .owner = THIS_MODULE,};
可以看出,htb_qdisc_ops其实就是注册了htb管理queue的函数,最重要的莫过于:enqueue 和dequeue函数,它们作用如同它们的名字一样。那么到底将htb_qdisc_ops注册到那了呢?这就要看看register函数了static struct Qdisc_ops *qdisc_base;/**qdisc_base 就是系统维护所以qdisc所使用的变量,系统中的所有的qdisc都要*注册到这变量变量中*在struct Qdisc_ops中,包含了成员(struct Qdisc_ops *)next*也就是,所以的qdisc是以链表的形式存在的*/ int register_qdisc(struct Qdisc_ops *qops){ struct Qdisc_ops *q, **qp; int rc = -EEXIST; write_lock(&qdisc_mod_lock); /**首先,检测这个qdisc是否已经注册过了,这是通过比较id实现的,*id的类型是char 数组:char id[IFNAMSIZ];IFNAMESIZ=16*htb的id=”htb”*/ for (qp = &qdisc_base; (q = *qp) != NULL; qp = &q->next) if (!strcmp(qops->id, q->id)) goto out;/**然后检测ops中的enqueue、dequeue、peek函数,*如果这些函数都没有被初始化,将使用noop_qdisc_ops函数来初始化*noop_qdisc_ops也是Qdisc_ops结构,*它的作用就像是定义了Qdisc_ops的默认值*/ if (qops->enqueue == NULL) qops->enqueue = noop_qdisc_ops.enqueue; if (qops->peek == NULL) { if (qops->dequeue == NULL) qops->peek = noop_qdisc_ops.peek; else goto out_einval; } if (qops->dequeue == NULL) qops->dequeue = noop_qdisc_ops.dequeue;/**然后检测cl_ops成员。*cl_ops是结构Qdisc_class_ops,*它定义了用于管理挂载到这个qdisc下的所有class(或者qdisc)*/ if (qops->cl_ops) { const struct Qdisc_class_ops *cops = qops->cl_ops; if (!(cops->get && cops->put && cops->walk && cops->leaf)) goto out_einval; if (cops->tcf_chain && !(cops->bind_tcf && cops->unbind_tcf)) goto out_einval; }/**最后将新的qops插入到链表的尾部:*qp = qops;*这样就注册完成了*/ qops->next = NULL; *qp = qops; rc = 0;out: write_unlock(&qdisc_mod_lock); return rc; out_einval: rc = -EINVAL; goto out;}EXPORT_SYMBOL(register_qdisc);
Qdisc_class_ops是管理这个tree的,那么看看htb的cl_ops有哪些函数:static const struct Qdisc_class_ops htb_class_ops = { .graft = htb_graft, .leaf = htb_leaf, .qlen_notify = htb_qlen_notify, .get = htb_get, .put = htb_put, .change = htb_change_class, .delete = htb_delete, .walk = htb_walk, .tcf_chain = htb_find_tcf, .bind_tcf = htb_bind_filter, .unbind_tcf = htb_unbind_filter, .dump = htb_dump_class, .dump_stats = htb_dump_class_stats,};
我们知道,tc qdisc命令添加qdisc到某个设备后,为了对数据包进行分类,需要使用tc filter 来添加fitler到某个qdisc, 当数据包来时,通过fitler来区分数据包,并转发到不同的subqdisc 或者subclass。而绑定fitler都是通过函数:bind_tcf来实现的。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/csalp/archive/2011/05/23/6439727.aspx
HTB(hierarchy token buffer)是linux tc(traffic control)模块中的排队队列的一种。它的配置比CBQ要简单.同时实现功能也很强大。下面,就来看看,HTB在linux中的源码。
1、 Qdisc_ops的注册
先从module_init函数看起(遵从fudan_abc的建议)static int __init htb_module_init(void){ return register_qdisc(&htb_qdisc_ops);}
上面的code会调用register_qdisc函数,将htb_qdisc_ops注册到系统中,那么htb_qdisc_ops包含了那些内容:static struct Qdisc_ops htb_qdisc_ops __read_mostly = { .cl_ops = &htb_class_ops, .id = "htb", .priv_size = sizeof(struct htb_sched), .enqueue = htb_enqueue, .dequeue = htb_dequeue, .peek = qdisc_peek_dequeued, .drop = htb_drop, .init = htb_init, .reset = htb_reset, .destroy = htb_destroy, .dump = htb_dump, .owner = THIS_MODULE,};
可以看出,htb_qdisc_ops其实就是注册了htb管理queue的函数,最重要的莫过于:enqueue 和dequeue函数,它们作用如同它们的名字一样。那么到底将htb_qdisc_ops注册到那了呢?这就要看看register函数了static struct Qdisc_ops *qdisc_base;/**qdisc_base 就是系统维护所以qdisc所使用的变量,系统中的所有的qdisc都要*注册到这变量变量中*在struct Qdisc_ops中,包含了成员(struct Qdisc_ops *)next*也就是,所以的qdisc是以链表的形式存在的*/ int register_qdisc(struct Qdisc_ops *qops){ struct Qdisc_ops *q, **qp; int rc = -EEXIST; write_lock(&qdisc_mod_lock); /**首先,检测这个qdisc是否已经注册过了,这是通过比较id实现的,*id的类型是char 数组:char id[IFNAMSIZ];IFNAMESIZ=16*htb的id=”htb”*/ for (qp = &qdisc_base; (q = *qp) != NULL; qp = &q->next) if (!strcmp(qops->id, q->id)) goto out;/**然后检测ops中的enqueue、dequeue、peek函数,*如果这些函数都没有被初始化,将使用noop_qdisc_ops函数来初始化*noop_qdisc_ops也是Qdisc_ops结构,*它的作用就像是定义了Qdisc_ops的默认值*/ if (qops->enqueue == NULL) qops->enqueue = noop_qdisc_ops.enqueue; if (qops->peek == NULL) { if (qops->dequeue == NULL) qops->peek = noop_qdisc_ops.peek; else goto out_einval; } if (qops->dequeue == NULL) qops->dequeue = noop_qdisc_ops.dequeue;/**然后检测cl_ops成员。*cl_ops是结构Qdisc_class_ops,*它定义了用于管理挂载到这个qdisc下的所有class(或者qdisc)*/ if (qops->cl_ops) { const struct Qdisc_class_ops *cops = qops->cl_ops; if (!(cops->get && cops->put && cops->walk && cops->leaf)) goto out_einval; if (cops->tcf_chain && !(cops->bind_tcf && cops->unbind_tcf)) goto out_einval; }/**最后将新的qops插入到链表的尾部:*qp = qops;*这样就注册完成了*/ qops->next = NULL; *qp = qops; rc = 0;out: write_unlock(&qdisc_mod_lock); return rc; out_einval: rc = -EINVAL; goto out;}EXPORT_SYMBOL(register_qdisc);
Qdisc_class_ops是管理这个tree的,那么看看htb的cl_ops有哪些函数:static const struct Qdisc_class_ops htb_class_ops = { .graft = htb_graft, .leaf = htb_leaf, .qlen_notify = htb_qlen_notify, .get = htb_get, .put = htb_put, .change = htb_change_class, .delete = htb_delete, .walk = htb_walk, .tcf_chain = htb_find_tcf, .bind_tcf = htb_bind_filter, .unbind_tcf = htb_unbind_filter, .dump = htb_dump_class, .dump_stats = htb_dump_class_stats,};
我们知道,tc qdisc命令添加qdisc到某个设备后,为了对数据包进行分类,需要使用tc filter 来添加fitler到某个qdisc, 当数据包来时,通过fitler来区分数据包,并转发到不同的subqdisc 或者subclass。而绑定fitler都是通过函数:bind_tcf来实现的。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/csalp/archive/2011/05/23/6439727.aspx
linux 源码
linux 源码问题
LINUX相关
linux相关问题
linux相关问题
Linux相关问题
LINUX系统相关问题
谁知道在那儿下载 linux的源码
无线 UBS网卡 linux 驱动程序源码
在那里可以下到LINUX的源码
linux可以运行photoshop,tc,3d这些软件么?
想编好的程序,应多看吗?linux的源码在哪里?
如何可以得到Linux Fedora下的网卡驱动源码
Linux中的串口驱动源码文件在哪?
linux源码是用什么语言开发的
源码!!
如何安装linux?及相关组件?
linux操作系统服务器分区相关原理
菜鸟寻求Linux DOS的相关信息
LINUX相关的软件在那下载
求active shape model 的c++源码 及 相关资料
想学做博客网站,哪里有相关的源程序或者源码下载或者相关资料参考啊?
linux 系统下能安qq 吗? 有相关的软件吗?
有谁能介绍一下Linux操作系统的相关背景知识