/queue tree parent=global

It is not completely clear what /queue tree parent=global does exactly.
From the WiKi, where global is only really defined for simple queues (global-*) and queue tree is explained, I understand that parent=global for queue tree would be about the same as global-out for simple queues.
So, it would apply to “all outgoing interfaces”.
That is a bit unwieldy. Can I limit that by defining a queue tree for one or two interfaces specifically, and would the global tree then be for all other interfaces? or will it still include those defined interfaces?

I normally use queue tree with one tree attached to the internet interface and one to the LAN interface, so the internet queue shapes the upload and the LAN interface shapes the download.
Each interface gets a parent queue with 8 child queues, for each of the 8 priorities defined by “DSCP high 3 bits”. This works fine.

However, now I have a CCR1009 with 2 internet links and 3 LAN interfaces. Easy to manage the uploads, but the download is a lot more tricky.
Can I have a parent=global queue to handle all traffic towards the LAN while not intermixing the rates with the upload traffic to the two internet interfaces?
Having a separate queue tree on each LAN interface does not really work because they operate independently.

Can I have a parent=global queue to handle all traffic towards the LAN while not intermixing the rates with the upload traffic to the two internet interfaces?

Yes, that’s the way.

So parent=global shapes all interfaces that do not have their own more specific tree? (parent=ether1 for example)
And does this affect only ethernet interfaces? Or should I watch out for any tunnel or vlan interfaces, for example, to be included?
Unfortunately there is no “torch” on a queue tree …

I’m testing, but it does not appear to work like that!
On a test router (different network) where I have ether1 with a couple of VLANs on it (this router is a router between VLANs)
I had separate queue trees per VLAN. I added a queue tree for ether1 and for global and it appears these two are also
seeing the traffic from the VLANs. The queue tree for ether1 does not take away the traffic on the queue tree global.
That of course is what I require for the real-life router outlined in the first post: I want the outgoing data on the internet
interfaces to be excluded from the shaping of the data towards “all other” (LAN) interfaces.

It is quite unfortunate that we cannot have multiple packet marks, or else it would be possible to mark the traffic appropriately.

I would think that if you have a global queue tree and a queue tree on an interface that traffic would pass through both queues, and get limited by whichever one runs out of tokens first.

I’m having trouble decoding what it is you want to do.

It sounds like you want to do a rate-limit queue which applies to some customer regardless of which WAN interface the traffic arrived on, but not rate-limit traffic which arrives from other LAN interfaces, and you only want this to apply to “download” traffic. Uploads should be caught by individual WAN-interface queues…

Maybe you could make a diagram that shows your traffic flows and what sort of queueing you want to accomplish?

Yes, that is what it looks like. However, in this case it is not what I need. The reply by pukkita made me think it would be like I need.

I’m having trouble decoding what it is you want to do.

It sounds like you want to do a rate-limit queue which applies to some customer regardless of which WAN interface the traffic arrived on, but not rate-limit traffic which arrives from other LAN interfaces, and you only want this to apply to “download” traffic. Uploads should be caught by individual WAN-interface queues…

No, it is actually quite simple: normally, you can shape the traffic in each direction by configuring 2 queue trees, one on the WAN interface (for the upload) and one on the LAN interface (for the download).
I don’t really want to rate-limit any user, however I want to shape the traffic so that traffic priorities can be respected (DSCP) and the WAN link never gets fully saturated (to avoid long delays due to uncontrollable buffer bloat).
This works fine in your normal router with 1 WAN and 1 LAN. However, this router has 2 WANs and 3 LANs. (all inside the same company, but we separate office, guest and “building control” networks). So I mainly want to shape the traffic towards the LANs so that it does not overwhelm the WAN links. Also I want to send higher priority traffic first.
For this, I use the simple marking by priority shown before:

/ip firewall mangle
add action=set-priority chain=postrouting comment="From dscp high 3 bits" \
    new-priority=from-dscp-high-3-bits passthrough=yes
add action=mark-packet chain=postrouting comment="Priority 0" \
    new-packet-mark=prio0 passthrough=no priority=0
add action=mark-packet chain=postrouting comment="Priority 1" \
    new-packet-mark=prio1 passthrough=no priority=1
add action=mark-packet chain=postrouting comment="Priority 2" \
    new-packet-mark=prio2 passthrough=no priority=2
add action=mark-packet chain=postrouting comment="Priority 3" \
    new-packet-mark=prio3 passthrough=no priority=3
add action=mark-packet chain=postrouting comment="Priority 4" \
    new-packet-mark=prio4 passthrough=no priority=4
add action=mark-packet chain=postrouting comment="Priority 5" \
    new-packet-mark=prio5 passthrough=no priority=5
add action=mark-packet chain=postrouting comment="Priority 6" \
    new-packet-mark=prio6 passthrough=no priority=6
add action=mark-packet chain=postrouting comment="Priority 7" \
    new-packet-mark=prio7 passthrough=no priority=7

(and similar for IPv6 but it requires 64 rules there due to missing “from dscp high 3 bits”)
Then I have those 2 queue trees, a queue for each interface with 8 children matching the prio0..prio7 marks and sorting the priorities.

