¿Exactamente cuándo se realiza PMTUD? (Descubrimiento de MTU de ruta)

21

En las discusiones que han surgido de otras preguntas en este sitio , me di cuenta de que no tengo una comprensión sólida de cuándo se realiza Path MTU Discovery (PMTUD).

lo que hace: descubre la MTU más baja en una ruta del Cliente al Servidor).
cómo lo hace: envíe paquetes progresivamente más grandes con su conjunto de bits "No fragmentar" y vea qué tan grande de un paquete puede pasar sin obtener un error "ICMP Need to Fragment".

Mi pregunta es específicamente entonces, ¿ cuándo realizará un host PMTUD?

Estoy buscando casos específicos. No solo algo genérico como "cuando un host quiere descubrir la ruta MTU". Puntos de bonificación si puede proporcionar una captura de paquetes de un host que lo hace, o proporcionar instrucciones para generar dicha captura de paquetes.

Además, me refiero específicamente a IPv4. Sé que en IPv6 los enrutadores transitorios no son responsables de la fragmentación, y puedo imaginar que PMTUD ocurre con mucha más frecuencia. Pero por ahora, estoy buscando ejemplos específicos de PMTUD en IPv4. (aunque si la única captura de paquetes que puede armar de PMTUD está en IPv6, me encantaría verla)

Eddie
fuente
¿Se realiza PMTUD desde la MTU más baja a la más alta? ¿O el dispositivo que realiza PMTUD prueba primero la MTU más grande y luego baja en un gran incremento hasta que el paquete pasa y luego sube en incrementos más pequeños, luego alterna de ida y vuelta hasta que se haga una determinación final?
cpt_fink
@cpt_fink, hay algunas estrategias. Las implementaciones modernas del mensaje de Fragmentación necesaria de ICMP incluyen en la carga útil de ICMP la MTU del enlace para el que se requería fragmentación. Eso lo hace fácil, ya que el host inicial sabe de inmediato cuál es la ruta MTU. Las implementaciones más antiguas tienen que usar varias estrategias para 'buscar' la MTU correcta para usar. Esas estrategias se describen en RFC1191 en la Sección 5. Varían desde el valor predeterminado automático al IP mínimo (576), hasta el uso de una tabla de MTU 'comunes' para buscar de manera más eficiente (ver RFC1191 Sección 7.1).
Eddie
2
Esta es una pregunta interesante. Estaba investigando sobre PMTUD y encontré esto. Aunque es viejo, decidí responder porque tenía exactamente la misma pregunta y después de algunas horas de investigación pude encontrar una respuesta bastante decente (supongo). Intentaré actualizar y apoyar mi respuesta con una captura de paquetes mañana, si es posible.
Filipe Gonçalves

Respuestas:

15

La respuesta es simple: cuando el anfitrión lo desee. De Verdad. Es así de simple.

La explicación a continuación asume un entorno de solo IPv4, ya que IPv6 elimina la fragmentación en los enrutadores (obligando al host a lidiar siempre con la fragmentación y el descubrimiento de MTU).

No existe una regla estricta que rija cuándo (o incluso si) un host realiza Path MTU Discovery. La razón por la que surgió PMTUD es que la fragmentación se considera dañina por varias razones. Para evitar la fragmentación de paquetes, el concepto de PMTUD se hizo realidad como una solución alternativa. Por supuesto, un buen sistema operativo debería usar PMTUD para minimizar la fragmentación.

Entonces, naturalmente, la semántica exacta de cuándo se usa PMTUD depende del sistema operativo del remitente, en particular, la implementación del socket. Solo puedo hablar para el caso específico de Linux, pero otras variantes de UNIX probablemente no son muy diferentes.

En Linux, PMTUD está controlado por la IP_MTU_DISCOVERopción de socket. Puede recuperar su estado actual getsockopt(2)especificando el nivel IPPROTO_IPy la IP_MTU_DISCOVERopción. Esta opción es válida SOCK_STREAMsolo para sockets (un SOCK_STREAMsocket es un socket confiable bidireccional, orientado a la conexión; en la práctica es un socket TCP, aunque son posibles otros protocolos), y cuando se configura, Linux realizará PMTUD exactamente como se define en RFC 1191.

Tenga en cuenta que, en la práctica, PMTUD es un proceso continuo; los paquetes se envían con el conjunto de bits de DF, incluidos los paquetes de protocolo de enlace de 3 vías, puede considerarlo como una propiedad de conexión (aunque una implementación puede estar dispuesta a aceptar un cierto grado de fragmentación en algún momento y dejar de enviar paquetes con el DF conjunto de bits). Por lo tanto, PMTUD es solo una consecuencia del hecho de que todo en esa conexión se envía con DF.

¿Qué pasa si no configuras IP_MTU_DISCOVER?

Hay un valor por defecto. Por defecto, IP_MTU_DISCOVERestá habilitado en los SOCK_STREAMsockets. Esto se puede leer o cambiar leyendo /proc/sys/net/ipv4/ip_no_pmtu_disc. Un valor cero significa que IP_MTU_DISCOVERestá habilitado por defecto en los nuevos sockets; un no cero significa lo contrario.

