今回は Linux Bridge (ネットワークブリッジ) でタグ VLAN (IEEE 802.1Q) を使う方法について。 設定が足らなくてだいぶ悩んだのでメモしておく。
使った環境は次の通り。
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DESCRIPTION="Ubuntu 18.04.1 LTS" $ uname -r 4.15.0-29-generic $ ip -V ip utility, iproute2-ss180129 $ sudo apt-cache show iproute2 | grep -i version Version: 4.15.0-2ubuntu1
下準備
最初に、今回使うパッケージをインストールしておく。
$ sudo apt-get -y install iproute2 tcpdump iputils-ping
Linux Bridge でタグ VLAN を有効にする
準備ができたところで、早速本題に入る。
Linux Bridge でタグ VLAN を扱うには vlan_filtering
を有効にする必要がある。
vlan_filtering
は ip(8) で有効にできる。
例えば ip(8) を使ってブリッジを作る場合には、次のように有効にできる。
これは br0
という名前でブリッジを作るときの例。
$ sudo ip link add dev br0 type bridge vlan_filtering 1
また、作ったあとからでも次のように有効にできる。 brctl(8) とか使って作った場合にも、これでいけるはず。
$ sudo ip link add dev br0 type bridge $ sudo ip link set dev br0 type bridge vlan_filtering 1
ブリッジを作ったら状態を UP に設定する。
$ sudo ip link set br0 up
ここからは、上記の設定が正しく動いていることを確認していく。
アクセスポートを追加する
続いては、タグ VLAN を有効にした Linux Bridge に実際にアクセスポートを追加する。 追加するネットワークインターフェースには veth インターフェースを使う。 また、あとから ping(8) で疎通を確認できるように Network Namespace をつなげておく。
まずは Network Namespace を用意する。
$ sudo ip netns add ns1
続いて veth インターフェースのペアを作成する。
$ sudo ip link add ns1-veth0 type veth peer name br0-veth0
片方の veth インターフェースを、先ほど作った Network Namespace に所属させる。
$ sudo ip link set ns1-veth0 netns ns1
所属させたネットワークインターフェースを使える状態にして IP アドレスとして 192.0.2.1/24
を付与しておく。
$ sudo ip netns exec ns1 ip link set ns1-veth0 up $ sudo ip netns exec ns1 ip addr add dev ns1-veth0 192.0.2.1/24
veth インターフェースのもう片方は、先ほど作った Linux Bridge に追加しておく。
$ sudo ip link set br0-veth0 master br0 $ sudo ip link set br0-veth0 up
準備ができたので、やっと VLAN の設定をしていく。 その前に、まずは bridge(8) で現状を確認しておく。 デフォルトでは、次のように VLAN ID として 1 が使われるように見えている。 これは、ようするに 802.1Q VLAN を使っていない状態。
$ bridge vlan show dev br0-veth0
port vlan ids
br0-veth0 1 PVID Egress Untagged
そこで、bridge(8) を使ってポートに VLAN を設定する。 今回は Linux Bridge に追加したポートを使った通信で VLAN ID 100 が使われるように設定してみよう。 代わりに、既存のルールは削除しておく。
$ sudo bridge vlan add vid 100 dev br0-veth0 pvid untagged $ sudo bridge vlan del dev br0-veth0 vid 1
設定は以下のようになった。
$ bridge vlan show dev br0-veth0
port vlan ids
br0-veth0 100 PVID Egress Untagged
通信先 (対向) を用意する
ns1
に続いて、もう一つ ns2
という名前で Network Namespace を用意して、先ほどと同じようにセットアップしておく。
これは ns1
から ping(8) を打つときの相手になる。
$ sudo ip netns add ns2 $ sudo ip link add ns2-veth0 type veth peer name br0-veth1 $ sudo ip link set ns2-veth0 netns ns2 $ sudo ip netns exec ns2 ip link set ns2-veth0 up $ sudo ip netns exec ns2 ip addr add dev ns2-veth0 192.0.2.2/24 $ sudo ip link set br0-veth1 master br0 $ sudo ip link set br0-veth1 up $ sudo bridge vlan add vid 100 dev br0-veth1 pvid untagged $ sudo bridge vlan del dev br0-veth1 vid 1
通信を観察する
準備ができたので、Linux Bridge の通信を tcpdump(1) でパケットキャプチャする。
$ sudo tcpdump -nel -i br0 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on br0, link-type EN10MB (Ethernet), capture size 262144 bytes
パケットキャプチャの準備ができたら、別のターミナルから ns1
から ns2
に向かって ping を打ってみよう。
$ sudo ip netns exec ns1 ping -c 3 192.0.2.2 PING 192.0.2.2 (192.0.2.2) 56(84) bytes of data. 64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.114 ms 64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.060 ms 64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.073 ms --- 192.0.2.2 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2036ms rtt min/avg/max/mdev = 0.060/0.082/0.114/0.024 ms
打ち終わったら tcpdump(1) を実行していたターミナルに戻る。 すると、次のように 802.1Q のデータフレームが観測できているはず。 VLAN ID にも、ちゃんと 100 が使われていることが分かる。
$ sudo tcpdump -nel -i br0 ...(略)... 18:20:18.031208 b6:05:b6:b6:c6:e3 > a2:bd:24:29:d8:76, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 192.0.2.1 > 192.0.2.2: ICMP echo request, id 1453, seq 1, length 64 18:20:18.031240 a2:bd:24:29:d8:76 > b6:05:b6:b6:c6:e3, ethertype 802.1Q (0x8100), length 102: vlan 100, p 0, ethertype IPv4, 192.0.2.2 > 192.0.2.1: ICMP echo reply, id 1453, seq 1, length 64 ...(略)
めでたしめでたし。
スマートPythonプログラミング: Pythonのより良い書き方を学ぶ
- 作者: もみじあめ
- 発売日: 2016/03/12
- メディア: Kindle版
- この商品を含むブログ (1件) を見る