https://github.com/bobuhiro11/mininetlab の紹介。
Mininet を使うと単一のマシン上でいくつかのスイッチとホストを動作させることができる。 これを使って仮想的にホストを2つ立ち上げ、その間をFRRパッケージに含まれるBGP(Unnumbered)で接続してみる。 Mininetでは以下のようにPythonでトポロジや各ホストにおけるコマンド実行について記述できる。
一見複雑にみえるFRRもdaemons
、vtysh.conf
、frr.conf
の3つのファイルを正しく配置しておけば、
frrinit.sh start
で簡単に起動できる。
ホストごとにnetns
は分割されているが、mountns
は分割されていない(要確認)ため、
/etc/frr
や/var/run/frr
が2つのホスト間で衝突してしまいFRRが正常に起動できなかった。
これはprivateDirs = ['/etc/frr', '/var/run/frr']
によって回避できる。
#!/usr/bin/env python
from mininet.net import Mininet
from mininet.log import setLogLevel
import time
frr_conf = '''
hostname {name}
password zebra
!
router bgp {asnum}
bgp router-id {router_id}
bgp bestpath as-path multipath-relax
neighbor h1-eth0 interface remote-as external
neighbor h2-eth0 interface remote-as external
address-family ipv4 unicast
network {router_id}/32
network {network}
exit-address-family
!
line vty
!
end
'''
vtysh_conf = '''
service integrated-vtysh-config
'''
daemons = '''
bgpd=yes
vtysh_enable=yes
zebra_options=" -A 127.0.0.1 -s 90000000"
bgpd_options=" -A 127.0.0.1"
'''
def put_file(host, file_name, content, **kwargs):
with open("/tmp/tmp", mode="w") as f:
f.write(content.format(**kwargs))
host.cmdPrint("cp /tmp/tmp " + file_name)
def run():
setLogLevel('info')
net = Mininet()
privateDirs = ['/etc/frr', '/var/run/frr']
h1 = net.addHost('h1', ip='192.168.0.1/24',
privateDirs=privateDirs, asnum=65001)
h2 = net.addHost('h2', ip='192.168.0.2/24',
privateDirs=privateDirs, asnum=65002)
net.addLink(h1, h2)
net.start()
for i, h in enumerate(net.hosts):
put_file(h, "/etc/frr/daemons", daemons)
put_file(h, "/etc/frr/vtysh.conf", vtysh_conf)
put_file(h, "/etc/frr/frr.conf", frr_conf, name=h.name,
router_id=h.IP(), asnum=h.params['asnum'],
network='192.168.1.{}/32'.format(i+1))
h.cmd("/usr/lib/frr/frrinit.sh start")
h.cmd('ip address add 192.168.1.{}/32 dev {}-eth0'.format(i+1, h.name))
time.sleep(5)
h1.cmdPrint('vtysh -c "show bgp summary"')
h1.cmdPrint('vtysh -c "show ip bgp"')
h1.cmdPrint('ip route')
# send ping in the advertised route
h1.cmdPrint('ping -c 1 192.168.1.2')
net.stop()
return 0
if __name__ == '__main__':
run()
実行方法は以下の通り。
今回示したPythonコードは bgp_unnumbered.py
として保存されているとする。
BGPによって192.168.1.X
のIPが広報されている。
# Ubuntu 20.04 LTS を想定
$ apt install -y frr
$ git clone git://github.com/mininet/mininet
$ pushd mininet
$ git checkout -b mininet-2.3.0 2.3.0
$ ./util/install.sh -nv
$ popd
$ python bgp_unnumbered.py
*** Configuring hosts
h1 h2
*** Starting controller
*** Starting 0 switches
*** h1 : ('cp /tmp/tmp /etc/frr/daemons',)
*** h1 : ('cp /tmp/tmp /etc/frr/vtysh.conf',)
*** h1 : ('cp /tmp/tmp /etc/frr/frr.conf',)
*** h2 : ('cp /tmp/tmp /etc/frr/daemons',)
*** h2 : ('cp /tmp/tmp /etc/frr/vtysh.conf',)
*** h2 : ('cp /tmp/tmp /etc/frr/frr.conf',)
*** h1 : ('vtysh -c "show bgp summary"',)
IPv4 Unicast Summary:
BGP router identifier 192.168.0.1, local AS number 65001 vrf-id 0
BGP table version 4
RIB entries 7, using 1288 bytes of memory
Peers 2, using 41 KiB of memory
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
h1-eth0 4 65002 5 5 0 0 0 00:00:03 2
h2-eth0 4 0 0 0 0 0 0 never Idle
Total number of neighbors 2
*** h1 : ('vtysh -c "show ip bgp"',)
BGP table version is 4, local router ID is 192.168.0.1, vrf id 0
Default local pref 100, local AS 65001
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
Network Next Hop Metric LocPrf Weight Path
*> 192.168.0.1/32 0.0.0.0 0 32768 i
*> 192.168.0.2/32 h1-eth0 0 0 65002 i
*> 192.168.1.1/32 0.0.0.0 0 32768 i
*> 192.168.1.2/32 h1-eth0 0 0 65002 i
Displayed 4 routes and 4 total paths
*** h1 : ('ip route',)
192.168.0.0/24 dev h1-eth0 proto kernel scope link src 192.168.0.1
192.168.0.2 via 169.254.0.1 dev h1-eth0 proto bgp metric 20 onlink
192.168.1.2 via 169.254.0.1 dev h1-eth0 proto bgp metric 20 onlink
*** h1 : ('ping -c 1 192.168.1.2',)
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.037 ms
--- 192.168.1.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.037/0.037/0.037/0.000 ms
*** Stopping 0 controllers
*** Stopping 1 links
.
*** Stopping 0 switches
*** Stopping 2 hosts
h1 h2
*** Done
ミニマムな構成でFRRの動作を検証できるようになった。 徐々に実践的なネットワーク構成へと拡張させていきたい。 おわり。