Permalink: 2014-05-09 03:53:00+09:00 by ruy@ainoniwa.net in technical tags: network openvswitch gns3 virtualbox vxlan social:

さまりー

VXLANネットワークを構築する際のサンプルコンフィグレーション マルチキャスト編。

openvswitchの持つVXLAN機能ではなく、Linux kernelで作ったVXLANポートをopenvswitchに接続するだけです。

環境構成には、GNS3とVirtualBoxを使用します。

環境構成図

図のようなGNS3+VirtualBox環境をもとに、VXLANネットワークを作ります。ユニキャストの時と大体同じです。

unicast_vxlan_001.png

openvswitchのバージョンだけちょっと上がってますけど、特にこれでなきゃいけないというものでもないです。

登場人物:

Router-01 : BSDRP 1.5 on VirtualBox
node-01 : BSDRP 1.5 on VirtualBox
node-02 : BSDRP 1.5 on VirtualBox
node-03 : BSDRP 1.5 on VirtualBox
node-04 : BSDRP 1.5 on VirtualBox
ovs01 : Ubuntu-12.04.4 + openvswitch-2.1.0 on VirtualBox
ovs02 : Ubuntu-12.04.4 + openvswitch-2.1.0 on VirtualBox

OSとopenvswitchはインストール済みと言うことで先に進みます。

構築予定図

図のようなVXLANネットワークを構築しましょー

multicast_vxlan_002.png

VXLANの設定準備

Linux kernelがVXLANをするには、Cで直接VXLANを扱うか、iproute2(ubuntuのパッケージ名はiproute)のipコマンドから設定する方法があるのですが、普通に後者を選択するだろ、常識的に考えて...

まず、iproute2がvxlanを使えるようになったのがいつなのか、チラッと確認しておきます。

えーと、2012-10-01にvxlan supportって書いてあるから、少なくともそれ以降のビルドだと可能性あるよね。

と言うわけで、ubuntuのiproute2がVXLANを扱えるか確認してみます。が、20111117-1ubuntu2.1とか書いてあるし無理そうだ。:

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.4 LTS"
$ dpkg -s iproute | grep Version
Package: iproute
Status: install ok installed
Multi-Arch: foreign
Priority: required
Section: net
Installed-Size: 982
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Version: 20111117-1ubuntu2.1
Provides: arpd
Depends: libc6 (>= 2.14), libdb5.1
Recommends: libatm1
Suggests: iproute-doc
Conflicts: arpd
Conffiles:
 /etc/iproute2/rt_realms 7137bdf40e8d58c87ac7e3bba503767f
 /etc/iproute2/rt_protos 95ce0b4b5b79f5a8a45941fb418a904c
 /etc/iproute2/rt_dsfield 4264d5c7c8298300185aa04e1a736934
 /etc/iproute2/rt_scopes 6298b8df09e9bda23ea7da49021ca457
 /etc/iproute2/ematch_map 0b9befbbbee4b415319b8070f18b9b88
 /etc/iproute2/group 3aea2c0e0dd75e13a5f8f48f2936915f
 /etc/iproute2/rt_tables a1313318d6778fe6b8c680248ef5a463
Description: networking and traffic control tools
 The iproute suite, also known as iproute2, is a collection of
 utilities for networking and traffic control.
 .
 These tools communicate with the Linux kernel via the (rt)netlink
 interface, providing advanced features not available through the
 legacy net-tools commands 'ifconfig' and 'route'.
Homepage: http://www.linux-foundation.org/en/Net:Iproute2
Original-Maintainer: Debian iproute maintainers <ah-iproute@debian.org>

一応、ip linkコマンドにvxlanオプションが見えるかも確認してみるけど、TYPEにvxlanが無いのでやっぱり無理そう。:

$ ip link help
Usage: ip link add [link DEV] [ name ] NAME
                   [ txqueuelen PACKETS ]
                   [ address LLADDR ]
                   [ broadcast LLADDR ]
                   [ mtu MTU ]
                   type TYPE [ ARGS ]
       ip link delete DEV type TYPE [ ARGS ]

       ip link set { dev DEVICE | group DEVGROUP } [ { up | down } ]
                          [ arp { on | off } ]
                          [ dynamic { on | off } ]
                          [ multicast { on | off } ]
                          [ allmulticast { on | off } ]
                          [ promisc { on | off } ]
                          [ trailers { on | off } ]
                          [ txqueuelen PACKETS ]
                          [ name NEWNAME ]
                          [ address LLADDR ]
                          [ broadcast LLADDR ]
                          [ mtu MTU ]
                          [ netns PID ]
                          [ netns NAME ]
                          [ alias NAME ]
                          [ vf NUM [ mac LLADDR ]
                                   [ vlan VLANID [ qos VLAN-QOS ] ]
                                   [ rate TXRATE ] ]
                          [ master DEVICE ]
                          [ nomaster ]
       ip link show [ DEVICE | group GROUP ]

TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | can | bridge }

iproute2をソースからインストールしてもいいんだけど、カーネルソースとか要求されるのも面倒だし、Cloud Tools Archiveを利用しよう。

インストール手順はこんな感じ。:

$ sudo apt-get install python-software-properties
$ sudo add-apt-repository cloud-archive:tools
$ sudo apt-get update
$ sudo apt-get install iproute

改めてip link helpを確認。:

$ ip link help
Usage: ip link add [link DEV] [ name ] NAME
                   [ txqueuelen PACKETS ]
                   [ address LLADDR ]
                   [ broadcast LLADDR ]
                   [ mtu MTU ]
                   [ numtxqueues QUEUE_COUNT ]
                   [ numrxqueues QUEUE_COUNT ]
                   type TYPE [ ARGS ]
       ip link delete DEV type TYPE [ ARGS ]

       ip link set { dev DEVICE | group DEVGROUP } [ { up | down } ]
                          [ arp { on | off } ]
                          [ dynamic { on | off } ]
                          [ multicast { on | off } ]
                          [ allmulticast { on | off } ]
                          [ promisc { on | off } ]
                          [ trailers { on | off } ]
                          [ txqueuelen PACKETS ]
                          [ name NEWNAME ]
                          [ address LLADDR ]
                          [ broadcast LLADDR ]
                          [ mtu MTU ]
                          [ netns PID ]
                          [ netns NAME ]
                          [ alias NAME ]
                          [ vf NUM [ mac LLADDR ]
                                   [ vlan VLANID [ qos VLAN-QOS ] ]
                                   [ rate TXRATE ] ]
                                   [ spoofchk { on | off} ] ]
                          [ master DEVICE ]
                          [ nomaster ]
       ip link show [ DEVICE | group GROUP ] [up]

TYPE := { vlan | veth | vcan | dummy | ifb | macvlan | can |
          bridge | ipoib | ip6tnl | ipip | sit | vxlan }

TYPEにvxlanがあるし、大丈夫そう。

今となっては最新版ではないので非常にどうでもいいことだが、linux-image-3.8.0-34-genericを使用している場合は、multicast vxlanはカーネルパニックの可能性があるので回避すべきです。

Configuration

router-01

ifconfig em1 172.16.1.1/24 up
ifconfig em2 172.16.2.1/24 up
service pimdd onestart

node-01

ifconfig em1 192.168.0.1/24 up

node-02

ifconfig em1 192.168.0.1/24 up

node-03

ifconfig em1 192.168.0.2/24 up

node-04

ifconfig em1 192.168.0.2/24 up

ovs01

面倒なのでrootで作業します。:

sudo su -
for i in `seq 0 5`; do ip link set up eth${i}; done
ip addr flush dev eth3
ip addr add 172.16.1.11/24 dev eth3
ip route add 172.16.2.0/24 via 172.16.1.1
ip link add vxlan1 type vxlan id 1 group 239.0.1.1 ttl 10 dev eth3
ip link add vxlan2 type vxlan id 2 group 239.0.1.1 ttl 10 dev eth3
ip link set up vxlan1
ip link set up vxlan2
for br in `ovs-vsctl list-br`; do ovs-vsctl del-br ${br}; done
ovs-vsctl add-br ovs0
ovs-vsctl add-port ovs0 eth1 tag=10
ovs-vsctl add-port ovs0 eth2 tag=20
ovs-vsctl add-port ovs0 vxlan1 tag=10
ovs-vsctl add-port ovs0 vxlan2 tag=20

デフォルトのvxlanインタフェースのTTLは1なので、間にルータが挟まる場合はちゃんとTTLを増やしておきましょう。

ovs02

ovs01とeth3の設定以外は一緒:

sudo su -
for i in `seq 0 5`; do ip link set up eth${i}; done
ip addr flush dev eth3
ip addr add 172.16.2.12/24 dev eth3
ip route add 172.16.1.0/24 via 172.16.2.1
ip link add vxlan1 type vxlan id 1 group 239.0.1.1 ttl 10 dev eth3
ip link add vxlan2 type vxlan id 2 group 239.0.1.1 ttl 10 dev eth3
ip link set up vxlan1
ip link set up vxlan2
for br in `ovs-vsctl list-br`; do ovs-vsctl del-br ${br}; done
ovs-vsctl add-br ovs0
ovs-vsctl add-port ovs0 eth1 tag=10
ovs-vsctl add-port ovs0 eth2 tag=20
ovs-vsctl add-port ovs0 vxlan1 tag=10
ovs-vsctl add-port ovs0 vxlan2 tag=20

