8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

お家でBGP!containerlab x FRRoutingで学ぶBGP経路制御シミュレーション

Last updated at Posted at 2025-10-17

はじめに

GMOコネクトの永田です。

前回に引き続きcontainerlabを試していきます。

「ルーターと言えばBGPでしょ!」ということで、今回はFRRoutingでBGPを試してみます。

BGPであれば、どこのご家庭でもお使いの一般的なProtocolであり、設定例も潤沢にあるかな?と思っていましたが、意外と少なかったのでまとめてみます。

まとめ

  • containerlabを使うと、topology図に沿った構成が簡単に実現可能
    • 複数Routerでの経路伝搬も簡単に試すことができる
  • BGPを設定する場合、FRRoutingではRFC8212の設定もあるので要注意

試したtopology

今回はsrc/dstとも別のRouter(別のAS)に所属し、Router間(AS間)をBGPでの経路伝搬とします。

とてもシンプルな構成ですね!

AS65001などと書いているのがAS番号です。経路制御を行うRouterを一意に識別する番号です。今回は「Private AS番号」と呼ばれるローカルで自由に使える番号を利用しています。

AS番号含め、BGPの用語や概念については、以下のページを参照してください。

topology設定

では早速containerlabでtopologyを組んでいきます。

clab yml

できました!
上記topology図の通り素直に nodeslinks を記載するだけですね。
bindsに vtysh.conf が増えていますが、FRRの設定のところで説明します。

name: clab-mini-topo
topology:
  nodes:
    r1:
      kind: linux
      image: quay.io/frrouting/frr:10.4.1
      binds:
        - r1/daemons:/etc/frr/daemons
        - r1/frr.conf:/etc/frr/frr.conf
        - r1/vtysh.conf:/etc/frr/vtysh.conf
    r2:
      kind: linux
      image: quay.io/frrouting/frr:10.4.1
      binds:
        - r2/daemons:/etc/frr/daemons
        - r2/frr.conf:/etc/frr/frr.conf
        - r2/vtysh.conf:/etc/frr/vtysh.conf
    src:
      kind: linux
      image: praqma/network-multitool:latest
      exec:
        - "ip link set eth1 up"
        - "ip addr add 192.168.1.11/24 dev eth1"
        - "ip route add 192.168.0.0/16 via 192.168.1.1 dev eth1"
    dst:
      kind: linux
      image: praqma/network-multitool:latest
      exec:
        - "ip link set eth1 up"
        - "ip addr add 192.168.2.11/24 dev eth1"
        - "ip route add 192.168.0.0/16 via 192.168.2.1 dev eth1"
  links:
    # for bgp peering
    - endpoints: [r1:eth2, r2:eth2]
    # for host connectivity
    - endpoints: [src:eth1, r1:eth1]
    - endpoints: [dst:eth1, r2:eth1]

FRRouting Config

次にFRRoutingのConfigでBGPをサポートするようにします。

daemons(r1/r2とも同じ)

前回からの差分は、bgpd=yes に変更したのみです。

zebra=yes
bgpd=yes
ospfd=yes
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=yes
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
staticd=no
pbrd=no
bfdd=no
fabricd=no

vtysh_enable=yes
zebra_options=" -s 90000000 --daemon -A 127.0.0.1"
bgpd_options="   --daemon -A 127.0.0.1"
ospfd_options="  --daemon -A 127.0.0.1"
ospf6d_options=" --daemon -A ::1"
ripd_options="   --daemon -A 127.0.0.1"
ripngd_options=" --daemon -A ::1"
isisd_options="  --daemon -A 127.0.0.1"
pimd_options="  --daemon -A 127.0.0.1"
ldpd_options="  --daemon -A 127.0.0.1"
nhrpd_options="  --daemon -A 127.0.0.1"
eigrpd_options="  --daemon -A 127.0.0.1"
babeld_options="  --daemon -A 127.0.0.1"
sharpd_options="  --daemon -A 127.0.0.1"
staticd_options="  --daemon -A 127.0.0.1"
pbrd_options="  --daemon -A 127.0.0.1"
bfdd_options="  --daemon -A 127.0.0.1"
fabricd_options="  --daemon -A 127.0.0.1"

