Dans certaines zones géographiques (exemples : Grenoble, Strasbourg), il y a une étape supplémentaire afin de remplacer la Livebox : les requêtes DHCP doivent être envoyées avec une priorité de VLAN bien définie (« 6 »).
Oui, comme nous l'apprend johndescs, on peut définir la priorité d'une trame 802.1Q (VLAN).
Pour ce faire, au lieu de créer l'interface avec la commande /sbin/ip l a link eth0 name $IFACE type vlan id 832
, il faut utiliser la commande /sbin/ip l a link eth0 name $IFACE type vlan id 832 egress-qos-map 0:6
. Ensuite, il faut ajouter la règle suivante : sudo iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1
. Pour qu'elle soit positionnée automatiquement au boot, il est possible d'utiliser le logiciel netfilter-persistent couplé à iptables-persistent. C'est tout. Ce sont les uniques changements, le reste du tuto ne change pas. Notons que la commande qui repose sur iproute2 peut être remplacée par vconfig set_egress_map $IFACE 0 6
.
Que signifie ce paramétrage avec iproute ? Sa compréhension n'est pas aisée.
Disons qu'en gros, il existe trois types de marquage de la priorité :
Il y a une correspondance entre sk_priority et VLAN priority. Par défaut, une interface VLAN n'a pas de priorité de sortie. On peut voir cela dans /proc/net/vlan/<nom_interface>
. Exemple :
$ sudo cat /proc/net/vlan/orange
orange VID: 832 REORDER_HDR: 1 dev->priv_flags: 1001
total frames received 4
total bytes received 948
Broadcast/Multicast Rcvd 0
total frames transmitted 6
total bytes transmitted 1374
Device: eth0
INGRESS priority mappings: 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0
EGRESS priority mappings:
Il n'y a bien rien en egress. Donc, aucune sk_priority ne sera appliquée à un quelconque paquet. Nous pouvons essayer avec sudo iptables -t mangle -I POSTROUTING -o test -p icmp -j CLASSIFY --set-class 0:5
: les trames éthernet contenant un ping (ICMP echo request de son vrai nom) n'auront pas une priorité de 5 quand on les capturera avec wireshark ou autre. Si nous recréons notre interface VLAN avec une correspondance 5:5 (une sk_priority de 5 sera traduite en VLAN priority de 5) avec sudo ip l a link eth0 name test type vlan id 42 egress-qos-map 5:5
, notre règle iptables devient fonctionnelle : les trames Ethernet contenant des ICMP echo request sont marquées avec une VLAN priority de 5. Les autres trames Ethernet restent inchangées.
Par défaut, les paquets n'ont aucune sk_priority définie. C'est pour cela qu'au début de ce shaarli, j'ai ajouté une correspondance 0:6 : les trames contenant des paquets qui n'ont pas de sk_priority (et reçoivent donc la sk_priority par défaut, « 0 ») sont marquées avec une VLAN priority de 6. C'est le cas des requêtes DHCP donc ça fonctionne. \o/
Je te vois venir : tu penses que j'agis mal en marquant tooooous les paquets sortants avec une VLAN priority à 6 et tu voudrais faire ceci pour optimiser mon tuto :
$ sudo iptables -t mangle -I POSTROUTING -o orange -p udp --sport 68 --dport 67 -j CLASSIFY --set-class 0:6
$ sudo ip l a link eth0 name test type vlan id 42 egress-qos-map 6:6
Ça ne fonctionnera pas car, comme nous le rappelle johndescs, l'implémentation DHCP de l'ISC utilise des sockets raw pour communiquer. Or, les sockets raw échappent totalement à Netfilter en sortie. Il n'est pas possible de capturer de tels paquets ni de leur appliquer un quelconque traitement.
Pourquoi je parle de DSCP ci-dessus ? Parce que le noyau Linux converti automatiquement les DSCP en VLAN prority (quand l'egress est activé, bien entendu). Ce qui est logique puisque les VLAN priority reprennent les classes les moins granulaires de DSCP. Ce qui est illogique puisqu'un VLAN est normalement dédié à un seul usage donc on ne devrait pas faire fluctuer sa priorité si la nature du trafic échangé diffère… Démonstration ? sudo ip l a link eth0 name test type vlan id 42 egress-qos-map 1:1 2:2 3:3 4:4 5:5 6:6 7:7
. ping -Q 72 <IP>
génère des paquets avec un DSCP égal à 0x48 (hexadécimal) et une priorité de VLAN de 2 (lire ll'article pointé par le lien précédant pour comprendre le calcul réalisé par le noyau pour faire correspondre un marquage DSCP à une VLAN priority). ping -Q 16
génère des paquets avec un DSCP égal à 10 et une priorité de VLAN égale à 6. Cela fonctionne aussi avec un petit programme en C qui utilise int val = 0xe0; setsockopt(sock, IPPROTO_IP, IP_TOS, &val, sizeof(val));
.
Ben alors ?! Puisque l'implémentation DHCP de l'ISC assigne toujours un ToS de 4 (donc un DSCP égal à 0x10 donc une VLAN priority égale à 6), on ne devrait rien avoir à faire d'autre que sudo ip l a link eth0 name orange type vlan id 42 egress-qos-map 6:6
?! Sauf que les sockets raw, utilisées par dhclient, échappent aussi à ce sous-système… LALA.
À quoi sert la règle iptables -t mangle -I POSTROUTING -o orange -j CLASSIFY --set-class 0:1
? Pour que tout le reste du trafic (le trafic non-émis via des sockets raw) ait une sk_priority égale à 1. Comme nous n'avons pas configuré la correspondance sur l'interface, les trames Ethernet contenant ce trafic seront marquées avec une VLAN priority à 0, ce qui est ce qu'attend Orange. Oui, si t'envoies tout ton trafic avec une VLAN priority à 6, ton débit sera limité à 300 ko/s environ et la latence explosera à 2-3 secondes au moindre téléchargement. Si tu utilises une autre priorité de VLAN, 0 ou 1, par exemple, ton débit sera limité à 4 mo/s environ et la latence explosera à 300 ms.
ÉDIT DU 29/07/2017 À 20H55 : ajout de l'indispensable marquage du reste du trafic émis en priorité 0. FIN DE L'ÉDIT.