TLDR: How to use iptables to classify ingress packets with the same class as egress for the same connection.
It's not entirely clear by your question what method of classification you're referring to, but in general if we're talking about traffic shaping using tc
and queuing disciplines, the following applies.
act_connmark
As ingress qdisc processing is done before netfilter, you cannot directly classify ingress traffic using iptables (without recompiling your kernel with IMQ, see below). You can however indirectly classify it by using connection tracking. If available on your kernel you can use the act_connmark module, designed for this exact purpose, which adds a connmark
action to tc
filters that support it.
# 0. Load modules and IFB device
modprobe act_connmark
modprobe ifb
ip link set ifb0 up
# 1. Classify packets by marking them
iptables -t mangle -A POSTROUTING -p tcp --sport 22 -j MARK --set-mark 1
# 2. Append rule to save the packet mark to the connection mark
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark
# 3. Restore the connection mark to the packet mark with 'action connmark'
# before redirecting to the ifb-device
tc qdisc add dev eth0 handle ffff: ingress
tc qdisc add dev ifb0 handle 1: root
tc filter add dev eth0 parent ffff: prio 1 \
protocol ip u32 match u32 0 0 flowid ffff:1 \
action connmark \
action mirred egress redirect dev ifb0
# 4. Apply filters to classify packets based on their mark
# ... setup qdiscs and classes as usual on ifb0... then
tc filter add dev ifb0 parent 1: prio 1 protocol ip handle 1 fw classid 1:01
IMQ
IMQ (Intermediate Queueing Device) circumvents the normal flow of traffic in the kernel by, as I understand it, looping it back through a virtual device after netfilter processing. It is not merged with the kernel tree, thus is not included in most distributions, and requires you the patch and compile the kernel yourself. If you do so, it would work something like this:
# classify and save mark in POSTROUTING as before... then
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -j IMQ --todev 0
# ... setup qdiscs and classes as usual on imq0 ... then
tc filter add dev imq0 parent 1: prio 1 protocol ip handle 1 fw classid 1:01
This would also enable you to do more advanced classifications on ingress using iptables, that might be very cumbersome using plain u32 filters, such as arbitrary port ranges. I cannot speak to the performance or elegance of this solution though, I'm guessing there's a reason it never got merged.