├── .gitignore ├── motion_activity.sh ├── topology.png ├── motion_activity.py ├── configs.py ├── dynamicflow.py ├── add_queues.py ├── README.md ├── staticflow.py ├── postflow.py ├── iot_sdn.py ├── testminiTopo.py ├── data_flows.py ├── OVSminiTopo.py └── miniTopo.py /.gitignore: -------------------------------------------------------------------------------- 1 | configs.py 2 | removed/ 3 | *.pyc 4 | *.py~ 5 | .gitignore 6 | -------------------------------------------------------------------------------- /motion_activity.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/sh 2 | 3 | sudo python motion_activity.py 4 | -------------------------------------------------------------------------------- /topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y0Username/iotDynamicPri/HEAD/topology.png -------------------------------------------------------------------------------- /motion_activity.py: -------------------------------------------------------------------------------- 1 | import os 2 | import dynamicflow as df 3 | 4 | df.post_dynamic_flows() 5 | -------------------------------------------------------------------------------- /configs.py: -------------------------------------------------------------------------------- 1 | CONTROLLER_IP = '192.168.56.101' 2 | CONTROLLER_PORT = 6653 3 | IP_BASE = '10.0.5.0/24' 4 | IPERF_INT_BASE_PORT = 5000 5 | IPERF_ST_BASE_PORT = 5010 6 | ST_BAND = 50 7 | INT_BAND = 50 8 | #EXPERIMENT_DURATION = 20 9 | VER = 1 10 | MAC_PREFIX = '00:00:00:00:00:' 11 | IP_PREFIX = '10.0.5.' 12 | -------------------------------------------------------------------------------- /dynamicflow.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | internet = '10.0.5.2' 4 | edgeserver = '10.0.5.1' 5 | 6 | level2Switches = ['s4','s5','s6','s7'] 7 | level3Switches = ['s2','s3'] 8 | 9 | s2_internet_hosts=['10.0.5.3','10.0.5.6'] 10 | s3_internet_hosts=['10.0.5.9','10.0.5.12'] 11 | s2_video_cameras=['10.0.5.4','10.0.5.7'] 12 | s3_video_cameras=['10.0.5.10','10.0.5.13'] 13 | 14 | def post_dynamic_flows(): 15 | cmd = 'sudo ovs-ofctl mod-flows s2 ip,nw_dst='+edgeserver+',actions=set_queue:234,NORMAL' 16 | os.system(cmd) 17 | cmd = 'sudo ovs-ofctl mod-flows s3 ip,nw_dst='+edgeserver+',actions=set_queue:234,NORMAL' 18 | os.system(cmd) 19 | 20 | cmd = 'sudo ovs-ofctl mod-flows s2 ip,nw_dst='+internet+',actions=set_queue:123,NORMAL' 21 | os.system(cmd) 22 | cmd = 'sudo ovs-ofctl mod-flows s3 ip,nw_dst='+internet+',actions=set_queue:123,NORMAL' 23 | os.system(cmd) 24 | 25 | if __name__ == '__main__': 26 | # This runs if this file is executed directly 27 | post_dynamic_flows() 28 | -------------------------------------------------------------------------------- /add_queues.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | level2=['s4','s5','s6','s7'] 4 | level3=['s2','s3'] 5 | level2_link='100000000' 6 | level2_minq='25000000' 7 | level2_maxq='75000000' 8 | 9 | level3_link='150000000' 10 | level3_minq='50000000' 11 | level3_maxq='100000000' 12 | 13 | 14 | def add_HTB_queues(): 15 | 16 | for switch in level2: 17 | cmd = 'sudo ovs-vsctl set port '+switch+'-eth5 qos=@newqos -- --id=@newqos create QoS type=linux-htb other-config:max-rate='+level2_link+' queues:123=@1q queues:234=@2q -- --id=@1q create queue other-config:min-rate=10000000 other-config:max-rate='+level2_minq+' -- --id=@2q create queue other-config:min-rate=20000000 other-config:max-rate='+level2_maxq 18 | os.system('nohup '+cmd) 19 | 20 | for switch in level3: 21 | cmd = 'sudo ovs-vsctl set port '+switch+'-eth5 qos=@newqos -- --id=@newqos create QoS type=linux-htb other-config:max-rate='+level3_link+' queues:123=@1q queues:234=@2q -- --id=@1q create queue other-config:min-rate=10000000 other-config:max-rate='+level3_minq+' -- --id=@2q create queue other-config:min-rate=20000000 other-config:max-rate='+level3_maxq 22 | os.system('nohup '+cmd) 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iotDynamicPri 2 | Dynamic Traffic Prioritization in IoT networks using SDN (ONOS Controller and Mininet Topology) 3 | 4 | Run: `sudo mn --controller=remote,ip=192.168.56.101 --custom=iot_sdn.py --topo=mytopo` 5 | 6 | ### Description: 7 | With the growth of IoT, the number of push-and-forget devices are increasing in traditional networks. These IoT devices are used for some application at the edge server or the cloud. 8 | The goal of the project is to effectively prioritize traffic in a network which is mixture of IoT and traditional network. We leverage the application level knowledge of the IoT network to analyse the importance of the data. Using SDN, this application layer knowledge can be translated into traffic priorities. 9 | 10 | For example, consider a campus network with motion sensor, camera and computers generating user traffic as shown in the topology. For a particular floor in the building, if the motion sensor detect any movement, the cameras should be given higher priority to stream HD video and web trffic should given lower priority. Similarly when there is no motion, the cameras should only stream SD video and we should not let the camera's UDP traffic take over the link bandwidth. 11 | 12 | ### Topology: 13 | 14 | ![Topology](https://github.com/Y0Username/iotDynamicPri/blob/master/topology.png) 15 | -------------------------------------------------------------------------------- /staticflow.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | internet = '10.0.5.2' 4 | edgeserver = '10.0.5.1' 5 | 6 | level2Switches = ['s4','s5','s6','s7'] 7 | level3Switches = ['s2','s3'] 8 | 9 | s2_internet_hosts=['10.0.5.3','10.0.5.6'] 10 | s3_internet_hosts=['10.0.5.9','10.0.5.12'] 11 | s2_video_cameras=['10.0.5.4','10.0.5.7'] 12 | s3_video_cameras=['10.0.5.10','10.0.5.13'] 13 | 14 | #Queue 123 is low priority 15 | #Queue 234 is high priority 16 | 17 | def post_static_flows(): 18 | for host in s2_internet_hosts: 19 | #TODO 20 | cmd = 'sudo ovs-ofctl add-flow s2 ip,priority=6653,nw_src='+host+',nw_dst='+internet+',idle_timeout=0,actions=set_queue:234,normal' 21 | os.system(cmd) 22 | for host in s3_internet_hosts: 23 | #TODO 24 | cmd = 'sudo ovs-ofctl add-flow s3 ip,priority=6653,nw_src='+host+',nw_dst='+internet+',idle_timeout=0,actions=set_queue:234,normal' 25 | os.system(cmd) 26 | 27 | for camera in s2_video_cameras: 28 | #TODO 29 | cmd = 'sudo ovs-ofctl add-flow s2 ip,priority=6653,nw_src='+camera+',nw_dst='+edgeserver+',idle_timeout=0,actions=set_queue:123,normal' 30 | os.system(cmd) 31 | for camera in s3_video_cameras: 32 | #TODO 33 | cmd = 'sudo ovs-ofctl add-flow s3 ip,priority=6653,nw_src='+camera+',nw_dst='+edgeserver+',idle_timeout=0,actions=set_queue:123,normal' 34 | os.system(cmd) 35 | 36 | if __name__ == '__main__': 37 | # This runs if this file is executed directly 38 | post_static_flows() 39 | -------------------------------------------------------------------------------- /postflow.py: -------------------------------------------------------------------------------- 1 | import json 2 | import requests 3 | 4 | 5 | 6 | action = 'POST' 7 | # path = 'http://192.168.56.101:8181/onos/v1/flows/' 8 | server = '192.168.56.101' 9 | port = '8181' 10 | path = '/onos/v1/flows/' 11 | device1 = 'of:0000000000000001' 12 | device2 = 'of:0000000000000002' 13 | session = requests.Session() 14 | session.auth = ('onos', 'rocks') 15 | datas = [] 16 | data = { 17 | "priority": 10, 18 | "timeout": 0, 19 | "isPermanent": True, 20 | "deviceId": "of:0000000000000001", 21 | "treatment": 22 | {"instructions": [{"type":"OUTPUT","port":"3"}]}, 23 | "selector": 24 | {"criteria":[{"type":"IN_PORT","port":1}, 25 | {"type":"ETH_DST","mac":"00:00:00:00:00:02"}, 26 | {"type":"ETH_SRC","mac":"00:00:00:00:00:01"}]}} 27 | datas.append(data) 28 | data = { 29 | "priority": 10, 30 | "timeout": 0, 31 | "isPermanent": True, 32 | "deviceId": "of:0000000000000001", 33 | "treatment": 34 | {"instructions": [{"type":"OUTPUT","port":"1"}]}, 35 | "selector": 36 | {"criteria":[{"type":"IN_PORT","port":2}, 37 | {"type":"ETH_DST","mac":"00:00:00:00:00:01"}, 38 | {"type":"ETH_SRC","mac":"00:00:00:00:00:02"}]}} 39 | datas.append(data) 40 | data = { 41 | "priority": 10, 42 | "timeout": 0, 43 | "isPermanent": True, 44 | "deviceId": "of:0000000000000002", 45 | "treatment": 46 | {"instructions":[{"type":"OUTPUT","port":"2"}]}, 47 | "selector": 48 | {"criteria":[{"type":"IN_PORT","port":1}, 49 | {"type":"ETH_DST","mac":"00:00:00:00:00:01"}, 50 | {"type":"ETH_SRC","mac":"00:00:00:00:00:02"}]}} 51 | datas.append(data) 52 | data = { 53 | "priority": 10, 54 | "timeout": 0, 55 | "isPermanent": True, 56 | "deviceId": "of:0000000000000002", 57 | "treatment": 58 | {"instructions":[{"type":"OUTPUT","port":"1"}]}, 59 | "selector": 60 | {"criteria":[{"type":"IN_PORT","port":3}, 61 | {"type":"ETH_DST","mac":"00:00:00:00:00:02"}, 62 | {"type":"ETH_SRC","mac":"00:00:00:00:00:01"}]}} 63 | datas.append(data) 64 | 65 | 66 | for data in datas: 67 | req = requests.Request(action, 'http://%s:%s%s%s' % (server, port, path, data["deviceId"]), 68 | data=json.dumps(data), auth=session.auth) 69 | resp = session.send(req.prepare()) 70 | resp.raise_for_status() 71 | 72 | -------------------------------------------------------------------------------- /iot_sdn.py: -------------------------------------------------------------------------------- 1 | """Custom topology example 2 | 3 | Two directly connected switches plus a host for each switch: 4 | 5 | host --- switch --- switch --- host 6 | 7 | Adding the 'topos' dict with a key/value pair to generate our newly defined 8 | topology enables one to pass in '--topo=mytopo' from the command line. 9 | """ 10 | 11 | from mininet.topo import Topo 12 | 13 | class MyTopo( Topo ): 14 | "Simple topology example." 15 | 16 | def __init__( self ): 17 | "Create custom topo." 18 | 19 | # Initialize topology 20 | Topo.__init__( self ) 21 | 22 | # Add hosts and switches 23 | edgeServer = self.addHost( 'h1' ) 24 | internet = self.addHost( 'h2' ) 25 | Host1 = self.addHost( 'h3' ) 26 | Host2 = self.addHost( 'h4' ) 27 | Host3 = self.addHost( 'h5' ) 28 | Host4 = self.addHost( 'h6' ) 29 | Host5 = self.addHost( 'h7' ) 30 | Host6 = self.addHost( 'h8' ) 31 | Host7 = self.addHost( 'h9' ) 32 | Host8 = self.addHost( 'h10' ) 33 | Host9 = self.addHost( 'h11' ) 34 | Host10 = self.addHost( 'h12' ) 35 | Host11 = self.addHost( 'h13' ) 36 | Host12 = self.addHost( 'h14' ) 37 | coreSwitch = self.addSwitch( 's1' ) 38 | disSwitch1 = self.addSwitch( 's2' ) 39 | disSwitch2 = self.addSwitch( 's3' ) 40 | accSwitch1 = self.addSwitch( 's4' ) 41 | accSwitch2 = self.addSwitch( 's5' ) 42 | accSwitch3 = self.addSwitch( 's6' ) 43 | accSwitch4 = self.addSwitch( 's7' ) 44 | 45 | # Add links 46 | self.addLink( edgeServer, coreSwitch) 47 | self.addLink( internet, coreSwitch) 48 | self.addLink( coreSwitch, disSwitch1 ) 49 | self.addLink( coreSwitch, disSwitch2 ) 50 | self.addLink( disSwitch1, disSwitch2 ) 51 | self.addLink( disSwitch1, accSwitch1 ) 52 | self.addLink( disSwitch1, accSwitch2 ) 53 | self.addLink( disSwitch2, accSwitch3 ) 54 | self.addLink( disSwitch2, accSwitch4 ) 55 | self.addLink( accSwitch1, Host1 ) 56 | self.addLink( accSwitch1, Host2 ) 57 | self.addLink( accSwitch1, Host3 ) 58 | self.addLink( accSwitch2, Host4 ) 59 | self.addLink( accSwitch2, Host5 ) 60 | self.addLink( accSwitch2, Host6 ) 61 | self.addLink( accSwitch3, Host7 ) 62 | self.addLink( accSwitch3, Host8 ) 63 | self.addLink( accSwitch3, Host9 ) 64 | self.addLink( accSwitch4, Host10 ) 65 | self.addLink( accSwitch4, Host11 ) 66 | self.addLink( accSwitch4, Host12 ) 67 | 68 | 69 | topos = { 'mytopo': ( lambda: MyTopo() ) } 70 | -------------------------------------------------------------------------------- /testminiTopo.py: -------------------------------------------------------------------------------- 1 | from mininet.net import Mininet 2 | from mininet.node import RemoteController, Host, OVSKernelSwitch 3 | from mininet.node import Switch, Link, Node 4 | from mininet.cli import CLI 5 | from mininet.link import TCLink, Intf 6 | from mininet.log import setLogLevel 7 | import logging as log 8 | 9 | CONTROLLER_IP = '192.168.56.101' 10 | CONTROLLER_PORT = 6653 11 | IP_BASE = '10.0.5.0/24' 12 | 13 | def setup_topology(): 14 | """ 15 | Builds the Mininet network, including all hosts, servers, switches, links. 16 | """ 17 | net = Mininet(topo=None, 18 | build=False, 19 | ipBase=IP_BASE, 20 | autoSetMacs=True, 21 | ) 22 | 23 | log.info('Adding controller') 24 | c0 = net.addController(name='c0', 25 | controller=RemoteController, 26 | ip=CONTROLLER_IP, 27 | port=CONTROLLER_PORT, 28 | ) 29 | 30 | #Adding a dummy switch for networking 31 | log.info("Adding standalone switch") 32 | s1 = net.addSwitch('s1', cls=OVSKernelSwitch) #, failMode='standalone') 33 | 34 | # Connecting to VM interface 35 | Intf('eth2', node=s1) 36 | 37 | log.info("Adding switch") 38 | s2 = net.addSwitch('s2', cls=OVSKernelSwitch) 39 | 40 | log.info("Adding hosts") 41 | h1 = net.addHost('h1', ip='10.0.5.1', mac='00:00:00:00:00:01') 42 | h2 = net.addHost('h2', ip='10.0.5.2', mac='00:00:00:00:00:2') 43 | 44 | log.info("Adding links") 45 | l1 = net.addLink(h1, s2, 46 | cls=TCLink, bw=10 47 | # , delay=_delay, jitter=_jitter, loss=_loss 48 | ) 49 | l2 = net.addLink(s2, h2, 50 | cls=TCLink, bw=10 51 | # , delay=_delay, jitter=_jitter, loss=_loss 52 | ) 53 | # Add link between the host and standalone switch 54 | l3 = net.addLink(h1, s1) 55 | # l4 = net.addLink(s1, s2) 56 | 57 | # Build the network. 58 | log.info('Building network') 59 | net.build() 60 | 61 | # Start the network. 62 | log.info('Starting network') 63 | 64 | # Starting the controller 65 | log.info( 'Starting controllers') 66 | for controller in net.controllers: 67 | controller.start() 68 | 69 | # Start the switch without connecting it to controller 70 | net.get('s1').start([c0]) 71 | # Starting other switches with connecting to controller 72 | net.get('s2').start([c0]) 73 | 74 | # net.start() 75 | 76 | # Configure the MAC address and IP address of the host interface that connects to dummy switch 77 | h1.cmd('ifconfig h1-eth1 hw ether 00:00:00:00:01:11') 78 | h1.cmd('dhclient h1-eth1') 79 | 80 | # Drop the user in to a CLI so user can run commands. 81 | CLI( net ) 82 | 83 | # After the user exits the CLI, shutdown the network. 84 | log.info('Stopping network') 85 | net.stop() 86 | 87 | if __name__ == '__main__': 88 | # This runs if this file is executed directly 89 | setLogLevel( 'info' ) 90 | setup_topology() 91 | 92 | # Allows the file to be imported using `mn --custom --topo miniTopo` 93 | # topos = { 94 | # 'miniTopo': MiniTopo 95 | # } 96 | -------------------------------------------------------------------------------- /data_flows.py: -------------------------------------------------------------------------------- 1 | from mininet.net import Mininet 2 | from mininet.node import RemoteController, Host, OVSKernelSwitch, Controller 3 | from mininet.node import Switch, Link, Node, OVSController, DefaultController 4 | from mininet.cli import CLI 5 | from mininet.link import TCLink, Intf 6 | from mininet.log import setLogLevel 7 | import logging as log 8 | from OVSminiTopo import * 9 | from configs import * 10 | from time import sleep, time 11 | import dynamicflow as df 12 | import sys 13 | import os 14 | #client_iperfs=[] 15 | #server_iperfs=[] 16 | 17 | def _get_mininet_nodes(mininet,nodes): 18 | """ 19 | Choose the actual Mininet Hosts (rather than just strings) that will 20 | be subscribers. 21 | :param List[str] nodes: 22 | :return List[Node] mininet_nodes: 23 | """ 24 | return [mininet.get(n) for n in nodes] 25 | def progress(t): 26 | tmp=t 27 | while t > 0: 28 | print(' %3d seconds left \r' % (t)) 29 | t -= 1 30 | sys.stdout.flush() 31 | if t==tmp/2: 32 | df.post_dynamic_flows() 33 | sleep(1) 34 | 35 | print '\r\n' 36 | 37 | 38 | def setup_traffic_generators(mininet, EXPERIMENT_DURATION): 39 | """Each traffic generating host starts an iperf process aimed at 40 | (one of) the server(s) in order to generate random traffic and create 41 | congestion in the experiment. Traffic is all UDP because it sets the bandwidth. 42 | 43 | NOTE: iperf v2 added the capability to tell the server when to exit after some time. 44 | However, we explicitly terminate the server anyway to avoid incompatibility issues.""" 45 | 46 | internet_hosts=['h3','h6','h9','h12'] 47 | stream_hosts=['h4','h7','h10','h13'] 48 | 49 | internet_srv = mininet.getNodeByName('h2') 50 | edge_srv = mininet.getNodeByName('h1') 51 | 52 | switches=['s1','s2','s3','s4','s5','s6','s7'] 53 | ports=['eth0','eth1','eth2','eth3'] 54 | 55 | for s in switches: 56 | sw=mininet.getNodeByName(s) 57 | for p in ports: 58 | tmp=s+"-"+p 59 | fn="/home/onos/iotDynamicPri/Results/"+tmp+".pcap" 60 | sw.popen('tcpdump -i %s -s 65535 -w %s'% (tmp, fn), shell=True) 61 | 62 | generators = _get_mininet_nodes(mininet, internet_hosts) 63 | log.info("*** Starting background traffic generators for internet") 64 | # We enumerate the generators to fill the range of ports so that the server 65 | # can listen for each iperf client. 66 | for n, g in enumerate(generators): 67 | log.info("iperf from %s to %s" % (g, internet_srv)) 68 | # can't do self.net.iperf([g,s]) as there's no option to put it in the background 69 | i = internet_srv.popen('iperf3 -p %d -s > /home/onos/iotDynamicPri/Results/Internet/%s_%s.txt &' % (IPERF_INT_BASE_PORT + n, internet_srv,g), shell=True) 70 | #server_iperfs.append(i) 71 | i = g.popen('iperf3 -p %d -t %d -c %s -i %d -b %dM > /home/onos/iotDynamicPri/Results/Internet/%s.txt &' % (IPERF_INT_BASE_PORT + n, EXPERIMENT_DURATION, internet_srv.IP(), VER, INT_BAND, g), shell=True) 72 | #client_iperfs.append(i) 73 | 74 | 75 | generators = _get_mininet_nodes(mininet, stream_hosts) 76 | log.info("*** Starting background traffic generators for streaming") 77 | # We enumerate the generators to fill the range of ports so that the server 78 | # can listen for each iperf client. 79 | for n, g in enumerate(generators): 80 | log.info("iperf from %s to %s" % (g, edge_srv)) 81 | # can't do self.net.iperf([g,s]) as there's no option to put it in the background 82 | i = edge_srv.popen('iperf3 -p %d -s > /home/onos/iotDynamicPri/Results/Stream/%s_%s.txt &' % (IPERF_ST_BASE_PORT + n, edge_srv, g), shell=True) 83 | 84 | #server_iperfs.append(i) 85 | i = g.popen('iperf3 -p %d -t %d -u -b %dM -c %s -i %d > /home/onos/iotDynamicPri/Results/Stream/%s.txt &' % (IPERF_ST_BASE_PORT + n, EXPERIMENT_DURATION, ST_BAND, edge_srv.IP(), VER, g), shell=True) 86 | #client_iperfs.append(i) 87 | progress(EXPERIMENT_DURATION+5) 88 | os.system('pkill iperf3') 89 | os.system('pkill tcpdump') 90 | -------------------------------------------------------------------------------- /OVSminiTopo.py: -------------------------------------------------------------------------------- 1 | from mininet.net import Mininet 2 | from mininet.node import RemoteController, Host, OVSKernelSwitch, Controller 3 | from mininet.node import Switch, Link, Node, OVSController, DefaultController 4 | from mininet.cli import CLI 5 | from mininet.link import TCLink, Intf 6 | from mininet.log import setLogLevel 7 | import logging as log 8 | from configs import * 9 | import data_flows as df 10 | 11 | def setup_topology(): 12 | """ 13 | Builds the Mininet network, including all hosts, servers, switches, links. 14 | """ 15 | hosts = [] 16 | switches = [] 17 | links = [] 18 | 19 | 20 | log.info('Adding controller') 21 | c0 = net.addController(name='c0' 22 | #, controller=RemoteController, 23 | #ip=CONTROLLER_IP, 24 | #port=CONTROLLER_PORT, 25 | ) 26 | 27 | # Adding a Standalone switch 28 | #switches[0] = net.addSwitch('s21', cls=OVSKernelSwitch, failMode='standalone') 29 | 30 | # Connecting the standalone switch to the interface on the machine/VM 31 | #Intf('eth1', node=s21) 32 | 33 | for switch in range(1,8): 34 | sname = 's' + str(switch) 35 | log.info("Adding switch %s" % sname) 36 | s = net.addSwitch(sname)#, cls=OVSKernelSwitch) 37 | switches.append(s) 38 | 39 | # Connecting to VM interface 40 | # Intf('eth2', node=switches[0]) 41 | 42 | for host in range(1,15): 43 | hname = 'h' + str(host) 44 | log.info("Adding host %s" % hname) 45 | h = net.addHost(hname) #, ip=IP_PREFIX+str(host), mac=MAC_PREFIX+str(host)) 46 | hosts.append(h) 47 | 48 | manual_links = [['s1', 'h1', 100], ['s1', 'h2', 100], ['s1', 's2', 50 ], 49 | ['s1', 's3', 50 ], #['s2', 's3', 50 ], 50 | ['s2', 's4', 50 ], 51 | ['s2', 's5', 50 ], ['s3', 's6', 50 ], ['s3', 's7', 50 ], 52 | ['s4', 'h3', 10 ], ['s4', 'h4', 10 ], ['s4', 'h5', 10 ], 53 | ['s5', 'h6', 10 ], ['s5', 'h7', 10 ], ['s5', 'h8', 10 ], 54 | ['s6', 'h9', 10 ], ['s6', 'h10',10 ], ['s6', 'h11',10 ], 55 | ['s7', 'h12',10 ], ['s7', 'h13',10 ], ['s7', 'h14',10 ], 56 | ] 57 | for link in manual_links: 58 | from_link = link[0] 59 | to_link = link[1] 60 | log.debug("Adding link from %s to %s" % (from_link, to_link)) 61 | bw = link[2] 62 | ''' 63 | _bw = attributes.get('bw', 10) # in Mbps 64 | _delay = '%fms' % attributes.get('latency', 10) 65 | _jitter = '1ms' 66 | _loss = error_rate 67 | ''' 68 | l = net.addLink(link[0], link[1]) 69 | # l = net.addLink(net.get(from_link), net.get(to_link) 70 | #, cls=TCLink, bw=bw 71 | # , delay=_delay, jitter=_jitter, loss=_loss 72 | # ) 73 | links.append(l) 74 | 75 | # Link for internet 76 | # l = net.addLink('h1', 's1') 77 | # links.append(l) 78 | 79 | ''' 80 | #Simple minimal topolgy code 81 | #TODO: move to a different file 82 | sname = 's' + '1' 83 | log.info("Adding switch %s" % sname) 84 | s = net.addSwitch(sname, cls=OVSKernelSwitch) 85 | 86 | # for host in range(1,2): 87 | # hname = 'h' + str(host) 88 | # log.info("Adding host %s" % hname) 89 | h1 = net.addHost('h1') 90 | h = net.addHost('h2') 91 | 92 | l = net.addLink('s1', 'h1', 93 | cls=TCLink, bw=10 94 | # , delay=_delay, jitter=_jitter, loss=_loss 95 | ) 96 | l1 = net.addLink('s1', 'h2', 97 | cls=TCLink, bw=10 98 | # , delay=10ms, jitter=1ms, loss=error_rate 99 | ) 100 | ''' 101 | 102 | # Build the network 103 | log.info('Building network') 104 | net.build() 105 | 106 | # Start the network 107 | log.info('Starting network') 108 | net.start() 109 | 110 | # info('*** Configure h1\'s controller communication interface\n') 111 | # hosts[0].cmd('ifconfig h1-eth1 hw ether 00:00:00:00:01:11') 112 | 113 | # info('*** Configure h1\'s IP address\n') 114 | # hosts[0].cmd('dhclient h1-eth1') 115 | 116 | #net.pingAll() 117 | #Starting the internet and stream traffic 118 | df.setup_traffic_generators(net) 119 | #Popen("killall -9 top bwm-ng", shell=True).wait() 120 | # Drop the user in to a CLI so user can run commands. 121 | CLI( net ) 122 | 123 | # After the user exits the CLI, shutdown the network. 124 | log.info('Stopping network') 125 | net.stop() 126 | 127 | 128 | 129 | if __name__ == '__main__': 130 | # This runs if this file is executed directly 131 | net = Mininet(topo=None, 132 | build=False, 133 | ipBase='10.0.0.0/8', 134 | autoSetMacs=True, 135 | ) 136 | setLogLevel( 'info' ) 137 | setup_topology() 138 | 139 | #generators = _get_mininet_nodes(12) 140 | #print(generators) 141 | 142 | # Allows the file to be imported using `mn --custom --topo minimal` 143 | # topos = { 144 | # 'minimal': MinimalTopo 145 | # } 146 | -------------------------------------------------------------------------------- /miniTopo.py: -------------------------------------------------------------------------------- 1 | from mininet.net import Mininet 2 | from mininet.node import RemoteController, Host, OVSKernelSwitch 3 | from mininet.node import Switch, Link, Node 4 | from mininet.cli import CLI 5 | from mininet.link import TCLink, Intf 6 | from mininet.log import setLogLevel 7 | import logging as log 8 | from subprocess import Popen, PIPE 9 | import os 10 | import add_queues 11 | import data_flows as df 12 | from configs import * 13 | import staticflow as sf 14 | 15 | LEVEL_1_BW=100 16 | LEVEL_2_BW=100 17 | LEVEL_3_BW=150 18 | LEVEL_4_BW=300 19 | 20 | net = Mininet(topo=None, 21 | build=False, 22 | ipBase=IP_BASE, 23 | autoSetMacs=True, 24 | ) 25 | 26 | def setup_topology(): 27 | """ 28 | Builds the Mininet network, including all hosts, servers, switches, links. 29 | """ 30 | hosts = [] 31 | switches = [] 32 | links = [] 33 | 34 | 35 | log.info('Adding controller') 36 | c0 = net.addController(name='c0', 37 | controller=RemoteController, 38 | ip=CONTROLLER_IP, 39 | port=CONTROLLER_PORT, 40 | ) 41 | 42 | # Adding a Standalone switch 43 | #switches[0] = net.addSwitch('s21', cls=OVSKernelSwitch, failMode='standalone') 44 | 45 | # Connecting the standalone switch to the interface on the machine/VM 46 | #Intf('eth1', node=s21) 47 | 48 | for switch in range(1,8): 49 | sname = 's' + str(switch) 50 | log.info("Adding switch %s" % sname) 51 | s = net.addSwitch(sname, cls=OVSKernelSwitch) 52 | switches.append(s) 53 | 54 | # Connecting to VM interface 55 | Intf('eth2', node=switches[0]) 56 | 57 | for host in range(1,15): 58 | hname = 'h' + str(host) 59 | log.info("Adding host %s" % hname) 60 | h = net.addHost(hname, ip=IP_PREFIX+str(host), mac=MAC_PREFIX+str(host)) 61 | hosts.append(h) 62 | 63 | manual_links = [['s1', 'h1', LEVEL_4_BW], ['s1', 'h2', LEVEL_4_BW], ['s1', 's2', 3 ], 64 | ['s1', 's3', 3 ], #['s2', 's3', 0 ], 65 | ['s2', 's4', 2 ], 66 | ['s2', 's5', 2 ], ['s3', 's6', 2 ], ['s3', 's7', 2 ], 67 | ['s4', 'h3', LEVEL_1_BW ], ['s4', 'h4', LEVEL_1_BW ], ['s4', 'h5', LEVEL_1_BW ], 68 | ['s5', 'h6', LEVEL_1_BW ], ['s5', 'h7', LEVEL_1_BW ], ['s5', 'h8', LEVEL_1_BW ], 69 | ['s6', 'h9', LEVEL_1_BW ], ['s6', 'h10',LEVEL_1_BW ], ['s6', 'h11',LEVEL_1_BW ], 70 | ['s7', 'h12',LEVEL_1_BW ], ['s7', 'h13',LEVEL_1_BW ], ['s7', 'h14',LEVEL_1_BW ]] 71 | for link in manual_links: 72 | from_link = link[0] 73 | to_link = link[1] 74 | log.debug("Adding link from %s to %s" % (from_link, to_link)) 75 | bw = link[2] 76 | ''' 77 | _bw = attributes.get('bw', 10) # in Mbps 78 | _delay = '%fms' % attributes.get('latency', 10) 79 | _jitter = '1ms' 80 | _loss = error_rate 81 | ''' 82 | if bw not in [2,3]: 83 | l = net.addLink(net.get(from_link), net.get(to_link), 84 | cls=TCLink, bw=bw 85 | # , delay=_delay, jitter=_jitter, loss=_loss 86 | ) 87 | links.append(l) 88 | else: 89 | l = net.addLink(link[0], link[1], intfName2=link[1]+'-eth5') 90 | links.append(l) 91 | 92 | 93 | # Link for internet 94 | l = net.addLink('h1', 's1', intfName1='h1-eth1') 95 | links.append(l) 96 | 97 | ''' 98 | #Simple minimal topolgy code 99 | #TODO: move to a different file 100 | sname = 's' + '1' 101 | log.info("Adding switch %s" % sname) 102 | s = net.addSwitch(sname, cls=OVSKernelSwitch) 103 | 104 | # for host in range(1,2): 105 | # hname = 'h' + str(host) 106 | # log.info("Adding host %s" % hname) 107 | h1 = net.addHost('h1') 108 | h = net.addHost('h2') 109 | 110 | l = net.addLink('s1', 'h1', 111 | cls=TCLink, bw=10 112 | # , delay=_delay, jitter=_jitter, loss=_loss 113 | ) 114 | l1 = net.addLink('s1', 'h2', 115 | cls=TCLink, bw=10 116 | # , delay=10ms, jitter=1ms, loss=error_rate 117 | ) 118 | ''' 119 | 120 | # Build the network 121 | log.info('Building network') 122 | net.build() 123 | 124 | # Start the network 125 | log.info('Starting network') 126 | net.start() 127 | 128 | # info('*** Configure h1\'s controller communication interface\n') 129 | hosts[0].cmd('ifconfig h1-eth1 hw ether 00:00:00:00:01:11') 130 | 131 | # info('*** Configure h1\'s IP address\n') 132 | #hosts[0].cmd('dhclient h1-eth1') 133 | 134 | # Adding links with Queues with Linux HTB 135 | add_queues.add_HTB_queues() 136 | 137 | net.pingAll() 138 | #Starting the internet and stream traffic 139 | df.setup_traffic_generators(net) 140 | 141 | while True: 142 | user_input = raw_input("Input your choice: \n 1. Static \n 2. Dynamic \n 3. CLI \n") 143 | if user_input=='static' or user_input=='Static' or user_input=='1': 144 | sf.post_static_flows() 145 | df.setup_traffic_generators(net, 30) 146 | elif user_input=='dynamic' or user_input=='Dynamic' or user_input=='2': 147 | sf.post_static_flows() 148 | df.setup_traffic_generators(net, 60) 149 | elif user_input=='cli' or user_input=='CLI' or user_input=='3': 150 | # Drop the user in to a CLI so user can run commands. 151 | CLI( net ) 152 | else: 153 | continue 154 | 155 | # After the user exits the CLI, shutdown the network. 156 | log.info('Stopping network') 157 | net.stop() 158 | 159 | 160 | 161 | if __name__ == '__main__': 162 | # This runs if this file is executed directly 163 | setLogLevel( 'info' ) 164 | setup_topology() 165 | 166 | #generators = _get_mininet_nodes(12) 167 | #print(generators) 168 | 169 | # Allows the file to be imported using `mn --custom --topo minimal` 170 | # topos = { 171 | # 'minimal': MinimalTopo 172 | # } 173 | --------------------------------------------------------------------------------