Esta pergunta é quase igual a uma pergunta não respondida mais antiga encontradaaquina lista de discussão do kernel (créditos a Simon Paillard). Aqui está uma recapitulação (parafraseada):
Quando um host executando o kernel Linux está conectado a um switch com espionagem IGMP habilitada, temos o seguinte cenário:
- Uma interface é membro de um grupo multicast. (Join) relatórios são executados.
- Ocorre uma falha no link (por exemplo, desconexão do cabo).
- O switch libera a associação multicast dessa porta.
- O link volta a funcionar (por exemplo, cabo reconectado).
- Neste ponto, o kernel aguarda uma consulta do switch antes de enviar uma nova solicitação de adesão ao IGMP.
- Isso significa que o aplicativo perde pacotes entre o momento em que o link volta a funcionar e o aninhamento da Consulta Geral agendada (valor padrão em RFC: 125 segundos).
Isso parece indicar que o kernel do Linux não se encarrega de reenviar junções após uma reconexão. Alguém com conhecimento mais íntimo da especificação IGMP pode confirmar se as reingressões devem ser reenviadas após a reconexão?
É tarefa do aplicativo em nível de usuário verificar falhas de link e reemitir solicitações de junção para o switch após a reconexão?
Curiosamente, o kernel do Windows parece se encarregar de reenviar solicitações de junção quando os links voltam a funcionar após serem desativados.
Responder1
Logicamente, acho que sim. Porque posso ver isso no código IPv6 do Linux. E aRFCdiz que a espionagem MLD IPv6 deve ser muito semelhante à espionagem IGMP IPv4.
Na prática, este código addrconf foi adicionado para ipv6 - onde o kernel suporta DAD e RS/RA. Eu não ficaria surpreso se não houvesse equivalente para o ipv4 nas versões atuais do kernel.
} 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