TLDR: How to use iptables to classify ingress packets with the same class as egress for the same connection.
Não está totalmente claro por sua pergunta a que método de classificação você está se referindo, mas, em geral, se estamos falando de modelagem de tráfego usando tc
e disciplinas de enfileiramento, aplica-se o seguinte.
act_connmark
Como o processamento do qdisc de ingresso é feito antes do netfilter, você não pode classificar diretamente o tráfego de entrada usando o iptables (sem recompilar seu kernel com o IMQ, veja abaixo). No entanto, você pode classificá-lo indiretamente usando o rastreamento de conexão. Se disponível em seu kernel, você pode usar o módulo act_connmark, projetado para esse propósito exato, que adiciona uma ação connmark
aos filtros tc
que o suportam.
# 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
O IMQ (Intermediate Queuing Device) contorna o fluxo normal de tráfego no kernel, como eu o entendo, retornando através de um dispositivo virtual após o processamento do netfilter. Ele não é mesclado com a árvore do kernel, portanto, não é incluído na maioria das distribuições e requer o patch e a compilação do kernel. Se você fizer isso, funcionaria algo assim:
# 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
Isso também permitiria que você fizesse classificações mais avançadas no ingresso usando o iptables, o que pode ser muito complicado usando filtros simples do u32, como intervalos de porta arbitrários. No entanto, não posso falar sobre o desempenho ou a elegância dessa solução, suponho que exista uma razão pela qual ela nunca foi mesclada.