シナプス技術者ブログ

シナプスの技術者公式ブログ。インターネットで、鹿児島の毎日を笑顔にします。

FRRouting + VRF-Lite + VLAN + BGP

技術部の中野です。

とあるネットワークにおいて、以下の3つの要件を必要とするサービスを検討しています。

  1. 1つの物理インターフェースをVLANで分割
  2. VLAN毎にVRF-Liteでルーティングテーブルを分離
  3. BGPで経路交換

今回、この要件の実現方法として、オープンソースのルーティングプロトコルスタックである「FRRouting」を検証してみました。

構成

今回、検証に用いたLinuxディストリビューションやFRRoutingのバージョンは、以下のとおりとなっています。

項目 バージョン
Linuxディストリビューション Ubuntu 20.04.4 LTS
FRRouting FRR 8.2.2

なお、FRRoutingはUbuntuにて提供されているパッケージではなく、FRR Debian repositoryからインストールしました。

物理ネットワーク構成

物理的なネットワーク構成は、1台のLinuxマシンの物理インターフェースをVLANで分割し、内部にBLUE/GREENと2つのVRFを作成しています。

また、BLUE/GREENのVRFはそれぞれ、外部のルータとBGPにより経路交換を行います。

論理ネットワーク構成

論理的なネットワーク構成は、BLUE/GREENの2つのVRFにおいて、まったく同じIPアドレス体系のネットワークを設定しています。

環境構築

環境構築は、2つのステップに分けて行います。

  1. Linux(Ubuntu)上で、パケット転送や物理インターフェース/VRF/VLANのネットワークデバイスの設定
  2. FRRouting上で、IPアドレスやBGPの設定

Ubuntuのネットワーク設定は、Netplanやsystemd-networkdなど利用することが一般的ですが、以下の理由により利用しないこととしました。

  • Netplanは現時点(2022-03-24)では、VRFをサポートされていない
  • systemd-networkdでは、VRF/VLANはサポートされている
    • 新たな仮想ルータを追加時のVRF/VLAN追加や、既存の仮想ルータを削除時のVRF/VLAN削除に、systemd-networkdを再起動する必要がある
    • systemd-networkdの再起動時、既存の仮想ルータのネットワークが一時的に停止する

そのため、仮想ルータ単位でネットワークを設定するスクリプトを作成し、独自のsystemdのserviceとして設定するようにしました。

パケット転送設定

まずは、Linuxサーバをルータとして動作させるため、パケット転送を許可する設定を行います。

/usr/bin/sudo /bin/sh -c '/usr/sbin/sysctl -w net.ipv4.ip_forward=1 >> /etc/sysctl.d/local.conf'

物理インターフェースの設定

VRFで利用するeno2やens6f0などの物理インターフェースは、Netplanでは管理せず、前述のsystemdから呼ばれるスクリプトにて管理するようにしました。

実際の処理は、以下のように物理インターフェースをアップさせるだけとなっています。

/usr/bin/sudo /usr/sbin/ip link set dev eno2 up
/usr/bin/sudo /usr/sbin/ip link set dev ens6f0 up

仮想ルータBLUEの設定

VRFやVLANの設定は、仮想ルータ毎に設定しています。こちらも、前述のsystemdから呼ばれるスクリプトにて管理するようにしました。

以下は、仮想ルータBLUEの設定です。

# Add vrf
/usr/bin/sudo /usr/sbin/ip link add dev BLUE type vrf table 10
/usr/bin/sudo /usr/sbin/ip link set dev BLUE up

# Add LAN
/usr/bin/sudo /usr/sbin/ip link add link eno2 name BLUE-LAN type vlan id 10
/usr/bin/sudo /usr/sbin/ip link set dev BLUE-LAN master BLUE up

# Add WAN
/usr/bin/sudo /usr/sbin/ip link add link ens6f0 name BLUE-WAN type vlan id 11
/usr/bin/sudo /usr/sbin/ip link set dev BLUE-WAN master BLUE up

仮想ルータGREENの設定

以下は、仮想ルータGREENの設定です。

# Add vrf
/usr/bin/sudo /usr/sbin/ip link add dev GREEN type vrf table 20
/usr/bin/sudo /usr/sbin/ip link set dev GREEN up

