TC u32: ¿cómo hacer coincidir los protocolos L2 en los núcleos recientes?

12

Tengo un buen moldeador, con filtrado hash, construido en un puente de Linux. En resumen, las br0conexiones externaly internallas interfaces físicas, los paquetes etiquetados con VLAN se conectan "transparentemente" (es decir, no hay interfaces VLAN allí).

Ahora, diferentes núcleos lo hacen de manera diferente. Puedo estar equivocado con los rangos exactos de versiones de kernel, por favor perdóname. Gracias.

2.6.26

Entonces, en debian, 2.6.26 y superior (hasta 2.6.32, creo) --- esto funciona:

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

Aquí, "kernel" coincide con dos bytes en el campo "protocolo" con 0x8100, pero cuenta el comienzo del paquete ip como una "posición cero" (perdón por mi inglés, si no estoy claro).

2.6.32

Nuevamente, en debian (no he construido el núcleo de vainilla), 2.6.32-5 --- esto funciona:

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

Aquí, "kernel" coincide con el mismo protocolo, pero cuenta el desplazamiento desde el comienzo del encabezado de este protocolo --- Tengo que agregar 4 bytes al desplazamiento (20, no 16 para la dirección dst). Está bien, parece más lógico, en cuanto a mí.

3.2.11, el último establo ahora

Esto funciona --- como si no hubiera una etiqueta 802.1q en absoluto:

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

El problema es que hasta ahora no pude encontrar una manera de hacer coincidir la etiqueta 802.1q.

Etiqueta 802.1q coincidente en el pasado

Podría hacer esto antes de la siguiente manera:

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

Ahora soy incapaz de igualar 802.1q etiqueta con at 0, at -2, at -4, at -6o por el estilo. El principal problema que tengo cero éxitos cuentan --- este filtro no se está comprobando en absoluto "protocolo equivocado", en otras palabras.

Por favor, alguien, ayúdenme :-)

¡Gracias!

browniano
fuente

Respuestas:

4

La etiqueta VLAN se elimina de skb en los núcleos recientes. Pruebe algo como esto para hacer una meta coincidencia en skb:

tc filter add dev internal protocol all parent 1:0 prio 100 basic match 'meta(vlan mask 0xfff eq 0x0ed8)' flowid 1:300
Así
fuente
Un intento de agregar un filtro raíz protocol allme da RTNETLINK answers: Invalid argument(3.3.4 kernel aquí). Probaré esto con núcleos más nuevos. Gracias.
brownian
Esto funcionó para mí con Debian Wheezy Kernel 3.2.0. He agregado otra respuesta con todos los detalles.
Nick Craig-Wood
3

Tenía que hacer exactamente esto. Descubrí que la respuesta sugerida por @Thusitha era la forma correcta de hacerlo para los nuevos núcleos.

Probado con Debian Wheezy Kernel 3.2.0-4 e iproute (de donde proviene el comando tc) versión 20120521-3 + b3

Aquí está el script completo, las tc filterlíneas son casi exactamente como lo especifica @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
fuente
Extraño, protocol allme dio un error en el núcleo de vainilla. Debería comprobarlo más. Gracias.
brownian
1

Recomendaría usar wireshark para capturar lo que pasa por la interfaz como visible en el espacio de usuario, y usar eso para escribir el filtro. Me pregunto si tal vez la interfaz está eliminando las etiquetas de VLAN por alguna razón (a pesar de estar configurada para conectarse de forma transparente). ¿Quizás está agregando etiquetas adicionales o algo así?

Falcon Momot
fuente
No, definitivamente no está eliminando la etiqueta VLAN: todo funciona (el tráfico se conmuta a través de troncales en los conmutadores de hardware), excepto los filtros en el modelador. Sin embargo, miraré más de cerca. Observé la capacidad de descarga de etiquetas VLAN, pero esos controladores no son capaces de descargar videos.
brownian
tcpdumpmuestra ID de vlan en todas las interfaces bridgey puertos.
brownian
Ahora mi buen shaper funciona en Linux kernel 3.3.4, todo funciona muy bien, excepto el filtrado de etiquetas 8021q (puedo vivir sin él). El problema sigue sin resolverse. Gracias de todos modos.
browniano
1

Puede marcar paquetes vlan con 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

Luego aplique la conformación basada en las marcas. ebtables e iptables comparten la misma marca.

No lo he hecho yo todavía. Entonces es más bien una corazonada.

rhasti
fuente
Dudo que funcione sin problemas en el enlace de 10 Gb ... Me gustaría evitar las tablas *. Gracias por la sugerencia de todos modos.
brownian
@brownian ¿crees que hacer exactamente el mismo filtrado en iproute2 será un mayor rendimiento? Es el mismo núcleo, la misma ruta de código, los mismos algoritmos. Mientras no haga accidentalmente algo como activar el seguimiento de conexión, no debería ver la diferencia. * las tablas pueden afectar el rendimiento porque puede hacer muchas cosas complejas. Pero eso no significa que lo hará .
tylerl
@tylerl Desde que en realidad tengo para filtrar con iproute2 (cientos de clientes en la misma VLAN, un grupo de filtros hashes) - cualquier otra comprobación adicional para cada paquete va afectar al rendimiento, creo.
brownian
0

Intente desactivar la reorder_hdropción en la interfaz vlan. Si la opción de reordenar encabezado está habilitada, las etiquetas de los marcos se eliminarán. Compruébelo por comando ip -d link list dev vlan_iface.

Hombre malvado
fuente
1
Por favor, ¿puede aclarar cuándo se quita y cuándo se vuelve a insertar? Quiero decir, un marco etiquetado entra en el puente de Linux y luego sale de otra interfaz: ¿cuándo / dónde ocurren estas manipulaciones de etiquetas y cuándo / dónde tcse llaman los filtros? ¿Tienes un enlace a un mapa o algo así? ¡Gracias!
brownian
Por favor, otro pensamiento: ¿a qué interfaz vlan te refieres? Ese puente no tiene una interfaz vlan (escribí "Quiero decir, no hay interfaces VLAN allí" en el primer párrafo).
browniano