这是一个令菜ji的我心态爆炸的实验。。。
实验拓扑:
在路由器r1, r2上开启OSPFv3进程(我在实验中也顺便加了OSPFv2进程,所以后面会看到有关OSPFv2的代码)
实验的代码如下:
#!/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 -w net.ipv4.ip_forward=1') # '-w' is not necessary
self.cmd('sysctl -w net.ipv6.conf.all.forwarding=1') # this enable ipv6 forwarding on router ! ! !
def terminate(self):
self.cmd('sysctl -w net.ipv4.ip_forward=0')
self.cmd('sysctl -w net.ipv6.conf.all.forwarding=0')
super(LinuxRouter, self).terminate()
class NetworkTopo(Topo):
'''
h1 h1-eth0:r1-eth2
h2 h2-eth0:r2-eth2
r1 r1-eth1:r2-eth1 r1-eth2:h1-eth0
r2 r2-eth1:r1-eth1 r2-eth2:h2-eth0
'''
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)
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')
self.addLink(h1, router1, intfName2='r1-eth2',
params2={'ip': '10.0.1.10/24'}) # params2 define the eth2 ip address
self.addLink(h2, router2, intfName2='r2-eth2', params2={'ip': '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')
h1 = net.getNodeByName('h1')
h2 = net.getNodeByName('h2')
'''
Configure ipv6 for interface.
'''
r1.cmd('ifconfig r1-eth1 inet6 add 2001:1::12/96')
r2.cmd('ifconfig r2-eth1 inet6 add 2001:1::21/96')
r1.cmd('ifconfig r1-eth2 inet6 add 1::10/96')
h1.cmd('ifconfig h1-eth0 inet6 add 1::1/96')
h1.cmd('route -6 add default gw 1::10 dev h1-eth0') # add ipv6 default route for h1
r2.cmd('ifconfig r2-eth2 inet6 add 2::20/96')
h2.cmd('ifconfig h2-eth0 inet6 add 2::2/96')
h2.cmd('route -6 add default gw 2::20 dev h2-eth0') # add ipv6 default route for h2
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')
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')
r1.cmd('ospf6d -f /usr/local/etc/R1ospf6d.conf -d -z ~/desktop/R1zebra.api -i ~/desktop/R1ospf6d.interface')
r2.cmd('ospf6d -f /usr/local/etc/R2ospf6d.conf -d -z ~/desktop/R2zebra.api -i ~/desktop/R2ospf6d.interface')
CLI(net)
net.stop()
os.system("killall -9 ospfd ospf6d zebra") # this command can also be used to check whether the daemons had been set up
os.system("rm -f *api*")
os.system("rm -f *interface*")
if __name__ == '__main__':
setLogLevel('info')
run()
先写配置文件zebra.conf, ospf6d.conf。
zebra的配置文件书写就不多说了,具体可以见我另外一篇博客(其实很简单的):
https://blog.csdn.net/shamansi99/article/details/104107958
以r1为例,写配置文件r1ospf6d.conf:
!
! Zebra configuration saved from vty
! 2003/11/28 00:49:49
!
hostname R1
password R1
enable password R1
!
interface r1-eth1 ! this is the default configuration of the interface
ipv6 ospf6 cost 1
ipv6 ospf6 hello-interval 10
ipv6 ospf6 dead-interval 40
ipv6 ospf6 retransmit-interval 5
ipv6 ospf6 priority 1
ipv6 ospf6 transmit-delay 1
ipv6 ospf6 instance-id 0 ! note that only with same instance-id, can the interfaces interact with each other
!
interface r1-eth2
ipv6 ospf6 cost 1
ipv6 ospf6 hello-interval 10
ipv6 ospf6 dead-interval 40
ipv6 ospf6 retransmit-interval 5
ipv6 ospf6 priority 0
ipv6 ospf6 transmit-delay 1
ipv6 ospf6 instance-id 0
!
interface r1-eth3
ipv6 ospf6 cost 1
ipv6 ospf6 hello-interval 10
ipv6 ospf6 dead-interval 40
ipv6 ospf6 retransmit-interval 5
ipv6 ospf6 priority 0
ipv6 ospf6 transmit-delay 1
ipv6 ospf6 instance-id 0
!
interface lo
ipv6 ospf6 cost 1
ipv6 ospf6 hello-interval 10
ipv6 ospf6 dead-interval 40
ipv6 ospf6 retransmit-interval 5
ipv6 ospf6 priority 0
ipv6 ospf6 transmit-delay 1
ipv6 ospf6 instance-id 0
!
router ospf6
router-id 10.0.3.10
interface r1-eth1 area 0.0.0.0 ! setup area of the interface
interface r1-eth2 area 0.0.0.0
interface r1-eth3 area 0.0.0.0
interface lo area 0.0.0.0
!
log stdout
service advanced-vty
!
debug ospf6 neighbor state
r2的配置文件也是差不多的。
请注意,在将接口声明进OSPFv3域时,最好也将loopback进去,此时如果lo有global的ipv6地址,也是同样可以生成动态路由的,其他节点也能根据这个lo ipv6地址将数据转发到该lo所属的节点。无特殊情况,最好将节点的所有interface都声明进去。
接下来运行实验:
h1 ping6 h2一开始不通,后来通了,说明实验成功!
注意,不能用pingall验证h1, h2之间是否ipv6能够ping通,因为pingall默认是使用ipv4进行ping的,这里使用pingall是为了观察OSPFv3路由器是否完成路由表更新(之前说过嘛,我还加了OSPFv2进程,OSPFv3的更新时间跟OSPFv2的时间差不多,因此可以借助OSPFv2来判断OSPFv3是否完成更新)
小结
这是一个令菜ji的我心态爆炸的实验。。。其实OSPFv3路由实验跟OSPFv2的是差不多的,只是在配置文件上有些差别,但是配置也不是很难写,但是还是花费了我很多时间,因为,我忘了在路由器上开启ipv6转发功能!!!! 难怪我拼命debug都解决不了,后来是我导师的提醒才注意到这一点的。。。害。。。
其实一开始也不是没想到开启ipv6转发功能。开启ipv4的比较简单,就是sysctl net.ipv4.ip_forward=1就可以了,于是我就推导ipv6应该就是sysctl net.ipv6.ip_forward=1,然而系统说没有这个参数,然后我就顺理成章的以为sysctl net.ipv4.ip_forward=1也开启了ipv6的转发功能了。。。