But now it becomes more complicated:

        +------------+
        |            |
LAN1 ---|            |       
        |            |--- WAN1 ---> internet
        |            |
LAN2 ---|   CCR1009  |
        |            |
        |            |--- WAN2 ---> internet
LAN3 ---|            |       
        |            |
        +------------+

For the upload it is still the right thing to have a separate queue tree on each WAN because you want to shape the WANs separately.
For the download, ideally there should be a single queue tree that shapes the 3 LANs together. I.e. not really on the interfaces, but on the “general flow of data towards the LAN”.
I hoped that having a global tree and 2 specific trees for the upload would do that, but unfortunately the global tree also includes the traffic towards the WAN interfaces.

Unfortunately a packet can have only a single mark, and a queue tree can match only on “or” between packet marks.
The setup would be quite easy to do when I could add a packet mark for “towards LAN” and still have the prio0..prio7 marks derived from DSCP,
and also a mark “from_WAN1” and “from_WAN2” to have separate shaping for each of them.
But this is not possible because RouterOS implements only a single mark per packet and a single match per queue item. Something else has to be found…

You don’t need different packets for upload/download, just make sure that for a given traffic category, you mark traffic on both directions. It’s the parent which will dictate if QoS will be applied on upload or download, depending on parent interface, you can use same packet marks.

parent=global will take into account all traffic traversing the router.

Remember it is queue tree, not queue simple. queue tree only has upload shapers, so for download you need to shape the upload of the LAN interface.

okay - what you do is make a general priority marking set of rules in the forward chain.
Then in postrouting, you can use the existing marks to re-mark the upstream traffic with wan-specific marks.

e.g.:
out-interface-list=!wan action=accept passthrough=no (for efficiency)
packet-mark=prio1 new-packet-mark=prio1wan
etc…

then the WAN queues use packet-mark=prioXwan instead of just prioX

and then put all qtrees under parent=global?
i’d still need quite some marks of course: prio1wan1 prio1wan2 (total 16), prio1lanfromwan1 prio1lanfromwan2 (total 16 as well) and likely some mark to pass everything not to be shaped.

No, I’d say let the WAN queue trees parent to the proper interfaces and use the same mark for either one - less marks.

Basically, the global HTB is one of the last things to happen, and of course interface queue trees happen even later, which is why the postrouting chain is your last chance to mark stuff.
The global tree should miss the upstream traffic because none of the upstream marks will be matched by the global tree. That will make the global tree operate in a downstream-only direction.

Another way to possibly achieve your goal would be to replace the global queue tree with simple queues w/o any packet marks to match, and their upstream set to unlimited. One simple queue per LAN segment. Each having target = x.x.x.0/24 (or whatever the LAN segments’ IP ranges are). Then you wouldn’t need to worry about using special marks for upstream and downstream. Let each interface keep its own queue tree for QoS purposes, and let the simple queues limit the per-segment traffic. (I think this may have the unwanted side-effect of rate-limiting the LAN-to-LAN rates as well, though)

LAN-to-LAN traffic isn’t an issue because there isn’t any (i.e. it is disallowed, that is the reason for having separate LANs)
The reason I want to avoid simple queues is that they don’t work for IPv6.
We have IPv6 on the LANs, unfortunately (due to the lack of route marking and NAT) only from one of the internet links. You know about that deficiency :slight_smile:
With qtrees I can mark traffic both in IPv4 and IPv6 and then shape the two together on each interface (with the 8 priorities).

As it is now, upstream isn’t a problem because the prio0…prio7 marks that are applied postrouting are nicely matched in the two qtrees on the WAN interfaces.
I guess I could add extra marking after the current mangle rules (when I remove the passthrough=no) that re-marks traffic going towards the LAN,
e.g. “when mark prio0 and output interface in list LAN set mark prio0lan”, or even “when mark prio0 and output interface in list LAN and input interface WAN1 set mark prio0lanfromwan1”
and similar for wan2. Then I can setup a parent=global queue that matches all those prio#lanfromwan#" marks and because the prio0..prio7 marks are gone
the upload traffic won’t be matched there.

That is something I can try in a test environment. Of course it means a lot more rules to be traversed for each packet, e.g. in the IPv6 mangle table there now are 64 rules (one for each DSCP value) but due to passthrough=no the processing stops once the DSCP is matches, so they can be sorted on frequency of DSCP value occurrence. And now I’ll get those 16 additional matches for the LAN-bound traffic as well. Maybe I can use jump/return to optimize a bit.

Well, that didn’t work because it isn’t possible to match on in-interface in the postrouting chain.
So I had to mark packets incoming from the WAN links in the prerouting chain with a mark indicating the source, then in the postrouting chain
replace that mark by an appropriate priority mark when that input mark is found, or a generic priority mark when not. This results in 24 rules
in the postrouting mangle table for IPv4 and 192 rules in the postrouting table for IPv6, but fortunately passthrough=no can be set on them
and most packets of course have DSCP 00 and are matched early.
It appears to work correctly, we’ll see what the CPU load will be when the users arrive monday :slight_smile: