美文网首页
traffic control

traffic control

作者: 分享放大价值 | 来源:发表于2020-11-01 12:41 被阅读0次

    tc 队列规则分为四大类:ingress,clsact,classless和classful。
    ingress
    Linux中的QoS分为入口(Ingress)部分和出口(Egress)部分,入口部分主要用于进行入口流量限速(policing),出口部分主要用于队列调度(queuing scheduling)。

    大多数排队规则(qdisc)都是用于输出方向的,输入方向只有一个排队规则,即ingress qdisc。ingress qdisc本身的功能很有限,但可用于重定向incoming packets。通过Ingress qdisc把输入方向的数据包重定向到虚拟设备ifb,而ifb的输出方向可以配置多种qdisc,就可以达到对输入方向的流量做队列调度的目的。

    The ingress qdisc itself does not require any parameters. It differs from other 
    qdiscs in that it does not occupy the root of a device. Attach it like this:
    # tc qdisc add dev eth0 ingress
    This allows you to have other, sending qdiscs on your device besides the ingress qdisc.
    
    Ingress qdisc (known as ffff:) can't have any children classes. (hence the 
    existence of IMQ) The only thing you can do with the ingress qdisc is attach 
    filters.
    # tc qdisc add dev eth0 ingress
    # tc filter add dev eth0 parent ffff: protocol ip prio 10 u32 match ip src 0.0.0.0/0 police rate 2048kbps burst 1m drop flowid :1
    

    clsact
    clsact主要用于bpf的hook点。clsact qdisc提供两个特殊的钩子称为ingress和egress,让classifier可以附加上去。ingress和egress的钩子都位于网络数据路径的中心接收和发送位置,设备上的每个包都在这里通过。
    ingress钩子从__netif_receive_skb_core() -> sch_handle_ingress()调用,
    egress钩子从__dev_queue_xmit() -> sch_handle_egress()调用。

    classless 无类队列
    用作根队列或者叶子队列,而且不能设置filter规则,常见的无类队列如下:

    [p|b]fifo: 使用最简单的qdisc(排队规则),纯粹的先进先出。只
    有一个参数:limit ,用来设置队列的长度。
    pfifo是以数据包的个数为单位;bfifo是以字节数为单位。
    
    pfifo_fast: 在编译内核时,如果打开了"Advanced Router"编译选
    项,pfifo_fast就是系统的标准qdisc(排队规则)。它的队列包括三个
    band。在每个band里面,使用先进先出规则。而三个band的优先
    级也不相同,band 0 的优先级最高,band 2的最低。如果band 0
    里面有数据包,系统就不会处理band 1 里面的数据包,band 1 和 
    band 2 之间也是一样的。数据包是按照服务类型(Type Of 
    Service,TOS )被分配到三个band里面的。
    
    red: red是Random Early Detection(随机早期探测)的简写。如
    果使用这种qdsic,当带宽的占用接近与规定的带宽时,系统会随
    机的丢弃一些数据包。他非常适合高带宽的应用。
    
    sfq: sfq是Stochastic Fairness Queueing 的简写。它会按照会话
    (session --对应与每个TCP 连接或者UDP流)为流量进行排序,然
    后循环发送每个会话的数据包。
    
    tbf: tbf是 Token Bucket Filter 的简写,适用于把流速降低到某个值。
    

    无类队列的设置

    如果没有可分类qdisc,不可分类qdisc 只能附属于设备的根。
    它们的用法如下:
    #给设备dev添加根队列(指定了root就是根队列)
    tc qdisc add dev DEV root QDISC QDISC_PARAMETERS
    
    #要删除一个不可分类qdisc,需要使用如下命令
    tc qdisc del dev DEV root
    
    一个网络接口上如果没有设置qdisc,pfifo_fast就作为缺省的
    qdisc。可通过"ip link show dev DEV"查看默认或者设置的qdisc。
    
    #比如给网卡eth0设置根队列tbf
    tc qdisc add dev eth0 root tbf rate 1024kbit limit 1024kbit burst 1024
    

    classful 分类队列
    可分类QDISC包括

    CBQ: CBQ是 Class Based Queueing(基于类别排队)的缩写。
    它实现了一个丰富的连接共享类别结构,既有限制(shaping)带
    宽的能力,也具有带宽优先级别管理的能力。带宽限制是通过计算
    连接的空闲时间完成的。空闲时间的计算标准是数据包离队事件的
    频率和下层连接(数据链路层)的带宽。
            
    HTB: HTB是Hierarchy Token Bucket 的缩写。通过在实践基础上
    的改进,它实现一个丰富的连接共享类别体系。使用HTB可以很容
    易地保证每个类别的带宽,虽然它也允许特定的类可以突破带宽上
    限,占用别的类的带宽。HTB可以通过TBF(Token Bucket 
    Filter)实现带宽限制,也能够划分类别的优先级。
    
    PRIO: PRIO qdisc 不能限制带宽,因为属于不同类别的数据包是
    顺序离队的。使用PRIO qdisc 可以很容易对流量进行优先级管
    理,只有属于高优先级类别的数据包全部发送完毕,参会发送属于
    低优先级类别的数据包。为了方便管理,需要使用iptables 或者 
    ipchains 处理数据包的服务类型(Type Of Service,TOS)。
    

    有类队列的设置

    Linux流量控制主要分为建立队列、建立分类和建立过滤器三个方面。
    基本实现步骤:
    1) 针对网络物理设备(如以太网卡eth0)绑定一个队列qdisc;
    2) 在该队列上建立分类class;
    3) 为每一分类建立一个基于路由的过滤器filter;
    4) 最后与过滤器相配合,建立特定的路由表。
    
    环境模拟实例。
    流量控制器上的以太网卡(eth0)的IP地址为 192.168.1.66, 在其上建立一
    个CBQ队列。假设包的平均大小为1000字节,包间隔发送单元的大小为8字
    节,可接收冲突的发送最长包的数目为20字节。
       
    假如有如下三种类型的流量需要控制:
    1)发往主机1的,其IP地址为192.168.1.24。其流量带宽控制在8Mbit,优先级为 2;
    2)发往主机2的,其IP地址为192.168.1.30。其流量带宽控制在1Mbit,优先级为1;
    3)发往子网1的,其子网号为192.168.1.0。子网掩码为255.255.255.0。流量带宽控制在1Mbit,优先级为6。
    
    a. 建立队列
    一般情况下,针对一个网卡只需建立一个队列。
             tc qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit avpkt 1000 cell 8 mpu 64
    
    b. 建立分类
    一般情况下,针对一个队列需建立一个根分类,然后再在其上建立子分类。
    对于分类,按其分类的编号顺序起作用,编号小的优先;一但符合某个分类
    匹配规则,通过该分类发送数据包,则其后的分类不再起作用。
    1) 创建根分类1:1;分配带宽为10Mbit,优先级别为8。
    该队列的最大可用带宽为10Mbit,实际分配的带宽为10Mbit,可接收
    冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为
    1514字节,优先级别为8,包的平均大小为1000字节,包间隔发送单
    元的大小为8字节,相当于实际带宽的加权速率为1Mbit。
             tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate 10Mbit maxburst 20 allot 1514 prio 8 avpkt 1000 cell 8 weight 1Mbit
    
    2) 创建分类1:2,其父类为1:1,分配带宽为 8Mbit, 优先级别为2。
    该队列的最大可用带宽为10Mbit,实际分配的带宽为8Mbit,可接收
    冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为
    1514字节,优先级别为2,包的平均大小为1000字节,包间隔发送单
    元的大小为8字节,相当于实际带宽的加权速率为800Kbit,分类的分离点为1:0,且不可借用未使用带宽。
             tc class add dev eth0 parent 1:1 classid 1:2 cbq bandwidth 10Mbit rate 8Mbit maxburst 20 allot 1514 prio 2 avpkt 1000 cell 8 weight 800Kbit split 1:0 bounded
    
    3) 创建分类1:3,其父分类为1:1,分配带宽为1Mbit,优先级别为1。
    该队列的最大可用带宽是10Mbit,实际分配的带宽为1Mbit,可接收冲
    突的发送最长包数目为20字节;最大传输单元加MAC头的大小为
    1514字节,优先级别为1,包的平均大小为1000字节,包间隔发送单
    元的大小为8字节,相当于实际带宽的加权速率为100Kbit,分类的分离点为1:0。
             tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 10Mbit rate 1Mbit maxburst 20 allot 1514 prio 1 avpkt 1000 cell 8 weight 100Kbit split 1:0
    
    4) 创建分类 1:4,其父分类为1:1,分配带宽为1Mbit,优先级别为6。
    该队列的最大可用带宽为10Mbit,实际分配的带宽为1Mbit,可接收
    冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为
    1514字节,优先级别为6,包的平均大小为1000字节,包间隔发送单
    元的大小为8字节,相当于实际带宽的加权速率为100Kbit,分类的分离点为1:0
             tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 10 Mbit rate 1Mbit maxburst 20 allot 1514 prio 6 avpkt 1000 cell 8 weight 100Kbit split 1:0
    
    c. 创建过滤器
    过滤器主要服务于分类。
    一般只需针对根分类提供一个过滤器,然后为每个子分类提供路由映射。
    1) 应用路由分类器到cbq队列的根,父分类编号为1:0;过滤协议为ip,优先级别为100,过滤器为基于路由表。
             tc filter add dev eth0 parent 1:0 protocol ip prio 100 route
    2) 建立路由映射分类 1:2 , 1:3 , 1:4
             tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 2 flowid 1:2
             tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 3 flowid 1:3
             tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 4 flowid 1:4
    
    d. 建立路由
    该路由是与前面所建立的路由映射一一对应。
    1) 发往主机192.168.1.24的数据包通过分类2转发(分类2的速率8Mbit)
             ip route add 192.168.1.24 dev eth0 via 192.168.1.66 realm 2 
    2) 发往主机192.168.1.30的数据包通过分类3转发(分类3的速率1Mbit)
             ip route add 192.168.1.30 dev eth0 via 192.168.1.66 realm 3
    3) 发往子网192.168.1.0/24 的数据包通过分类4转发(分类4的速率1Mbit)
             ip route add 192.168.1.0/24 dev eth0 via 192.168.1.66 realm 4
    

    关于filter和class
    队列规则上能不能添加filter,能不能分类取决于 qdisc->ops->cl_ops中的函数指针。
    如果cl_ops提供了tcf_chain函数,则支持给qdisc添加filter,
    如果cl_ops提供了change函数,则支持给qdisc分类。

    关于handle
    handle由两部分组成,格式为a:b,其中a表示主序列号,b表示从序列号。
    主序列号a唯一标识一个队列规则qdisc,对于ingress和clsact来说,其父为0xFFFFFFF1U,主序列号为0xffff。
    从序列号b表示类id,对于ingress和clsact来说,无分类的概念,所以从序列号为0。

    参考

    http://www.tldp.org/HOWTO/Traffic-Control-HOWTO/classless-qdiscs.html#qs-fifo
    https://www.cnblogs.com/ricks/p/10108911.html
    https://blog.csdn.net/eydwyz/article/details/53392227
    https://blog.csdn.net/pwl999/article/details/82706679

    相关文章

      网友评论

          本文标题:traffic control

          本文链接:https://www.haomeiwen.com/subject/tfqmmktx.html