建设网站宽度最好是多少,wordpress基础优化,wordpress漂亮破解主题,南京哪个网站做物业贷LINUX TC:HTB相关源码 收藏HTB(hierarchy token buffer)是linux tc(traffic control)模块中的排队队列的一种。它的配置比CBQ要简单.同时实现功能也很强大。下面#xff0c;就来看看#xff0c;HTB在linux中的源码。1、 Qdisc_ops的注册先从module_init函数看起(…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];IFNAMESIZ16*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;elsegoto 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来实现的。