Tried to post this yesterday but it failed due to too many replies to one topic. I already emailed it to the OP but submitting it here too for completeness.
No - you may think it is working but it is not. Currently the way you have things set up, it will work like this:
Customers on Private IPs: 100% of upload traffic and 100% of download traffic will get filed as “upload” and placed in the “upload” queue
Customers on Public IPs:80% of upload traffic and 80% of download traffic will get filed as “upload” and placed in the “upload” queue. About 20% of upload traffic and 20% of download traffic will get filed as “download” and placed in the “download” queue.
Because you see traffic for public IP customers in both the upload and download queues, you think it is working. It is not.
What is happening is, you are currently labeling the entire connection (bi-directional conversation) “25 up” or “25 down” based on who initiates the conversation. If the far side (on the Internet) is the first to send a packet in the conversation with your customer, everything in the connection thereafter, regardless of which direction it is sent in, is marked as “down”. If the near side (the customer) is the first to send a packet in the conversation with someone on the Internet, everything in that connection is marked as “up”.
However, the customers on private IPs are not reachable from people on the Internet. Therefore it is impossible, due to the nature of private IPs, for someone on the Internet to take the first step in initiating a connection to the customer - the customer must always take the first step. Because your rules are marking the packets based on whoever takes the first step in the conversation, it is impossible for any packets to private IPs be marked “down”, and only some packets to public IPs will be marked “down”.
You understand correctly - that is exactly what I was thinking.
I agree with the other poster that interface attached queue trees are preferable to global-attached queue trees with CCR, due to a single parent being on a single core. This is not always possible to roll out depending on configuration (ex. if there is more than one customer-facing interface). I use simple queues for this.