tc u32 - comment faire correspondre les protocoles L2 dans les noyaux récents?

12

J'ai un joli shaper, avec un filtrage haché, construit sur un pont Linux. En bref, les br0connexions externalet internalles interfaces physiques, les paquets balisés VLAN sont pontés "de manière transparente" (je veux dire, aucune interface VLAN n'est là).

Maintenant, différents noyaux le font différemment. Je peux me tromper avec les plages de versions exactes du noyau, veuillez me pardonner. Merci.

2.6.26

Donc, dans Debian, 2.6.26 et plus (jusqu'à 2.6.32, je crois) --- cela fonctionne:

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200

Ici, "kernel" correspond à deux octets dans le champ "protocol" avec 0x8100, mais compte le début du paquet ip comme une "position zéro" (désolé pour mon anglais, si je ne suis pas clair).

2.6.32

Encore une fois, dans debian (je n'ai pas construit de noyau vanilla), 2.6.32-5 --- cela fonctionne:

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 at 20 flowid 1:200

Ici, "noyau" correspond à la même chose pour le protocole, mais compte l'offset depuis le début de l'en-tête de ce protocole --- Je dois ajouter 4 octets pour l'offset (20, pas 16 pour l'adresse dst). C'est bon, ça me semble plus logique, pour moi.

3.2.11, la dernière écurie maintenant

Cela fonctionne --- comme s'il n'y avait pas de balise 802.1q du tout:

tc filter add dev internal protocol ip parent 1:0 prio 100 \
    u32 ht 1:64 match ip dst 192.168.1.100 flowid 1:200

Le problème est que je n'ai pas trouvé de moyen de faire correspondre la balise 802.1q jusqu'à présent.

Balise 802.1q correspondante dans le passé

Je pourrais le faire avant comme suit:

tc filter add dev internal protocol 802.1q parent 1:0 prio 100 \
    u32 match u16 0x0ed8 0x0fff at -4 flowid 1:300

Maintenant , je suis incapable de faire correspondre 802.1Q tag avec at 0, at -2, at -4, at -6ou comme ça. Le principal problème que j'ai zéro compte de coups --- ce filtre n'est pas vérifié du tout, "mauvais protocole", en d'autres termes.

S'il vous plaît, n'importe qui, aidez-moi :-)

Merci!

brownien
la source

Réponses:

4

La balise VLAN est supprimée de skb dans les noyaux récents. Essayez quelque chose comme ça pour faire un méta-match dans skb:

tc filter add dev internal protocol all parent 1:0 prio 100 basic match 'meta(vlan mask 0xfff eq 0x0ed8)' flowid 1:300
Thusitha
la source
Une tentative pour ajouter un filtre racine protocol allme donne RTNETLINK answers: Invalid argument(noyau 3.3.4 ici). Je vais tester cela avec des noyaux plus récents. Je vous remercie.
brownian
Cela a fonctionné pour moi avec le noyau Debian Wheezy 3.2.0. J'ai ajouté une autre réponse avec tous les détails.
Nick Craig-Wood
3

Je devais faire exactement ça. J'ai trouvé que la réponse suggérée par @Thusitha était la bonne façon de le faire pour les nouveaux noyaux.

Testé avec le noyau Debian Wheezy 3.2.0-4 et iproute (d'où vient la commande tc) version 20120521-3 + b3

Voici le script complet, les tc filterlignes étant presque exactement celles spécifiées par @Thusitha

function qos() {
    if="$1"
    vlan1="$2"
    vlan2="$3"

    # delete previous
    tc qdisc del dev $if root >/dev/null 2>&1
    tc qdisc del dev $if ingress >/dev/null 2>&1

    # Root HTB for $if
    tc qdisc add dev $if root handle 1: htb r2q 1 default 1

    # Root class to borrow from
    tc class add dev $if parent 1: classid 1:1 htb quantum 1000000 rate 500mbit ceil 500mbit burst 64k prio 2
    tc qdisc add dev $if parent 1:1 handle 101 sfq perturb 10

    # class for vlan1
    tc class add dev $if parent 1:1 classid 1:106 htb quantum 1000000 rate 1.00mbit ceil 1.00mbit burst 6k
    tc qdisc add dev $if parent 1:106 handle 107 sfq perturb 10
    tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan1})" flowid 1:106

    # class for vlan2
    tc class add dev $if parent 1:1 classid 1:108 htb quantum 1000000 rate 1.00mbit ceil 10.00mbit burst 6k
    tc qdisc add dev $if parent 1:108 handle 108 sfq perturb 10
    tc filter add dev $if protocol all parent 1: prio 100 basic match "meta(vlan mask 0xfff eq ${vlan2})" flowid 1:108

}