vtysh.conf(r1/r2とも同じ)

この後、FRRのvtyshを使ってBGPの状態を参照したいのですが、/etc/frr/vtysh.conf が存在しないとエラーとなるため、事前に作成しておきます。

service integrated-vtysh-config

今回はbgpdなどdaemon毎の設定ではなく、frr.conf に全deamonの設定を集約するので上記としています。

Control whether integrated frr.conf file is written when ‘write file’ is issued.

These commands need to be placed in vtysh.conf to have any effect. Note that since vtysh.conf is not written by FRR itself, they therefore need to be manually placed in that file.

frr.conf(r1)

最後に設定本体のfrr.cofを見ていきます。

frr version 10.4.1_git
frr defaults traditional
hostname router1
no ipv6 forwarding
!
# I/F settings
interface eth1
 ip address 192.168.1.1/24
!
interface eth2
 ip address 192.168.12.1/24
!
interface lo
 ip address 10.10.10.1/32
!
# AS-PATH filter for outbound (own routes only)
bgp as-path access-list OWN-ROUTES permit ^$
!
route-map BGP-OUT permit 10
 match as-path OWN-ROUTES
exit
!
# AS-PATH filter for inbound (only allow routes from neighbor)
bgp as-path access-list IN-ROUTES permit 65002
!
route-map BGP-IN permit 10
 match as-path IN-ROUTES
exit
!
# BGP Configuration for Router1(AS65001)
router bgp 65001
  # no bgp ebgp-requires-policy
  neighbor 192.168.12.2 remote-as 65002
  !
  address-family ipv4 unicast
    network 192.168.1.0/24
    neighbor 192.168.12.2 soft-reconfiguration inbound
    neighbor 192.168.12.2 route-map BGP-OUT out
    neighbor 192.168.12.2 route-map BGP-IN in
  exit-address-family
exit
!
line vty
!

I/F settings

I/F settings からの3つは、topology図に記載があるNIC(src向けとAS65002向けの2つ)+lo(local)であり、それに沿ったNIC名とIPアドレスを指定しています。

BGP setting

次に、ちょっと飛ばしてBGP設定の本体を見ます。

# BGP Configuration for Router1(AS65001)
router bgp 65001
  # no bgp ebgp-requires-policy
  neighbor 192.168.12.2 remote-as 65002
  !
  address-family ipv4 unicast
    network 192.168.1.0/24
    neighbor 192.168.12.2 soft-reconfiguration inbound
    neighbor 192.168.12.2 route-map BGP-OUT out
    neighbor 192.168.12.2 route-map BGP-IN in
  exit-address-family
exit
  • router bgp 65001 から exit までが、bgp設定です
  • neighbor 192.168.12.2 remote-as 65002
    • お隣のASを指定します。今回はtopologyで書いた通りのIPとAS番号を指定します
  • address-family ipv4 unicast の中の network 192.168.1.0/24 が、本ASが起点となって周知したい経路情報です。今回はsrcが所属するIP Rangeになります
  • neighbor 192.168.12.2 soft-reconfiguration inbound
    • これはOptionalなのですが、受信した経路情報をRouting Tableとは別に保持するかどうかの設定です。今回はdebugしやすように設定をいれています
  • neighbor 192.168.12.2 route-map BGP-OUT outneighbor 192.168.12.2 route-map BGP-IN in
    • 本ASから出ていく経路情報(out)と入ってくる経路情報(in)のpolicy(フィルタリング条件)となります
    • RFC8212 Default External BGP (EBGP) Route Propagation Behavior without Policies に準拠した設定です (正直めんどくさい)
    • in/outそれぞれにpolicyを設定しています。policyの具体的な内容は後述
    • なお、no bgp ebgp-requires-policy の設定を入れると無視することも可能です(上記サンプルではコメントアウトされているところ)

bgp ebgp-requires-policy

This command requires incoming and outgoing filters to be applied for eBGP sessions as part of RFC-8212 compliance. Without the incoming filter, no routes will be accepted. Without the outgoing filter, no routes will be announced.

