[翻译]ROS DSCP基于带HTB的QOS (2925人路过)
00:37 , 引用(0) Via 本站原创
最近想学习ROS有关的DSCP限速,在国内论坛基本上找不到有价值的资料,只好到ROS的官方论坛注册个帐号,以便查阅。
找到DSCP相关的标题,于是进行翻译,译完后,才发现这个脚本是要硬件支持的,但既然翻译出来了,就发出来大家共享。
ROS的官方论坛是全E文的,看一下还可以理解大意,但要用中文完全表达出来还真有点困难,所以,不当与错误在所难免,还请指正。
首先来普及下ROS常识:ROS的原产地是拉脱维亚共和国。
相信不少人都不知ROS产自哪,甚至认为是美国鬼子的产品。
DSCP based QoS with HTB
About
This page tries to describe a way to prioritize traffic by using DSCP tags. The DiffServ Code Point is a field in the IP header that allows you to classify traffic. DSCP is meant to be administered in a per-hob-based way, allowing each router on a path to determine how each traffic class should be prioritized. The solution described in this document is built around the Hierarchical Token Bucket queuing algorithm in RouterOS, dividing the 64 possible DSCP code values into the 8 queues available. This solution also utilizes the tree-based queuing, in order to have a parent queue do bandwidth control, with sub-queues for each possible DSCP value.
这一页想说明一种通过使用dscp标志优先通过的方法。DiffServ Code Point是一个允许分类通信的IP头的一个区域。dscp意思是指通过per-hob-based方法的管理,允许每个路由器在一条通道上,决定哪一等级应当被优先通过。本文所描述的解决办法是建立在ROS中的等级令牌桶算法,将64个可能的DSCP代码值分解为8个可用的队列。为了有一个父队列做为带宽控制,父队列中带有每个可能的DSCP值的子队列,这个方案也运用了tree-based队列。
The actual queuing is done as per this table:
实际队列处理如下表:
Name Precendence DSCP Range HTB Priority
Routing (default) 000 (0) 000000(0) – 000111 (7) 8
Priority 001 (1) 001000 (8) – 001111 (15) 7
Immediate 010( (2) 010000 (16) – 010111 (23) 6
Flash 011 (3) 011000 (24) – 011111 (31) 5
Flash Override 100 (4) 100000 (32) – 100111 (39) 4
Critical 101 (5) 101000 (40) – 101111 (47) 3
Internetwork Control 110 (6) 111000 (48) – 110111 (55) 2
Network Control 111 (7) 111000 (56) – 111111 (63) 1
This solution has been tested on RB450, RB600 and RB1000 using any 3.x interface.
这个方案已在使用任何3.x接口的rb450,rb600和rb10003进行测试.
DSCP marking/mangling
dscp标记/识别
In order to match DSCP values in your queues, it is necessary to mark the packets using firewall mangling. This is best done with this command:
为了匹配在队列中的dscp值,必须用防火墙识别编码来标记数据包。最好用这个命令处理:
:for x from 0 to 63 do={/ip firewall mangle add action=mark-packet chain=postrouting \
comment=("dscp_" . $x . "_eth") disabled=no dscp=$x new-packet-mark=("dscp_" . $x . "_eth") passthrough=no}
This command creates 64 lines under /ip firewall mangle, that simply marks each packet with a DSCP value to be processed later.
这行命令在/ip firewall mangle 建立64行,每行用一个DSCP值简单标记每一个包,以便以后处理。
Having that done, it's time to move on to the actual queues.
完成这些后,是时候设置实际队列了。
Set up the queue tree
设置队列树
The next example assumes that ether1 is the wan interface, and your available bandwidth is 5Mbit/s.
下一个例子假设ether1是wan接口,并且你的带宽是5M。
/queue tree
add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=5000000 name=ether1 \
parent=ether1 queue=default
#prio8
:for z from 0 to 7 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=0 \
name=("routine_" . $z . "_ether1") packet-mark=("dscp_" . $z . "_eth") parent=ether1 priority=8 queue=ethernet-default}
#prio7
:for z from 8 to 15 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=0 \
name=("priority_" . $z . "_ether1") packet-mark=("dscp_" . $z . "_eth") parent=ether1 priority=7 queue=ethernet-default}
#prio 6
:for z from 16 to 23 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=0 \
name=("immediate_" . $z . "_ether1") packet-mark=("dscp_" . $z . "_eth") parent=ether1 priority=6 queue=ethernet-default}
#prio 5
:for z from 24 to 31 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=0 \
name=("flash_" . $z . "_ether1") packet-mark=("dscp_" . $z . "_eth") parent=ether1 priority=5 queue=ethernet-default}
#prio 4
:for z from 32 to 39 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=0 \
name=("flash_override_" . $z . "_ether1") packet-mark=("dscp_" . $z . "_eth") parent=ether1 priority=4 queue=ethernet-default}
#prio 3
:for z from 40 to 47 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=0 \
name=("critical_" . $z . "_ether1") packet-mark=("dscp_" . $z . "_eth") parent=ether1 priority=3 queue=ethernet-default}
#prio 2
:for z from 48 to 55 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=0 \
name=("intercon_" . $z . "_ether1") packet-mark=("dscp_" . $z . "_eth") parent=ether1 priority=2 queue=ethernet-default}
#prio 1
:for z from 56 to 63 do={/queue tree add burst-limit=0 burst-threshold=0 burst-time=0s disabled=no limit-at=0 max-limit=0 \
name=("netcon_" . $z . "_ether1") packet-mark=("dscp_" . $z . "_eth") parent=ether1 priority=1 queue=ethernet-default}
Remarks
备注
This solution is the most flexible solution I could come up with. It is built around the philosophy that highest DSCP marking is served first. The actual shaping of the interface could be moved to a simple queue in order to be able to police differently on upstream and downstream, but I prefer to shape in both ends of a circuit, so when you have different upload and download speed, you should shape in according to the upload speed.
这个方案是是我们讨论的最灵活的解决办法。它是围绕着最高DSCP标记是服务第一的哲学建立的。接口的实际限速可以被移到一个简单的队列,以便能管理不同的上行和下行流。但我更喜欢在一个回路的两个终点限速,所以当你有不同的上传和下载速度,你应该根据上传速度限速。
Further Refinements by BrotherDust
用brotherdust进一步改进
Using the former script as a starting point, I have devised the following script:
使用以前的脚本作为一个起点,我设计了以下脚本:
#Set interface here
:global outboundInterface "ether1"
#Set bandwidth of the interface (remember, this is for OUTGOING)
:global interfaceBandwidth 0
#Set where in the chain the packets should be mangled
:global mangleChain postrouting
#Don't mess with these. They set the parameters for what is to follow
:global queueName ("qos_" . $outboundInterface)
:global qosClasses [:toarray "netcon,intercon,critical,flash_override,flash,immedate,priority,routine"]
:global qosIndex 64
#Set up mangle rules for all 64 DSCP marks
#This is different in that the highest priority packets are mangled first.
:for indexA from 63 to 0 do={
/ip firewall mangle add \
action=mark-packet \
chain=$mangleChain \
comment=("dscp_" . $indexA) \
disabled=no \
dscp=$indexA \
new-packet-mark=("dscp_" . $indexA) \
passthrough=no
}
#Add a base queue to the queue tree for the outbound interface
/queue tree add \
max-limit=$interfaceBandwidth \
name=$queueName \
parent=$outboundInterface \
priority=1
#Set up queues in queue tree for all 64 classes, subdivided by 8.
:for indexA from=0 to=7 do={
:local subClass ([:pick $qosClasses $indexA] . "_" . $outboundInterface)
/queue tree add \
name=$subClass \
parent=$queueName \
priority=($indexA+1) \
queue=ethernet-default
:for indexB from=0 to=7 do={
:set qosIndex ($qosIndex-1)
/queue tree add \
name=($subClass . "_" . $indexB) \
parent=$subClass \
priority=($indexB+1) \
packet-mark=("dscp_" . $qosIndex) \
queue=ethernet-default
}
}
Set the variables accordingly on the globals, paying attention to the comments. This script creates an even more granular priority structure by creating 64 different priorities subdivided by 8 master priorities. So, this is what it will look like this under interface queues when you enter it in the console:
根据globals设置变量,注意注释。此脚本通过将8个主要的优先次序细分为64个不同的优先次序,创建一个更精细的优先级结构。因此,这就是为什么在接口队列下当你在控制台输入的时候它看起来好象这样:
Some usage notes:
使用的一些注释:
1. Remember! The way that this script is set up by default is such that it will only work with outgoing traffic. It's best practices (in my opinion) to keep it set up that way as doing it for incoming traffic would be redundant.
1、记住!这个脚本默认设置的通道只对外出数据流有用。我认为,用这个方法来设置流入数据是多余的。
2. If this going to be applied to more than one interface, cut the script up so that it doesn't make the mangle rules again.
2、如果这个应用在超过一个接口,剪切掉脚本,使它不能重复建立mangel规则。
3. Bandwidth parameter need not be set. It's just for if you have an interface with fixed bandwidth or you you want to limit that interface. If it is set it must be in bits per second. I have not yet tested this on a wireless interface because the rates are unstable and I want them to be as fast as possible.
3、带宽参数不需要设置。那是因为如果你有一个固定带宽的接口或者你想限制那个接口。如果要设置则必须以bit每秒为单位。由于它的速率不稳定并且我想它尽可能快,我没有在无线接口中测试。
Updated on 20090604: I changed the script slightly to reverse the mangling chain. Now highest priority packets are processed first. Probably not going to make a huge difference. But we'll see.
20090604更新:我倒转mangle链来轻微改变这个脚本,现在,最高优先级的包先处理,可能不会形成巨大的不同。但是我们可以看到。
Updated on 20100514: In response to the comments below: OSPF packets with DSCP tag 48 do not get priority 8 globally; rather, they get priority 8 inside of a priority 2 queue. This script creates an extremely granular queue structure to work with. Most people do not need this level of granularity. For the most part they will delete the queues that aren't needed.
20100514更新:回答下面的注释:有48确DSCP标记的OSPF包不能完全取得8级优先;然而,它们可以在一个2级优先的队列中取得8级优先。此脚本创建一个非常精细的工作队列结构,大多数人不需要这种级别的精度。他们将删除大部分无用的队列。
Comment on difference between this solution and first solution
在这个方法和第一个方法之间不同的注释
Please note that the DSCP tagging strategy here is completely different from that of the first script. Please consider if this fits within your current QoS setup before applying it. For instance, RouterOS automatically tags dynamic routing with DSCP value 48, and following this script, routing updates will have priority 8, which is the lowest priority. In practical network setup, I suggest you only handle the DSCP codes that you know your network is using. My current mangle setup script looks like this:
请注意在这的DSCP标记策略与第一个脚本完全不同,在应用之前请仔细考虑这是否符合你当前的QOS设置。例如,ROS自动将动态路由用DSCP值48来标记,根据这个脚本,路由更新有8级优先,这是最低优先级,在实际的网络设置,我建议你只处理你知道的你的网络所使用的DSCP代码,我现在的mangle设置脚本如下:
/ip firewall mangle add action=mark-packet chain=postrouting comment=dscp.0 disabled=no \
dscp=0 new-packet-mark=dscp.0 passthrough=no
/ip firewall mangle add action=mark-packet chain=postrouting comment=dscp.46 disabled=no \
dscp=46 new-packet-mark=dscp.46 passthrough=no
/ip firewall mangle add action=mark-packet chain=postrouting comment=dscp.48 disabled=no \
dscp=48 new-packet-mark=dscp.48 passthrough=no
:for x from 1 to 45 do={/ip firewall mangle add action=mark-packet chain=postrouting \
comment=dscp.1-45 disabled=no dscp=$x new-packet-mark=dscp.other passthrough=no}
/ip firewall mangle add action=mark-packet chain=postrouting comment=dscp.47 disabled=no \
dscp=47 new-packet-mark=dscp.other passthrough=no
:for x from 49 to 63 do={/ip firewall mangle add action=mark-packet chain=postrouting \
comment=dscp.49-63 disabled=no dscp=$x new-packet-mark=dscp.other passthrough=no}
This basically gives you four markings:
这主要给你4点提示:
1 dscp.0 for packets that have no DSCP tags
1 dscp.0 是给没有DSCP标记的包
2 dscp.46 for EF packets (my VoIP traffic)
2 dscp.46 是给EF 包
3 dscp.48 for routing updates
3 dscp.48 是给路由更新
4 dscp.other for all other DSCP values
4 dscp.other 是给所有其它DSCP数据
I am then able to assemble a queue tree where unmarked packets have the lowest priority, followed by dscp.other, dscp.46 and dscp.48, under the philosophy that routing updates should always be prioritized highest - without them, nothing works, then VoIP, other prioritized packets and lowest of all, non-marked packets.
根据 dscp.other, dscp.46 和 dscp.48,在路由更新通常有最高优先级的哲学体系中(不是这样,没有东西会工作,何况所有数据中的 VoIP、其它优先级和最低给的包,没有标记的包),我们有能力装配一个有最低优先级没有标记包的队列树。
ROS更改网卡MAC地址
禁止 ROS WINBOX 通过 MAC 登录
ros+radiusmanager到期自动跳转到通知页面
分享Tomato DualWan使用ADSL的QOS设置
ROS 3.XX PPPOE到期自动禁用
ROS PPPOE服务器账号到期web提醒设置
ROS 3.0以上的版本hotspot功能都有问题!
ros自动arp绑定,并使用arp表初始化dhcp表
请教老大关于ROS3.3的3线ADSL的PCC负载问题,附我用的脚本,请老大指点迷津!
ros实验环境搭建与PCC+HTB+PCQ+NTH实践!
作者:77run@齐齐奔跑 -- 骑士威科技
地址:http://blog.77run.com/ROS-DSCP-HTB-QOS/
版权所有©转载时必须以链接形式注明作者和原始出处及本声明!
大 | 中 | 小 

