Routing based on DSCP (or packet mark) [SOLVED]

I’m a bit stuck and hoping someone can assist. I have 2 ISP connections. One of those ISPs I use only to route voice traffic (i.e. anything marked DSCP CS3 or EF). I was using static routes for a while, but my carrier seems to have just added many new IPs and ranges, so this is not manageable any more.

I used to run Vyatta community, and I had a script that would mark packets with DSCP 24 (CS3) or 46 (EF). It used the PREROUTING table for this. Then Vyatta would route based on the mark. Unfortunately I lost the script, and I can’t seem to make this work in VyOS 1.1.5.

here’s an example of what I’m using to mark packets:

iptables -I PREROUTING -i eth0.10 -t mangle -m dscp --dscp 46 -j MARK --set-mark 20

It appears to be marking the packets:

root@vyatta:~# iptables -vt mangle -L PREROUTING Chain PREROUTING (policy ACCEPT 7299K packets, 6515M bytes) pkts bytes target prot opt in out source destination 114 43227 MARK all -- eth0.10 any anywhere anywhere DSCP match 0x18 MARK set 0x14

Now where I am stuck is how to set the next hop of marked packets to my second ISP? I don’t see any way to do policy routing based directly off of DSCP. I tried configuring a route-map that sets the next-hop based on tag, but it doesn’t appear to do anything.

Can anyone help?

EDIT: FOUND THE SOLUTION
The tip about a second route table was the key. I modified my script somewhat and it’s working.
Here’s a simplified version of what I did:

#!/bin/bash
# flush the PREROUTING mangle table
iptables -t mangle -F PREROUTING

# mark packets with DSCP set to CS3 or EF
iptables -I PREROUTING -i eth0 -t mangle -m dscp --dscp 46 -j MARK --set-mark 20
iptables -I PREROUTING -i eth0 -t mangle -m dscp --dscp 24 -j MARK --set-mark 20
iptables -I PREROUTING -i eth1 -t mangle -m dscp --dscp 46 -j MARK --set-mark 20
iptables -I PREROUTING -i eth1 -t mangle -m dscp --dscp 24 -j MARK --set-mark 20

ip route flush table 2
ip route add default via 67.x.x.x dev eth2 table 2
ip route add 127.0.0.0/8 dev lo table 2
ip route add 10.x.2.0/24 dev eth0 table 2
ip route add 10.x.5.0 dev eth1 table 2
ip route add 67.x.x.0/24 dev eth2 table 2

ip route flush cache
ip rule flush
ip rule add from all table main priority 32766
ip rule add fwmark 20 table 2 priority 1000

You could probably create a new route table and send the packets to that.

Are you running hard or soft phones, or a gateway?

Primarily hard phones, but I work in the VOIP/telecommunications industry and run all kinds of stuff from phones, soft phones, gateways, SBCs, you name it in my home lab. I also use it for all my business calls, which is why I want my secondary ISP to only carry QoS marked traffic.

I’ve looked at creating a secondary route table, but I’m not too familiar with that. How would I direct DSCP marked traffic to that route table?

Could you post your solution here? I’d like to see it.

Thanks!

I edited the first post to include the solution. It is a simplified version of my script, but all I removed were entries for additional subnets and interfaces unique to my network.