なんとなくEVPN理解

EVPNを知って実際に動かしてみました、記録です。

 

EVPN(Ethernet VPN)とは

 

すごいざっくり書くとシンプルなL2VPNを実現する技術です。

広域イーササービスやDCのlayer2 networkで活躍するらしいです。

EVPNの仕組みとしてやってることはどうやらBGPでMACアドレスを広報するらしいです。えっBGPで…?

 

 

MP-BGP(Multi Protocol BGP)とは

 

通常のBGP-4(通常のBGPの事を指す)ではMACアドレスなんて経路広報出来ません、BGP-4はIPv4 onlyです。

そこで登場するのがMP-BGP、MP(Multi Protocol)ということはIPv4 unicastだけではありません。扱えるものがIPv4-vpn-unicastやIPv6関連だったりとたくさん増えました。

その扱える中にEVPNがあるということになります。

ここらへんの話が気になる方はこのRFCの中のAFI/SAFIを見てみると幸せになります。

BGPにとっては結構重要なものです。あと一つ覚えておくといいのはBGP-4, BGP4+(MP-BGPの事を指す)でもOPEN メッセージのやりとりでもネゴシエーションするためにこの識別子は使われています。パケットを見てみるのも良いかもしれません。

tex2e.github.io

 

BGP4+はそれだけではありません、もっと拡張されています。

なんとBGP PathAttributeが改造されています。パケットをBGP-4、BGP4+と比較して見ていきます。

 

これがBGP4+

f:id:eniyEniy:20210406022458p:plain

こっちがBGP4

f:id:eniyEniy:20210406022646p:plain

全然違うことが分かると思います。なんならBGP4+のPath Attributeに新入りも来ています。

 

MP_REACH_NLRIとは

 

BGP4+で追加されたPath AttributeですこれはBGP4にもNLRIがいますが、BGP4+では拡張されたNLRIという扱いになっています。AFI/SAFIやNext hop addr length RD RT labelといった情報が含まれています

 

そもそもNLRIはBGP4ではPathAttributeではありません。BGP4では中身も経路広報したいprefixをかくだけのものでした。

ちなみに先程説明したAFI/SAFIの情報が入ってきます。今さっきは説明してなかったのですが組み合わせが決まっており以下のような組み合わせになっています

www.juniper.net

ちなみにEVPNでは

AFI = 25 SFAI = 70 という形になっています。

 

RD RT についてはVRFという存在を知ることになります。なにをしているのかというと互いに値が同じだったら互いに同じルーティングテーブルを共有しているという考えでとりあえずはいいと思っています。ちょっとこれはEVPNで考えると少しむずかしいのでまた新たに追加されているlabel技術を使ったL3VPNのMPLS-VPNなどを使用してみると理解出来ると思います。

 

BGP4+ではどのようにMACアドレスが埋め込まれているかと言うと、MP_REACH_NLRIの中のNLRIにBGP4+専用の経路広報用MACアドレスフォーマットを用意してくれています。

f:id:eniyEniy:20210409212243p:plain


通信してくれる手順を紹介した所で、次はパケットを飛ばしたりする環境づくりです。

 

Vxlanとは

 

すごいシンプルに書くとやっていることはL3のネットワークでL2のネットワークを展開出来るというものです。

VNIという識別子を元に通信を行い、VTEPという出口を目標にVxlanのトンネルを築いています。

 

ここまでの手順を用いてEVPNは完成します。こいつを作ってやることでBGP4+とVxlanを組み合わせることで大規模なネットワークのL2VPN、EVPNが完成するということになっています。

EVPNの構成の仕方としてデータプレーンとコントロールプレーンという概念にわけられており

BGP4+がどのようにデータをやり取りするかを決めるコントロールプレーンで

Vxlanがデータを流すデータプレーンということになっています。

データプレーンはVxlanだけではありません。MPLSであったり、PBBも存在します。

これらのデータプレーンは使用用途によって変わったりします。

 

これらを踏まえた上で検証していきます

 

FRRoutingを利用したEVPN+Vxlanの検証

 

今回の検証ではFRRを用いたネットワークを構築するためにTINETというソフトウェアを使用します。

github.com

 

こちらのソフトウェアはyamlファイルを書くだけでFRR基準のネットワークが構築することが出来ます。とっとも便利です。

 

検証用トポロジー

 

f:id:eniyEniy:20210411161120p:plain

TINET config


