Ethernetの源別multicastとINCLUDE・EXCLUDE¶
文書バージョン:1.2.0
対象GitHubバージョン:v1.2.0
文書ID:guide-ethernet-source-filter
文書状態:公開用完成稿
更新履歴¶
| 文書バージョン | 更新日 | 更新内容 |
|---|---|---|
1.2.0 |
2026-10-22 |
v1.2.0の対象タグ・文書版を確定。過去の測定基準と公開済み履歴を保持 |
1.1.0 |
2026-10-16 |
初版:源別membershipのmodeだけを変える6入力実習、正式版実測、期限後のfloodと実Viewerを追加 |
目的:同じgroupでも送信元によって配送を選ぶ¶
multicastは複数の受信先へ送る仕組みです。静的multicastの実習ではgroupに対する出口を固定しました。今回は動的Ethernetの源別membershipを使い、「このgroupのうち、どのIP送信元をこのportへ配送するか」を調べます。
要求は、送信元集合の意味と、配送先が0になる場合、登録期限が切れた場合を説明できることです。集合を 192.0.2.1 の一つに固定し、modeだけを変えます。include は集合にある送信元を受理し、exclude は集合にない送信元を受理します。送るframeのIP送信元も 192.0.2.1 なので、同じ集合でも最初の配送先が変わります。
profileは ethernet.l2.dynamic.v1。数値と画面は正式v1.1.4 Release、source b45515644dfc65c205216d564d5bf7ef00280622 から取得しました。掲載時のmain c67e153cc3bcf1f6ac0303d23023ce8ae4a4f533 に含まれる後続NED修正は、この正式版の測定へ含めていません。
構成と責務:Switchの登録とEndpointの購読を分ける¶
公開Ethernetの1 Switch・3 Endpoint配線を変更せず使います。物理配線は次の往復3組です。矢印は今回主に使う方向です。
Main.a.tx → Main.sw.rx_a Main.sw.tx_a → Main.a.rx
Main.b.tx → Main.sw.rx_b Main.sw.tx_b → Main.b.rx
Main.c.tx → Main.sw.rx_c Main.sw.tx_c → Main.c.rx
| 構成 | 責務・境界 | 固定する依存 |
|---|---|---|
| Endpoint a | 時刻100/3000000psに別々のframeを生成する | VID10、PCP0、payload空、IP送信元192.0.2.1・group239.1.1.1 |
| Link | wire直列化と伝搬を表す | 1Gbps・伝搬1000ps、全link up |
| Switch sw | IPのfamily/group/sourceに対する登録を検索し、候補portを選ぶ | tx_bに一つのmembership、静的L2 multicast集合は空、router登録なし |
| 動的control | membershipを時刻0に設定し、2000000psに失効させる | mode以外のkey・sources・lifetimeは同一 |
| Endpoint b/c | 届いたL2 multicastを静的購読条件で受け付ける | 両者ともVID10・MAC01:00:5e:01:01:01を購読、RX処理0ps |
Switchの登録は (switch, VID, family, group, port) がkeyです。今回は Main.sw / 10 / ipv4 / 239.1.1.1 / Main.sw.tx_b。この登録からEndpointの購読設定を自動生成することはありません。cはL2 groupを購読していても、最初のSwitch配送候補には登録されていません。
IPv4 group 239.1.1.1 は宛先MAC 01:00:5e:01:01:01 に対応します。frameの ip_multicast は明示metadataで、payloadから実IP headerを解析する機能ではありません。family/source/group の入力整合を検査しますが、ここではdataを空にしています。
利用フロー:登録中と期限後の二つの送信を追う¶
- INIでNED・model・workloadを接続し、CLIでvalidateします。
- 時刻0にmembershipを設定します。登録の有効区間は
[0, 2000000)psです。 - aが100psに
ipv4:0を生成し、609100psにswへ到着します。swは2000psの処理後、送信元集合とmodeで候補を選びます。 - includeならb向けのcopyを一つ作ります。excludeならこの送信元は不一致で候補0です。groupのmembershipが存在するためknownとして扱い、unknown floodへ変更しません。
- 2000000psにmembershipが削除されます。これはsourcesを空に変更した状態とは異なります。
- aが3000000psに別frame
ipv4:1を生成します。到着時にはgroupの登録も静的候補もrouter登録もないのでunknownとなり、共通設定unknown_multicast=floodに従ってb/cへ配送されます。
候補選択の後もingress除外・link/VID/STPの適格性検査があります。今回はすべて固定してmodeの影響だけを比較します。静的L2候補やrouter登録を追加するとそれらとの和集合になるため、excludeだけで全配送を禁止できるとは限りません。
手順:公開入力でmodeだけを変える¶
独立6入力ZIPを展開するか、リポジトリの examples/guide/ethernet-source-filter を使います。ZIPにはリポジトリ相対のディレクトリ構成があり、他の記事の入力は不要です。
| 入力 | 内容 |
|---|---|
models/ethdemo/Main.ned |
公開Ethernet配線を変更せず同梱 |
model.json |
公開VLAN設定を動的profileへ共通整理。Endpoint購読は公開dynamic modelから使用 |
include.json / exclude.json |
公開membership負荷からIPv4送信とjoin4を取り出し、Mainの接続名へ対応付ける |
include.ini / exclude.ini |
共通model・profile・上限時刻で、対応workloadを選ぶ |
membershipの共通部分は次のとおりです。exclude.json では mode だけを "exclude" にします。sources、group、port、lifetimeは変えません。
{
"id":"join4", "at_ps":"0", "kind":"membership_set",
"switch":"Main.sw", "port":"Main.sw.tx_b", "vid":10,
"family":"ipv4", "group":"239.1.1.1", "mode":"include",
"sources":["192.0.2.1"], "lifetime_ps":"2000000"
}
正式v1.1.4の dir-simulator をPATHに置き、リポジトリ又はZIP展開先のルートから実行します。これはBash用です。
mkdir -p source-results
for case in include exclude; do
dir-simulator validate --config examples/guide/ethernet-source-filter/$case.ini &&
dir-simulator run --config examples/guide/ethernet-source-filter/$case.ini \
--output source-results/$case &&
dir-simulator view --input source-results/$case/results.json \
--output source-results/$case-viewer.html
done
PowerShellでは $case の2値を各コマンドへ順に代入して実行できます。出力親ディレクトリを先に作り、各runは未使用の出力先を指定してください。validate/run/viewの各終了0、manifestの status: complete・partial: false を確認します。runのresults.jsonとCSV・診断・manifestを保存し、そのresults.jsonから作ったViewer HTMLをブラウザーで開きます。サーバーは不要です。
実測:候補0とunknown floodを区別する¶
tag付きMACは68byte、preamble/SFD込みwireは 8×(68+8)=608 bit。1Gbpsで608000ps、伝搬1000psなので、最初のa→sw arrivalは 100+609000=609100 psです。sw処理2000ps後に転送するとSOF611100ps、b到着1220100psになります。IFG込み占有704000psは到着時刻と別です。
| 観測 | include | exclude |
|---|---|---|
| 送信元集合 | {192.0.2.1} | {192.0.2.1} |
| 最初のsw処理完了 ps | 611100 | 611100 |
| 最初の転送先 | bのみ | 0、multicast_filtered |
| 最初のb受信完了 ps | 1220100 | なし |
| membership失効 ps | 2000000 | 2000000 |
| 次のsw処理完了 ps | 3611000 | 3611000 |
| 次の転送先・受信完了 ps | b/c、両方4220000 | b/c、両方4220000 |
| generated / serialized | 2 / 5 | 2 / 4 |
| forwarded / received | 2 / 3 | 1 / 2 |
| reception filtered / copy dropped | 0 / 0 | 1 / 0 |
frame数は両方2ですが、serialized はhopごとのcopy数です。excludeでもa→sw copyは送信完了し、sw receptionが multicast_filtered になります。存在しない出口copyをqueue dropとして数えません。次のframeは最初からworkloadに指定した独立した送信で、自動再送ではありません。
両runとも上限10000000psまでのcomplete結果で、events_exhausted・pending0です。最後のイベントは4315000psの資源解放でした。membershipの期限は生成時刻やarrivalからではなく、今回のset時刻0から2000000psです。
Viewer:登録集合、受信理由、期限を同じrunで見る¶
include-viewer.htmlを開き、時刻欄に611100と入力してJumpします。Policyのmembershipを展開し、tx_b・group・mode・sources・expires_atを見ます。exclude-viewer.htmlでも同じ時刻を見ます。keyとsourcesは同じでmodeだけが違います。1300000へ進めてipv4:0のa→sw行を選ぶと、includeはb受信完了、excludeはmulticast_filteredでb/c受信なしと確認できます。1999999で登録あり、2000000で登録なしになります。前の時刻へ戻すと同じ表が復元されます。5000000でipv4:1を調べ、両条件でb/cの受信完了を確認します。
次の2枚は正式v1.1.4の実Viewerで611100psのmembershipを展開し、390px表示で取得しました。


制約と次に確認すること¶
今回の測定は単一Switch・VID10・IPv4 group一つ・送信元一つ・2 frameだけです。IPv6、複数sources、INCLUDE空/EXCLUDE空、router portとの合成、refresh/leave、表容量、STP/link変更、期限とlookupの同時刻境界の全組合せは検証していません。空INCLUDEは明示受理0、空EXCLUDEは全source受理という仕様ですが、登録自体が消える期限切れとは区別してください。
membership_setはportを代表する集約状態を明示設定する抽象controlです。実IGMP/MLDのquery/report packetを生成・解析する機能、実IP packetのchecksumやheader処理、規格全体適合の証明ではありません。測定には正式sourceのclean dev buildを使い、最適化ビルドの性能比較はしていません。
詳しい候補集合と期限は正式版の動的Ethernet仕様、検証済み範囲は動的Ethernet検証仕様を参照してください。日本語検索では「集合」「配送」でこの記事を探せます。