Soll der Linux-Kernel beim Herstellen einer Verbindung einen „IGMP-Rejoin“ durchführen?

Soll der Linux-Kernel beim Herstellen einer Verbindung einen „IGMP-Rejoin“ durchführen?

Diese Frage ist fast identisch mit einer älteren unbeantworteten FrageHierin der Mailingliste des Kernels (Danke an Simon Paillard). Hier ist eine (paraphrasierte) Zusammenfassung:

Wenn ein Host, auf dem der Linux-Kernel läuft, mit einem Switch verbunden ist, bei dem IGMP-Snooping aktiviert ist, ergibt sich das folgende Szenario:

  • Eine Schnittstelle ist Mitglied einer Multicast-Gruppe. (Join-)Berichte werden durchgeführt.
  • Es liegt ein Verbindungsfehler vor (z. B. eine Kabeltrennung).
  • Der Switch löscht die Multicast-Mitgliedschaft für diesen Port.
  • Die Verbindung wird wiederhergestellt (z. B. Kabel wieder angeschlossen).
  • An diesem Punkt wartet der Kernel auf eine Abfrage vom Switch, bevor er eine neue IGMP-Beitrittsmitgliedschaftsanforderung sendet.
  • Dies bedeutet, dass die Anwendung zwischen der Wiederherstellung der Verbindung und der nächsten geplanten allgemeinen Abfrage Pakete verpasst (Standardwert in RFC: 125 Sekunden).

Dies scheint darauf hinzudeuten, dass der Linux-Kernel sich nicht um das erneute Senden von Joins nach einer erneuten Verbindung kümmert. Kann jemand mit genaueren Kenntnissen der IGMP-Spezifikation bestätigen, ob erneute Joins bei einer erneuten Verbindung erneut gesendet werden sollen?

Ist es die Aufgabe der Anwendung auf Benutzerebene, nach Verbindungsfehlern zu suchen und bei erneuter Verbindung erneut Verbindungsanforderungen an den Switch zu senden?

Interessanterweise scheint der Windows-Kernel sich darum zu kümmern, dass Verbindungsanforderungen erneut gesendet werden, wenn Verbindungen nach einer Unterbrechung wiederhergestellt werden.

Antwort1

Logischerweise denke ich schon. Weil ich es im Linux IPv6-Code sehen kann. Und dieRFCbesagt, dass IPv6-MLD-Snooping dem IPv4-IGMP-Snooping sehr ähnlich sein soll.

In der Praxis wurde dieser Addrconf-Code für IPv6 hinzugefügt – wo der Kernel DAD und RS/RA unterstützt. Es würde mich nicht überraschen, wenn es in aktuellen Kernel-Versionen kein Äquivalent für IPv4 gibt.

    } else if (event == NETDEV_CHANGE) {
        if (!addrconf_link_ready(dev)) {
            /* device is still not ready. */
            rt6_sync_down_dev(dev, event);
            break;
        }

        if (!IS_ERR_OR_NULL(idev)) {
            if (idev->if_flags & IF_READY) {
                /* device is already configured -
                 * but resend MLD reports, we might
                 * have roamed and need to update
                 * multicast snooping switches
                 */
                ipv6_mc_up(idev);
                change_info = ptr;
                if (change_info->flags_changed & IFF_NOARP)
                    addrconf_dad_run(idev, true);
                rt6_sync_up(dev, RTNH_F_LINKDOWN);
                break;
            }
            idev->if_flags |= IF_READY;
        }

        pr_info("ADDRCONF(NETDEV_CHANGE): %s: link becomes ready\n",
            dev->name);

https://elixir.bootlin.com/linux/v5.1/source/net/ipv6/addrconf.c#L3546

verwandte Informationen