nodes:
  - name: R0
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net0 }
  - name: R1
    image: slankdev/frr- name: R2
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R1#net1 }
      - { name: net1, type: direct, args: R3#net0 }
  - name: R3
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R2#net1 }
      - { name: net1, type: direct, args: R4#net0 }
  - name: R4
    image: slankdev/frr
    interfaces:
      - { name: net0, type: direct, args: R3#net1 }


node_configs:        
  - name: R0
    cmds:
      - cmd: ip addr add 192.168.0.1/24 dev net0
      - cmd: ip link set net0 address 52:54:00:bb:02:00
  - name: R1
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: ip addr add 10.0.1.1/24 dev net1
      - cmd: ip link set net0 address 52:54:00:aa:01:01
      - cmd: ip link set net1 address 52:54:00:aa:01:02
      - cmd: ip link add br100 type bridge
      - cmd: ip link set dev br100 up
      - cmd: >-
          ip link add vxlan100 type vxlan id 100
          dstport 4789
      - cmd: ip addr add 192.168.0.2/24 dev br100
      - cmd: ip link set dev net0 master br100
      - cmd: ip link set dev net0 promisc on
      - cmd: ip link set dev net0 up
      - cmd: ip link set dev vxlan100 master br100
      - cmd: ip link set dev vxlan100 promisc on
      - cmd: ip link set dev vxlan100 up

      - cmd: >-
          vtysh -c "conf t"
          -c "interface lo"
          -c "ip address 1.1.1.1/32"
          -c "router ospf"
          -c "network 1.1.1.1/24 area 0"
          -c "network 10.0.1.0/24 area 0"
          -c "router bgp 65000"
          -c "neighbor 3.3.3.3 remote-as internal"
          -c "neighbor 3.3.3.3 update-source 1.1.1.1"
          -c "address-family l2vpn evpn"
          -c "neighbor 3.3.3.3 activate"
          -c "advertise-all-vni"
          -c "exit-address-family"
  - name: R2
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: ip addr add 10.0.1.2/24 dev net0
      - cmd: ip addr add 10.0.2.1/24 dev net1
      - cmd: ip link set net0 address 52:54:00:cc:01:01
      - cmd: ip link set net1 address 52:54:00:cc:02:01
      - cmd: >-
          vtysh -c "conf t"
          -c "interface lo"
          -c "ip address 2.2.2.2/32"
          -c "router ospf"
          -c "network 10.0.1.0/24 area 0"
          -c "network 10.0.2.0/24 area 0"
          -c "network 2.2.2.2/24 area 0"
  - name: R3
    cmds:
      - cmd: /usr/lib/frr/frr start
      - cmd: ip addr add 10.0.2.2/24 dev net0
      - cmd: ip link set net0 address 52:54:00:aa:02:00
      - cmd: ip link set net1 address 52:54:00:aa:02:01
      - cmd: ip link add br100 type bridge
      - cmd: ip link set dev br100 up
      - cmd: ip addr add 192.168.0.3/24 dev br100
      - cmd: >-
          ip link add vxlan100 type vxlan id 100
          dstport 4789
      - cmd: ip link set dev net1 master br100
      - cmd: ip link set dev net1 promisc on
      - cmd: ip link set dev net1 up
      - cmd: ip link set dev vxlan100 master br100
      - cmd: ip link set dev vxlan100 promisc on
      - cmd: ip link set dev vxlan100 up

      - cmd: >-
          vtysh -c "conf t"
          -c "interface lo"
          -c "ip address 3.3.3.3/32"
          -c "router ospf"
          -c "network 3.3.3.3/24 area 0"
          -c "network 10.0.2.0/24 area 0"
          -c "router bgp 65000"
          -c "neighbor 1.1.1.1 remote-as internal"
          -c "neighbor 1.1.1.1 update-source 3.3.3.3"
          -c "address-family l2vpn evpn"
          -c "neighbor 1.1.1.1 activate"
          -c "advertise-all-vni"
          -c "exit-address-family"
  - name: R4
    cmds:
      - cmd: ip addr add 192.168.0.4/24 dev net0
      - cmd: ip link set net0 address 52:54:00:bb:04:00
    interfaces:
      - { name: net0, type: direct, args: R0#net0 }
      - { name: net1, type: direct, args: R2#net0 }
    

 config解説

R1、R3に


- cmd: ip link add br100 type bridge
      - cmd: ip link set dev br100 up
      - cmd: >-
          ip link add vxlan100 type vxlan id 100
          dstport 4789
      - cmd: ip addr add 192.168.0.2/24 dev br100
      - cmd: ip link set dev net0 master br100
      - cmd: ip link set dev net0 promisc on
      - cmd: ip link set dev net0 up
      - cmd: ip link set dev vxlan100 master br100
      - cmd: ip link set dev vxlan100 promisc on
      - cmd: ip link set dev vxlan100 up

 このようなconfigがあると思います。

Vxlanインターフェースをこのようにブリッジのグループに所属してあげることでL2VPNとしての動きを見せる事が出来ます。反対側のルーターと同じVNI(ここではvxlan id 100という値)を見てけてあげるのがBGP4+の役目となっています。

ちなみに反対側のR0、R4からフレームをもらうことになっているのでnet0をブリッジのグループに所属させています。あとIPは飾りでつけても付けなくてもいいです。

このconfigの仕方はiproute2独自のやり方となっています。

wiki.archlinux.jp

 

R1、R2、R3の最初の動きとしてOSPFでPEルーター、Pルーター、PEルーターの経路情報を交換します。

 

R1、R3をIBGPでつなぎます。


    -c "router bgp 65000"
          -c "neighbor 3.3.3.3 remote-as internal"
          -c "neighbor 3.3.3.3 update-source 1.1.1.1"
          -c "address-family l2vpn evpn"
          -c "neighbor 3.3.3.3 activate"
          -c "advertise-all-vni"
          -c "exit-address-family"

address-family l2vpn evpn

これが前半で説明したBGP4+特有の識別子(アドレスファミリ)です。

advertise-all-vni

EVPNの機能を有効にする設定です。

 

実際に動かします。

 

R0(192.168.0.1)からR4(192.168.0.4)をpingが通るのを確認します。

R1でsummaryを確認してみると、State/PfxRcdに値があります。f:id:eniyEniy:20210411175025p:plain

 

R1でルートを確認してみると

f:id:eniyEniy:20210411175318p:plain

 

R4のMACアドレスが学習出来ています。

 

まとめ

EVPNの構成から実際に動かす所までをざっくりと書いてみました。

もし何かおかしな部分などがあればご指摘どんどんお願いします。