# Add LAN
/usr/bin/sudo /usr/sbin/ip link add link eno2 name GREEN-LAN type vlan id 20
/usr/bin/sudo /usr/sbin/ip link set dev GREEN-LAN master GREEN up

# Add WAN
/usr/bin/sudo /usr/sbin/ip link add link ens6f0 name GREEN-WAN type vlan id 21
/usr/bin/sudo /usr/sbin/ip link set dev GREEN-WAN master GREEN up

FRRoutingインストール

FRRoutingは、「FRR Debian repository」を参考に行います。

今回の検証では、8系を利用するため"frr-8"を指定しています。

curl -s https://deb.frrouting.org/frr/keys.asc | sudo apt-key add -
echo deb https://deb.frrouting.org/frr $(lsb_release -s -c) "frr-8" | sudo tee -a /etc/apt/sources.list.d/frr.list
sudo apt update && sudo apt install frr frr-pythontools

インストール直後は、BGPデーモンは無効になっているため、BGPデーモンを有効にします。

/usr/bin/sudo /usr/bin/sed -i -e 's/bgpd=no/bgpd=yes/g' /etc/frr/daemons

FRRoutingを再起動します。

/usr/bin/sudo /usr/bin/systemctl restart frr.service

FRRoutingの設定

FRRoutingの設定は、「VTY shell」と呼ばれる専用シェルにてインタラクティブに設定しますが、Ciscoライクな操作感なため、Cisco社製のルータやスイッチ等を触ったことのある方は、スムーズに操作できると思います。

VTY shellの起動方法は以下のとおりです。

$ /usr/bin/sudo /usr/bin/vtysh

Hello, this is FRRouting (version 8.2.2).
Copyright 1996-2005 Kunihiro Ishiguro, et al.

frr# configure terminal
frr(config)#

この検証では、以下の設定しています。

  • BLUE用/GREEN用に、それぞれ2つのインターフェースをIPアドレスを設定
  • 広報経路・受信経路はprefix-list/route-mapにてフィルタ
  • 自ASは「64512」、相手ASは「64513」にて設定

実際の設定はこちら。

frr# show running-config no-header
frr version 8.2.2
frr defaults traditional
hostname frr
log syslog
no ipv6 forwarding
service integrated-vtysh-config
!
interface BLUE-LAN
 ip address 10.0.0.1/24
exit
!
interface BLUE-WAN
 ip address 10.0.3.1/30
exit
!
interface GREEN-LAN
 ip address 10.0.0.1/24
exit
!
interface GREEN-WAN
 ip address 10.0.3.1/30
exit
!
router bgp 64512 vrf BLUE
 bgp router-id 10.0.0.1
 bgp log-neighbor-changes
 neighbor BLUE-PEER peer-group
 neighbor BLUE-PEER remote-as 64513
 neighbor 10.0.3.2 peer-group BLUE-PEER
 !
 address-family ipv4 unicast
  network 10.0.0.0/24
  neighbor BLUE-PEER soft-reconfiguration inbound
  neighbor BLUE-PEER route-map BLUE-in in
  neighbor BLUE-PEER route-map BLUE-out out
 exit-address-family
exit
!
router bgp 64512 vrf GREEN
 bgp router-id 10.0.0.1
 bgp log-neighbor-changes
 neighbor GREEN-PEER peer-group
 neighbor GREEN-PEER remote-as 64513
 neighbor 10.0.3.2 peer-group GREEN-PEER
 !
 address-family ipv4 unicast
  network 10.0.0.0/24
  neighbor GREEN-PEER soft-reconfiguration inbound
  neighbor GREEN-PEER route-map GREEN-in in
  neighbor GREEN-PEER route-map GREEN-out out
 exit-address-family
exit
!
ip prefix-list BLUE-LAN seq 1 permit 10.0.0.0/24
ip prefix-list BLUE-WAN seq 1 permit 10.0.1.0/24
ip prefix-list GREEN-LAN seq 1 permit 10.0.0.0/24
ip prefix-list GREEN-WAN seq 1 permit 10.0.1.0/24
!
route-map BLUE-out permit 1
 match ip address prefix-list BLUE-LAN
exit
!
route-map BLUE-in permit 1
 match ip address prefix-list BLUE-WAN
exit
!
route-map GREEN-out permit 1
 match ip address prefix-list GREEN-LAN
exit
!
route-map GREEN-in permit 1
 match ip address prefix-list GREEN-WAN
