Должно ли ядро ​​Linux выполнять «повторное присоединение IGMP» при установлении соединения?

Должно ли ядро ​​Linux выполнять «повторное присоединение IGMP» при установлении соединения?

Этот вопрос почти такой же, как и более старый неотвеченный вопрос, найденныйздесьв списке рассылки ядра (спасибо Саймону Пайярду). Вот (перефразированный) обзор:

Когда хост, работающий под управлением ядра Linux, подключен к коммутатору с включенным IGMP-отслеживанием, мы имеем следующий сценарий:

  • Интерфейс является членом многоадресной группы. Выполняются (присоединяются) отчеты.
  • Произошел сбой связи (например, отключение кабеля).
  • Коммутатор очищает многоадресное членство для этого порта.
  • Связь восстанавливается (например, кабель снова подключается).
  • На этом этапе ядро ​​ждет запроса от коммутатора, прежде чем отправить новый запрос на присоединение к IGMP.
  • Это означает, что приложение пропускает пакеты между моментом восстановления соединения и запланированным общим запросом (значение по умолчанию в RFC: 125 секунд).

Кажется, это указывает на то, что ядро ​​Linux не заботится о повторной отправке joins после повторного подключения. Может ли кто-нибудь с более глубоким знанием спецификации IGMP подтвердить, должны ли rejoins повторно отправляться после повторного подключения?

Является ли задачей приложения пользовательского уровня проверку наличия сбоев в соединении и повторную отправку запросов на присоединение к коммутатору при повторном подключении?

Интересно, что ядро ​​Windows, похоже, заботится о повторной отправке запросов на присоединение, когда соединения восстанавливаются после сбоя.

решение1

Логично, я так думаю. Потому что я вижу это в коде Linux IPv6. ИЗапрос на предложение (ЗП)говорится, что отслеживание IPv6 MLD должно быть очень похоже на отслеживание IPv4 IGMP.

На практике этот код addrconf был добавлен для ipv6 - где ядро ​​поддерживает DAD и RS/RA. Я не удивлюсь, если в текущих версиях ядра нет эквивалента для ipv4.

    } 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

Связанный контент