首页 > 编程知识 正文

路由器限速原理,运营商网络带宽怎么控制的

时间:2023-05-04 17:07:01 阅读:140402 作者:2475

tc端口流量控制tc真是个大洞,干了一天才知道问题出在哪里,并记录下来。

tc开场白首先: http://www.Sina.com/http://www.Sina.com/http://www.Sina.com /重要的事情说三遍,漏洞就出现在这里,容易晕过去。 换言之,tc只是出站(出网卡)流量,与进来的流量无关,当然这句话也不完整。 因为在本地环路lo中也是这样的。

更具体地说,很容易将包分解为[ source-IP ]|[ source-port ]|[ other-data ]|[ destination-IP ]|[ destination-port ]

这对以后的说明和理解有很大的帮助。 这个包显然是从source-ip机器的source-port发送的,通过source机器的网卡。tc只管发包,不管收包的事

具体操作首先要简单了解tc的三大功能,其他可以忽略。 当然要想深入思考,请去看看参考资料demo。 这三个可以很容易地实现端口通信量控制的目标,但重点其实是后面两个。

tc-qdisc :队列规则。 后面使用的是htb级别的令牌桶队列。 队列用于管理消息的出入和分发。 tc-class :定义队列规则类。 每个类都可以很容易地理解为子队列,并且有独立的规则。 tc-filter :定义过滤器。 可以使用端口控制。 如果与iptables合作,还可以专门过滤带有特殊标记的包。 实际上是将包过滤放到特定类的队列中。 试了一次实际操作就知道了,这里默认对外的网卡是enp8s0,本地环回是lo。 两者都可以实现端口控制流。

首先,删除root现有的队列规则。 del是delete,root是根队列,dev是device,enp8s0是网卡名称,可以在ip addr中显示。

sudo tc qdisc del root dev enp8s0

重建根队列规则(处理句柄很容易理解handle。 如C所示,1:实际上是1:0。 这意味着,默认值为0,因此此队列的“名称”为133600。 htb是分层令牌桶或要使用的队列类型,如果未指定要前往传入包的子类,则缺省值为default 3

sudotcqdiscaddrootdevenp 8s0handle 1: htb default 3

在该队列上构建子类,设置带宽上限实现该子类的控制流。 (parent用于指定父类,classid与上述handle一样用于指定此子类的名称,rate用于控制流。 由于ceil和rate默认为一致,如果只将流量稳定为一个值的话,就没有必要追加写ceil。 这里,带宽的上限是220

sudotcclassaddevenp 8s0parent 1: classid 1:1 htb rate 20m bit

然后,可以在此子类中重建两个子类。 请注意,带宽不能超过父类1:1的20mbps。

sudotcclassaddevenp 8s0parent 1:1 classid 1:2 htb rate 10 mbit

sudotcclassaddevenp 8s0parent 1:1 classid 1:3 htb rate5mbit

正如您所看到的,当数据包分发到1:2订阅队列时,带宽最大为10mbps。 如果没有分发到特定的订阅队列,则如默认设置3所示,将分发到1:3的订阅队列。 带宽最大为5mbps。

如何分发与过滤器有关。 (protocol是协议类别,用ip就可以了。 此外,还可能指定tcp、udp等。 prio是优先级级别。 sport是source port的意思,也可以设定dport,即destination port。0xffff用于设置端口范围或偏移量。 这里的效果是单一端口。 flowid表示满足过滤器条件的包将分发到哪个流。 在这里,我们将数据包分发到1:2子类的队列中。)。

sudotcfilteraddevenp 8s0protocolipparent 1:0 prio 1u 32 matchipsport 123450 xffff lowid 1:2

到此为止,12345端口的电流限制已经完成。 但是,请注意,这是tc只管发包,不管收包的事电流限制,而不是tc只管发包,不管收包的事电流限制。 要将收到的数据包限制为流式传输,只有两种方法。 1 )一个是制作中继网卡,将该网卡所接收到的包再发送到名为enp8s0的网卡,在对该中继网卡设定规则的情况下,为因此如果要做限流,在 destination 机器上的网卡设置规则是没有意义的,只能在 source 机器的网卡上限制规则。2 )插件