¿Qué pasa con los enchufes sin conexión?

Esto es complicado porque los enchufes no confiables y sin conexión no retransmiten segmentos perdidos. Se convierte en responsabilidad del usuario empaquetar los datos en fragmentos del tamaño de MTU. Además, se espera que el usuario realice las retransmisiones necesarias en caso de un mensaje de error demasiado grande . Entonces, esencialmente el código de usuario debe reimplementar PMTUD. Sin embargo, si está preparado para el desafío, puede forzar el bit DF pasando la IP_PMTUDISC_DObandera a setsockopt(2).

La línea de fondo

  • El anfitrión decide cuándo (y si) usar PMTUD
  • Cuando usa PMTUD, es como un atributo de conexión, sucede continuamente (pero en cualquier momento la implementación es libre de dejar de hacerlo)
  • Los diferentes sistemas operativos utilizan enfoques diferentes, pero por lo general, los enchufes confiables y orientados a la conexión realizan PMTUD por defecto, mientras que los enchufes no confiables y sin conexión no
Filipe Gonçalves
fuente
4

Normalmente, el descubrimiento de unidad de transmisión máxima de ruta (PMTUD) ocurre cada vez que un host piensa que un paquete se descartó debido a que es demasiado grande.

Esto puede ser en respuesta a la respuesta de fragmentación requerida de ICMP (tipo 3, código 4) que indica explícitamente que el paquete se descartó. En la práctica típica, todos los paquetes IPv4 se configuran con el conjunto de indicadores "no fragmentar" (DF), por lo que cualquier paquete que supere la MTU generará dicha respuesta. IPv6 no admite fragmentación en absoluto.

Algunos enrutadores o firewalls de host eliminan todos los ICMP a menudo porque un administrador ingenuo cree que ICMP es un riesgo de seguridad . O, algunos esquemas de agregación de enlaces pueden interrumpir la entrega de ICMP . En RFC4821 se propone un mecanismo alternativo para descubrir la MTU que no se basa en ICMP .

tracepathes mi herramienta de Linux favorita para probar MTU. Aquí hay un ejemplo de un host con una MTU 9001 en la LAN, pero que debe atravesar una VPN IPsec para llegar a 10.33.32.157:

$ tracepath -n 10.33.32.157
 1?: [LOCALHOST]                                         pmtu 9001
 1:  10.1.22.1                                             0.122ms pmtu 1500
 1:  169.254.3.1                                           1.343ms pmtu 1422
 1:  10.255.254.61                                        23.790ms 
 2:  no reply
^C [this host won't return an ICMP port unreachable, so tracepath won't terminate]

Los errores ICMP se pueden observar con tcpdump:

$ sudo tcpdump -p -ni eth0 'icmp and icmp[0] == 3 and icmp[1] == 4'
14:46:57.313690 IP 10.1.22.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1500), length 36
14:46:57.315080 IP 169.254.3.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1422), length 556

Los descubrimientos de MTU se almacenan en caché. En Linux, esto se puede observar y enjuagar ip(tenga cuidado con los cambios desde Linux 3.6 ):

$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache  expires 591sec mtu 1422
$ sudo ip route flush cache
$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache

Para TCP, se puede evitar exceder la MTU como parte de la configuración de la conexión. En el SYN enviado por cada extremo se incluye un tamaño máximo de segmento (MSS). El encabezado TCP (20 bytes excluyendo opciones ) y el encabezado IP (20 bytes) significan que MSS y MTU están relacionados por una diferencia de 40 bytes.

Aquí hay un ejemplo de una configuración de conexión entre estos dos hosts al transferir un archivo grande con scp:

$ sudo tcpdump -p -ni eth0 'host 10.33.32.157 and tcp[13]&2 == 2'
IP 10.1.22.194.45853 > 10.33.32.157.22: Flags [S], seq 634040018, win 26883, options [mss 8961,sackOK,TS val 10952240 ecr 0,nop,wscale 7], length 0
IP 10.33.32.157.22 > 10.1.22.194.45853: Flags [S.], seq 1371736848, ack 634040019, win 26847, options [mss 1379,sackOK,TS val 10824267 ecr 10952240,nop,wscale 7], length 0

En el primer paquete, el host local propone un MSS de 8961. Esta es la MTU 9001 configurada, menos 40 bytes. El SYN / ACK devuelto tiene un MSS de 1379, lo que implica una MTU de 1419. Sé que en esta red el host remoto también envió 8961, pero un enrutador ha modificado el valor ya que sabe que la ruta incluye una ruta de Internet ( MTU 1500) una sobrecarga desde un túnel IPsec. Este enrutador también modificó nuestro MSS enviado de 8961 para que aparezca como 1419 en el otro host. Esto se llama sujeción MSS .

Entonces, en cierto sentido, PMTUD está sucediendo todo el tiempo. En la práctica, puede que nunca suceda si la sujeción de MSS está en su lugar y todo el tráfico se produce a través de TCP, o si ninguno de los enrutadores tiene una MTU menor que la configurada en los puntos finales. Incluso sin la sujeción de MSS, puede ocurrir solo en raras ocasiones, cuando caduca el caché.

Phil Frost
fuente