本文中实验的所有内容来自:https://github.com/qyang18/Mininet-Quagga
实验的拓扑如下:
下面是实验的代码QuaggaOSPF.py:
#!/usr/bin/python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import Node
from mininet.log import setLogLevel, info
from mininet.cli import CLI
import time
import os
class LinuxRouter( Node ):
"A Node with IP forwarding enabled."
def config( self, **params ):
super( LinuxRouter, self).config( **params )
# Enable forwarding on the router
self.cmd( 'sysctl net.ipv4.ip_forward=1' )
def terminate( self ):
self.cmd( 'sysctl net.ipv4.ip_forward=0' )
super( LinuxRouter, self ).terminate()
class NetworkTopo( Topo ):
"A LinuxRouter connecting three IP subnets"
def build( self, **_opts ):
defaultIP1 = '10.0.3.10/24' # IP address for r1-eth1
defaultIP2 = '10.0.3.20/24'
router1 = self.addNode( 'r1', cls=LinuxRouter, ip=defaultIP1 ) # cls = class
router2 = self.addNode( 'r2', cls=LinuxRouter, ip=defaultIP2 )
h1 = self.addHost( 'h1', ip='10.0.1.100/24', defaultRoute='via 10.0.1.10') # define gateway
h2 = self.addHost( 'h2', ip='10.0.2.100/24', defaultRoute='via 10.0.2.20')
self.addLink(router1,router2,intfName1='r1-eth1',intfName2='r2-eth1') # r1-eth1 <-> r2-eth1
self.addLink(h1,router1,intfName2='r1-eth2',params2={ 'ip' : '10.0.1.10/24' })
# h1-eth0 <-> r1-eth2, r1-eth2 = 10.0.1.10/24
self.addLink(h2,router2,intfName2='r2-eth2',params2={ 'ip' : '10.0.2.20/24' })
# h2-eth0 <-> r2-eth2, r2-eth2 = 10.0.2.20/24
def run():
"Test linux router"
topo = NetworkTopo()
net = Mininet(controller = None, topo=topo ) # no controller
net.start()
info( '*** Routing Table on Router:\n' )
r1=net.getNodeByName('r1')
r2=net.getNodeByName('r2')
info('starting zebra and ospfd service:\n')
r1.cmd('zebra -f /usr/local/etc/r1zebra.conf -d -z ~/desktop/r1zebra.api -i ~/desktop/r1zebra.interface')
# -z, -i一个都不能少,*zebra.api, *zebra.interface会在启动时自动创建,下同
# 不过有一点要注意,*zebra.api, *zebra.interface必须创建在桌面(不知为啥)
time.sleep(1) # time for zebra to create api socket
r2.cmd('zebra -f /usr/local/etc/r2zebra.conf -d -z ~/desktop/r2zebra.api -i ~/desktop/r2zebra.interface')
r1.cmd('ospfd -f /usr/local/etc/r1ospfd.conf -d -z ~/desktop/r1zebra.api -i ~/desktop/r1ospfd.interface')
r2.cmd('ospfd -f /usr/local/etc/r2ospfd.conf -d -z ~/desktop/r2zebra.api -i ~/desktop/r2ospfd.interface')
CLI( net )
net.stop()
os.system("killall -9 ospfd zebra") # 杀死进程
os.system("rm -f *api*") # 移除.api文件
os.system("rm -f *interface*") # 移除.interface文件
if __name__ == '__main__':
setLogLevel( 'info' )
run()
第一步先给r1, r2配置*zebra.conf文件:
$ cd /usr/local/etc $ cp zebra.conf.sample r1zebra.conf $ cp zebra.conf.sample r2zebra.conf
第二步,给r1, r2配置*ospfd.conf文件:
$ cd /usr/local/etc $ cp ospfd.conf r1ospfd.conf $ cp ospfd.conf r2ospfd.conf
第三步,编辑r1ospfd.conf, r2ospfd.conf:
hostname r1_ospfd password 123 #设置密码 enable password 123 #加入这条语句会在运行时自动激活密码,不必输入 router ospf #声明路由协议为OSPF ospf router-id 10.0.3.10 #设置OSPF路由器的标识 network 10.0.3.0/24 area 0 #设置网络所处的OSPF area network 10.0.1.0/24 area 0 debug ospf event log file /usr/local/etc/r1ospfd.log #日志文件
事实上,也可以通过将接口声明进OSPF area,来将网络声明进去,这种情况个人认为会更加方便。详细的做法可以参照Quagga的官方文档,也挺简单的。
最后,运行QuaggaOSPF.py,并进行pingall测试:
$ sudo python QuaggaOSPF.py mininet> pingall
稍等40s,路由表就更新完成,到时就能ping通啦。
小结
(1) mininet中的addHost, addLink操作要熟用起来,熟悉其用法。
(2) mininet中的cmd, python中的os要好好使用,会有大用处。
(3) -z, -i一个都不能少,其具体作用本人并不是很理解,后续会做进一步的了解,此外还要注意,r1/r2zebra.api, r1/r2zebra.interface必须创建在py文件所在目录下。
(4) 学会写ospf的配置文件。