BGP setting - route-map

最後に、先ほど飛ばした設定を見ます。ここが経路情報の送受信policy本体です。

# AS-PATH filter for outbound (own routes only)
bgp as-path access-list OWN-ROUTES permit ^$
!
route-map BGP-OUT permit 10
 match as-path OWN-ROUTES
exit
!
# AS-PATH filter for inbound (only allow routes from neighbor)
bgp as-path access-list IN-ROUTES permit 65002
!
route-map BGP-IN permit 10
 match as-path IN-ROUTES
exit
!
  • bgp as-path access-list OWN-ROUTES permit ^$
    • BGP送信用に、自身が伝搬元となる経路情報のみ許可
    • AS_PATHが空のものを指定
      • AS_PATHについては、先ほどのJPNICのページを参照してください
  • oute-map BGP-OUT permit 10 match as-path OWN-ROUTES
    • BGP-OUT という名前で先ほどの「自身が伝搬元」を許可(permit
  • bgp as-path access-list IN-ROUTES permit 65002
    • BGP受信用に、お隣(AS65002)からのみ許可
  • route-map BGP-IN permit 10 match as-path IN-ROUTES
    • 上記の受信を許可

policyですが、FFRのドキュメントにサンプルもあるので、参考にするのも良いです。

Bogon ASN filter policy configuration example

bgp as-path access-list 99 permit _0_
bgp as-path access-list 99 permit _23456_
bgp as-path access-list 99 permit _1310[0-6][0-9]_|_13107[0-1]_
bgp as-path access-list 99 seq 20 permit ^65

frr.conf(r2)

設定内容はr1と同じ考え方です。IP RangeやAS番号などをr2向けに変更しています。

frr version 10.4.1_git
frr defaults traditional
hostname router2
no ipv6 forwarding
!
# I/F settings
interface eth1
 ip address 192.168.2.1/24
!
interface eth2
 ip address 192.168.12.2/24
!
interface lo
 ip address 10.10.10.2/32
!
# AS-PATH filter for outbound (own routes only)
bgp as-path access-list OWN-ROUTES permit ^$
!
route-map BGP-OUT permit 10
 match as-path OWN-ROUTES
exit
!
# AS-PATH filter for inbound (only allow routes from neighbor)
bgp as-path access-list IN-ROUTES permit 65001
!
route-map BGP-IN permit 10
 match as-path IN-ROUTES
exit
!
# BGP Configuration for Router2(AS65002)
router bgp 65002
  # no bgp ebgp-requires-policy
  neighbor 192.168.12.1 remote-as 65001
  !
  address-family ipv4 unicast
    network 192.168.2.0/24
    neighbor 192.168.12.1 soft-reconfiguration inbound
    neighbor 192.168.12.1 route-map BGP-OUT out
    neighbor 192.168.12.1 route-map BGP-IN in
  exit-address-family
exit
!
line vty
!

動かしてみた

topologyの起動

containerlabで起動します。(同じclab nameで起動中の場合は、--reconfigure optionもつけてください)

❯ containerlab deploy -t bgp-mini-topo.clab.yml
01:42:07 INFO Containerlab started version=0.71.0
01:42:07 INFO Parsing & checking topology file=bgp-mini-topo.clab.yml
01:42:07 INFO Destroying lab name=clab-mini-topo
01:42:07 INFO Removed container name=clab-clab-mini-topo-r1
01:42:07 INFO Removed container name=clab-clab-mini-topo-r2
01:42:07 INFO Removed container name=clab-clab-mini-topo-dst
01:42:07 INFO Removed container name=clab-clab-mini-topo-src
01:42:07 INFO Removing host entries path=/etc/hosts
01:42:07 INFO Removing SSH config path=/etc/ssh/ssh_config.d/clab-clab-mini-topo.conf
01:42:07 INFO Removing directory path=/Users/nagatatakahiko/work/aist/aist-pcs-telemetry/example/clab-bgp-mini-topo/clab-clab-mini-topo
01:42:07 INFO Creating lab directory path=/Users/nagatatakahiko/work/aist/aist-pcs-telemetry/example/clab-bgp-mini-topo/clab-clab-mini-topo
01:42:07 INFO unable to adjust Labdir file ACLs: operation not supported
01:42:07 INFO Creating container name=src
01:42:07 INFO Creating container name=dst
01:42:07 INFO Creating container name=r1
01:42:07 INFO Creating container name=r2
01:42:07 INFO Created link: r1:eth2 ▪┄┄▪ r2:eth2
01:42:07 INFO Created link: dst:eth1 ▪┄┄▪ r2:eth1
01:42:07 INFO Created link: src:eth1 ▪┄┄▪ r1:eth1
01:42:07 INFO Executed command node=src command="ip link set eth1 up" stdout=""
01:42:07 INFO Executed command node=src command="ip addr add 192.168.1.11/24 dev eth1" stdout=""
01:42:07 INFO Executed command node=src command="ip route add 192.168.0.0/16 via 192.168.1.1 dev eth1" stdout=""
01:42:07 INFO Executed command node=dst command="ip link set eth1 up" stdout=""
01:42:07 INFO Executed command node=dst command="ip addr add 192.168.2.11/24 dev eth1" stdout=""
01:42:07 INFO Executed command node=dst command="ip route add 192.168.0.0/16 via 192.168.2.1 dev eth1" stdout=""
01:42:08 INFO Adding host entries path=/etc/hosts
01:42:08 INFO Adding SSH config for nodes path=/etc/ssh/ssh_config.d/clab-clab-mini-topo.conf
You are on the latest version (0.71.0)
╭─────────────────────────┬─────────────────────────────────┬─────────┬───────────────────╮
│           Name          │            Kind/Image           │  State  │   IPv4/6 Address  │
├─────────────────────────┼─────────────────────────────────┼─────────┼───────────────────┤
│ clab-clab-mini-topo-dst │ linux                           │ running │ 172.20.20.2       │
│                         │ praqma/network-multitool:latest │         │ 3fff:172:20:20::2 │
├─────────────────────────┼─────────────────────────────────┼─────────┼───────────────────┤
│ clab-clab-mini-topo-r1  │ linux                           │ running │ 172.20.20.5       │
│                         │ quay.io/frrouting/frr:10.4.1    │         │ 3fff:172:20:20::5 │
├─────────────────────────┼─────────────────────────────────┼─────────┼───────────────────┤
│ clab-clab-mini-topo-r2  │ linux                           │ running │ 172.20.20.4       │
│                         │ quay.io/frrouting/frr:10.4.1    │         │ 3fff:172:20:20::4 │
├─────────────────────────┼─────────────────────────────────┼─────────┼───────────────────┤
│ clab-clab-mini-topo-src │ linux                           │ running │ 172.20.20.3       │
│                         │ praqma/network-multitool:latest │         │ 3fff:172:20:20::3 │
╰─────────────────────────┴─────────────────────────────────┴─────────┴───────────────────╯

r1のBGPおよびrouting tableの確認

さて、BGPを確認していきます。
bashで入ってvtyshを呼び出してもいいのですが、直接でも入れるのでそちらの方法にしています。

❯ docker exec -it clab-clab-mini-topo-r1 vtysh


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

r1# 

BGPのsummaryを見てみます。

r1# show bgp summary

IPv4 Unicast Summary:
BGP router identifier 10.10.10.1, local AS number 65001 VRF default vrf-id 0
BGP table version 2
RIB entries 3, using 384 bytes of memory
Peers 1, using 17 KiB of memory

Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd   PfxSnt Desc
192.168.12.2    4      65002         8         9        2    0    0 00:03:28            1        1 N/A

Total number of neighbors 1

State/PfxRcd(受信した経路情報)が1、PfxSnt(送信した経路情報)が1ですので、期待通り動作していそうですね!

送受信した経路情報の詳細をもうちょっと見てみます。

まずは送信した経路情報です。

r1# show ip bgp nei 192.168.12.2 advertised-routes
BGP table version is 2, local router ID is 10.10.10.1, vrf id 0
Default local pref 100, local AS 65001
Status codes:  s suppressed, d damped, h history, u unsorted, * 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
 *>  192.168.1.0/24   0.0.0.0                  0         32768 i

Total number of prefixes 1

srcが所属するIP Range( 192.168.1.0/24 )を送っており、期待通りです。

次に、受信した経路情報です。

r1# show ip bgp nei 192.168.12.2 received-routes
BGP table version is 2, local router ID is 10.10.10.1, vrf id 0
Default local pref 100, local AS 65001
Status codes:  s suppressed, d damped, h history, u unsorted, * 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
 *> 192.168.2.0/24   192.168.12.2             0             0 65002 i

Total number of prefixes 1

dstが所属するIP Range( 192.168.2.0/24 )を受信しており、こちらも期待通りです。

最後に、r1のip routeを見ます。

r1# show ip route
Codes: K - kernel route, C - connected, L - local, 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, t - Table-Direct,
       > - selected route, * - FIB route, q - queued, r - rejected, b - backup
       t - trapped, o - offload failure

IPv4 unicast VRF default:
K>* 0.0.0.0/0 [0/0] via 172.20.20.1, eth0, weight 1, 00:07:30
L * 10.10.10.1/32 is directly connected, lo, weight 1, 00:07:29
C>* 10.10.10.1/32 is directly connected, lo, weight 1, 00:07:29
C>* 172.20.20.0/24 is directly connected, eth0, weight 1, 00:07:30
L>* 172.20.20.5/32 is directly connected, eth0, weight 1, 00:07:30
C>* 192.168.1.0/24 is directly connected, eth1, weight 1, 00:07:29
L>* 192.168.1.1/32 is directly connected, eth1, weight 1, 00:07:29
B>* 192.168.2.0/24 [20/0] via 192.168.12.2, eth2, weight 1, 00:07:25
C>* 192.168.12.0/24 is directly connected, eth2, weight 1, 00:07:29

B>* 192.168.2.0/24 [20/0] via 192.168.12.2, eth2, weight 1, 00:07:25 と、BGPで追加された経路情報であること、dstの所属するIP Range向けにeth2経由でr2に行けば良いとなっていて、期待通りですね!😊

src-->dstの疎通確認

最後に、みんな大好きpingで疎通確認してみましょう!
src containerに入ってpingします。

❯ docker exec -it clab-clab-mini-topo-src bash

bash-5.1# ping -c 4 192.168.2.11
PING 192.168.2.11 (192.168.2.11) 56(84) bytes of data.
64 bytes from 192.168.2.11: icmp_seq=1 ttl=62 time=0.058 ms
64 bytes from 192.168.2.11: icmp_seq=2 ttl=62 time=0.145 ms
64 bytes from 192.168.2.11: icmp_seq=3 ttl=62 time=0.193 ms
64 bytes from 192.168.2.11: icmp_seq=4 ttl=62 time=0.174 ms

--- 192.168.2.11 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3055ms
rtt min/avg/max/mdev = 0.058/0.142/0.193/0.051 ms

ついでにみんな大好きtracerouteで経路を確認してみます。

bash-5.1# traceroute 192.168.2.11
traceroute to 192.168.2.11 (192.168.2.11), 30 hops max, 46 byte packets
 1  192.168.1.1 (192.168.1.1)  0.009 ms  0.014 ms  0.006 ms
 2  192.168.12.2 (192.168.12.2)  0.008 ms  0.025 ms  0.006 ms
 3  192.168.2.11 (192.168.2.11)  0.004 ms  0.023 ms  0.005 ms

topology図通りの経路になっていますね!😊

(再掲)まとめ

  • containerlabを使うと、topology図に沿った構成が簡単に実現可能
    • 複数Routerでの経路伝搬も簡単に試すことができる
  • BGPを設定する場合、FRRoutingではRFC8212の設定もあるので要注意

最後に、GMOコネクトでは研究開発や国際標準化に関する支援や技術検証をはじめ、幅広い支援を行っておりますので、何かありましたらお気軽にお問合せください。

お問合せ: https://gmo-connect.jp/contactus/

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?