You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
7.8 KiB
Python

5 months ago
#!/usr/bin/env python
from math import sqrt
import os
from signal import SIGINT
from time import sleep
from mininet.cli import CLI
from mininet.net import Mininet
from mininet.util import dumpNodeConnections, moveIntf, pmonitor
from mininet.log import setLogLevel, info
from mininet.link import TCLink
from mininet.node import Node
from sys import argv
import xml.etree.ElementTree as ET
from mininet.topo import Topo
from mininet.link import TCLink
# It would be nice if we didn't have to do this:
# pylint: disable=arguments-differ
class GraphmlTopo(Topo):
ip_counter = (0,1)
def increment_ip_counter(self):
b3, b4 = GraphmlTopo.ip_counter
if b4 < 254:
b4 += 1
else:
b3 += 1
b4 = 1
GraphmlTopo.ip_counter = b3, b4
def build(self, filename='topology.graphml', subnet=True):
positions = dict()
try:
graph = ET.parse(filename).getroot()
except Exception as error:
print('oops: ', error)
exit(1)
for node in graph.iter('{http://graphml.graphdrawing.org/xmlns}node'):
node_id = int(node.get('id')) + 1
privateDirs = ['/var/log','/var/run']
self.addHost('h%i' % node_id, privateDirs=privateDirs) #,
#cls=LinuxRouter)
x_pos = node.find('.//data[@key="x"]')
y_pos = node.find('.//data[@key="y"]')
positions[node_id] = (x_pos, y_pos)
for link in graph.iter('{http://graphml.graphdrawing.org/xmlns}edge'):
link_id = int(link.get('id')) + 1
source = int(link.get('source')) + 1
target = int(link.get('target')) + 1
if subnet:
intfName_s, addr1, params_s = self.format_intf_params(link_id, source)
intfName_t, addr2, params_t = self.format_intf_params(link_id, target)
else:
intfName_s, addr1, params_s = self.format_intf_params_incremental(source, 16)
intfName_t, addr2, params_t = self.format_intf_params_incremental(target, 16)
linkopts = dict() # dict(bw=10, delay='5ms', loss=20, max_queue_size=1000, use_htb=True)
# to implement a function which from nodes positions return linkopts
self.addLink('h%i' % source, 'h%i' % target, key=link_id, cls=TCLink,
intfName1=intfName_s, addr1=addr1, params1=params_s,
intfName2=intfName_t, addr2=addr2 ,params2=params_t,
**linkopts)
def format_intf_params_incremental(self, node_id, subnet_mask_cidr):
b3, b4 = GraphmlTopo.ip_counter
self.increment_ip_counter()
addr = '00:00:00:00:00:%02i' % (node_id)
params = {'ip': '10.0.%i.%i/%i' % (b3, b4, subnet_mask_cidr)}
return None, addr, params
def format_intf_params(self, link_id, node_id):
intf_name = 'h%i-eth%i' % (node_id, link_id)
addr = '00:00:00:00:%02i:%02i' % (link_id, node_id)
ip = '10.0.%i.%i/24' % (link_id, node_id)
params = {'ip': ip}
return intf_name, addr, params
def calculate_link_params(pos_1, pos_2, x=2):
distance = sqrt((pos_1['x'] + pos_2['x'])^2 - (pos_1['y'] + pos_2['y'])^2)
Tx_W = 2
Rx_W = 2
class LinuxRouter(Node):
def config(self, **params):
self.cmd('sysctl net.ipv4.ip_forward=1')
def terminate(self):
self.cmd('sysctl net.ipv4.ip_forward=0')
super(LinuxRouter, self).terminate()
def startRTMonitor(self):
self.popenRTMonitor = self.popen('bash routing-table-monitor.sh')
def stopRTMonitor(self):
self.popenRTMonitor.send_signal(SIGINT)
self.popenRTMonitor.wait()
class OLSRRouter(LinuxRouter):
def config(self, **params):
super(OLSRRouter, self).config(**params)
self.popenOLSR = self.popen('olsrd', '-nofork' , '-i', *self.intfNames())
def terminate(self):
self.popenOLSR.send_signal(SIGINT)
self.popenOLSR.wait()
super(OLSRRouter, self).terminate()
class OLSRRouterMonitored(OLSRRouter):
def config(self, **params):
self.startRTMonitor()
super(OLSRRouterMonitored, self).config(**params)
def terminate(self):
if self.popenRTMonitor:
self.popenRTMonitor.send_signal(SIGINT)
super(OLSRRouterMonitored, self).terminate()
class BATMANDRouter(LinuxRouter):
def config(self, **params):
super(BATMANDRouter, self).config(**params)
batman_param=[]#sum([['-a', i.IP()+'/32'] for i in self.intfList()],[])
batman_param.extend(self.intfNames())
self.cmd('batmand', *batman_param)
def terminate(self):
# self.popenBATMAND.send_signal(SIGINT)
# self.popenBATMAND.wait()
super(BATMANDRouter, self).terminate()
class BATMANDRouterMonitored(BATMANDRouter):
def config(self, **params):
self.startRTMonitor()
super(BATMANDRouterMonitored, self).config(**params)
def terminate(self):
if self.popenRTMonitor:
self.popenRTMonitor.send_signal(SIGINT)
super(BATMANDRouterMonitored, self).terminate()
class BATMANADVRouter(LinuxRouter):
def config(self, **params):
super(BATMANADVRouter, self).config(**params)
if self.cmd('lsmod', '|', 'grep', '-q', 'batman') is not 0:
self.cmd('modprobe', 'batman-adv')
self.batman_intf = '%s-bat0' % self.name
self.cmd()
for intf in self.intfNames():
self.cmd('batctl', '-m', self.batman_intf, 'if', 'add', intf)
moveIntf(self.batman_intf, self)
id = int(self.name[1:])
self.cmd('ip', 'address', 'add', '192.168.123.%i/24' % id, 'dev', self.batman_intf)
self.cmd('ip', 'link', 'set', 'up', 'dev', self.batman_intf)
def terminate(self):
self.cmd('batctl', '-m', self.batman_intf, 'if', 'destroy')
super(BATMANADVRouter, self).terminate()
def routing_table_monitor_test(net):
info("monitoring routing tables\n")
while (net.pingAll() != 0):
sleep(5)
info("routing tables converged\n")
log("stop link h1-h14")
disable_link(net['h1'], net['h14'])
#net['h11'].stop()
# sleep(60)
# for host in net.hosts:
# host.cmd('kill %bash')
def log(event):
os.system('echo "{}:\t\t$(date +"%T %N")" >> logs/global.log'.format(event))
def do_disable_link(self, line):
net = self.mn
h1, h2 = line.split(" ")
disable_link(net[h1], net[h2])
def disable_link(host1, host2):
intf1, intf2 = host1.connectionsTo(host2)[0]
host1.cmd('iptables -A INPUT -m mac --mac-source', intf2.MAC(), '-j DROP')
def do_enable_olsrd(self, line):
net = self.mn
enable_olsrd(net)
def enable_olsrd(net):
for host in net.hosts:
host.cmd('olsrd -i ' + ' '.join(host.intfNames()))
hosts = {'linuxrouter': LinuxRouter,
'olsrrouter': OLSRRouter,
'batmanadvrouter': BATMANADVRouter,
'batmandrouter': BATMANDRouter}
topos = {'gmltopo': GraphmlTopo}
CLI.do_enable_olsrd = do_enable_olsrd
CLI.do_disable_link = do_disable_link
def perfTest():
topo = GraphmlTopo(filename='rural2.graphml')
net = Mininet(topo=topo, link=TCLink, host=OLSRRouterMonitored)
net.start()
info("Dumping host connections\n")
dumpNodeConnections(net.hosts)
CLI(net)
net.stop()
def perfTestBatman():
topo = GraphmlTopo(filename='rural2.graphml', subnet=False)
net = Mininet(topo=topo, link=TCLink, host=BATMANDRouterMonitored)
net.start()
routing_table_monitor_test(net)
info("Dumping host connections\n")
dumpNodeConnections(net.hosts)
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel('info')
# Prevent test_simpleperf from failing due to packet loss
perfTest()
#perfTestBatman()