EC SONiC VS で EVPN BGP L2VNI -- 設定編

# はじめに
記事のテーマとして、最初は EVPN を使わず、純粋な BGP を試そうと考えましたが、SONiC のgerneral ユースケースであるデータセンターの視点からみると、EVPN の方が拡張性の高いという点で、EVPN BGP L2VNI に記事を焦点を当てることにしました。

純粋なBGPを使う場合、Leaf/Spineの構造をうまく作ることが難しいと思います。なぜなら、Spineは単純にトラフィックを転送する役割を担い、一方Leafはサーバーや外部からのトラフィックを受け取ってより複雑な処理を行う役割を果たすため、やっぱり EVPN 環境が最も適切だと考えられるからです。今回の目標の一つは、SONiCを使用して、GNS3でEVPN VxLANをどれだけ検証できるかを確かめることです。


# 環境
- OS version: EC SONiC VS 202111版、VS の導入について、前回の記事で[SONiC VS 仮想スイッチを使ってみよう [Community/Edgecore]](https://qiita.com/cyo-chang/items/3f987d1b3e8303e40988) ご参考ください
- ESXi VMware
    - ゲスト OS：Ubuntu Linux (64 ビット)


# 事前準備
### GNS3
GNS3 で Spine 2 台、Leaf 4 台、VPCS 4 台を用意します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/cad76af3-9d91-0559-b38d-d9a9c53bcc90.png)

### iptables forward chain をチェックします。
iptables は Linuxベースのファイアウォールで、それによってトラフィックを制御することができるますが、EC SONiC VS 上で、FORWARチェーン は ARP パケットをドロップするので、`sudo ebtables -D FORWARD -p arp -j DROP` コマンドで 、SONiC node から FORWARD チェーンのルールを削除する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/cb1f688b-88a2-c145-1052-eb12a0dacd8f.png)

# Topology
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/b6399871-28f7-07b9-8da9-c59e1012a6be.png)
### AS number について
ECMPでベストパスアルゴリズムを算出するために、best path の選択基準があり、その1つは AS 番号です。これにより、以下のように AS Number を設計するのは推奨です*1。

- リーフ（VTEP node）の AS　番号を別々にする
- ボーダーリーフの AS 番号は 同じにする
- スパイン同士の AS 番号は 同じにする

今記事は、ボーダーリーフを想定しないです。

### 用語について
| Term       | Definition   |
|-----------|------------------|
|Router ID|Router ID は Loopback IP によって作成され、AS内のルーターを識別するために使用される。Router IDはユニックにする必要があり、そうでないと、BGPセッションを立ち上がれない。|
| VLAN-VNI mapping | VXLAN tunnel へ通らせるため、VLANとVNIへのマッピングを作成する  |
| VTEP (VXLAN Tunnel End Point)  | SRC IPアドレスによって指定される VXLAN トンネルの発信および/または終端を行うエンティティです。VTEP は 1 台のデバイスに 1 つだけ許可されます。VTEP の IP アドレスはLoopback IPアドレスを使用 |
| NVO (Network Virtualization Overlay) | VxLANは、NVO というソリューションの一つだど認識すればよいと思う   |

