9.7. Das intermediate queueing Device (IMQ)

Das intermediate queueing Device ist keine QDisc aber in seiner Verwendung fest daran gebunden. Innerhalb Linux werden QDiscs auf Netzwerkgeräte und alles was eine Warteschlange für Geräte benötigt, als Warteschlange zuerst QDisc benutzt. Durch dieses Konzept ergeben sich zwei Einschränkungen:

  1. Nur die Ausgangskontrolle ist möglich (eine EingangsQDisc existiert, aber die Möglichkeiten sind sehr begrenzt im Vergleich zu classful qdisc).

  2. Eine QDisc kann nur den Verkehr von einer Schnittstelle sehen, globale Einschränkungen können nicht umgesetzt werden.

IMQ kann helfen, diese zwei Einschränkungen aufzulösen. Kurz gesagt, du kannst alles setzen, was du in einer QDisc auswählst. Speziell markierte Pakete werden im Netfilter NF_IP_PRE_ROUTING und NF_IP_POST_ROUTING abgefangen und passieren die QDisc über ein angeschlossenes IMQ-Gerät. Ein iptables-Target dient zur Kennzeichnung der Pakete.

Auf diese Weise kannst du ein Shaping auf einkommendes anwenden, sobald du Pakete markieren kannst die von irgendwo kommen und/oder Schnittstellen als Klassen behandeln kannst um globale Grenzen zu setzen. Du kannst auch viele andere Sachen tun, wie etwa nur deinen HTTP-Verkehr in einer QDisc zu bringen, neue Verbindungsanforderungen in einer QDisc setzen, ...

9.7.1. Beispielkonfiguration

Das Erste, was einem in den Sinn kommen könnte, ist die Verwendung von einkommenden Shaping um dir selbst eine garantiert hohe Bandbreite zu gewährleisten. ;) Die Konfiguration ist wie bei jeder anderen Schnittstelle:

tc qdisc add dev imq0 root handle 1: htb default 20

tc class add dev imq0 parent 1: classid 1:1 htb rate 2mbit burst 15k

tc class add dev imq0 parent 1:1 classid 1:10 htb rate 1mbit
tc class add dev imq0 parent 1:1 classid 1:20 htb rate 1mbit

tc qdisc add dev imq0 parent 1:10 handle 10: pfifo
tc qdisc add dev imq0 parent 1:20 handle 20: sfq

tc filter add dev imq0 parent 10:0 protocol ip prio 1 u32 match \
		ip dst 10.0.0.230/32 flowid 1:10
In diesem Beispiel wir u32 für die Klassifizierung verwendet. Andere Klassifizierer sollten wie erwartet funktionieren. Weiterer Traffic muss ausgewählt und markiert und in die Warteschlange imq0 eingereiht werden.
iptables -t mangle -A PREROUTING -i eth0 -j IMQ --todev 0

ip link set imq0 up

Die IMQ-iptables-Ziele sind korrekt in den PREROUTING- und POSTROUTING-Ketten der mangle-Tabelle. Der Syntax lautet:

IMQ [ --todev n ]	n : number of imq device
Ein ip6table-Ziel wird ebenfalls unterstützt.

Bitte beachte das Traffic nicht in die Warteschlange gestellt wird sobald das Ziel erreicht ist, sondern danach. Die genaue Stelle, an der der Verkehr das imq-Device erreicht, hängt von der Richtung des Traffics (in/out) ab. Diese vordefinierten Netfilter-Hooks verwendet iptables:

enum nf_ip_hook_priorities {
        NF_IP_PRI_FIRST = INT_MIN,
        NF_IP_PRI_CONNTRACK = -200,
        NF_IP_PRI_MANGLE = -150,
        NF_IP_PRI_NAT_DST = -100,
        NF_IP_PRI_FILTER = 0,
        NF_IP_PRI_NAT_SRC = 100,
        NF_IP_PRI_LAST = INT_MAX,
};

Für den einkommenden Traffic registriert imq selbstständig mit NF_IP_PRI_MANGLE + 1 die Priorität, das bedeutet, Pakete, welche das imq-Device nach der mangle-PREROUTING-Kette erreichen, werden direkt weitergegeben.

Bei der Austritts-imq besagt NF_IP_PRI_LAST, dass durch die Filtertabelle verworfene Pakete keine Bandbreite beeinträchtigen.

Die Patche und weitere Informationen findet man auf GIThub.