exit
!
end

確認

インターフェースの状態

各インターフェースの状態を一覧確認は「show interface brief」にて行います。

結果はVRF毎にて出力され、状態(up/down)やIPアドレスが表示されます。

なお、defaultのeno1のインターフェースは、このサーバの管理用として設定しているものです。

frr# show interface brief
Interface       Status  VRF             Addresses
---------       ------  ---             ---------
BLUE            up      BLUE
BLUE-LAN        up      BLUE            10.0.0.1/24
BLUE-WAN        up      BLUE            10.0.3.1/30

Interface       Status  VRF             Addresses
---------       ------  ---             ---------
GREEN           up      GREEN
GREEN-LAN       up      GREEN           10.0.0.1/24
GREEN-WAN       up      GREEN           10.0.3.1/30

Interface       Status  VRF             Addresses
---------       ------  ---             ---------
eno1            up      default         XXX.XXX.XXX.XXX/24
eno2            up      default
ens6f0          up      default
ens6f1          up      default
lo              up      default

BGPピアの状態

BGPピアの状態確認は「show bgp vrf all ipv4 summary」にて行います。

こちらも結果はVRF毎にて出力され、リモートASや受信経路数/広報経路数などが表示されます。

frr# show bgp vrf all ipv4 summary

IPv4 Unicast Summary (VRF BLUE):
BGP router identifier 10.0.0.1, local AS number 64512 vrf-id 6
BGP table version 11
RIB entries 3, using 552 bytes of memory
Peers 1, using 723 KiB of memory
Peer groups 1, using 64 bytes of memory

Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd   PfxSnt Desc
10.0.3.2        4      64513      5741      5749        0    0    0 00:01:09            1        1 N/A

Total number of neighbors 1

IPv4 Unicast Summary (VRF GREEN):
BGP router identifier 10.0.0.1, local AS number 64512 vrf-id 9
BGP table version 12
RIB entries 3, using 552 bytes of memory
Peers 1, using 723 KiB of memory
Peer groups 1, using 64 bytes of memory

Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd   PfxSnt Desc
10.0.3.2        4      64513      5742      5751        0    0    0 00:01:04            1        1 N/A

Total number of neighbors 1

VRFを指定してBGPピアの状態を見る場合は、以下のようにVRF名を指定します。

frr# show bgp vrf BLUE ipv4 summary

IPv4 Unicast Summary (VRF BLUE):
BGP router identifier 10.0.0.1, local AS number 64512 vrf-id 6
BGP table version 11
RIB entries 3, using 552 bytes of memory
Peers 1, using 723 KiB of memory
Peer groups 1, using 64 bytes of memory

Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd   PfxSnt Desc
10.0.3.2        4      64513      5751      5759        0    0    0 00:11:09            1        1 N/A

Total number of neighbors 1

広報経路の確認

広報している経路の確認は、「show bgp vrf <VRF名> ipv4 neighbors <ピア先のIPアドレス> advertised-routes」にて行います。

以下は、BLUEのVRFの10.0.3.2のピアへの広報経路の確認結果で、10.0.0.0/24を広報しています。

frr# show bgp vrf BLUE ipv4 neighbors 10.0.3.2 advertised-routes
BGP table version is 17, local router ID is 10.0.0.1, vrf id 6
Default local pref 100, local AS 64512
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0/24      0.0.0.0                  0         32768 i

Total number of prefixes 1

受信経路の確認

受信した経路の確認は、「show bgp vrf <VRF名> ipv4 neighbors <ピア先のIPアドレス> received-routes」にて行います。

以下は、BLUEのVRFの10.0.3.2のピアからの受信経路の確認結果で、10.0.1.0/24、172.16.0.0/12の2経路を受信しています。

received-routesコマンドでは、受信ポリシーに関わらず、全ての受信経路が表示されます。

frr# show bgp vrf BLUE ipv4 neighbors 10.0.3.2 received-routes
BGP table version is 17, local router ID is 10.0.0.1, vrf id 6
Default local pref 100, local AS 64512
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.1.0/24      10.0.3.2                               0 64513 i
*> 172.16.0.0/12    10.0.3.2                               0 64513 i

Total number of prefixes 2 (1 filtered)

受信ポリシー後の受信経路を確認