設定確認

ovs01

# ovs-vsctl show
df9a4a09-f1b8-42a3-80e5-708377f68142
    Bridge "ovs0"
        Port "eth1"
            tag: 10
            Interface "eth1"
        Port "vxlan1"
            tag: 10
            Interface "vxlan1"
        Port "ovs0"
            Interface "ovs0"
                type: internal
        Port "eth2"
            tag: 20
            Interface "eth2"
        Port "vxlan2"
            tag: 20
            Interface "vxlan2"
    ovs_version: "2.1.0"
# ip -d link show vxlan1
10: vxlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT
    link/ether 56:3f:5b:5f:83:7f brd ff:ff:ff:ff:ff:ff promiscuity 1
    vxlan id 1 group 239.0.1.1 dev eth3 port 32768 61000 ttl 10 ageing 300
# ip -d link show vxlan2
11: vxlan2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT
    link/ether 36:ea:79:6f:b3:19 brd ff:ff:ff:ff:ff:ff promiscuity 1
    vxlan id 2 group 239.0.1.1 dev eth3 port 32768 61000 ttl 10 ageing 300

ovs02

# ovs-vsctl show
df9a4a09-f1b8-42a3-80e5-708377f68142
    Bridge "ovs0"
        Port "vxlan2"
            tag: 20
            Interface "vxlan2"
        Port "ovs0"
            Interface "ovs0"
                type: internal
        Port "vxlan1"
            tag: 10
            Interface "vxlan1"
        Port "eth1"
            tag: 10
            Interface "eth1"
        Port "eth2"
            tag: 20
            Interface "eth2"
    ovs_version: "2.1.0"
# ip -d link show vxlan1
10: vxlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT
    link/ether 1e:52:85:ad:f8:34 brd ff:ff:ff:ff:ff:ff promiscuity 1
    vxlan id 1 group 239.0.1.1 dev eth3 port 32768 61000 ttl 10 ageing 300
# ip -d link show vxlan2
11: vxlan2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master ovs-system state UNKNOWN mode DEFAULT
    link/ether 26:ad:c8:20:46:e6 brd ff:ff:ff:ff:ff:ff promiscuity 1
    vxlan id 2 group 239.0.1.1 dev eth3 port 32768 61000 ttl 10 ageing 300

動作確認

ovs01

VXLANのマルチキャストグループを239.0.1.1にしたので、"link 01:00:5e:00:01:01"が追加されていればオッケー:

#  ip maddr show dev eth3
5:      eth3
        link  01:00:5e:00:00:01
        link  33:33:00:00:00:01
        link  01:00:5e:00:01:01
        inet  239.0.1.1
        inet  224.0.0.1
        inet6 ff02::1
        inet6 ff01::1

ovs02

# ip maddr show dev eth3
5:      eth3
        link  01:00:5e:00:00:01
        link  33:33:00:00:00:01
        link  01:00:5e:00:01:01
        inet  239.0.1.1
        inet  224.0.0.1
        inet6 ff02::1
        inet6 ff01::1

router-01

# tcpdump -i em1 -s 65535 -w /tmp/multicast-vxlan_router-01_em1.pcap

node-01

疎通も問題なさそう:

# ping -c 20 192.168.0.2
PING 192.168.0.2 (192.168.0.2): 56 data bytes
64 bytes from 192.168.0.2: icmp_seq=0 ttl=64 time=5.546 ms
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=1.131 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=1.436 ms
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=1.558 ms
64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=1.258 ms
64 bytes from 192.168.0.2: icmp_seq=5 ttl=64 time=1.385 ms
64 bytes from 192.168.0.2: icmp_seq=6 ttl=64 time=1.549 ms
64 bytes from 192.168.0.2: icmp_seq=7 ttl=64 time=1.713 ms
64 bytes from 192.168.0.2: icmp_seq=8 ttl=64 time=1.588 ms
64 bytes from 192.168.0.2: icmp_seq=9 ttl=64 time=1.515 ms
64 bytes from 192.168.0.2: icmp_seq=10 ttl=64 time=1.866 ms
64 bytes from 192.168.0.2: icmp_seq=11 ttl=64 time=1.657 ms
64 bytes from 192.168.0.2: icmp_seq=12 ttl=64 time=1.789 ms
64 bytes from 192.168.0.2: icmp_seq=13 ttl=64 time=1.628 ms
64 bytes from 192.168.0.2: icmp_seq=14 ttl=64 time=1.646 ms
64 bytes from 192.168.0.2: icmp_seq=15 ttl=64 time=1.495 ms
64 bytes from 192.168.0.2: icmp_seq=16 ttl=64 time=1.547 ms
64 bytes from 192.168.0.2: icmp_seq=17 ttl=64 time=1.219 ms
64 bytes from 192.168.0.2: icmp_seq=18 ttl=64 time=1.612 ms
64 bytes from 192.168.0.2: icmp_seq=19 ttl=64 time=1.775 ms

