EVPN/VXLANをVyOSで触ってみた

## なぜ触ろうと思ったのか
DMMのインフラ部ネットワークグループでアルバイトをさせていただいており、
EVPN/VXLANを実際に構築してみて面白いと思い、自宅にも導入したくなったからです。
(Hyper-Vの仮想スイッチがQinQに対応していないという問題点の解消のためでもありますが…)

## 今回使う技術と物
・L3SWは実機を用意するのが大変なのでVyOSで代用
・実行環境は自宅の仮想化基盤上に構築しているWindowsServer(ネットワーク検証用)のHyper-V上(ネステッド構成)
・L3SW間はP2P接続で、BGP Unnumberedで経路交換
#### 全体の注意点
・コマンドの実行結果やconfigで伏せておきたい部分は生の出力値から書き換えを行っています。
・誤っている部分があるかもしれません。見つけ次第修正させていただきます。
#### 参考資料
https://inside.dmm.com/entry/2022/09/21/dmm-evpn-vxlan_1

松原先輩が書かれたこちらの記事を参考にさせていただいております。
非常にわかりやすいので皆様も読んでみてください。

## ちなみに脱線しますが…(読み飛ばしてOK)
DMMのアルバイトを始める前とその後のネットワーク、VXLANを導入する箇所をご紹介しておきます。
#### 旧ネットワーク図
![名称未設定ファイル-構築前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668438/787e0cd5-dc5e-6914-872c-0b95aa0a3ef7.png)
#### 現在のネットワーク
光回線が10Gbps*2本になったのを境に大きく変更しました。
自宅DCとクラウドのVTEP間でやりとりします。
ルータとファイアウォールはネットワーク用仮想化基盤上で動作させており、ルータはVyOS、ファイアウォールはSophos XG Firewallを使用しています。
![名称未設定ファイル-構築後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668438/383f7d24-8174-c5e5-8717-8ed0320da0d6.png)
今回のEVPN/VXLANを導入することによって、
クラウドにもHyper-Vゲストをライブマイグレーションできるようになります。