受信ポリシーによりフィルタリングされた後の受信した経路の確認は、「show bgp vrf <VRF名> ipv4 neighbors <ピア先のIPアドレス> routes」にて行います。

以下は、BLUEのVRFの10.0.3.2のピアからの受信経路の確認結果で、2経路受け取ったうちの10.0.1.0/24の1経路のみが受理されています。

frr# show bgp vrf BLUE ipv4 neighbors 10.0.3.2 routes
BGP table version is 17, local router ID is 10.0.0.1, vrf id 6
Default local pref 100, local AS 64512
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

   Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.1.0/24      10.0.3.2                               0 64513 i

Displayed  1 routes and 2 total paths

ルーティングテーブルの確認

ルーティングテーブルの確認は「show ip routes vrf all」にて行います。

結果はVRF毎にて出力されます。

frr# show ip route vrf all
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

VRF BLUE:
C>* 10.0.0.0/24 is directly connected, BLUE-LAN, 4d22h52m
B>* 10.0.1.0/24 [20/0] via 10.0.3.2, BLUE-WAN, weight 1, 00:02:32
C>* 10.0.3.0/30 is directly connected, BLUE-WAN, 4d22h52m

VRF GREEN:
C>* 10.0.0.0/24 is directly connected, GREEN-LAN, 4d22h52m
B>* 10.0.1.0/24 [20/0] via 10.0.3.2, GREEN-WAN, weight 1, 00:00:25
C>* 10.0.3.0/30 is directly connected, GREEN-WAN, 4d22h52m

VRF default:
K>* 0.0.0.0/0 [0/0] via 192.168.27.254, eno1, 4d22h52m
C>* XXX.XXX.XXX.0/24 is directly connected, eno1, 4d22h52m

特定のVRFのルーティングテーブルの確認

特定のVRFのルーティングテーブルの確認は「show ip routes vrf <VRF名>」にて行います。

frr# show ip route vrf BLUE
Codes: K - kernel route, C - connected, S - static, R - RIP,
       O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
       T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,
       f - OpenFabric,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

VRF BLUE:
C>* 10.0.0.0/24 is directly connected, BLUE-LAN, 4d22h52m
B>* 10.0.1.0/24 [20/0] via 10.0.3.2, BLUE-WAN, weight 1, 00:03:31
C>* 10.0.3.0/30 is directly connected, BLUE-WAN, 4d22h52m

pingによる疎通確認

現時点の最新版(FRRouting 8.2.2)の「VTY shell」では、VRF上のIPアドレスに対するpingはできないようです。

そのため、Linux(Ubuntu)から「ip vrf exec」コマンドにて実行します。

$ /usr/bin/sudo /usr/sbin/ip vrf exec BLUE /usr/bin/ping -c 5 10.0.1.1
PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.
64 bytes from 10.0.1.1: icmp_seq=1 ttl=255 time=0.179 ms
64 bytes from 10.0.1.1: icmp_seq=2 ttl=255 time=0.188 ms
64 bytes from 10.0.1.1: icmp_seq=3 ttl=255 time=0.146 ms
64 bytes from 10.0.1.1: icmp_seq=4 ttl=255 time=0.145 ms
64 bytes from 10.0.1.1: icmp_seq=5 ttl=255 time=0.147 ms

--- 10.0.1.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4100ms
rtt min/avg/max/mdev = 0.145/0.161/0.188/0.018 ms

まとめ

FRRoutingでVRF-LiteやVLANを検証してみて、Netplanの未サポートやsystemd-networkの課題もありましたが、その部分さえ気にならなければ十分に安定して利用可能だと感じました。

また、FRRoutingはオープンソースソフトウェアであるため、不可解な挙動やコマンドの出力結果に疑問がある場合、公開されているコードを読むことで理解が深めやすいという点もありました。

FRRoutingを始めとするオープンソースのルーティングプロトコルスタックは、ネットワーク/BGP/サーバ/Linuxが好きな私にとって、いい意味で遊べる環境だと思いました。

GitHubのリポジトリ「FRRouting/frr: The FRRouting Protocol Suite」を見ていると、開発が盛んなので、今後の機能拡充が楽しみです。

おまけ

検証中に、とあるコマンドを実行すると必ずbgpdがクラッシュする不具合を発見しましたので、GitHubのIssueに報告したところ、その日のうちにPull Requesが作成され、既にマージされていました。