他にはたくさんありますが、[VXLANチュートリアル](https://www.janog.gr.jp/meeting/janog37/download_file/vxlan.pdf)に参考すれば、VxLANの基本を身につけると思います。

# CLI コンフィグ
### spine-1
```
admin@spine-1:~$ sudo config interface ip add Loopback0 1.1.1.1/32
admin@spine-1:~$ sudo config interface ip add Ethernet4 11.0.0.0/31
admin@spine-1:~$ sudo config interface ip add Ethernet8 11.0.1.0/31
admin@spine-1:~$ sudo config interface ip add Ethernet12 11.0.2.0/31
admin@spine-1:~$ sudo config interface ip add Ethernet16 11.0.3.0/31
admin@spine-1:~$ vtysh
spine-1# configure terminal
spine-1(config)# router bgp 65000
spine-1(config-router)# bgp router-id 1.1.1.1
spine-1(config-router)# no bgp ebgp-required-policy
spine-1(config-router)# bgp bestpath as-path multipath-relax
spine-1(config-router)# neighbor FABRIC peer-group
spine-1(config-router)# neighbor FABRIC remote-as external
spine-1(config-router)# neighbor Ethernet4 interface peer-group FABRIC
spine-1(config-router)# neighbor Ethernet8 interface peer-group FABRIC 
spine-1(config-router)# neighbor Ethernet12 interface peer-group FABRIC 
spine-1(config-router)# neighbor Ethernet16 interface peer-group FABRIC 
spine-1(config-router)# address-family ipv4
spine-1(config-router-af)# redistribute connected
spine-1(config-router-af)# exit
spine-1(config-router)# address-family l2vpn evpn
spine-1(config-router-af)# neighbor FABRIC activate
spine-1(config-router-af)# advertise-all-vni
spine-1(config-router-af)# end
spine-1# write
spine-1# exit
admin@spine-1:~$ sudo config save -y
```
### spine-2
```
admin@spine-2:~$ sudo config interface ip add Loopback0 2.2.2.2/32
admin@spine-2:~$ sudo config interface ip add Ethernet20 11.0.4.0/31
admin@spine-2:~$ sudo config interface ip add Ethernet24 11.0.5.0/31
admin@spine-2:~$ sudo config interface ip add Ethernet28 11.0.6.0/31
admin@spine-2:~$ sudo config interface ip add Ethernet32 11.0.7.0/31
spine-2# configure terminal
spine-2(config)# router bgp 65000
spine-2(config-router)# bgp router-id 2.2.2.2
spine-2(config-router)# no bgp ebgp-required-policy
spine-2(config-router)# bgp bestpath as-path multipath-relax
spine-2(config-router)# neighbor FABRIC peer-group
spine-2(config-router)# neighbor FABRIC remote-as external
spine-2(config-router)# neighbor Ethernet20 interface peer-group FABRIC
spine-2(config-router)# neighbor Ethernet24 interface peer-group FABRIC 
spine-2(config-router)# neighbor Ethernet28 interface peer-group FABRIC 
spine-2(config-router)# neighbor Ethernet32 interface peer-group FABRIC 
spine-2(config-router)# address-family ipv4
spine-2(config-router-af)# redistribute connected
spine-2(config-router-af)# exit
spine-2(config-router)# address-family l2vpn evpn
spine-2(config-router-af)# neighbor FABRIC activate
spine-2(config-router-af)# advertise-all-vni
spine-2(config-router-af)# end
spine-2# write
admin@spine-2:~$ sudo config save -y
```
### leaf-1
```
admin@leaf-1:~$ sudo config interface ip add Loopback0 3.3.3.3/32
admin@leaf-1:~$ sudo config interface ip add Ethernet4 11.0.0.1/31
admin@leaf-1:~$ sudo config interface ip add Ethernet20 11.0.4.1/31
admin@leaf-1:~$ sudo config vlan add 10
admin@leaf-1:~$ sudo config vlan add 20
admin@leaf-1:~$ sudo config vlan member add 10 Ethernet40
admin@leaf-1:~$ sudo config interface ip add Vlan10 172.16.10.1/24
admin@leaf-1:~$ sudo config interface ip add Vlan20 172.16.20.1/24
admin@leaf-1:~$ sudo config vxlan add vtep 3.3.3.3
admin@leaf-1:~$ sudo config vxlan evpn_nvo add nvo vtep
admin@leaf-1:~$ sudo config vxlan map add vtep 10 1000
admin@leaf-1:~$ sudo config vxlan map add vtep 20 2000
admin@leaf-1:~$ vtysh
leaf-1# configure terminal
leaf-1(config)# router bgp 65101
leaf-1(config-router)# bgp router-id 3.3.3.3
leaf-1(config-router)# no bgp ebgp-required-policy
leaf-1(config-router)# bgp bestpath as-path multipath-relax
leaf-1(config-router)# neighbor FABRIC peer-group
leaf-1(config-router)# neighbor FABRIC remote-as external
leaf-1(config-router)# neighbor Ethernet4 interface peer-group FABRIC
leaf-1(config-router)# neighbor Ethernet20 interface peer-group FABRIC 
leaf-1(config-router)# address-family ipv4
leaf-1(config-router-af)# redistribute connected
leaf-1(config-router-af)# exit
leaf-1(config-router)# address-family l2vpn evpn
leaf-1(config-router-af)# neighbor FABRIC activate
leaf-1(config-router-af)# advertise-all-vni
leaf-1(config-router-af)# end
leaf-1# write
leaf-1# exit
admin@leaf-1:~$ sudo config save -y
```
### leaf-2
```
admin@leaf-2:~$ sudo config interface ip add Loopback0 4.4.4.4/32
admin@leaf-2:~$ sudo config interface ip add Ethernet8 11.0.1.1/31
admin@leaf-2:~$ sudo config interface ip add Ethernet24 11.0.5.1/31
admin@leaf-2:~$ sudo config vlan add 10
admin@leaf-2:~$ sudo config vlan add 20
admin@leaf-2:~$ sudo config vlan member add 20 Ethernet40
admin@leaf-2:~$ sudo config interface ip add Vlan10 172.16.10.2/24
admin@leaf-2:~$ sudo config interface ip add Vlan20 172.16.20.2/24
admin@leaf-2:~$ sudo config vxlan add vtep 4.4.4.4
admin@leaf-2:~$ sudo config vxlan evpn_nvo add nvo vtep
admin@leaf-2:~$ sudo config vxlan map add vtep 10 1000
admin@leaf-2:~$ sudo config vxlan map add vtep 20 2000
admin@leaf-2:~$ vtysh
leaf-2# configure terminal
leaf-2(config)# router bgp 65102
leaf-2(config-router)# bgp router-id 4.4.4.4
leaf-2(config-router)# no bgp ebgp-required-policy
leaf-2(config-router)# bgp bestpath as-path multipath-relax
leaf-2(config-router)# neighbor FABRIC peer-group
leaf-2(config-router)# neighbor FABRIC remote-as external
leaf-2(config-router)# neighbor Ethernet8 interface peer-group FABRIC
leaf-2(config-router)# neighbor Ethernet24 interface peer-group FABRIC 
leaf-2(config-router)# address-family ipv4
leaf-2(config-router-af)# redistribute connected
leaf-2(config-router-af)# exit
leaf-2(config-router)# address-family l2vpn evpn
leaf-2(config-router-af)# neighbor FABRIC activate
leaf-2(config-router-af)# advertise-all-vni
leaf-2(config-router-af)# end
leaf-2# write
leaf-2# exit
admin@leaf-2:~$ sudo config save -y
```
### leaf-3
```
admin@leaf-3:~$ sudo config interface ip add Loopback0 5.5.5.5/32
admin@leaf-3:~$ sudo config interface ip add Ethernet12 11.0.2.1/31
admin@leaf-3:~$ sudo config interface ip add Ethernet28 11.0.6.1/31
admin@leaf-3:~$ sudo config vlan add 10
admin@leaf-3:~$ sudo config vlan add 20
admin@leaf-3:~$ sudo config vlan member add 10 Ethernet40
admin@leaf-3:~$ sudo config interface ip add Vlan10 172.16.10.3/24
admin@leaf-3:~$ sudo config interface ip add Vlan20 172.16.20.3/24
admin@leaf-3:~$ sudo config vxlan add vtep 5.5.5.5
admin@leaf-3:~$ sudo config vxlan evpn_nvo add nvo vtep
admin@leaf-3:~$ sudo config vxlan map add vtep 10 1000
admin@leaf-3:~$ sudo config vxlan map add vtep 20 2000
admin@leaf-3:~$ vtysh
leaf-3# configure terminal
leaf-3(config)# router bgp 65103
leaf-3(config-router)# bgp router-id 5.5.5.5
leaf-3(config-router)# no bgp ebgp-required-policy
leaf-3(config-router)# bgp bestpath as-path multipath-relax
leaf-3(config-router)# neighbor FABRIC peer-group
leaf-3(config-router)# neighbor FABRIC remote-as external
leaf-3(config-router)# neighbor Ethernet12 interface peer-group FABRIC
leaf-3(config-router)# neighbor Ethernet28 interface peer-group FABRIC 
leaf-3(config-router)# address-family ipv4
leaf-3(config-router-af)# redistribute connected
leaf-3(config-router-af)# exit
leaf-3(config-router)# address-family l2vpn evpn
leaf-3(config-router-af)# neighbor FABRIC activate
leaf-3(config-router-af)# advertise-all-vni
leaf-3(config-router-af)# end
leaf-3# write
leaf-3# exit
admin@leaf-3:~$ sudo config save -y
```
### leaf-4
```
admin@leaf-4:~$ sudo config interface ip add Loopback0 6.6.6.6/32
admin@leaf-4:~$ sudo config interface ip add Ethernet16 11.0.3.1/31
admin@leaf-4:~$ sudo config interface ip add Ethernet32 11.0.7.1/31
admin@leaf-4:~$ sudo config vlan add 10
admin@leaf-4:~$ sudo config vlan add 20
admin@leaf-4:~$ sudo config vlan member add 20 Ethernet40
admin@leaf-4:~$ sudo config interface ip add Vlan10 172.16.10.4/24
admin@leaf-4:~$ sudo config interface ip add Vlan20 172.16.20.4/24
admin@leaf-4:~$ sudo config vxlan add vtep 6.6.6.6
admin@leaf-4:~$ sudo config vxlan evpn_nvo add nvo vtep
admin@leaf-4:~$ sudo config vxlan map add vtep 10 1000
admin@leaf-4:~$ sudo config vxlan map add vtep 20 2000
admin@leaf-4:~$ vtysh
leaf-4# configure terminal
leaf-4(config)# router bgp 65103
leaf-4(config-router)# bgp router-id 6.6.6.6
leaf-4(config-router)# no bgp ebgp-required-policy
leaf-4(config-router)# bgp bestpath as-path multipath-relax
leaf-4(config-router)# neighbor FABRIC peer-group
leaf-4(config-router)# neighbor FABRIC remote-as external
leaf-4(config-router)# neighbor Ethernet16 interface peer-group FABRIC
leaf-4(config-router)# neighbor Ethernet32 interface peer-group FABRIC 
leaf-4(config-router)# address-family ipv4
leaf-4(config-router-af)# redistribute connected
leaf-4(config-router-af)# exit
leaf-4(config-router)# address-family l2vpn evpn
leaf-4(config-router-af)# neighbor FABRIC activate
leaf-4(config-router-af)# advertise-all-vni
leaf-4(config-router-af)# end
leaf-4# write
leaf-4# exit
admin@leaf-4:~$ sudo config save -y
```

# 設定確認 (VTEP のみ)
### IPv4 BGP session
`show ip bgp sum` SONiC CLIで確認し、leaf それぞれの BGP session は無事で AS65000 の spine に接続されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/a8d2d628-3cf6-b168-f0e6-ea60fbbfeb4a.png)