--- 192.168.0.2 ping statistics ---
20 packets transmitted, 20 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.131/1.746/5.546/0.891 ms

node-02

node-01とほぼ同時にpingを実行しているけど、特に問題なく疎通できてる:

# ping -c 20 192.168.0.2
PING 192.168.0.2 (192.168.0.2): 56 data bytes
64 bytes from 192.168.0.2: icmp_seq=0 ttl=64 time=4.398 ms
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=2.044 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=1.737 ms
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=1.865 ms
64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=1.604 ms
64 bytes from 192.168.0.2: icmp_seq=5 ttl=64 time=1.118 ms
64 bytes from 192.168.0.2: icmp_seq=6 ttl=64 time=1.462 ms
64 bytes from 192.168.0.2: icmp_seq=7 ttl=64 time=1.740 ms
64 bytes from 192.168.0.2: icmp_seq=8 ttl=64 time=1.510 ms
64 bytes from 192.168.0.2: icmp_seq=9 ttl=64 time=1.541 ms
64 bytes from 192.168.0.2: icmp_seq=10 ttl=64 time=1.528 ms
64 bytes from 192.168.0.2: icmp_seq=11 ttl=64 time=1.385 ms
64 bytes from 192.168.0.2: icmp_seq=12 ttl=64 time=1.552 ms
64 bytes from 192.168.0.2: icmp_seq=13 ttl=64 time=1.503 ms
64 bytes from 192.168.0.2: icmp_seq=14 ttl=64 time=1.662 ms
64 bytes from 192.168.0.2: icmp_seq=15 ttl=64 time=1.747 ms
64 bytes from 192.168.0.2: icmp_seq=16 ttl=64 time=1.661 ms
64 bytes from 192.168.0.2: icmp_seq=17 ttl=64 time=1.612 ms
64 bytes from 192.168.0.2: icmp_seq=18 ttl=64 time=1.646 ms
64 bytes from 192.168.0.2: icmp_seq=19 ttl=64 time=1.517 ms

--- 192.168.0.2 ping statistics ---
20 packets transmitted, 20 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.118/1.742/4.398/0.636 ms

router-01

マルチキャストグループの状態(残念ながら、この出力はすぐ消えちゃう):

# netstat -g

IPv4 Virtual Interface Table
 Vif   Thresh   Local-Address   Remote-Address    Pkts-In   Pkts-Out
  0         1   172.16.1.1                             14          2
  1         1   172.16.2.1                             14          2

IPv4 Multicast Forwarding Table
 Origin          Group             Packets In-Vif  Out-Vifs:Ttls
 172.16.2.12     239.0.1.1              14    1    0:1
 172.16.1.11     239.0.1.1              14    0    1:1


IPv6 Multicast Interface Table is empty

IPv6 Multicast Forwarding Table is empty

結果確認

wireshark氏にお任せする。

こんな感じでデコードします。

multicast_vxlan_003.png multicast_vxlan_004.png

VNI=1の 192.168.0.1 <-> 192.168.0.2

multicast_vxlan_005.png

VNI=2の 192.168.0.1 <-> 192.168.0.2

multicast_vxlan_006.png

はい、うまいことIsolationされました。

特に、今回はブロードキャストフレームがマルチキャストに、その後のユニキャストフレームはユニキャストでカプセル化されているところが重要ですの。

マルチキャストを使わずに、ユニキャストトンネルだけを使用する場合(すなわち、openvswitchのVXLAN実装のみを使用する場合)、 拠点が3つ以上になると、フルメッシュトンネルを設定した時点でブロードキャストが複数のユニキャストパケットとなってループを発生させてしまいますが、 ブロードキャスト、マルチキャスト、あて先不明ユニキャストの各フレームをマルチキャストでカプセル化する場合は、その問題を回避することが出来ます。

ただし、途中経路がマルチキャストに対応する必要があるため、途中経路の設定を一切変更できずマルチキャストに対応できない場合は、openvswitchとOpenFlowによるループ防止フローを各自で挿入する必要があると考えられます。

ちなみに、今回取得したpcapファイルはこちらです。 : http://www.ainoniwa.net/data/pcap/multicast-vxlan_router-01_em1.pcap