1 Net_cls
1.1 原理
net_cls子系统是用来控制进程使用网络资源的,它并不直接控制网络读写,而是给网络包打上一个标记,具体的网络包控制由tc机制来处理。
net_cls实现的基本的思想就是将控制组和内核现有的网络包分类和调度的机制相关联。net_cls通过给控制组分配一个类标识符(classid)来指定该控制组的数据包将被分到哪个traffic class(net_cls只支持可分类的qdsic队列规则)。数据包在发送的时候会根据添加到设备qdisc上的cgroup filter将数据包分到与其classid相符的traffic class队列中,再由设备上设置的具体qdsic来控制数据包的发送,以达到控制网络资源使用的目的。
创建一个挂有net_cls的cgroup后,在其下会生有个名为net_cls.classid(默认初始值为0)的文件,通过这个文件指定该组进程相关的数据包进入哪个traffic class。通过向文件写入形如0xAAAABBBB的十六进制值(AAAA为主处理号,BBBB为次处理号,读取该值是以十进制显示),设置cgroup的classid后,再进行相应的tc配置,添加符合classid的traffic class,并使用cgroup filter。这样当cgroup中的进程需要使用网络接口发送数据包的时候,则会按照接口上classid相应的tc策略控制进程对网络资源的使用。
整体形式如下:
1.2 实现
net_cls中对应的核心数据结构为
structcgroup_cls_state{
struct cgroup_subsys_state css; //对应cgroup子系统状态描述符css
u32 classid; //用用于记录该cgroup的classid
};
cgroup_cls_state记录了该组设置的classid,对net_cls.classid读写时操作的就是这个值。在发送数据包过程中,内核会将进程所在的cgroup的classid存储在skb->sk->sk_classid中。
为了能和tc机制结合,net_cls模块添加了一个名为cgroup的filter,其相应的操作函数结构如下:
staticstruct tcf_proto_ops cls_cgroup_ops __read_mostly = {
.kind