关于过滤器的sport和dport的意思,以前面提到的包的结构为例进行说明。 例如sport 1234

5指的是这个包是从本地的12345端口发出的包,满足这类条件的包就能通过这个过滤器。而dport 12345指的是这个包是本地发出的包(不管是哪个端口的),且包发往的目的端口是12345,满足这类条件的包可通过过滤器,而不是本地收到的发到12345端口的包,即使是本地发到本地12345端口的包,也是在发送的时候就限流了。此外过滤器还能设置目的ip,只要是发往那个ip地址的包就会通过过滤器,这里就不细说了。可以发现这里提到的全部都是发包,这也就是为什么前面一直在强调tc影响的是发包而不是收包了。

测试结果

前置环境装个iperf3就可以了:sudo apt-get install iperf3

我们假定有两个机器,ip地址分别是192.168.1.101和192.168.1.102。

将上述tc规则设置在101机器的enp8s0网卡上。

接着在101机器上的12345端口设置服务端(s是server,p是port):

pc101: iperf3 -s -p 12345

102机器上设置客户端,并从服务端收取数据(c是client,后接对接服务端的ip。R代表反向,即从服务端接收数据,不加-R选项则是客户端往服务端发数据。i是interval,代表发送间隔,t是time,代表测试时长):

pc102: iperf3 -c 192.168.1.101 -p 12345 -R -i 1 -t 3

可以发现从192.168.1.101的12345端口发出的包被限流到10mbps了。iperf3不能设置client的端口,所以这里用了-R来间接完成从12345端口发包。

当然也可以把12345端口设为目的端口,即之前tc的filter的条件设为(将sport改成dport,还是在101机器上设置,记得先用tc filter delete删掉原有条件):

pc101: sudo tc filter add dev enp8s0 protocol ip parent 1:0 prio 1 u32 match ip dport 12345 0xffff flowid 1:2

不过这时候反过来,让102机器作为服务端,并设置端口为12345。

pc102: iperf3 -s -p 12345

然后用101机器作为客户端发送数据到服务端,测试带宽(不用带-R选项了!):

pc101: iperf3 -c 192.168.1.102 -p 12345 -i 1 -t 3

可以发现发包带宽也是被限制在10mbps左右(肯定是会有波动的,但会在10mbps附近一个小范围内)。

不管是哪种方式,tc限流最终都是落在发包上。

在一台机器上做tc限流

跟之前提到的具体操作几乎没有任何区别,只需要把设备名从enp8s0改成lo即可,因为本地端口之间的通信走的都是lo回环。

设置完tc规则和filter条件后,用两个终端或者tmux开启多窗口的方式来用iperf3分别开服务端和客户端。

后续操作和原理与之前在两台机器上的完全一致,就不多说了。

查看网卡的规则

再给一些查看网卡规则的指令,有时候也可以确认规则是否生效,以及流量是否被分配到某一个子类规则队列中,流量和包数有多少等等。

简单查看(设备可以换成lo等等,查看的除了qdisc也可以换成class,filter等):

tc qdisc ls dev enp8s0

详细查看(还可以看class的流量和包数等):

tc -s qdisc ls dev enp8s0

其他-利用iptables完成相同工作

也可以用iptables完成分发,前面步骤还是一样的,只有最后的filter不太一样(这里的handle 10以及后续的参数指的是将标志为10的包分发给classid为1:2的flow):

tc filter add dev enp8s0 parent 1:0 protocol ip prio 1 handle 10 fw classid 1:2

然后用iptables对指定端口的包设置特殊的标志,完成端口绑定tc队列(只要保证--set-能干的太阳的值和handle的值一致就可以了)。

iptables -A OUTPUT -t mangle -p tcp --sport 12345 -j MARK --set-能干的太阳 10

由于这些规则还是基于本机的tc设置的,因此控制的还是发包(sport指定的是本机发包的source端口,即使改成dport也是这个包发往的目的端口号)。

参考资料 tc控制端口带宽tc高级控流demotc参数/manpage

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。