qos eth1 1234 1235
qos eth2 2345 2346
Nick Craig-Wood
la source
Étrange, protocol allm'a donné une erreur dans le noyau vanille. Je devrais vérifier plus. Je vous remercie.
brownian
1

Je recommanderais d'utiliser Wireshark pour capturer ce qui passe par l'interface comme visible dans l'espace utilisateur et l'utiliser pour écrire le filtre. Je me demande si l'interface supprime peut-être les balises VLAN pour une raison quelconque (bien qu'elle soit configurée pour un pont transparent). Peut-être que cela ajoute des balises supplémentaires ou quelque chose?

Falcon Momot
la source
Non, cela ne supprime pas la balise VLAN, certainement - tout fonctionne (le trafic est commuté via des troncs sur les commutateurs matériels), à l'exception des filtres dans le shaper. Je vais cependant regarder de plus près. J'ai regardé la capacité de déchargement des balises VLAN, mais ces pilotes ne sont pas capables de faire un déchargement vidéo.
brownian
tcpdumpaffiche les ID vlan sur toutes les interfaces bridgeet tous les ports informatiques.
brownian
Maintenant, mon joli shaper fonctionne avec un noyau linux 3.3.4, tout fonctionne très bien sauf le filtrage de balises 8021q (je peux vivre sans). Le problème n'est toujours pas résolu. Merci quand même.
brownian
1

Vous pouvez marquer des paquets vlan avec ebtables .

# mark packets according to the vlan id
ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 1 -j mark --mark-set 1
ebtables -i br0 -A PREROUTING -p 802_1Q --vlan-id 5 -j mark --mark-set 2

Ensuite, appliquez une mise en forme basée sur les marquages. ebtables et iptables partagent le même marquage.

Je ne l'ai pas encore fait moi-même. Donc c'est plutôt une intuition.

rhasti
la source
Je doute que cela fonctionnera sans problème sur le lien 10 Go ... Je voudrais éviter les * tables. Merci pour la suggestion quand même.
brownian
@brownian vous pensez que faire exactement le même filtrage dans iproute2 sera plus performant? C'est le même noyau, le même chemin de code, les mêmes algorithmes. Tant que vous ne faites pas accidentellement quelque chose comme activer le suivi des connexions, vous ne devriez pas voir de différence. * les tableaux peuvent avoir un impact sur les performances car ils peuvent faire beaucoup de choses complexes. Mais cela ne signifie pas que ce sera le cas .
tylerl
@tylerl Puisque je dois filtrer avec iproute2 (des centaines de clients dans le même vlan, un tas de filtres hachés) - toute autre vérification supplémentaire pour chaque paquet aura un impact sur les performances, je crois.
brownian
0

Essayez de désactiver l' reorder_hdroption sur l'interface vlan. Si l'option de réorganisation de l'en-tête est activée, les balises des cadres sont supprimées. Vérifiez-le par commande ip -d link list dev vlan_iface.

Un homme maléfique
la source
1
Pouvez-vous préciser quand il est retiré et quand il est réinséré? Je veux dire, un cadre balisé entre dans un pont Linux et le quitte ensuite d'une autre interface - quand / où ces manipulations de balises se produisent, et quand / où les tcfiltres sont appelés? Avez-vous un lien vers une carte ou comme ça? Merci!
brownien
S'il vous plaît, une autre pensée: quelle interface vlan voulez-vous dire? Ce pont n'a pas d'interface vlan unique (j'ai écrit "Je veux dire, aucune interface VLAN n'est là" dans le premier paragraphe).
brownian