naoki86star

インターネットの片隅でなにかしら書いてみる

ipv6 over tunnel by vxlan

いまさらながら、自分の初めての hello VXLAN! な内容。IPv6パケットもIPv4で張ったVXLANを通るよねを試してみた。

きっかけ

 openflow switchのとある機種のマニュアルで、VXLAN可能、とあったのを見た。
 昔々、BigIPってアプライアンスでVXLANが設定できる、と聞いたことがあってVXLANという単語を覚えた*1。トンネルするときに使う?くらいにしか知らないのだが、IPv6パケットもくぐらせることできるのかどうか知りたい知っておきたい、とふと思いつきまずローカル環境で試してみる。*2

仮想環境(Linux + openvswitch)

 openflow switchの機能なんだからopen-vswitchで試せるだろう*3ってことで、VM3台+lxdを使ったVMを組み合わせたテスト構成は以下の通り。

          +------seg1------+
          |     +----+     |
          |     | k1 |     |
          |     +--+-+     |
          |        |       |
          | +------------+ |
          | |    ovs1    | |
          | +-----+------+ |
          +-------|--------+
         +--------+--------+ 192.168.200.0/24
 +-------|-------+ +-------|-------+
 | +-----+-----+ | | +-----+-----+ |
 | |    ovs2   | | | |    ovs3   | |
 | +-----------+ | | +-----------+ |
 |        |      | |        |      |
 |     +----+    | |     +----+    |
 |     | l1 |    | |     | m1 |    |
 |     +----+    | |     +----+    |
 +------seg2-----+ +------seg3-----+
  • (OSはubuntu18.04)
  • seg1,seg2,seg3をそれぞれVMとして立てる。それぞれがローカルLANを模擬してるつもり。この3ノードは192.168.200.0/24で結ばれる。
  • k1,l1,m1を、それぞれlxdのコンテナでVMとして立ち上げる。PCを模擬しているつもり。
  • ovs1,ovs2,ovs3は、openvswicthのブリッジで、それぞれのlxdコンテナノード内のVMと、openvswicthで作成するVXLANポートをつなげる。
  • 作成するVXLANポートは合計4つ。seg1からはseg2,seg3両方にトンネルを張る。seg2,seg3からはseg1だけにトンネルを張る。

tun_kl : seg1(192.168.200.101) -> seg2(192.168.200.102)
tun_km : seg1(192.168.200.101) -> seg2(192.168.200.102)
tun_lk : seg1(192.168.200.102) -> seg2(192.168.200.101)
tun_mk : seg1(192.168.200.103) -> seg2(192.168.200.101)

ローカルLANの間を通るのに、トンネルをくぐっていく感じ。

結果の要点
  • IPv4でつないだVXLANでIPv6パケットも通ってくれる。ただし、最大IPサイズはIPv4よりさらに小さくなる。
  • VXLANポートを選んでopenflowのエントリをadd/delすることで、パスの制御が実現できそう。
  • (GREトンネルのポートも、ovs-ofctlでほぼ同じようにできて同じように動作した。こっちのほうが若干最大IPサイズが大きくできる。)
  • ARPのopenflowエントリは、手抜きでNORMAL*4
ログ(あとでなにをしたか思い出すため)
  • lxdの最初のおまじない、lxdbrは自分で明示的に作成することした
  • profileはdefaultを使う、nictypeにはbridgedを使うのでdefaultで間に合った
root@seg1:~# lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]: seg1
Name of the storage backend to use (btrfs, dir, lvm) [default=btrfs]:
Create a new BTRFS pool? (yes/no) [default=yes]:
Would you like to use an existing block device? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=15GB]: 2GB
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]: no
Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]:
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
root@seg1:~#

root@seg1:~# lxc launch ubuntu:18.04 k1 -p default
root@seg1:~# lxc network create lxdbr0 ipv6.address=fc00:0:0:1::fffe/64 ipv4.address=172.31.1.254/24 ipv4.nat=false ipv6.nat=false
root@seg1:~# lxc network attach lxdbr0 k1 default eth0
  • コンテナVM達にIPを与えてあげる(以下の例はovs1のみ)
root@seg1:~# lxc exec k1 -- ifconfig eth0 up
root@seg1:~# lxc exec k1 -- ip addr add 172.31.1.1/24 dev eth0
root@seg1:~# lxc exec k1 -- ip -6 addr add fc00:0:0:1::1/64 dev eth0
root@seg1:~# lxc exec k1 -- route add default dev eth0
root@seg1:~# lxc exec k1 -- route -6 add default dev eth0
  • VXLANの作成まで(以下の例はovs1のみ)
root@seg1:~# ovs-vsctl add-br ovs1
root@seg1:~# ovs-vsctl add-port ovs1 lxdbr0
root@seg1:~# ovs-vsctl add-port ovs1 tun_kl -- set interface tun_kl type=vxlan options:remote_ip=192.168.200.102 options:dst_port=8472
root@seg1:~# ovs-vsctl add-port ovs1 tun_km -- set interface tun_km type=vxlan options:remote_ip=192.168.200.103 options:dst_port=8472
  • openflow エントリの作成*5
root@seg1:~# ovs-ofctl del-flows ovs1

root@seg1:~# ovs-ofctl add-flow ovs1 arp,actions=flood
root@seg1:~# ovs-ofctl add-flow ovs1 ip,nw_dst=172.31.1.0/24,actions=output:1
root@seg1:~# ovs-ofctl add-flow ovs1 ip,nw_dst=172.31.2.0/24,actions=output:2
root@seg1:~# ovs-ofctl add-flow ovs1 ip,nw_dst=172.31.3.0/24,actions=output:3
root@seg1:~# ovs-ofctl add-flow ovs1 icmp6,ipv6_dst=ff00::/8,actions=flood
root@seg1:~# ovs-ofctl add-flow ovs1 ip6,ipv6_dst=fc00:0:0:1::0/64,actions=output:1
root@seg1:~# ovs-ofctl add-flow ovs1 ip6,ipv6_dst=fc00:0:0:2::0/64,actions=output:2

*1:カタカナ文字のように聞こえてた感じ

*2:実際のあるかもしれない需要は非対称通信で片道だけ設定できるといいのだがとりあえず簡易な構成にて試す

*3:open-vswitchで動いたとして、使うopenflow switchが実装しているかどうかが別問題なのは周知の通り、ベースのopen-vswitchのバージョンも違うだろうし。

*4:実際はswitchをL3で使うことを想定してるのでここはがんばらない

*5:ここでの例レベルであればactions=normal:L2スイッチモードだけでもpingは通ってくれた。L3の経路コントロールについて観察とか考えていきたいので一旦actions=normalを削除し、制御のopenflow エントリを作成する