Your script is not very CPU efficient in the use of layer 7 rules - by not using connection marking, you are unnecessarily running extra traffic through the rule, and risk hitting a brick wall on slower routers on fast connections.
Also please put your config script in the ‘code’ option otherwise it takes up a huge amount of vertical space and you cannot see anything except your script..
I tried this from scripts, and changed the interface names. It doesn’t create any queues however.
I can’t see any way to see what the issue is - it doesn’t log anything - so I ran the script from the terminal again. I get a couple of syntax errors and also a couple of “ambiguous value of parent, more than one possible value matches input”. No idea if that is just as a result of running via terminal or not.
The only reason it would not be working is if your IPv6 package is disabled, since I include rules for ipv6. Either enable ipv6 in system->packages->ipv6->enable and reboot, or remove the following block from the script:
:for dscpValue from 0 to 7 do={
/ipv6 firewall mangle add action=accept \
chain=postrouting dscp=$dscpValue \
comment="IP Precedence 0 (DSCP $dscpValue) - Best Effort (Low Priority) (default)"
}
:for indexA from 1 to 7 do={
:local qosIndex (7-$indexA)
# skip best effort in list
:if ($indexA <= (8-$beQueuePriority)) do={ :set qosIndex (8-$indexA) }
:local subClass ([:pick $qosClasses $qosIndex] )
:for dscpValue from ($indexA*8) to (($indexA*8)+7) do={
/ipv6 firewall mangle add action=mark-packet chain=$mangleChain comment=("IP Precedence " . $indexA . " (DSCP " . $dscpValue . ") - " . $subClass . " (apply packet mark ip_precedence_" . $indexA . ")") \
disabled=no dscp=$dscpValue new-packet-mark=("ip_precedence_" . $indexA) passthrough=no
}
}
Here.. to make it even easier, I enhanced the script so that it checks whether the IPv6 package is enabled and doesn’t try to install the mangle rules if IPv6 is not there:
# this is based on IntrusDave's QoS script, slightly modified
# qosClasses are largely based on Cisco QoS recommendations with a few slight modifications
#Set outbound interface here
:local outboundInterface "ether1"
#Set bandwidth of the outbound interface
:local outInterfaceBandwidth 4900k
#Set inbound interface here
:local inboundInterface "bridge"
#Set bandwidth of the inbound interface
:local inInterfaceBandwidth 34500k
#Set type of queue here
:local queueType wireless-default
#Set where in the chain the packets should be mangled
:local mangleChain postrouting
#Don't mess with these. They set the parameters for what is to follow
:local queueName ("QoS_" . $outboundInterface)
:local inQueueName ("QoS_" . $inboundInterface)
# qosClasses from highest to lowest priority
:local qosClasses [:toarray "Network Control (Top Priority),Internetwork Control (High Priority),Voice (Medium-High Priority),Interactive Video (Medium Priority),Critical Data or Call Signaling (Medium-Low Priority),Best Effort (Low Priority),Background (Very Low Priority),Scavenger (Bottom Priority)"]
# maps queue priorities from highest to lowest to IP precedence values
:local priorityToIpPrecedenceMappings [:toarray "7,6,5,4,3,0,2,1"]
# queue priority used for best effort traffic (IP precedence 0)
:local beQueuePriority 6
/ip firewall mangle add action=set-priority \
chain=postrouting new-priority=from-dscp-high-3-bits \
passthrough=yes comment="Respect DSCP tagging"
/ip firewall mangle add action=set-priority \
chain=postrouting new-priority=6 packet-size=0-123 \
passthrough=yes protocol=tcp tcp-flags=ack comment="Prioritize ACKs"
/ip firewall mangle add action=accept \
chain=postrouting priority=0 dscp=0 \
comment="IP Precedence (Packet Priority) 0 - Best Effort (Low Priority) (default)"
:for indexA from 1 to 7 do={
:local qosIndex (7-$indexA)
# skip best effort in list
:if ($indexA <= (8-$beQueuePriority)) do={ :set qosIndex (8-$indexA) }
:local subClass ([:pick $qosClasses $qosIndex] )
/ip firewall mangle add action=mark-packet chain=$mangleChain comment=("IP Precedence (aka Packet Priority) " . $indexA . " - " . $subClass . " (apply packet mark ip_precedence_" . $indexA . ")") \
disabled=no priority=($indexA) new-packet-mark=("ip_precedence_" . $indexA) passthrough=no
}
:if ([/system package find name=ipv6 disabled=no] = "") do={
:log info "IPv6 package is not installed - skipping IPv6 mangle rules";
} else={
:for dscpValue from 0 to 7 do={
/ipv6 firewall mangle add action=accept \
chain=postrouting dscp=$dscpValue \
comment="IP Precedence 0 (DSCP $dscpValue) - Best Effort (Low Priority) (default)"
}
:for indexA from 1 to 7 do={
:local qosIndex (7-$indexA)
# skip best effort in list
:if ($indexA <= (8-$beQueuePriority)) do={ :set qosIndex (8-$indexA) }
:local subClass ([:pick $qosClasses $qosIndex] )
:for dscpValue from ($indexA*8) to (($indexA*8)+7) do={
/ipv6 firewall mangle add action=mark-packet chain=$mangleChain comment=("IP Precedence " . $indexA . " (DSCP " . $dscpValue . ") - " . $subClass . " (apply packet mark ip_precedence_" . $indexA . ")") \
disabled=no dscp=$dscpValue new-packet-mark=("ip_precedence_" . $indexA) passthrough=no
}
}
}
/queue tree add max-limit=$outInterfaceBandwidth name=$queueName parent=$outboundInterface comment="Uplink QoS" queue=$queueType
:for queuePriority from=1 to=8 do={
:local qosIndex ($queuePriority-1)
:local subClass ([:pick $qosClasses $qosIndex] )
:local ipPrecedence ([:pick $priorityToIpPrecedenceMappings $qosIndex])
:local ipPrecedenceMark ("ip_precedence_" . $ipPrecedence)
:if ($ipPrecedence = "0") do={ :set ipPrecedenceMark ("no-mark") }
/queue tree add \
name=("IP Precedence " . $ipPrecedence . ". " . $subClass . " - " . $outboundInterface ) \
parent=$queueName \
priority=($queuePriority) \
queue=$queueType \
packet-mark=$ipPrecedenceMark \
comment=("Queue Priority " . $queuePriority)
}
/queue tree add max-limit=$inInterfaceBandwidth name=$inQueueName parent=$inboundInterface comment="Downlink QoS" queue=$queueType
:for queuePriority from=1 to=8 do={
:local qosIndex ($queuePriority-1)
:local subClass ([:pick $qosClasses $qosIndex] )
:local ipPrecedence ([:pick $priorityToIpPrecedenceMappings $qosIndex])
:local ipPrecedenceMark ("ip_precedence_" . $ipPrecedence)
:if ($ipPrecedence = "0") do={ :set ipPrecedenceMark ("no-mark") }
/queue tree add \
name=("IP Precedence " . $ipPrecedence . ". " . $subClass . " - " . $inboundInterface ) \
parent=$inQueueName \
priority=($queuePriority) \
queue=$queueType \
packet-mark=$ipPrecedenceMark \
comment=("Queue Priority " . $queuePriority)
}
Sorry to hijack the thread, just wanted to ask a quick question. In the situation mentioned where the bandwidth is split but the one device doesnt use all the bandwidth allocated to it: I thought that in this case with PCQ if the one device doesnt use all of its available bandwidth that it would be available for the other device(s) to use?
PCQ allows you to set a per client rate limit as well. If you set this, the bandwidth per client will be limited to this. If you don’t, yes it becomes pretty much identical to SFQ. I expect in such cases that SFQ would be slightly more efficient.
The OP I think misunderstood PCQ but since he really just wanted an equal way of sharing bandwidth, I suggested SFQ because it would do that probably slightly more efficiently than PCQ.