diff --git a/project.py b/project.py index a01a19f..ec5b1fc 100644 --- a/project.py +++ b/project.py @@ -1,3 +1,5 @@ +import sys +import os from time import sleep from mininet.cli import CLI @@ -6,8 +8,10 @@ from mininet.util import dumpNodeConnections from mininet.log import setLogLevel, info from mininet.link import TCLink -from project.node import BATMANRouter, LinuxRouter, OLSRRouter -from project.topo import GraphmlTopo +sys.path.insert(0, os.getcwd() + '/project') + +from project.node import BATMANDRouter, LinuxRouter, OLSRRouter +from project.topo import GraphmlTopoUniqueSubnet, GraphmlTopoDifferentSubnet def monitor_test(net): for host in net.hosts: @@ -28,15 +32,15 @@ def enable_olsrd(net): -hosts = {'linuxrouter': LinuxRouter, 'olsrrouter': OLSRRouter, 'batmanrouter': BATMANRouter} -topos = {'gmltopo': GraphmlTopo} +hosts = {'linuxrouter': LinuxRouter, 'olsrrouter': OLSRRouter, 'batmanrouter': BATMANDRouter} +topos = {'gmltopo1': GraphmlTopoUniqueSubnet, 'gmltopo2': GraphmlTopoDifferentSubnet} CLI.do_enable_olsrd = do_enable_olsrd def perfTest(): - topo = GraphmlTopo(filename='rural-gephi.graphml') + topo = GraphmlTopoDifferentSubnet(filename='rural-gephi.graphml') net = Mininet(topo=topo, link=TCLink, host=LinuxRouter) net.start() diff --git a/project/node.py b/project/node.py index c61f8cf..3f6fd4e 100644 --- a/project/node.py +++ b/project/node.py @@ -1,34 +1,93 @@ +from signal import SIGINT from mininet.node import Node +from mininet.util import moveIntf class LinuxRouter(Node): - def config(self, **params): + 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.servicePid = self.cmd('olsrd -nofork -i ' + ' '.join(self.intfNames()) + ' >/dev/null 2>&1 & echo $!') - print(self.servicePid) + self.popenOLSR = self.popen('olsrd', '-nofork' , '-i', *self.intfNames()) def terminate(self): - self.cmd('kill ', self.servicePid) + self.popenOLSR.send_signal(SIGINT) + self.popenOLSR.wait() super(OLSRRouter, self).terminate() -class BATMANRouter(LinuxRouter): +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(BATMANRouter, self).config(**params) - self.servicePid = self.cmd('batmand ' + ' '.join(self.intfNames()) + '& echo $!') - print(self.servicePid) + 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('kill ' + self.servicePid) - super(BATMANRouter, self).terminate() + self.cmd('batctl', '-m', self.batman_intf, 'if', 'destroy') + super(BATMANADVRouter, self).terminate() diff --git a/project/topo.py b/project/topo.py index e54bb4b..82aca0a 100644 --- a/project/topo.py +++ b/project/topo.py @@ -1,22 +1,13 @@ #!/usr/bin/env python - -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): def build(self, filename='topology.graphml'): - positions = dict() try: @@ -27,10 +18,9 @@ class GraphmlTopo(Topo): 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) + self.addHost('h%i' % node_id, privateDirs=privateDirs) x_pos = node.find('.//data[@key="x"]') y_pos = node.find('.//data[@key="y"]') @@ -43,22 +33,41 @@ class GraphmlTopo(Topo): source = int(link.get('source')) + 1 target = int(link.get('target')) + 1 - intfName_s, addr1, params_s = self.format_intf_params(link_id, source) - intfName_t, addr2, params_t = self.format_intf_params(link_id, target) - - linkopts = dict() # dict(bw=10, delay='5ms', loss=20, max_queue_size=1000, use_htb=True) + linkopts = self.format_intf_params(source, target, link_id) + # dict(bw=10, delay='5ms', loss=20, max_queue_size=1000, use_htb=True) + # linkopts.update(self.) # 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) + self.addLink('h%i' % source, 'h%i' % target, cls=TCLink, **linkopts) + + def format_intf_params(self, source_id, target_id, link_id): + return dict() - 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 +class GraphmlTopoUniqueSubnet(GraphmlTopo): + + def format_intf_params(self, source_id, target_id, link_id): + + intf_name_s = 'h%i-eth%i' % (source_id, link_id) + intf_name_t = 'h%i-eth%i' % (target_id, link_id) + + addr_s = '00:00:00:00:%02i:%02i' % (source_id, link_id) + addr_t = '00:00:00:00:%02i:%02i' % (target_id, link_id) + + ip_s = '10.0.%i.%i/16' % (source_id, link_id) + ip_t = '10.0.%i.%i/16' % (target_id, link_id) + + return {'addr1' : addr_s, 'params1' : {'ip': ip_s}, + 'addr2' : addr_t, 'params2' : {'ip': ip_t}} + +class GraphmlTopoDifferentSubnet(GraphmlTopo): + + def format_intf_params(self, source_id, target_id, link_id): + + addr_s = '00:00:00:00:%02i:%02i' % (source_id, link_id) + addr_t = '00:00:00:00:%02i:%02i' % (target_id, link_id) + ip_s = '10.0.%i.%i/24' % (link_id, source_id) + ip_t = '10.0.%i.%i/24' % (link_id, target_id) + return {'addr1' : addr_s, 'params1' : {'ip': ip_s}, + 'addr2' : addr_t, 'params2' : {'ip': ip_t}} diff --git a/routing-table-monitor.sh b/routing-table-monitor.sh index fcc83be..4c87c75 100644 --- a/routing-table-monitor.sh +++ b/routing-table-monitor.sh @@ -1,9 +1,36 @@ name="$(ifconfig | awk -F- '$2 ~ /eth/ { print $1; exit;}')" -log_directory="./logs/" -log_file="${name}_routingtable.log" -log_path="${log_directory}${log_file}" -echo > "$log_path" +log_directory=$HOME/logs/ +log_file=${name}-rt.log + + +while [[ $# -gt 0 ]]; do + case $1 in + -c|--cmd) + RT_COMMAND="$2" + shift # past argument + shift # past value + ;; + -o|--output) + OUTPUT_FILE="$2" + shift # past argument + shift # past value + ;; + -*|--*) + echo "Unknown option $1" + exit 1 + ;; + esac +done + +: "${RT_COMMAND:='route -n'}" +: "${OUTPUT_FILE:=${log_directory}${log_file}}" + +echo "COMMAND: $RT_COMMAND" +echo "OUTPUT: $OUTPUT_FILE" + +echo > "$OUTPUT_FILE" +echo "starting at: $(date +"%T %N")" >> "$OUTPUT_FILE" function parse_diff () { @@ -18,12 +45,13 @@ function parse_diff () { function log () { while IFS= read -r line; do - echo -e "$(date +"%Y-%m-%d_%H-%M-%S")\t$2\t$line" >> ${log_path} + echo "here" + echo -e "$(date +"%T %N")\t$2\t$line" >> "$OUTPUT_FILE" done <<< "$1" } -curr=$(route -n) +curr=$($RT_COMMAND) atstart="$(echo "$curr" | sed '1,2d')" log "$atstart" "add:" @@ -31,8 +59,10 @@ log "$atstart" "add:" while true; do prev="$curr" - curr=$(route -n) + curr=$($RT_COMMAND) diff_out=$(diff -u <(echo "$prev") <(echo "$curr")) [ $? -eq 0 ] || parse_diff "$diff_out" + sleep 0.5 + done diff --git a/whole-project.py b/whole-project.py index 09c5d9f..c273e36 100644 --- a/whole-project.py +++ b/whole-project.py @@ -41,7 +41,7 @@ class GraphmlTopo(Topo): try: graph = ET.parse(filename).getroot() except Exception as error: - print('oops: ', error) + print(error) exit(1) for node in graph.iter('{http://graphml.graphdrawing.org/xmlns}node'): @@ -92,7 +92,7 @@ class GraphmlTopo(Topo): return intf_name, addr, params -def calculate_link_params(pos_1, pos_2, x=2): +def eval_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 @@ -164,6 +164,12 @@ class BATMANDRouterMonitored(BATMANDRouter): self.popenRTMonitor.send_signal(SIGINT) super(BATMANDRouterMonitored, self).terminate() + def startRTMonitor(self): + self.popenRTMonitor = self.popen( + 'bash routing-table-monitor.sh -c "ip route show table 66"' + ) + + class BATMANADVRouter(LinuxRouter): @@ -258,7 +264,7 @@ def perfTestBatman(): net = Mininet(topo=topo, link=TCLink, host=BATMANDRouterMonitored) net.start() - routing_table_monitor_test(net) + #routing_table_monitor_test(net) info("Dumping host connections\n") dumpNodeConnections(net.hosts) CLI(net) @@ -268,5 +274,5 @@ def perfTestBatman(): if __name__ == '__main__': setLogLevel('info') # Prevent test_simpleperf from failing due to packet loss - perfTest() - #perfTestBatman() + #perfTest() + perfTestBatman()