どうやら、今のところ Network Namespace 1 内では Linux Bridge の STP (Spanning Tree Protocol) がサポートされていないようだ。 今回は、以下のような実験を通して、それを実際に確かめてみる。
- 単一の Linux Bridge 内にループを作ってストームを引き起こす
- Linux Bridge の STP 機能を有効にしてストームが止まるか確かめる
使った環境は次のとおり。
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=20.04 DISTRIB_CODENAME=focal DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS" $ uname -rm 5.4.0-91-generic aarch64 $ ip -V ip utility, iproute2-ss200127 $ brctl -V bridge-utils, 1.6
もくじ
下準備
あらかじめ、必要なパッケージをインストールしておく。
$ sudo apt-get -y install iproute2 tcpdump bridge-utils watch
Network Namespace を使わずに STP が機能することを確かめる
まずは、システムをそのまま使って Linux Bridge の STP が機能することを確かめておく。
はじめに Linux Bridge を br0
という名前で追加する。
$ sudo ip link add dev br0 type bridge
veth (Virtual Ethernet) ペアを br-veth0
と br-veth1
という名前で用意する。
$ sudo ip link add br-veth0 type veth peer name br-veth1
一応、ドキュメンテーションアドレスの MAC アドレスを付与しておく。
$ sudo ip link set dev br-veth0 address 00:00:5E:00:53:01 $ sudo ip link set dev br-veth1 address 00:00:5E:00:53:02
インターフェイスの状態を UP にする。
$ sudo ip link set br-veth0 up $ sudo ip link set br-veth1 up
そして、両方のインターフェイスを先ほど作った br0
に所属させる。
これでループができる。
$ sudo ip link set br-veth0 master br0 $ sudo ip link set br-veth1 master br0
ただし、この時点ではブリッジの状態が DOWN のままなので、何も流れていない。
$ ip -s link show br0 3: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 00:00:5e:00:53:02 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0
おもむろにブリッジを UP にしてみよう。
$ sudo ip link set br0 up
すると、そのうちにすごい勢いでパケット数のカウンタが増えだすはず。 ストームが生じている。
$ ip -s link show br0 3: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 00:00:5e:00:53:02 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 2734413272 38328896 0 0 0 38328896 TX: bytes packets errors dropped carrier collsns 2909638 33833 0 0 0 0
watch コマンドとか使って確認するとわかりやすい。
$ watch -n 1 ip -s link show br0
tcpdump コマンドを使って確認すると IPv6 の NDP (Neighbor Discovery Protocol) が原因になっているはず。 中身は NA (Neighbor Advertisement) だったり RS (Router Solicitation) だったり、最初に流れるパケット次第。
$ sudo tcpdump -tnel -i br0 -c 5 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes 00:00:5e:00:53:02 > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86: fe80::200:5eff:fe00:5302 > ff02::1: ICMP6, neighbor advertisement, tgt is fe80::200:5eff:fe00:5302, length 32 00:00:5e:00:53:02 > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86: fe80::200:5eff:fe00:5302 > ff02::1: ICMP6, neighbor advertisement, tgt is fe80::200:5eff:fe00:5302, length 32 00:00:5e:00:53:02 > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86: fe80::200:5eff:fe00:5302 > ff02::1: ICMP6, neighbor advertisement, tgt is fe80::200:5eff:fe00:5302, length 32 00:00:5e:00:53:02 > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86: fe80::200:5eff:fe00:5302 > ff02::1: ICMP6, neighbor advertisement, tgt is fe80::200:5eff:fe00:5302, length 32 00:00:5e:00:53:02 > 33:33:00:00:00:01, ethertype IPv6 (0x86dd), length 86: fe80::200:5eff:fe00:5302 > ff02::1: ICMP6, neighbor advertisement, tgt is fe80::200:5eff:fe00:5302, length 32 5 packets captured 11083 packets received by filter 11051 packets dropped by kernel
ここで、ブリッジの STP を有効にしてみよう。
$ sudo brctl stp br0 on
$ brctl show br0
bridge name bridge id STP enabled interfaces
br0 8000.00005e005302 yes br-veth0
br-veth1
上記では、STP によってループがちゃんと遮断されてストームがピタっと止まるはず。
確認が終わったら一旦ブリッジは削除しておく。
$ sudo ip link delete br0
Network Namespace で STP が機能しないことを確かめる
では、続いて Network Namespace 内に作った Linux Bridge でも確かめてみよう。
まずは、bridge
という名前で Network Namespace を作成する。
$ sudo ip netns add bridge
その中に、先ほどと同じ br0
という名前で Linux Bridge を作る。
$ sudo ip netns exec bridge ip link add dev br0 type bridge
veth インターフェイスは、先ほど作ったものをそのまま流用する。
$ sudo ip link set br-veth0 netns bridge $ sudo ip link set br-veth1 netns bridge
インターフェイスの状態を UP にする。
$ sudo ip netns exec bridge ip link set br-veth0 up $ sudo ip netns exec bridge ip link set br-veth1 up
両方のインターフェイスをブリッジに接続する。
$ sudo ip netns exec bridge ip link set br-veth0 master br0 $ sudo ip netns exec bridge ip link set br-veth1 master br0
先ほどと同じように、この時点ではブリッジの状態が DOWN なのでフレームは流れない。
$ sudo ip netns exec bridge ip -s link show br0 2: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0
それでは、ブリッジを UP にしよう。
$ sudo ip netns exec bridge ip link set br0 up
すると、ブリッジのカウンタがもりもりと増えだす。 ここまでは想定内。
$ sudo ip netns exec bridge ip -s link show br0 2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 2430362024 33834240 0 0 0 33834240 TX: bytes packets errors dropped carrier collsns 2629020 30570 0 0 0 0
では、ブリッジの STP を有効にしてみよう。
表示の上では、ちゃんと STP enabled
が yes
になっている。
$ sudo ip netns exec bridge brctl stp br0 on $ sudo ip netns exec bridge brctl show br0 bridge name bridge id STP enabled interfaces br0 8000.00005e005301 yes br-veth0 br-veth1
しかし、残念ながらストームは止まらず、ブリッジのカウンタは増え続けている。
$ sudo ip netns exec bridge ip -s link show br0 2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 17477322936 241253904 0 0 0 241253904 TX: bytes packets errors dropped carrier collsns 20065998 233325 0 0 0 0 $ sudo ip netns exec bridge ip -s link show br0 2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 00:00:5e:00:53:01 brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 23684383864 327386610 0 0 0 327386610 TX: bytes packets errors dropped carrier collsns 27466110 319373 0 0 0 0
STP が機能していないようだ。
まとめ
残念ながら、今の Linux カーネルでは Network Namespace 内の Linux Bridge では STP が使えないらしい。 もちろん、これはあくまで「現時点では」という話であって、将来的に使えるようになる可能性はあるはずだけど。
参考
-
すべてのプロセスはいずれかの Network Namespace に所属するため、厳密に言うとシステムが所属している以外の (=非ルートな) Network Namespace ということになる↩