この質問は、以前に見つかった未回答の質問とほぼ同じです。ここカーネルのメーリングリストにあります(Simon Paillardに感謝します)。 (疑わしい)要約は次のとおりです。
Linuxカーネルを実行しているホストがIGMPスヌーピングが有効なスイッチに接続すると、次のシナリオが発生します。
- インターフェイスはマルチキャストグループのメンバーです。レポートを実行(結合)します。
- リンクエラーが発生しました(ケーブルの切断など)。
- スイッチはポートのマルチキャストメンバーシップを更新します。
- リンクの回復(例:ケーブルの再接続)
- この時点で、カーネルは新しい IGMP メンバーシップ要求を送信する前にスイッチのクエリを待ちます。
- これは、リンクが再開される時間とネストされた計画された一般クエリ(RFCのデフォルト値:125秒)の間でアプリケーションがパケットを失うことを意味します。
これは、Linuxカーネルが再接続した後に接続を再送信することを担当していないことを示しているようです。 IGMP仕様をより深く理解している人なら誰でも再接続時に再結合を再送信する必要があるかどうかを確認できますか?
リンク障害を確認し、再接続時にスイッチへの結合要求を再発行するのはユーザーレベルのアプリケーションの作業ですか?
興味深いことに、Windowsカーネルは、リンクがハングした後に再接続したときに結合要求を再送信する役割を担っているようです。
答え1
論理的にはそうだと思います。これはLinuxのIPv6コードで見ることができるからです。しかもRFCIPv6 MLDスヌーピングは、IPv4 IGMPスヌーピングと非常によく似ている必要があります。
実際、このaddrconfコードは、カーネルがDADとRS / RAをサポートするipv6に追加されました。現時点では、カーネルバージョンに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