¿Cómo configurar macvtap para que pase el paquete de multidifusión correctamente?

4

Estoy tratando de crear máquinas virtuales que puedan verse y hospedarse. Están alojados con qemu / kvm y se administran a través de libvirt. El adaptador de red de VM se crea con macvtap (modo VEPA) para el rendimiento.

Después de habilitar hairpinel cambio, la transmisión de unidifusión está bien, sin importar entre las máquinas virtuales o entre la máquina virtual y el host.

Sin embargo, cuando se trata de multidifusión, me enfrento con un problema. Encuentro que el host no puede hacer ping6 en cada VM. Con tcpdump, observo que ff02::1:ff00:212mi VM no recibe el paquete de solicitud de vecino a la dirección de multidifusión del host, cuya dirección ipv6 es 2001:da8:a0:600::212/64. Obviamente, este paquete de multidifusión debería haber sido pasado a VM por macvtap.

Como resultado del problema de la multidifusión, todo el paquete ipv6 se pierde porque Neighbor Discovery no puede funcionar correctamente.

Estoy seguro de que no hay nada con el conmutador, porque cuando ejecuto tcpdump sobre el adaptador de red físico, puedo ver la Solicitud de vecinos dos veces por segundo, una fuera, una adentro.

Después de configurar la interfaz macvtap sobre el host en modo promiscuo, la VM obtiene el paquete de Solicitud de vecinos, junto con algún otro paquete de multidifusión que debería ser filtrado por macvtap, pero no un paquete de unidifusión a otra VM, incluso cuando hago ping a otras 6 VM en anfitrión al mismo tiempo.

Entonces, creo que habilitar el modo promiscuo en toda la interfaz macvtap es una solución aceptable pero no elegante.

Todo mi host y VM es CentOS 7.0. Intenté instalar kernel-ml (linux 4.1.3) desde elrepo en mi host, pero no hay diferencia.

Entonces:

  1. ¿Cómo puedo configurar toda la interfaz macvtap en modo promiscuo cada vez que se inicia libvirt?
  2. No estoy familiarizado con el controlador de red. Pero de acuerdo con http://www.makelinux.net/ldd3/chp-17-sect-14 , sospecho que hay algunos errores en el controlador de macvlan para que el núcleo no pueda establecer la lista de multidifusión de la interfaz correctamente . Sin embargo, no hay set_multicast_list en linux / driver / net / {macvlan.c, macvtap.c}. ¿Dónde está el lugar correcto para buscar ayuda?

Ver también: https://bugzilla.redhat.com/show_bug.cgi?id=1035253

Dado92
fuente

Respuestas:

3

MacVlan de libvirt ha ganado soporte para multidifusión. Desafortunadamente, por defecto está deshabilitado, por trustGuestRxFilters=no, y la documentación no es explícita de que esto interrumpe la multidifusión y, por lo tanto, IPv6.

https://bugzilla.redhat.com/show_bug.cgi?id=1035253#c15

En mi opinión, el modelo natural sería permitir la multidifusión por defecto. macvlan permite la suplantación de MAC de todos modos, así como el envío a direcciones de multidifusión. Bloquear la recepción de multidifusión (pero no la transmisión) en una red a la que crees que estás conectado directamente es una sorpresa desagradable.

sourcejedi
fuente
Acabo de descubrir esta solución ocasionalmente. Muchas gracias. Esta característica requiere adicionalmente documentada.
Dado92
Gracias, eso causó muchos dolores de cabeza. Creo que tiene razón, sería natural configurar IPv6 (con la intención de que se use) y esperar que las cosas simplemente funcionen y la multidifusión es una parte tan esencial de IPv6 que agregar algo confuso libvirt config kungfu para que funcione no es obvio y útil aquí o al menos dar una advertencia de que necesita un modo promisorio en su interfaz macvtap mitigaría la situación poco clara.
3ronco
1

La respuesta de sourcejedi contiene la solución, pero tal vez no lo suficientemente explícita. Usando "virsh edit", configure el trustGuestRxFiltersatributo en el dispositivo de red:

<interface type='direct' trustGuestRxFilters='yes'>

Ver libvirt docs . Lo mismo se puede hacer para todas las interfaces en una red libvirt .

uncleremus
fuente
0

enfrentó el mismo problema con macvtap. Encontré una forma de solucionarlo, pero no sé cómo automatizarlo dentro de virsh. sudo ip link set dev macvtap0 allmulticast on

usuario1907661
fuente
Es más elegante que promisc, pero esto sigue siendo una solución. La única forma en que podría resolver configurarlo automáticamente es crontab.
Dado92
0

Encontré una solución, aunque no estoy muy seguro de si es completamente correcta.

Configure un enlace libvirt en el que active ALLMULTI después de que se inicie el dominio qemu.

/ etc / libvirt / hook / qemu

#!/bin/bash

if [ "$2" == "started" ]; then
 timestamp=$(date +"%Y-%m-%d %H:%M:%S")
 exists=$(ifconfig | grep macvtap0 | wc -l)

 if [ "$exists" -gt "0" ]; then
   ifconfig macvtap0 allmulti
   echo "$timestamp ALLMULTI set on macvtap0" >> /var/log/libvirt_hook_qemu.log
 fi
fi

El script me funciona en Ubuntu 14.04.3 + KVM / libvirt.

gargii
fuente
Esta solución no es perfecta para una gran cantidad de paquetes en la red ipv6.
Dado92
0

Esto es propiamente malo, pero si no desea habilitar toda la multidifusión, parece funcionar en el host:

bridge fdb add 33:33:ff:<lower 24 bits of v6 address> dev <macvtap if>

(permite la recepción de solo el grupo de multidifusión de nodo solicitado para una dirección v6 particular)

anarquético
fuente