### Underlay routing
Underlay routing の確認する方法は、`show ip route` で routing table を確認できます。
- leaf-1 and leaf-2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/d9575985-1f95-d651-ef4e-6c67f4d1c714.png)
- leaf-3 and leaf-4
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/94239268-87ea-de00-0379-07866e115b30.png)

### Vxlan interface 
`show vxlan interface` CLI で、VTEP IP は Loopback IPで生成されたのをわかりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/3cfeb429-c61b-b160-a065-307ae23fc2a3.png)

### VLAN-VNI mapping
VLAN-VNI のマッピング状況は、`show vxlan tunnel`で確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/cb95b960-61ee-64ca-b60e-8a8a98034352.png)

### Status for Vxlan tunneling
`show vxlan remotevtep` で VTEP tunnel のステータスを確認してみると、なんと Tunnel Status は Down になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/7f3a67a7-9168-9ec7-5a9f-0fcd304135cb.png)

Underlayのルーティングが適切に構築されているにも関わらず、OperStatus が正しく設定されない理由について調査すると、おそらくこの OperStatus の判断基準は、ASIC が Tunnel の情報を適切に書き込んでいるかを SAI からの通知を受け取ることに依存しています。このため、OperStatus が正常にならない原因は、VS はこの辺との統合はされていないだろうと思います。