## Unnumbered
アドレスを指定せずにBGPネイバーを発見し、IPv6のリンクローカルアドレスを用いて隣接関係を構築する手法です。
IPアドレスの節約やコンフィグの簡素化などの利点があります。
公式のドキュメントが役に立たなかったので検証に若干苦労しました。
#### 今回はこんな感じのものを作ります
![名称未設定ファイル-ページ6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668438/ee8f1d2b-01da-9879-ab16-a91ca1bdf7ba.png)
#### configはこんな感じ
※一部抜粋
~~~ config:leaf1-dc1
protocols {
    bgp {
        address-family {
            ipv4-unicast {
                network 203.0.113.1/32 {
                }
            }
            ipv6-unicast {
            }
        }
        neighbor eth0 {
            address-family {
                ipv4-unicast {
                }
                ipv6-unicast {
                }
            }
            interface {
                remote-as 65537
            }
        }
        parameters {
            router-id 203.0.113.1
        }
        system-as 65536
    }
~~~ 
~~~ config:leaf1-dc2
protocols {
    bgp {
        address-family {
            ipv4-unicast {
                network 203.0.113.2/32 {
                }
            }
            ipv6-unicast {
            }
        }
        neighbor eth0 {
            address-family {
                ipv4-unicast {
                }
                ipv6-unicast {
                }
            }
            interface {
                remote-as 65536
            }
        }
        parameters {
            router-id 203.0.113.2
        }
        system-as 65537
    }
~~~
ハマったことはneighbor部分の対向ASを指定する際、以下のように若干書き方が変化する点。
~~~ config:これはダメ
set protocol bgp neigbor eth0 remote-as <対向AS番号>
~~~
~~~ config:これが正解
set protocol bgp neigbor eth0 interface remote-as <対向AS番号>
~~~
#### 確認
※一部抜粋
正常にネクストホップがIPv6のリンクローカルアドレスになっているのが確認できます。
~~~ :leaf1-dc1/leaf1-dc2
vyos@leaf1-dc1:~$ show ip bgp neighbors
BGP neighbor on eth0: fe80::215:5dff:XXXX:XXXX, remote AS 65537, local AS 65536, external link
Hostname: leaf1-dc1
  BGP version 4, remote router ID 203.0.113.2, local router ID 203.0.113.1
  BGP state = Established, up for 03:49:45

vyos@leaf1-dc1:~$ show ip route bgp
B>* 203.0.113.2/32 [20/0] via fe80::215:5dff:XXXX:XXXX, eth0, weight 1, 04:19:35

vyos@leaf1-dc2:~$ show ip bgp neighbors
BGP neighbor on eth0: fe80::215:5dff:YYYY:YYYY, remote AS 65536, local AS 65537, external link
Hostname: leaf1-dc2
  BGP version 4, remote router ID 203.0.113.1, local router ID 203.0.113.2
  BGP state = Established, up for 04:15:19

vyos@leaf1-dc2:~$ show ip route bgp
B>* 203.0.113.1/32 [20/0] via fe80::215:5dff:YYYY:YYYY, eth0, weight 1, 04:19:22
~~~
~~~ :ping
vyos@leaf1-dc1:~$ ping 203.0.113.2
PING 203.0.113.2 (203.0.113.2) 56(84) bytes of data.
64 bytes from 203.0.113.2: icmp_seq=1 ttl=64 time=0.728 ms
64 bytes from 203.0.113.2: icmp_seq=2 ttl=64 time=0.838 ms
64 bytes from 203.0.113.2: icmp_seq=3 ttl=64 time=0.707 ms
^C
--- 203.0.113.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 0.707/0.757/0.838/0.057 ms
~~~

## 本題のEVPN/VXLAN
長くなってしまっているので簡単に書いていきます。
leaf1-dc1とleaf1-dc2のeth1配下の機器同士が通信できるようにしていきます。
今回はVLANパケットは無視します。
#### configはこんな感じ
※一部抜粋
~~~ :leaf1-dc1
interfaces {
    bridge br0 {
        member {
            interface eth1 {
            }
            interface vxlan0 {
            }
        }
        mtu 16000
    }
    ethernet eth0 {
        hw-id 00:15:5d:YY:YY:YY
        mtu 16000
    }
    ethernet eth1 {
        hw-id 00:15:5d:ZZ:ZZ:ZZ
        mtu 16000
    }
    loopback lo {
        address 203.0.113.1/32
    }
    vxlan vxlan0 {
        mtu 16000
        source-address 203.0.113.1
        vni 10000
    }
}

protocols {
    bgp {
        address-family {
            ipv4-unicast {
                network 203.0.113.1/32 {
                }
            }
            ipv6-unicast {
            }
            l2vpn-evpn {
                advertise-all-vni
            }
        }
        neighbor eth0 {
            address-family {
                ipv4-unicast {
                }
                ipv6-unicast {
                }
                l2vpn-evpn {
                }
            }
            interface {
                remote-as 65537
            }
        }
        parameters {
            router-id 203.0.113.1
        }
        system-as 65536
    }
}
~~~
~~~ :leaf1-dc2
interfaces {
    bridge br0 {
        member {
            interface eth1 {
            }
            interface vxlan0 {
            }
        }
        mtu 16000
    }
    ethernet eth0 {
        hw-id 00:15:5d:XX:XX:XX
        mtu 16000
    }
    ethernet eth1 {
        hw-id 00:15:5d:WW:WW:WW
        mtu 16000
    }
    loopback lo {
        address 203.0.113.2/32
    }
    vxlan vxlan0 {
        mtu 16000
        source-address 203.0.113.2
        vni 10000
    }
}

protocols {
    bgp {
        address-family {
            ipv4-unicast {
                network 203.0.113.2/32 {
                }
            }
            ipv6-unicast {
            }
            l2vpn-evpn {
                advertise-all-vni
            }
        }
        neighbor eth0 {
            address-family {
                ipv4-unicast {
                }
                ipv6-unicast {
                }
                l2vpn-evpn {
                }
            }
            interface {
                remote-as 65536
            }
        }
        parameters {
            router-id 203.0.113.2
        }
        system-as 65537
    }
}
~~~
今回重要なのはvxlanインターフェースももちろんですが、bridgeインターフェースと l2vpn-evpn、MTUの設定だと思います。
また、vniをアドバイスさせるadvertise-all-vniも必要です。
MTUは1500でも動作してpingも通りますが、スループットが全く出ませんでした。

パケットキャプチャを行ってみると正常にVXLANでカプセル化が行われており、宛先情報なども想定通りのものが入っていたため、EVPN/VXLANは正常に動作していると判断しました。
パケット構造を見るとVTEPによって合計40バイトのヘッダが付加されていることがわかりここが原因ではないかと感じ、とりあえずMTUを最大値にして解決しました。

#### 動作確認
leaf1-dc1/leaf1-dc2のeth0配下にいるPC同士が通信している際のadvertised-routes。
※一部抜粋
~~~ :leaf1-dc1
vyos@leaf1-dc1:~$ show bgp l2vpn evpn neighbors eth0 advertised-routes
   Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 172.16.255.1:6
*> [2]:[0]:[48]:[00:15:5d:GG:GG:GG]
                                       32768 i
*> [3]:[0]:[32]:[203.0.113.1]
                                       32768 i
Route Distinguisher: 172.16.255.2:2
*> [2]:[0]:[48]:[00:15:5d:HH:HH:HH]
                                           0 65537 i
*> [3]:[0]:[32]:[203.0.113.2]
                                           0 65537 i

Total number of prefixes 4
~~~
~~~ :leaf1-dc2
vyos@leaf1-dc2:~$ show bgp l2vpn evpn neighbors eth0 advertised-routes
   Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 203.0.113.1:6
*> [2]:[0]:[48]:[00:15:5d:GG:GG:GG]
                                           0 65536 i
*> [3]:[0]:[32]:[203.0.113.1]
                                           0 65536 i
Route Distinguisher: 203.0.113.2:2
*> [2]:[0]:[48]:[00:15:5d:HH:HH:HH]
                                       32768 i
*> [3]:[0]:[32]:[203.0.113.2]
                                       32768 i

Total number of prefixes 4
~~~
##### iperf3でスループットの測定も行いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668438/a24b9e1c-7824-c030-28a8-ef51b676d31e.png)
インターフェースのリンク速度が10Gに対して平均7.87Gbits/sec出ているため比較的高速に動作していそうです。
## 結論
今回の構成では問題なく通信を行うことができ、スループットも思った以上に高かったです。
MTUの値に関しては適当に設定を行っているため計算を行い適切なものにする必要があると思います。
今後検証していきます。