VS 側は、VTEP IPが正常に生成されているか、Linx Kernel からしか確認できないと考えて、`ip -o -de link show |grep vtep` で確認すると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/b1735af5-7f09-7622-f10c-8150eef3af78.png)
ここで、local の後に表示されている IP アドレスが VTEP の IP　アドレスであり、それぞれ VNI が　1000 と 2000 に関連付けられています。つまり、CLI は、`oper_down` になっても、Tunnel はうまく生成されていると思います。それは VS の制限の一つでしょう。

### ping 疎通
#### 目標
以下の Host 間の ping 疎通を試します！
- Host 1 -> Host 2
- Host 1 -> Host 3
- Host 1 -> Host 4

それぞれの ip 設定は
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/709914b2-06b1-323b-786d-b00e2a940753.png)

#### ping 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/02d12412-a677-b09b-d621-47ea6671f887.png)

#### VxLAN による Mac 学習
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3307184/a232ac00-60bb-32c8-e951-9f6bf93ebee2.png)
VS 版は、その MAC は local learned か remote learned か、区別できていないようです。
[Edgecore 正式のリファレンス](https://support.edge-core.com/hc/en-us/articles/900002720523--Enterprise-SONiC-EVPN-L2-VxLAN)から見ると、localかremote 区別できています。もしくは、今回の検証 VS バージョンは若干古いです。今後は要確認ですね。

## 最後に
せっかく環境をつくりましたから、今後この設定を失わないように、config_db.json や frr.conf の コンフィグファイルを Github に公開しまし、ぜひご参考ください。次回は ZTP で本記事のコンフィグを自動デプロイさせようと思います。

https://github.com/cyo-chang/sonic-gns3-configs-reference

# 参考
- *1 [Dutt, Dinesh G. "BGP in the Data Center." O'Reilly Media, Inc., August 2017.](https://accton-group.atlassian.net/wiki/download/attachments/59398091/BGP_in_the_DataCenter_Oreilly.pdf?version=1&modificationDate=1664173959000&cacheVersion=1&api=v2)
- [SONiCでVXLAN 2022 L2VNI編](https://qiita.com/masru0714/items/aca21a09ce4ce1107f05) (OSS SONiC との 実機検証)
- [Enterprise SONiC Distribution by Edgecore help center](https://support.edge-core.com/hc/en-us/categories/360002134713-Enterprise-SONiC-Distribution-by-Edgecore)
- [VXLANチュートリアル](https://www.janog.gr.jp/meeting/janog37/download_file/vxlan.pdf)