diff --git a/loader/UC2/Topology/UC2_IITSystem.py b/loader/UC2/Topology/UC2_IITSystem.py new file mode 100644 index 0000000..23e24bd --- /dev/null +++ b/loader/UC2/Topology/UC2_IITSystem.py @@ -0,0 +1,238 @@ +#!/usr/bin/python + +""" + Copyright (c) 2014, NetIDE Consortium (Create-Net (CN), Telefonica Investigacion Y Desarrollo SA (TID), Fujitsu + Technology Solutions GmbH (FTS), Thales Communications & Security SAS (THALES), Fundacion Imdea Networks (IMDEA), + Universitaet Paderborn (UPB), Intel Research & Innovation Ireland Ltd (IRIIL) ) + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + + Authors: + Elisa Rojas +""" + + +############################################################################################### +### Name: UC2_IITSystem.py +### Author: Elisa Rojas - elisa.rojas@telcaria.com +### Description: NetIDE UC2 Topology +############################################################################################### + +from os import popen +import logging +import sys + +# Mininet libraries +from mininet.cli import CLI +from mininet.net import Mininet +from mininet.topo import Topo +from mininet.util import errRun +from mininet.node import Controller, OVSKernelSwitch, RemoteController +from mininet.log import setLogLevel + +# Configuration Files +IPCONFIG = './IPCONFIG.dat' + +class IITSTopology (Topo): + + ### Topology class members + Devices = dict() + + ### Topology constructor + def __init__ (self, of_version): + ## Initialize Topology + super(IITSTopology, self).__init__() + + logger = logging.getLogger('NetIDE Logger') + + #OpenFlow version + if of_version == 'of13': + sconfig = {'protocols': 'OpenFlow13'} + else: + sconfig = {'protocols': 'OpenFlow10'} + # Switches + SW1 = self.addSwitch('s1', **sconfig) + SW2 = self.addSwitch('s2', **sconfig) + SW3 = self.addSwitch('s3', **sconfig) + SW4 = self.addSwitch('s4', **sconfig) + SW1b = self.addSwitch('s5', **sconfig) + SW2b = self.addSwitch('s6', **sconfig) + SW3b = self.addSwitch('s7', **sconfig) + SW4b = self.addSwitch('s8', **sconfig) + + # Hosts + H1 = self.addHost('h1') + H2 = self.addHost('h2') + H3 = self.addHost('h3') + H4 = self.addHost('h4') + H5 = self.addHost('h5') + + # Hypervisors + HH1 = self.addSwitch('s11', **sconfig) + HH2 = self.addSwitch('s12', **sconfig) + HH3 = self.addSwitch('s13', **sconfig) + HH4 = self.addSwitch('s14', **sconfig) + HH5 = self.addSwitch('s15', **sconfig) + + # Add links + #from hosts (H1,H2,H3,H4) to hosts-hypervisors (HH1,HH2,HH3,HH4) + #from down hosts-hypervisors (HH1,HH2,HH3,HH4) to SW1 and SW2 + self.addLink(H1, HH1) + self.addLink(H3, HH3) + self.addLink(H2, HH2) + self.addLink(H4, HH4) + self.addLink(H5, HH5) + #from hosts-hypervisors (HH1,HH2,HH3,HH4) to SW1, SW2 and SW4 + self.addLink(HH1, SW1) + self.addLink(HH1, SW1b) + self.addLink(HH3, SW1) + self.addLink(HH3, SW1b) + self.addLink(HH2, SW2) + self.addLink(HH2, SW2b) + self.addLink(HH4, SW2) + self.addLink(HH4, SW2b) + self.addLink(HH5, SW4) + self.addLink(HH5, SW4b) + + #from SW3 to SW1 and SW2 + self.addLink(SW3, SW1) + self.addLink(SW3, SW1b) + self.addLink(SW3, SW2) + self.addLink(SW3, SW2b) + self.addLink(SW3b, SW1) + self.addLink(SW3b, SW1b) + self.addLink(SW3b, SW2) + self.addLink(SW3b, SW2b) + #from SW3 to SW4 + self.addLink(SW3, SW4) + self.addLink(SW3, SW4b) + self.addLink(SW3b, SW4) + self.addLink(SW3b, SW4b) + #between peers + self.addLink(SW1, SW2) + self.addLink(SW1b, SW2b) + self.addLink(SW3, SW3b) + + logger.info('NetIDE - UC2 Topology created') + + ### Mutator for Devices + def SetDevices(self, Devices): + self.Devices = Devices + + ### Assign IPs, Masks and Routes to devices + def SetIPConfiguration(self, Devices, net): + + ## Internal configuration for Mininet (so that pingall and other Mininet's commands work ok and use correct IPs and so) + net.get("h1").setIP("10.0.1.11") + #net.get("h1").setIP("10.0.1.11", "24", "h1-eth0") + #net.get("h1").setIP("10.1.1.11", "24", "h1-eth1") + net.get("h2").setIP("10.0.1.12") + #net.get("h2").setIP("10.0.1.12", "24", "h2-eth0") + #net.get("h2").setIP("10.1.1.12", "24", "h2-eth1") + net.get("h3").setIP("10.0.1.13", "24") + #net.get("h3").setIP("10.0.1.13", "24", "h3-eth0") + #net.get("h3").setIP("10.1.1.13", "24", "h3-eth1") + net.get("h4").setIP("10.0.1.14", "24") + #net.get("h4").setIP("10.0.1.14", "24", "h4-eth0") + #net.get("h4").setIP("10.1.1.14", "24", "h4-eth1") + net.get("h5").setIP("10.0.1.15", "24") + #net.get("h5").setIP("10.0.1.15", "24", "h5-eth0") + #net.get("h5").setIP("10.1.1.15", "24", "h5-eth1") + + ## Hosts configuration (ipconfig/ifconfig) + try: + with open(IPCONFIG, 'r') as f: + for command in f: + if( len(command.split()) == 0): + break + + token = command.split('#') + for host in Devices: + if token[0] == host.name: + for tok in token[1:len(token)]: + tok.replace("\n", "") + host.popen(tok) #popen() opens a process by creating a pipe, forking, and invoking the shell + break + + logger.info('Successfully enforced initial ip settings to the UC topology') + f.close() + + except EnvironmentError: + logger.error("Couldn't load config file for ip addresses, check whether %s exists" % IPCONFIG) + +### Create a logger and configure it +def ConfigureLogger(): + # Create a log instance + logger = logging.getLogger('NetIDE Logger') + + # Set logging level + logger.setLevel(logging.INFO) + + handler = logging.StreamHandler() + handler.setLevel(logging.INFO) + + # Create a logging format + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + handler.setFormatter(formatter) + + # Add the handlers to the logger + logger.addHandler(handler) + + return logger + +### Network Emulator method +def UC2_IITS_Network(of_version): + + logger.info('=================== Mininet Topology SetUp ===================') + + # Create UC Topology instance + IITSTopo = IITSTopology(of_version) + + # Start mininet and load the topology + net = Mininet( topo=IITSTopo, controller=RemoteController, autoSetMacs = True ) + net.start() + setLogLevel( 'info' ) #setLogLevel( 'info' | 'debug' | 'output' ) + + # Get the devices + Devices = dict() + Devices = net.get('h1', 'h2', 'h3', 'h4', 'h5', 's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8') + IITSTopo.SetDevices(Devices) + logger.info('==============================================================\n') + + # Enforce IP configuration + logger.info('====================== IP Configuration ======================') + IITSTopo.SetIPConfiguration(Devices, net) + logger.info('==============================================================\n') + + # Start mininet CLI + CLI( net ) + + # Destroy network after exiting the CLI + net.stop() + + +######################################################################################################### +### Main +######################################################################################################### +if __name__ == '__main__': + if (len(sys.argv) > 1): + of_version = sys.argv[1] + else: + of_version = 'of10' + # Setup the logger + logger = ConfigureLogger() + + # Start network + UC2_IITS_Network(of_version) +######################################################################################################### + + +######################################################################################################### +### Load this module from mininet externally +######################################################################################################### +logger = ConfigureLogger() +topos = { 'IITS': ( lambda: UC2_IITS_Network() ) } +######################################################################################################### diff --git a/loader/UC2/Usecase_2.topology b/loader/UC2/Usecase_2.topology new file mode 100644 index 0000000..c003b57 --- /dev/null +++ b/loader/UC2/Usecase_2.topology @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/loader/UC2/Usecase_2.wb b/loader/UC2/Usecase_2.wb new file mode 100644 index 0000000..f2264f5 --- /dev/null +++ b/loader/UC2/Usecase_2.wb @@ -0,0 +1,218 @@ + + + + + 218a215f-df2d-456e-8183-51501b95374b + + + platform:/resource/Usecase_2/composition/composition.xml + + + + + dc61c61b-3ccb-48be-84bf-153f246c669c + + + platform:/resource/Usecase_2/Usecase_2.topology + + + + + + + e1dedeb9-3085-439f-9916-eab84482c6ff + + + IITS_NetManager_13.py + + + platform:/resource/Usecase_2/apps/iits_netmanager_13/src/IITS_NetManager_13.py + + + 7733 + + + Ryu + + + + + + --observe-links + + + 13NetManager + + + Network Engine + + + + + + + e56b0417-ec74-4452-b12b-8a2e339ddaaf + + + IITS_NetManager.py + + + platform:/resource/Usecase_2/apps/iits_netmanager/src/IITS_NetManager.py + + + 7733 + + + Ryu + + + + + + --observe-links + + + NetManager + + + Network Engine + + + + + + + + + + + + + + + + + + + + + + + + + + + 192.168.56.101 + + + + + + + + + + + + 22 + + + SSH_Localhost + + + + + + + + + + + + "~/.ssh/id_rsa" + + + + + + + + + vagrant + + + + + + + + + + + + + + + + + + + + + + + + + 192.168.56.101 + + + + + + + + + + + + 22 + + + NewSSH + + + + + + + + + + + + "~/.ssh/id_rsa" + + + + + + + + + vagrant + + + + + + + cf1d41a4-2578-4613-9d59-09cf730a0451 + + + 6644 + + + Ryu + + + diff --git a/loader/UC2/apps/iits_netmanager/iits_netmanager.params b/loader/UC2/apps/iits_netmanager/iits_netmanager.params new file mode 100644 index 0000000..17ade9a --- /dev/null +++ b/loader/UC2/apps/iits_netmanager/iits_netmanager.params @@ -0,0 +1,3 @@ +{ + "parameters": {} +} \ No newline at end of file diff --git a/loader/UC2/apps/iits_netmanager/iits_netmanager.sysreq b/loader/UC2/apps/iits_netmanager/iits_netmanager.sysreq new file mode 100644 index 0000000..0b6b1f3 --- /dev/null +++ b/loader/UC2/apps/iits_netmanager/iits_netmanager.sysreq @@ -0,0 +1,26 @@ +app: { + name: "Ryu IITS Netmanager", + version: "0.1", + controller: + { + name: "Ryu", + version: "3.30", + entrypoint: "src/IITS_NetManager.py", + port: 7733, + }, + hardwareReq: { + CPU: '1', + RAM: '1000', + OS: 'ANY' + }, + networkReq: { + protocolType: 'OpenFlow', + switchType: 'OpenFlow' + }, + softwareReq: { + software: { + name: 'python', + version: '3' + } + } +} diff --git a/loader/UC2/apps/iits_netmanager/src/IITS_NetManager.py b/loader/UC2/apps/iits_netmanager/src/IITS_NetManager.py new file mode 100644 index 0000000..ee18c3d --- /dev/null +++ b/loader/UC2/apps/iits_netmanager/src/IITS_NetManager.py @@ -0,0 +1,546 @@ +# Developed by Juan Manuel Sanchez, March 2016. + +""" +An OpenFlow 1.0 L2 static switching implementation. +""" + + +from ryu.base import app_manager +from ryu.controller import ofp_event +from ryu.controller.handler import MAIN_DISPATCHER +from ryu.controller.handler import set_ev_cls +from ryu.ofproto import ofproto_v1_0 +from ryu.ofproto import inet +from ryu.lib.mac import haddr_to_bin +from ryu.lib.packet import packet +from ryu.lib.packet import ethernet +from ryu.lib.packet import ether_types +from ryu.lib.packet import ipv4 +from ryu.lib.packet import arp +from ryu.topology import event, switches +from ryu.topology.api import get_switch, get_link +from ipaddr import IPv4Address + +from Configuration import * + +#Dictionaries of Host IPs/Switches IDs : columns/rows of the out_port_table +HOST = {ipp1:0, ipp2:1, ipp3:2, ipp4:3, ipp5:4} +SWITCH = {SW1_ID:0, SW2_ID:1, SW3_ID:2, SW4_ID:3, HH1_ID:4, HH2_ID:5, HH3_ID:6, HH4_ID:7, HH5_ID:8, SW1b_ID:9, SW2b_ID:10, SW3b_ID:11, SW4b_ID:12} + +class IITS_NetManager(app_manager.RyuApp): + OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] + + out_port_table = [[]] + + def __init__(self, *args, **kwargs): + super(IITS_NetManager, self).__init__(*args, **kwargs) + self.out_port_table_create(SWITCH, HOST) + self.mac_to_port = {} + self.link_down_route = {} + self.topology_api_app = self + self.datapath_list = {} + self.main_branch={} + self.main_branch_state={} + #Initiate Switch state to down(false) for every switch + self.switch_state = {} + for switch in SWITCH: + self.switch_state.setdefault(switch) + self.switch_state[switch] = False + + def all_switches_up(self): + for switch in self.switch_state: + if self.switch_state[switch] == False: + return False + return True + + def out_port_table_create(self, switches, hosts): + #Create table initialized to 1s, the prot that connects HHs to hosts + self.out_port_table = [[1 for i in range(len(hosts))] for j in range(len(switches))] + + def install_all_flows(self): + #In case of proactive behaviour + for switch in SWITCH: + datapath = self.datapath_list[switch] + for host in HOST: + out_port = self.out_port_table[SWITCH[switch]][HOST[host]] + actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] + self.add_flow(datapath, host, actions) + + def update_system_info(self, links_list): + #Update out_port_table alternative routes & main branch links + for link in links_list: + #link_down_route + self.link_down_route.setdefault(link.src.dpid) + #switch_state + self.switch_state.setdefault(link.src.dpid) + self.switch_state[link.src.dpid] = True + #Main branch links + self.main_branch.setdefault(link.src.dpid, {}) + self.main_branch_state.setdefault(link.src.dpid, {}) + #out_port_table + if link.src.dpid == SW1_ID: + if link.dst.dpid == SW2_ID: + self.out_port_table[SWITCH[SW1_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[SW1_ID]][HOST[ipp4]] = link.src.port_no + self.main_branch[SW1_ID][link.src.port_no] = SW2_ID + self.main_branch_state[SW1_ID][link.src.port_no] = True + if link.dst.dpid == SW3_ID: + self.out_port_table[SWITCH[SW1_ID]][HOST[ipp5]] = link.src.port_no + self.main_branch[SW1_ID][link.src.port_no] = SW3_ID + self.main_branch_state[SW1_ID][link.src.port_no] = True + if link.dst.dpid == HH1_ID: + self.out_port_table[SWITCH[SW1_ID]][HOST[ipp1]] = link.src.port_no + if link.dst.dpid == HH3_ID: + self.out_port_table[SWITCH[SW1_ID]][HOST[ipp3]] = link.src.port_no + if link.dst.dpid == SW3b_ID: + self.link_down_route[SW1_ID] = link.src.port_no + if link.src.dpid == SW2_ID: + if link.dst.dpid == SW1_ID: + self.out_port_table[SWITCH[SW2_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[SW2_ID]][HOST[ipp3]] = link.src.port_no + self.main_branch[SW2_ID][link.src.port_no] = SW1_ID + self.main_branch_state[SW2_ID][link.src.port_no] = True + if link.dst.dpid == SW3_ID: + self.out_port_table[SWITCH[SW2_ID]][HOST[ipp5]] = link.src.port_no + self.main_branch[SW2_ID][link.src.port_no] = SW3_ID + self.main_branch_state[SW2_ID][link.src.port_no] = True + if link.dst.dpid == HH2_ID: + self.out_port_table[SWITCH[SW2_ID]][HOST[ipp2]] = link.src.port_no + if link.dst.dpid == HH4_ID: + self.out_port_table[SWITCH[SW2_ID]][HOST[ipp4]] = link.src.port_no + if link.dst.dpid == SW3b_ID: + self.link_down_route[SW2_ID] = link.src.port_no + if link.src.dpid == SW3_ID: + if link.dst.dpid == SW1_ID: + self.out_port_table[SWITCH[SW3_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[SW3_ID]][HOST[ipp3]] = link.src.port_no + self.main_branch[SW3_ID][link.src.port_no] = SW1_ID + self.main_branch_state[SW3_ID][link.src.port_no] = True + if link.dst.dpid == SW2_ID: + self.out_port_table[SWITCH[SW3_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[SW3_ID]][HOST[ipp4]] = link.src.port_no + self.main_branch[SW3_ID][link.src.port_no] = SW2_ID + self.main_branch_state[SW3_ID][link.src.port_no] = True + if link.dst.dpid == SW4_ID: + self.out_port_table[SWITCH[SW3_ID]][HOST[ipp5]] = link.src.port_no + self.main_branch[SW3_ID][link.src.port_no] = SW4_ID + self.main_branch_state[SW3_ID][link.src.port_no] = True + if link.dst.dpid == SW4b_ID: + self.link_down_route[SW3_ID] = link.src.port_no + if link.src.dpid == SW4_ID: + if link.dst.dpid == SW3_ID: + self.out_port_table[SWITCH[SW4_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[SW4_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[SW4_ID]][HOST[ipp3]] = link.src.port_no + self.out_port_table[SWITCH[SW4_ID]][HOST[ipp4]] = link.src.port_no + self.main_branch[SW4_ID][link.src.port_no] = SW3_ID + self.main_branch_state[SW4_ID][link.src.port_no] = True + if link.dst.dpid == HH5_ID: + self.out_port_table[SWITCH[SW4_ID]][HOST[ipp5]] = link.src.port_no + if link.dst.dpid == SW3b_ID: + self.link_down_route[SW4_ID] = link.src.port_no + if link.src.dpid == HH1_ID: + if link.dst.dpid == SW1_ID: + self.out_port_table[SWITCH[HH1_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[HH1_ID]][HOST[ipp3]] = link.src.port_no + self.out_port_table[SWITCH[HH1_ID]][HOST[ipp4]] = link.src.port_no + self.out_port_table[SWITCH[HH1_ID]][HOST[ipp5]] = link.src.port_no + if link.dst.dpid == SW1b_ID: + self.link_down_route[HH1_ID] = link.src.port_no + #else: + #self.out_port_table[SWITCH[HH1_ID]][HOST[ipp1]] = link.src.port_no + if link.src.dpid == HH2_ID: + if link.dst.dpid == SW2_ID: + self.out_port_table[SWITCH[HH2_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[HH2_ID]][HOST[ipp3]] = link.src.port_no + self.out_port_table[SWITCH[HH2_ID]][HOST[ipp4]] = link.src.port_no + self.out_port_table[SWITCH[HH2_ID]][HOST[ipp5]] = link.src.port_no + if link.dst.dpid == SW2b_ID: + self.link_down_route[HH2_ID] = link.src.port_no + #else: + #self.out_port_table[SWITCH[HH2_ID]][HOST[ipp2]] = link.src.port_no + if link.src.dpid == HH3_ID: + if link.dst.dpid == SW1_ID: + self.out_port_table[SWITCH[HH3_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[HH3_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[HH3_ID]][HOST[ipp4]] = link.src.port_no + self.out_port_table[SWITCH[HH3_ID]][HOST[ipp5]] = link.src.port_no + if link.dst.dpid == SW1b_ID: + self.link_down_route[HH3_ID] = link.src.port_no + #else: + #self.out_port_table[SWITCH[HH3_ID]][HOST[ipp3]] = link.src.port_no + if link.src.dpid == HH4_ID: + if link.dst.dpid == SW2_ID: + self.out_port_table[SWITCH[HH4_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[HH4_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[HH4_ID]][HOST[ipp3]] = link.src.port_no + self.out_port_table[SWITCH[HH4_ID]][HOST[ipp5]] = link.src.port_no + if link.dst.dpid == SW2b_ID: + self.link_down_route[HH4_ID] = link.src.port_no + #else: + #self.out_port_table[SWITCH[HH4_ID]][HOST[ipp4]] = link.src.port_no + if link.src.dpid == HH5_ID: + if link.dst.dpid == SW4_ID: + self.out_port_table[SWITCH[HH5_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[HH5_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[HH5_ID]][HOST[ipp3]] = link.src.port_no + self.out_port_table[SWITCH[HH5_ID]][HOST[ipp4]] = link.src.port_no + if link.dst.dpid == SW4b_ID: + self.link_down_route[HH5_ID] = link.src.port_no + #else: + #self.out_port_table[SWITCH[HH5_ID]][HOST[ipp5]] = link.src.port_no + if link.src.dpid == SW1b_ID: + if link.dst.dpid == SW2b_ID: + self.out_port_table[SWITCH[SW1b_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[SW1b_ID]][HOST[ipp4]] = link.src.port_no + if link.dst.dpid == SW3_ID: + self.out_port_table[SWITCH[SW1b_ID]][HOST[ipp5]] = link.src.port_no + if link.dst.dpid == HH1_ID: + self.out_port_table[SWITCH[SW1b_ID]][HOST[ipp1]] = link.src.port_no + if link.dst.dpid == HH3_ID: + self.out_port_table[SWITCH[SW1b_ID]][HOST[ipp3]] = link.src.port_no + if link.src.dpid == SW2b_ID: + if link.dst.dpid == SW1b_ID: + self.out_port_table[SWITCH[SW2b_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[SW2b_ID]][HOST[ipp3]] = link.src.port_no + if link.dst.dpid == SW3_ID: + self.out_port_table[SWITCH[SW2b_ID]][HOST[ipp5]] = link.src.port_no + if link.dst.dpid == HH2_ID: + self.out_port_table[SWITCH[SW2b_ID]][HOST[ipp2]] = link.src.port_no + if link.dst.dpid == HH4_ID: + self.out_port_table[SWITCH[SW2b_ID]][HOST[ipp4]] = link.src.port_no + if link.src.dpid == SW3b_ID: + if link.dst.dpid == SW1_ID: + self.out_port_table[SWITCH[SW3b_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[SW3b_ID]][HOST[ipp3]] = link.src.port_no + if link.dst.dpid == SW2_ID: + self.out_port_table[SWITCH[SW3b_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[SW3b_ID]][HOST[ipp4]] = link.src.port_no + if link.dst.dpid == SW4_ID: + self.out_port_table[SWITCH[SW3b_ID]][HOST[ipp5]] = link.src.port_no + if link.src.dpid == SW4b_ID: + if link.dst.dpid == SW3_ID: + self.out_port_table[SWITCH[SW4b_ID]][HOST[ipp1]] = link.src.port_no + self.out_port_table[SWITCH[SW4b_ID]][HOST[ipp2]] = link.src.port_no + self.out_port_table[SWITCH[SW4b_ID]][HOST[ipp3]] = link.src.port_no + self.out_port_table[SWITCH[SW4b_ID]][HOST[ipp4]] = link.src.port_no + if link.dst.dpid == HH5_ID: + self.out_port_table[SWITCH[SW4b_ID]][HOST[ipp5]] = link.src.port_no + + def get_topology_data(self): + switch_list = get_switch(self.topology_api_app, None) + #switches=[switch.dp.id for switch in switch_list] + for switch in switch_list: + self.datapath_list.setdefault(switch.dp.id) + self.datapath_list[switch.dp.id] = switch.dp + links_list = get_link(self.topology_api_app, None) + #Add ports to out_port_table + self.update_system_info(links_list) + + #print self.out_port_table + #print self.link_down_route + + #Install flows in case of proactive behaviour + if PROACTIVE and self.all_switches_up(): + self.install_all_flows() + + def arp_unicast(self, msg): + datapath = msg.datapath + ofproto = datapath.ofproto + + pkt = packet.Packet(msg.data) + eth = pkt.get_protocols(ethernet.ethernet)[0] + src = eth.src + dst = eth.dst + dpid = datapath.id + in_port = msg.in_port + + self.mac_to_port.setdefault(dpid, {}) + # forward ARP + if src not in self.mac_to_port[dpid]: + self.mac_to_port[dpid][src] = in_port + try: + out_port = self.mac_to_port[dpid][dst] + except: + self.arp_multicast(msg) + return + actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] + data = None + if msg.buffer_id == ofproto.OFP_NO_BUFFER: + data = msg.data + + out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, + in_port=in_port, actions=actions, data=data) + datapath.send_msg(out) + + def arp_multicast(self, msg): + datapath = msg.datapath + ofproto = datapath.ofproto + + pkt = packet.Packet(msg.data) + eth = pkt.get_protocols(ethernet.ethernet)[0] + src = eth.src + dst = eth.dst + dpid = datapath.id + in_port = msg.in_port + + self.mac_to_port.setdefault(dpid, {}) + #Check whether the mac is known or not and if it comes from a different port than before and discard + if src in self.mac_to_port[dpid] and in_port != self.mac_to_port[dpid][src]: + #self.logger.info("Switch %s : known host %s", dpid, src) + return + + # learn a mac address to avoid loops. + self.mac_to_port[dpid][src] = in_port + #self.logger.info("Switch %s : mac learned %s port %s", dpid, src, in_port) + + + # and flood ARP + out_port = ofproto.OFPP_FLOOD + actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] + data = None + if msg.buffer_id == ofproto.OFP_NO_BUFFER: + data = msg.data + + out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, + in_port=in_port, actions=actions, data=data) + datapath.send_msg(out) + + def forward_arp(self, msg): + #Send arp packets according to the tree + pkt = packet.Packet(msg.data) + eth = pkt.get_protocols(ethernet.ethernet)[0] + dst = eth.dst + datapath = msg.datapath + dpid = datapath.id + in_port = msg.in_port + + self.logger.info("ARP in %s %s", dpid, in_port) + + pkt_arp = pkt.get_protocol(arp.arp) + src = pkt_arp.src_ip + if (dpid==HH1_ID) and (src == ipp1): + self.out_port_table[SWITCH[HH1_ID]][HOST[ipp1]] = in_port + if PROACTIVE and self.all_switches_up(): + self.add_priority_flow(self.datapath_list[HH1_ID], ipp1, in_port) + if (dpid==HH2_ID) and (src == ipp2): + self.out_port_table[SWITCH[HH2_ID]][HOST[ipp2]] = in_port + if PROACTIVE and self.all_switches_up(): + self.add_priority_flow(self.datapath_list[HH2_ID], ipp2, in_port) + if (dpid==HH3_ID) and (src == ipp3): + self.out_port_table[SWITCH[HH3_ID]][HOST[ipp3]] = in_port + if PROACTIVE and self.all_switches_up(): + self.add_priority_flow(self.datapath_list[HH3_ID], ipp3, in_port) + if (dpid==HH4_ID) and (src == ipp4): + self.out_port_table[SWITCH[HH4_ID]][HOST[ipp4]] = in_port + if PROACTIVE and self.all_switches_up(): + self.add_priority_flow(self.datapath_list[HH4_ID], ipp4, in_port) + if (dpid==HH5_ID) and (src == ipp5): + self.out_port_table[SWITCH[HH5_ID]][HOST[ipp5]] = in_port + if PROACTIVE and self.all_switches_up(): + self.add_priority_flow(self.datapath_list[HH5_ID], ipp5, in_port) + + if dst == 'ff:ff:ff:ff:ff:ff': + self.arp_multicast(msg) + else: + self.arp_unicast(msg) + + def forward_packet(self, msg): + datapath = msg.datapath + ofproto = datapath.ofproto + + pkt = packet.Packet(msg.data) + pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) + + dst = pkt_ipv4.dst + src = pkt_ipv4.src + + dpid = datapath.id + + self.logger.info("packet in %s %s %s %s", dpid, src, dst, msg.in_port) + # Get out_port for packet based on dst address and dpid + if dst in HOST: + out_port = self.out_port_table[SWITCH[dpid]][HOST[dst]] + else: + out_port = ofproto.OFPP_FLOOD + + actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] + + # install a flow to avoid packet_in next time + if out_port != ofproto.OFPP_FLOOD: + self.add_flow(datapath, dst, actions) + + data = None + if msg.buffer_id == ofproto.OFP_NO_BUFFER: + data = msg.data + + out = datapath.ofproto_parser.OFPPacketOut( + datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port, + actions=actions, data=data) + datapath.send_msg(out) + #print "ip packet forwarded" + + def add_flow(self, datapath, dst, actions): + ofproto = datapath.ofproto + + match = datapath.ofproto_parser.OFPMatch( + dl_type=ether_types.ETH_TYPE_IP, nw_dst=IPv4Address(dst)) + + mod = datapath.ofproto_parser.OFPFlowMod( + datapath=datapath, match=match, cookie=0, + command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, + priority=ofproto.OFP_DEFAULT_PRIORITY, + flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) + datapath.send_msg(mod) + + def add_priority_flow(self, datapath, dst, out_port): + self.logger.info("Added priority flow to %s in %s via %s", dst, datapath.id, out_port) + ofproto = datapath.ofproto + + actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] + + match = datapath.ofproto_parser.OFPMatch( + dl_type=ether_types.ETH_TYPE_IP, nw_dst=IPv4Address(dst)) + + mod = datapath.ofproto_parser.OFPFlowMod( + datapath=datapath, match=match, cookie=0, + command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, + priority=ofproto.OFP_DEFAULT_PRIORITY + 1, + flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) + datapath.send_msg(mod) + + def del_priority_flow(self, datapath, dst, out_port): + self.logger.info("Deleted priority flow to %s in %s via %s", dst, datapath.id, out_port) + ofproto = datapath.ofproto + + actions = [datapath.ofproto_parser.OFPActionOutput(out_port)] + + match = datapath.ofproto_parser.OFPMatch( + dl_type=ether_types.ETH_TYPE_IP, nw_dst=IPv4Address(dst)) + + mod = datapath.ofproto_parser.OFPFlowMod( + datapath=datapath, match=match, cookie=0, + command=ofproto.OFPFC_DELETE, idle_timeout=0, hard_timeout=0, + priority=ofproto.OFP_DEFAULT_PRIORITY + 1, + flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) + datapath.send_msg(mod) + + @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) + def _packet_in_handler(self, ev): + msg = ev.msg + datapath = msg.datapath + ofproto = datapath.ofproto + + pkt = packet.Packet(msg.data) + + eth = pkt.get_protocol(ethernet.ethernet) + if eth.ethertype == ether_types.ETH_TYPE_LLDP: + self.get_topology_data() + return + elif eth.ethertype == ether_types.ETH_TYPE_ARP: + # handle ARPs + self.forward_arp(msg) + elif eth.ethertype == ether_types.ETH_TYPE_IP: + pkt_ipv4 = pkt.get_protocol(ipv4.ipv4) + if pkt_ipv4.src == '0.0.0.0': + #ignore bootp packets + return + else: + self.forward_packet(msg) + + @set_ev_cls(ofp_event.EventOFPPortStatus, MAIN_DISPATCHER) + def _port_status_handler(self, ev): + msg = ev.msg + reason = msg.reason + datapath = msg.datapath + dpid = datapath.id + ofp = datapath.ofproto + ofp_port = msg.desc + port_no = msg.desc.port_no + + ofproto = msg.datapath.ofproto + if reason == ofproto.OFPPR_ADD: + self.logger.info("port added %s", port_no) + elif reason == ofproto.OFPPR_DELETE: + self.logger.info("port deleted %s", port_no) + #reset mac2port + self.mac_to_port={} + elif reason == ofproto.OFPPR_MODIFY: + #reset mac2port + self.mac_to_port={} + + self.logger.info("port modified in %s port %s port_state %s", dpid, port_no, ofp_port.state) + self.main_branch_state.setdefault(dpid, {}) + self.main_branch.setdefault(dpid, {}) + if port_no in self.main_branch_state[dpid]: + if ofp_port.state == ofp.OFPPS_LINK_DOWN and self.main_branch_state[dpid][port_no] == True: + self.main_branch_state[dpid][port_no] = False + #Switch to link_down behaviour and add priority flows + if dpid == SW1_ID: + if self.main_branch[dpid][port_no] == SW2_ID: + self.add_priority_flow(self.datapath_list[HH1_ID], ipp2, self.link_down_route[HH1_ID]) + self.add_priority_flow(self.datapath_list[HH1_ID], ipp4, self.link_down_route[HH1_ID]) + self.add_priority_flow(self.datapath_list[HH3_ID], ipp2, self.link_down_route[HH3_ID]) + self.add_priority_flow(self.datapath_list[HH3_ID], ipp4, self.link_down_route[HH3_ID]) + if self.main_branch[dpid][port_no] == SW3_ID: + self.add_priority_flow(self.datapath_list[SW1_ID], ipp5, self.link_down_route[SW1_ID]) + if dpid == SW2_ID: + if self.main_branch[dpid][port_no] == SW1_ID: + self.add_priority_flow(self.datapath_list[HH2_ID], ipp1, self.link_down_route[HH2_ID]) + self.add_priority_flow(self.datapath_list[HH2_ID], ipp3, self.link_down_route[HH2_ID]) + self.add_priority_flow(self.datapath_list[HH4_ID], ipp1, self.link_down_route[HH4_ID]) + self.add_priority_flow(self.datapath_list[HH4_ID], ipp3, self.link_down_route[HH4_ID]) + if self.main_branch[dpid][port_no] == SW3_ID: + self.add_priority_flow(self.datapath_list[SW2_ID], ipp5, self.link_down_route[SW2_ID]) + if dpid == SW3_ID: + if self.main_branch[dpid][port_no] == SW1_ID: + self.add_priority_flow(self.datapath_list[SW4_ID], ipp1, self.link_down_route[SW4_ID]) + self.add_priority_flow(self.datapath_list[SW4_ID], ipp3, self.link_down_route[SW4_ID]) + if self.main_branch[dpid][port_no] == SW2_ID: + self.add_priority_flow(self.datapath_list[SW4_ID], ipp2, self.link_down_route[SW4_ID]) + self.add_priority_flow(self.datapath_list[SW4_ID], ipp4, self.link_down_route[SW4_ID]) + if self.main_branch[dpid][port_no] == SW4_ID: + self.add_priority_flow(self.datapath_list[SW3_ID], ipp5, self.link_down_route[SW3_ID]) + if dpid == SW4_ID: + if self.main_branch[dpid][port_no] == SW3_ID: + self.add_priority_flow(self.datapath_list[HH5_ID], ipp1, self.link_down_route[HH5_ID]) + self.add_priority_flow(self.datapath_list[HH5_ID], ipp2, self.link_down_route[HH5_ID]) + self.add_priority_flow(self.datapath_list[HH5_ID], ipp3, self.link_down_route[HH5_ID]) + self.add_priority_flow(self.datapath_list[HH5_ID], ipp4, self.link_down_route[HH5_ID]) + elif ofp_port.state != ofp.OFPPS_LINK_DOWN and self.main_branch_state[dpid][port_no] == False: + #OF1.0 doesn't include a LINK_DOWN equivalent so we suppose if it has ben modified and is not down, it has to be up + self.main_branch_state[dpid][port_no] = True + #Delete priority flows and return to normal behaviour + if dpid == SW1_ID: + if self.main_branch[dpid][port_no] == SW2_ID: + self.del_priority_flow(self.datapath_list[HH1_ID], ipp2, self.link_down_route[HH1_ID]) + self.del_priority_flow(self.datapath_list[HH1_ID], ipp4, self.link_down_route[HH1_ID]) + self.del_priority_flow(self.datapath_list[HH3_ID], ipp2, self.link_down_route[HH3_ID]) + self.del_priority_flow(self.datapath_list[HH3_ID], ipp4, self.link_down_route[HH3_ID]) + if self.main_branch[dpid][port_no] == SW3_ID: + self.del_priority_flow(self.datapath_list[SW1_ID], ipp5, self.link_down_route[SW1_ID]) + if dpid == SW2_ID: + if self.main_branch[dpid][port_no] == SW1_ID: + self.del_priority_flow(self.datapath_list[HH2_ID], ipp1, self.link_down_route[HH2_ID]) + self.del_priority_flow(self.datapath_list[HH2_ID], ipp3, self.link_down_route[HH2_ID]) + self.del_priority_flow(self.datapath_list[HH4_ID], ipp1, self.link_down_route[HH4_ID]) + self.del_priority_flow(self.datapath_list[HH4_ID], ipp3, self.link_down_route[HH4_ID]) + if self.main_branch[dpid][port_no] == SW3_ID: + self.del_priority_flow(self.datapath_list[SW2_ID], ipp5, self.link_down_route[SW2_ID]) + if dpid == SW3_ID: + if self.main_branch[dpid][port_no] == SW1_ID: + self.del_priority_flow(self.datapath_list[SW4_ID], ipp1, self.link_down_route[SW4_ID]) + self.del_priority_flow(self.datapath_list[SW4_ID], ipp3, self.link_down_route[SW4_ID]) + if self.main_branch[dpid][port_no] == SW2_ID: + self.del_priority_flow(self.datapath_list[SW4_ID], ipp2, self.link_down_route[SW4_ID]) + self.del_priority_flow(self.datapath_list[SW4_ID], ipp4, self.link_down_route[SW4_ID]) + if self.main_branch[dpid][port_no] == SW4_ID: + self.del_priority_flow(self.datapath_list[SW3_ID], ipp5, self.link_down_route[SW3_ID]) + if dpid == SW4_ID: + if self.main_branch[dpid][port_no] == SW3_ID: + self.del_priority_flow(self.datapath_list[HH5_ID], ipp1, self.link_down_route[HH5_ID]) + self.del_priority_flow(self.datapath_list[HH5_ID], ipp2, self.link_down_route[HH5_ID]) + self.del_priority_flow(self.datapath_list[HH5_ID], ipp3, self.link_down_route[HH5_ID]) + self.del_priority_flow(self.datapath_list[HH5_ID], ipp4, self.link_down_route[HH5_ID]) + else: + self.logger.info("Illeagal port state %s %s", port_no, reason) diff --git a/loader/UC2/apps/iits_netmanager/src/pyretic/Commons.py b/loader/UC2/apps/iits_netmanager/src/pyretic/Commons.py new file mode 100644 index 0000000..0d34801 --- /dev/null +++ b/loader/UC2/apps/iits_netmanager/src/pyretic/Commons.py @@ -0,0 +1,56 @@ +""" + Copyright (c) 2014, NetIDE Consortium (Create-Net (CN), Telefonica Investigacion Y Desarrollo SA (TID), Fujitsu + Technology Solutions GmbH (FTS), Thales Communications & Security SAS (THALES), Fundacion Imdea Networks (IMDEA), + Universitaet Paderborn (UPB), Intel Research & Innovation Ireland Ltd (IRIIL) ) + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + + Authors: + Elisa Rojas +""" + +############################################################################################### +### Name: Commons.py +### Author: Elisa Rojas - elisa.rojas@telcaria.com +### Description: Global variables for Pyretic Modules +############################################################################################### + +# Pyretic libraries +from pyretic.lib import * +from pyretic.lib.corelib import * +from pyretic.lib.std import * + +################### IP Setup ################## +# Hosts +ipp1 = IPAddr('10.0.1.11') +ipp2 = IPAddr('10.0.1.12') +ipp3 = IPAddr('10.0.1.13') +ipp4 = IPAddr('10.0.1.14') +ipp5 = IPAddr('10.0.1.15') + +############################################### + +# Switches IDs +SW1_ID = 1 +SW2_ID = 2 +SW3_ID = 3 +SW4_ID = 4 +SW1b_ID = 5 +SW2b_ID = 6 +SW3b_ID = 7 +SW4b_ID = 8 + +# Protocols +ICMP = 1 +TCP = 6 +UDP = 17 +IP = 0x0800 + +# Messages +ERROR = -1 + +# Monitoring Interval period (in seconds) +MonitoringInterval = 5 diff --git a/loader/UC2/apps/iits_netmanager/src/pyretic/Monitor.py b/loader/UC2/apps/iits_netmanager/src/pyretic/Monitor.py new file mode 100644 index 0000000..1992c56 --- /dev/null +++ b/loader/UC2/apps/iits_netmanager/src/pyretic/Monitor.py @@ -0,0 +1,142 @@ +#!/usr/bin/python + +""" + Copyright (c) 2014, NetIDE Consortium (Create-Net (CN), Telefonica Investigacion Y Desarrollo SA (TID), Fujitsu + Technology Solutions GmbH (FTS), Thales Communications & Security SAS (THALES), Fundacion Imdea Networks (IMDEA), + Universitaet Paderborn (UPB), Intel Research & Innovation Ireland Ltd (IRIIL) ) + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + + Authors: + Georgios Katsikas +""" + +############################################################################################### +### Name: Monitor.py +### Author: Georgios Katsikas - katsikas@imdea.org +### Description: Module that gathers and prints useful statistics (e.g. pkt/byte counters) +############################################################################################### + +import os + +# Pyretic libraries +from pyretic.lib.corelib import * +from pyretic.lib.std import * +from pyretic.lib.query import * + +# Pyretic modules +from Commons import * + +### Monitoring Module for DC Topology ### +class Monitor(DynamicPolicy): + # Monitor Constructor + def __init__(self, monitoringInterval): + super(Monitor, self).__init__() + self.MonitoringInterval = monitoringInterval + self.SetInitialState() + + # Start monitoring + def SetInitialState(self): + #self.ByteQuery = self.ByteCounts() + self.PktQuery = self.PacketCounts() + self.PktCapture = self.PacketInsector() + self.UpdatePolicy() + + # Dynamically Update Policy + def UpdatePolicy(self): + self.policy = self.PktQuery + self.PktCapture # + self.ByteQuery + + # Prints counted packets + def PacketCountPrinter(self, PktCounts): + print("------------------------------ Packet Counts ------------------------------") + for k, v in sorted(PktCounts.items()): + print u'{0}: {1} pkts'.format(k, v) + print("---------------------------------------------------------------------------") + + # Counts packets every second + def PacketCounts(self): + q = count_packets(self.MonitoringInterval, ['srcip', 'switch', 'protocol']) + q.register_callback(self.PacketCountPrinter) + return q + + # Prints counted bytes + def ByteCountPrinter(self, ByteCounts): + print("------------------------------- Packet Bytes ------------------------------") + for k, v in sorted(ByteCounts.items()): + print u'{0}: {1} bytes'.format(k, v) + print("---------------------------------------------------------------------------") + + # Counts bytes every second + def ByteCounts(self): + q = count_bytes(self.MonitoringInterval, ['srcip', 'switch', 'protocol']) + q.register_callback(self.ByteCountPrinter) + return q + + # Packet capture + def PacketInsector(self): + q = packets(1, ['srcip', 'dstip', 'switch', 'protocol', 'ethtype']) + q.register_callback(self.PacketPrinter) + return q + + # Prints captured packet + def PacketPrinter(self, pkt): + print "------------------------------- Packet Content -----------------------------" + + # Capture Ethernet IP + ICMP/UDP/TCP + if pkt['ethtype'] == IP_TYPE: + print "Ethernet packet" + raw_bytes = [ord(c) for c in pkt['raw']] + print "Ethernet payload is %d" % pkt['payload_len'] + eth_payload_bytes = raw_bytes[pkt['header_len']:] + print "Ethernet payload is %d bytes" % len(eth_payload_bytes) + ip_version = (eth_payload_bytes[0] & 0b11110000) >> 4 + ihl = (eth_payload_bytes[0] & 0b00001111) + ip_header_len = ihl * 4 + ip_payload_bytes = eth_payload_bytes[ip_header_len:] + ip_proto = eth_payload_bytes[9] + print "IP Version = %d" % ip_version + print "IP Header_len = %d" % ip_header_len + print "IP Protocol = %d" % ip_proto + print "IP Payload is %d bytes" % len(ip_payload_bytes) + + # Number 6 is TCP + if ip_proto == TCP: + print "TCP packet" + tcp_data_offset = (ip_payload_bytes[12] & 0b11110000) >> 4 + tcp_header_len = tcp_data_offset * 4 + print "TCP Header Length = %d" % tcp_header_len + tcp_payload_bytes = ip_payload_bytes[tcp_header_len:] + print "TCP Payload is %d bytes" % len(tcp_payload_bytes) + if len(tcp_payload_bytes) > 0: + print "Payload:\t", + print ''.join([chr(d) for d in tcp_payload_bytes]) + # Number 17 is UDP + elif ip_proto == UDP: + print "UDP Packet" + udp_header_len = 8 + print "UDP Header Length = %d" % udp_header_len + udp_payload_bytes = ip_payload_bytes[udp_header_len:] + print "UDP Payload is %d bytes" % len(udp_payload_bytes) + if len(udp_payload_bytes) > 0: + print "Payload:\t", + print ''.join([chr(d) for d in udp_payload_bytes]) + # Number 1 is ICMP + elif ip_proto == ICMP: + print "ICMP packet" + print pkt + else: + print "Unhandled IP packet type" + # Capture Ethernet ARP + elif pkt['ethtype'] == ARP_TYPE: + print "ARP packet" + print pkt + else: + print "Unhandled packet type" + print "----------------------------------------------------------------------------" + +### Main Method ### +def main(): + return Monitor(MonitoringInterval) diff --git a/loader/UC2/apps/iits_netmanager/src/pyretic/RoutingSystem.py b/loader/UC2/apps/iits_netmanager/src/pyretic/RoutingSystem.py new file mode 100644 index 0000000..8539ed3 --- /dev/null +++ b/loader/UC2/apps/iits_netmanager/src/pyretic/RoutingSystem.py @@ -0,0 +1,377 @@ +#!/usr/bin/python + +""" + Copyright (c) 2014, NetIDE Consortium (Create-Net (CN), Telefonica Investigacion Y Desarrollo SA (TID), Fujitsu + Technology Solutions GmbH (FTS), Thales Communications & Security SAS (THALES), Fundacion Imdea Networks (IMDEA), + Universitaet Paderborn (UPB), Intel Research & Innovation Ireland Ltd (IRIIL) ) + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + + Authors: + Elisa Rojas +""" + +############################################################################################### +### Name: RoutingSystem.py +### Author: Elisa Rojas - elisa.rojas@telcaria.com +### Description: Routing System for the UC2 (TODO: Still to be improved) +############################################################################################### + +# Pyretic libraries +from pyretic.lib.std import * +from pyretic.lib.query import * +from pyretic.lib.corelib import * + +################################################################## +# Simple up/down routing applied to the architecture in UC2 # +# # +# This implementation will drop the first packet of each flow. # +# An easy fix would be to use network.inject_packet to send the # +# packet to its final destination. ### # +################################################################## +class RoutingSystem(DynamicPolicy): + def __init__(self, SwitchIDs, HostIPs): + super(RoutingSystem, self).__init__() + print("[Routing System]: __init__: %s %s" %(SwitchIDs, HostIPs)) ### + + self.topology = None + self.flood = flood() + + self.SwitchIDs = SwitchIDs + self.SwitchStates = None + self.reset_network_state() + self.HostIPs = HostIPs + self.nSwitch = len(SwitchIDs) + self.nHost = len(HostIPs) + + self.SwitchPolicies = [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None] #s1-s8[1-8]=switches, s11-s15[11-15]=hypervisors + self.EgressPolicy = drop + + self.set_initial_state() + + def set_initial_state(self): + print("[Routing System]: set_initial_state") ### + # Start a query of all the packets arriving in order to route them in the topology + self.query = packets(1, ['srcip','switch']) #packets() #self.query = packets(1, ['srcip']) #1, ['srcip', 'switch'] # Start a packet query + self.query.register_callback(self.RoutingSystemPolicy) # Handle events using callback function + self.forward = flood() # Initially floods all packet via ST #identity - return all packets (unmodified), which will later go to mac_learner + + # Capture all packets + self.all_packets = identity >> self.query + + self.update_policy() + + def reset_network_state(self): + #Switches state (first value is switch state, while the rest are ports states) #1:UP, 0:DOWN + + self.SW1State = [0, [0, 0, 0, 0, 0, 0, 0, 0, 0]] + self.SW2State = [0, [0, 0, 0, 0, 0, 0, 0, 0, 0]] + self.SW3State = [0, [0, 0, 0, 0, 0, 0, 0, 0, 0]] + self.SW4State = [0, [0, 0, 0, 0, 0, 0, 0, 0, 0]] + self.SW1bState = [0, [0, 0, 0, 0, 0, 0, 0, 0, 0]] + self.SW2bState = [0, [0, 0, 0, 0, 0, 0, 0, 0, 0]] + self.SW3bState = [0, [0, 0, 0, 0, 0, 0, 0, 0, 0]] + self.SW4bState = [0, [0, 0, 0, 0, 0, 0, 0, 0, 0]] + self.SwitchStates = [self.SW1State, self.SW2State, self.SW3State, self.SW4State, + self.SW1bState, self.SW2bState, self.SW3bState, self.SW4bState] + + def default_routing(self): + """Returns 'true' if the network uses default routing (no faulty links/switches)""" + for state in self.SwitchStates: + if state[0] == 0: + return false + return true + + def add_policy(self,switch,policy): + print("[Routing System]: add_policy for switch %s" %switch) + """Update policy for a specific switch""" + if self.SwitchPolicies[switch] is None: + self.SwitchPolicies[switch] = policy + else: + self.SwitchPolicies[switch] = self.SwitchPolicies[switch] + policy + #print(" %s<-%s = %s" %(switch, policy, self.SwitchPolicies[switch])) + + def update_policy(self): + print("[Routing System]: update_policy") + """Update policy (all switches)""" + i=0 + + if self.EgressPolicy is not None: + self.forward = self.EgressPolicy + i=1 + + for policy in self.SwitchPolicies: + #Only add policy if it is not None + if policy is not None: + if i==0: + self.forward = policy + i=1 + else: + self.forward = self.forward + policy + #If policy is None -> discard packets (i.e. no policy added to main policy) + + self.policy = self.forward + self.all_packets #we just forward non ARP packets (ARP packets are dropped, since they are just used for learning egress locations) + print(" self.policy %s" %self.policy) + + def set_network(self,network): + print("[Routing System]: set_network") ### + #TODO: See what's changed in the network, update self.SwitchStates and policy (if applicable) + + """Save network information for later forwarding""" + changed = False + if not network is None: + updated_network = network.topology + if not self.topology is None: + if self.topology != updated_network: + self.topology = updated_network + changed = True + else: + self.topology = updated_network + changed = True + if changed: + self.flood = parallel([ + match(switch=switch) >> + parallel(map(xfwd,ports)) + for switch,ports + in self.topology.switch_with_port_ids_list()]) + + print(" self.flood: %s" %self.flood) + print(" self.topology: %s" %self.topology) + + """Update network state""" + self.reset_network_state() + for switch in self.topology.nodes(): + if switch < 10: #If switch is part of the topology and not a "host hypervisor" + self.SwitchStates[switch-1][0] = 1 #If the switch is active, becomes UP (1) + + """Reset all switch policies""" + self.EgressPolicy = drop + self.SwitchPolicies = [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None] + mainBranch = [0, 0, 0, 0] #default routing has 4 main branches to distribute all the traffic, if some of them is down (either link's down or switch's down), we should add an alternative route + + + """Update policies for every switch with new network information (inter-switch routing)""" + for (s1,s2,port_nos) in self.topology.edges(data=True): + print(" edge: %s %s %s" %(s1,s2,port_nos)) + + #Default routing + if s1==self.SwitchIDs[0] and s2==self.SwitchIDs[1]: + p1 = (match(switch=s1,dstip=self.HostIPs[1]) | match(switch=s1,dstip=self.HostIPs[3])) >> xfwd(port_nos[s1]) + p2 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[2])) >> xfwd(port_nos[s2]) + self.add_policy(s1,p1) + self.add_policy(s2,p2) + mainBranch[0] = 1 #mainBranch 1 is up (S1-S2) + elif s1==self.SwitchIDs[0] and s2==self.SwitchIDs[2]: ###ERS + p3 = match(switch=s1,dstip=self.HostIPs[4]) >> xfwd(port_nos[s1]) + p4 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[2])) >> xfwd(port_nos[s2]) + self.add_policy(s1,p3) + self.add_policy(s2,p4) + mainBranch[1] = 1 #mainBranch 2 is up (S1-S3) + elif s1==self.SwitchIDs[1] and s2==self.SwitchIDs[2]: + p5 = match(switch=s1,dstip=self.HostIPs[4]) >> xfwd(port_nos[s1]) + p6 = (match(switch=s2,dstip=self.HostIPs[1]) | match(switch=s2,dstip=self.HostIPs[3])) >> xfwd(port_nos[s2]) + self.add_policy(s1,p5) + self.add_policy(s2,p6) + mainBranch[2] = 1 #mainBranch 3 is up (s2-S3) + elif s1==self.SwitchIDs[2] and s2==self.SwitchIDs[3]: + p7 = match(switch=s1,dstip=self.HostIPs[4]) >> xfwd(port_nos[s1]) + p8 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[1]) \ + | match(switch=s2,dstip=self.HostIPs[2]) | match(switch=s2,dstip=self.HostIPs[3])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p7) + self.add_policy(s2,p8) + mainBranch[3] = 1 #mainBranch 4 is up (S3-S4) + + for (s1,s2,port_nos) in self.topology.edges(data=True): + print(" edge: %s %s %s" %(s1,s2,port_nos)) + + #Non-default routing ###TODO (more options of down links to handle.......) + if mainBranch[0] == 0: #S1-S2 DOWN + if s1==self.SwitchIDs[4] and s2==self.SwitchIDs[5]: + p1 = (match(switch=s1,dstip=self.HostIPs[1]) | match(switch=s1,dstip=self.HostIPs[3])) >> xfwd(port_nos[s1]) + p2 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[2])) >> xfwd(port_nos[s2]) + self.add_policy(s1,p1) + self.add_policy(s2,p2) + if s1==self.SwitchIDs[2] and s2==self.SwitchIDs[4]: ###ERS + p3 = match(switch=s2,dstip=self.HostIPs[4]) >> xfwd(port_nos[s2]) + p4 = (match(switch=s1,dstip=self.HostIPs[0]) | match(switch=s1,dstip=self.HostIPs[2])) >> xfwd(port_nos[s1]) + self.add_policy(s2,p3) + self.add_policy(s1,p4) + if s1==self.SwitchIDs[2] and s2==self.SwitchIDs[5]: ###ERS + p5 = match(switch=s2,dstip=self.HostIPs[4]) >> xfwd(port_nos[s2]) + p6 = (match(switch=s1,dstip=self.HostIPs[1]) | match(switch=s1,dstip=self.HostIPs[3])) >> xfwd(port_nos[s1]) + self.add_policy(s2,p5) + self.add_policy(s1,p6) + if mainBranch[1] == 0: #S1-S3 DOWN + if s1==self.SwitchIDs[0] and s2==self.SwitchIDs[6]: + p11 = match(switch=s1,dstip=self.HostIPs[4]) >> xfwd(port_nos[s1]) + p12 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[2])) >> xfwd(port_nos[s2]) + self.add_policy(s1,p11) + self.add_policy(s2,p12) + if s1==self.SwitchIDs[3] and s2==self.SwitchIDs[6]: + p13 = match(switch=s2,dstip=self.HostIPs[4]) >> xfwd(port_nos[s2]) + p14 = (match(switch=s1,dstip=self.HostIPs[0]) | match(switch=s1,dstip=self.HostIPs[1]) \ + | match(switch=s1,dstip=self.HostIPs[2]) | match(switch=s1,dstip=self.HostIPs[3])) \ + >> xfwd(port_nos[s1]) + self.add_policy(s2,p13) + self.add_policy(s1,p14) + if mainBranch[2] == 0: #S2-S3 UP + if s1==self.SwitchIDs[1] and s2==self.SwitchIDs[6]: + p21 = match(switch=s1,dstip=self.HostIPs[4]) >> xfwd(port_nos[s1]) + p22 = (match(switch=s2,dstip=self.HostIPs[1]) | match(switch=s2,dstip=self.HostIPs[3])) >> xfwd(port_nos[s2]) + self.add_policy(s1,p21) + self.add_policy(s2,p22) + if s1==self.SwitchIDs[3] and s2==self.SwitchIDs[6]: + p23 = match(switch=s2,dstip=self.HostIPs[4]) >> xfwd(port_nos[s2]) + p24 = (match(switch=s1,dstip=self.HostIPs[0]) | match(switch=s1,dstip=self.HostIPs[1]) \ + | match(switch=s1,dstip=self.HostIPs[2]) | match(switch=s1,dstip=self.HostIPs[3])) \ + >> xfwd(port_nos[s1]) + self.add_policy(s2,p23) + self.add_policy(s1,p24) + if mainBranch[3] == 0: #S3-S4 DOWN + if s1==self.SwitchIDs[2] and s2==self.SwitchIDs[7]: + p31 = match(switch=s1,dstip=self.HostIPs[4]) >> xfwd(port_nos[s1]) + p32 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[1]) \ + | match(switch=s2,dstip=self.HostIPs[2]) | match(switch=s2,dstip=self.HostIPs[3])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p31) + self.add_policy(s2,p32) + + #Manually adding routes for hypervisors (hypervisors-switches links - "external") + for (s1,s2,port_nos) in self.topology.edges(data=True): + + #Default routing + switch1=self.SwitchIDs[0] + switch2=self.SwitchIDs[1] + switch4=self.SwitchIDs[3] + + #Non-default routing + if mainBranch[0] == 0: #S1-S2 DOWN + switch1=self.SwitchIDs[4] + switch2=self.SwitchIDs[5] + #if mainBranch[1] == 0: #S1-S3 DOWN + #if mainBranch[2] == 0: #S2-S3 DOWN + if mainBranch[3] == 0: #S3-S4 DOWN + switch4=self.SwitchIDs[7] + + if s1==switch1 and s2==11: #HH1 + p11 = match(switch=s1,dstip=self.HostIPs[0]) >> xfwd(port_nos[s1]) + p12 = (match(switch=s2,dstip=self.HostIPs[1]) | match(switch=s2,dstip=self.HostIPs[2]) \ + | match(switch=s2,dstip=self.HostIPs[3]) | match(switch=s2,dstip=self.HostIPs[4])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p11) + self.add_policy(s2,p12) + if s1==switch2 and s2==12: #HH2 + p13 = match(switch=s1,dstip=self.HostIPs[1]) >> xfwd(port_nos[s1]) + p14 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[2]) \ + | match(switch=s2,dstip=self.HostIPs[3]) | match(switch=s2,dstip=self.HostIPs[4])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p13) + self.add_policy(s2,p14) + if s1==switch1 and s2==13: #HH3 + p15 = match(switch=s1,dstip=self.HostIPs[2]) >> xfwd(port_nos[s1]) + p16 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[1]) \ + | match(switch=s2,dstip=self.HostIPs[3]) | match(switch=s2,dstip=self.HostIPs[4])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p15) + self.add_policy(s2,p16) + if s1==switch2 and s2==14: #HH4 + p15 = match(switch=s1,dstip=self.HostIPs[3]) >> xfwd(port_nos[s1]) + p16 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[1]) \ + | match(switch=s2,dstip=self.HostIPs[2]) | match(switch=s2,dstip=self.HostIPs[4])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p15) + self.add_policy(s2,p16) + if s1==switch4 and s2==15: #HH5 + p17 = match(switch=s1,dstip=self.HostIPs[4]) >> xfwd(port_nos[s1]) + p18 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[1]) \ + | match(switch=s2,dstip=self.HostIPs[2]) | match(switch=s2,dstip=self.HostIPs[3])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p17) + self.add_policy(s2,p18) + + """ + #Check branch by branch to build the routes (mainBranch[0] affects HH1, HH2, HH3 and HH4; mainBranch[3] affects HH5) + if mainBranch[0] == 1: #S1-S2 UP + if s1==self.SwitchIDs[0] and s2==11: #HH1 + p11 = match(switch=s1,dstip=self.HostIPs[0]) >> xfwd(port_nos[s1]) + p12 = (match(switch=s2,dstip=self.HostIPs[1]) | match(switch=s2,dstip=self.HostIPs[2]) \ + | match(switch=s2,dstip=self.HostIPs[3]) | match(switch=s2,dstip=self.HostIPs[4])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p11) + self.add_policy(s2,p12) + if s1==self.SwitchIDs[1] and s2==12: #HH2 + p13 = match(switch=s1,dstip=self.HostIPs[1]) >> xfwd(port_nos[s1]) + p14 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[2]) \ + | match(switch=s2,dstip=self.HostIPs[3]) | match(switch=s2,dstip=self.HostIPs[4])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p13) + self.add_policy(s2,p14) + if s1==self.SwitchIDs[0] and s2==13: #HH3 + p15 = match(switch=s1,dstip=self.HostIPs[2]) >> xfwd(port_nos[s1]) + p16 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[1]) \ + | match(switch=s2,dstip=self.HostIPs[3]) | match(switch=s2,dstip=self.HostIPs[4])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p15) + self.add_policy(s2,p16) + if s1==self.SwitchIDs[1] and s2==14: #HH4 + p15 = match(switch=s1,dstip=self.HostIPs[3]) >> xfwd(port_nos[s1]) + p16 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[1]) \ + | match(switch=s2,dstip=self.HostIPs[2]) | match(switch=s2,dstip=self.HostIPs[4])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p15) + self.add_policy(s2,p16) + #else: + + + #if mainBranch[1] == 1: #S1-S3 UP + #else: + + #if mainBranch[2] == 1: #S2-S3 UP + #else: + + if mainBranch[3] == 1: #S3-S4 UP + if s1==self.SwitchIDs[3] and s2==15: #HH5 + p17 = match(switch=s1,dstip=self.HostIPs[4]) >> xfwd(port_nos[s1]) + p18 = (match(switch=s2,dstip=self.HostIPs[0]) | match(switch=s2,dstip=self.HostIPs[1]) \ + | match(switch=s2,dstip=self.HostIPs[2]) | match(switch=s2,dstip=self.HostIPs[3])) \ + >> xfwd(port_nos[s2]) + self.add_policy(s1,p17) + self.add_policy(s2,p18) + #else: + """ + + + #Manually adding routes for hypervisors (hypervisors-host links - "internal") + #egress = "%s[%s]" %(pkt['switch'],pkt['inport']) + #print(" egress: %s -> %s" %(egress,self.topology.egress_locations(pkt['switch']))) + for sw in [11, 12, 13, 14, 15]: + for el in self.topology.egress_locations(sw): + print(" el: %s -> %s" %(el,el.port_no)) + #self.EgressPolicy = if_(match(dstmac=pkt['srcmac'],switch=pkt['switch']),fwd(pkt['inport']),self.EgressPolicy) #weird MAC for secondary interfaces + self.EgressPolicy = if_(match(dstip=self.HostIPs[sw-11],switch=sw),fwd(el.port_no),self.EgressPolicy) + #print(" self.EgressPolicy: %s" %self.EgressPolicy) + + + self.update_policy() + + def RoutingSystemPolicy(self, pkt): + + SwitchID = pkt['switch'] + print("[Routing System]: Switch ID: %s; Input port: %s" %(SwitchID,pkt['inport'])) + #print pkt + + if pkt['ethtype'] == IP_TYPE: + print " Ethernet packet" + + elif pkt['ethtype'] == ARP_TYPE: + print " ARP packet" + + + #self.update_policy() + #print(" self.topology: %s" %self.topology) + + diff --git a/loader/UC2/apps/iits_netmanager/src/pyretic/UC2_IITS_NetManager.py b/loader/UC2/apps/iits_netmanager/src/pyretic/UC2_IITS_NetManager.py new file mode 100644 index 0000000..0f3b8d7 --- /dev/null +++ b/loader/UC2/apps/iits_netmanager/src/pyretic/UC2_IITS_NetManager.py @@ -0,0 +1,80 @@ +#!/usr/bin/python + +""" + Copyright (c) 2014, NetIDE Consortium (Create-Net (CN), Telefonica Investigacion Y Desarrollo SA (TID), Fujitsu + Technology Solutions GmbH (FTS), Thales Communications & Security SAS (THALES), Fundacion Imdea Networks (IMDEA), + Universitaet Paderborn (UPB), Intel Research & Innovation Ireland Ltd (IRIIL) ) + + All rights reserved. This program and the accompanying materials + are made available under the terms of the Eclipse Public License v1.0 + which accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html + + Authors: + Elisa Rojas +""" + +############################################################################################### +### Name: UC2_IITS_NetManager.py +### Author: Elisa Rojas - elisa.rojas@telcaria.com +### Description: Pyretic Implementation of NetIDE UC2 - Main Module +############################################################################################### + +import os + +# Pyretic libraries +from pyretic.lib.std import * +from pyretic.lib.corelib import * + +# Generic Pyretic Modules +from Commons import * +from pyretic.modules.mac_learner import mac_learner +from Monitor import Monitor +from RoutingSystem import RoutingSystem + +### Main class for UC2 Integrated IT System Implementation +class UC2_IITS_NetManager(DynamicPolicy): + def __init__(self): + super(UC2_IITS_NetManager, self).__init__() + self.policy = None + + # Initialize and Start + self.SetInitialState() + + # Initial configuration of DC Application + def SetInitialState(self): + # RS configuration + + #Switches IDs + self.EdgeSwitches = [SW1_ID, SW2_ID, SW1b_ID, SW2b_ID] + self.AggrSwitches = [SW3_ID, SW3b_ID] + self.CoreSwitches = [SW4_ID, SW4b_ID] + self.SwitchIDs = [SW1_ID, SW2_ID, SW3_ID, SW4_ID, SW1b_ID, SW2b_ID, SW3b_ID, SW4b_ID] + #self.SwitchIDs = [self.EdgeSwitches, self.AggrSwitches, self.CoreSwitches] + + #Final host IPs + self.HostIPs = [ipp1, ipp2, ipp3, ipp4, ipp5] + + return self.Start() + + # Dynamically update enforced policy based on the last values of all the modules + def Start(self): + # Handle ARP + ARPPkt = match(ethtype=ARP_TYPE) + + # Instantiate Rerouting System + RS = RoutingSystem(self.SwitchIDs, self.HostIPs) # self.LB_Device, self.ClientIPs, self.ServerIPs, self.PublicIP + + self.policy = ( + #( ARPPkt >> mac_learner() ) + # ARP - L2 Learning Switches + RS + # Routing System + Monitor(MonitoringInterval) # Monitoring + ) + + return self.policy + +################################################################################ +### Bootstrap Use Case +################################################################################ +def main(): + return UC2_IITS_NetManager() diff --git a/loader/UC2/composition/composition.xml b/loader/UC2/composition/composition.xml new file mode 100644 index 0000000..66ea9e6 --- /dev/null +++ b/loader/UC2/composition/composition.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + diff --git a/loader/UC2/controllers.json b/loader/UC2/controllers.json new file mode 100644 index 0000000..7f87c3d --- /dev/null +++ b/loader/UC2/controllers.json @@ -0,0 +1,15 @@ +{ + "server": { + "host": "localhost", + "type": "odl" + }, + "clients": { + "vagrant-ubuntu-trusty-64": { + "identity": "~/testvm-bare/.vagrant/machines/default/virtualbox/private_key", + "apps": [], + "host": "localhost", + "user": "vagrant", + "port": 2222 + } + } +} \ No newline at end of file diff --git a/loader/UC2/parameters.json b/loader/UC2/parameters.json new file mode 100644 index 0000000..ec8c764 --- /dev/null +++ b/loader/UC2/parameters.json @@ -0,0 +1,28 @@ +{ + "iits_netmanager" :{ + "ipp1" : "10.0.1.11", + "ipp2" : "10.0.1.12", + "ipp3" : "10.0.1.13", + "ipp4" : "10.0.1.14", + "ipp5" : "10.0.1.15", + + "SW1_ID" : "1", + "SW2_ID" : "2", + "SW3_ID" : "3", + "SW4_ID" : "4", + + "SW1b_ID" : "5", + "SW2b_ID" : "6", + "SW3b_ID" : "7", + "SW4b_ID" : "8", + + "HH1_ID" : "11", + "HH2_ID" : "12", + "HH3_ID" : "13", + "HH4_ID" : "14", + "HH5_ID" : "15", + + "PROACTIVE" : "False" + + } +} diff --git a/loader/UC2/representations.aird b/loader/UC2/representations.aird new file mode 100644 index 0000000..b95cf5e --- /dev/null +++ b/loader/UC2/representations.aird @@ -0,0 +1,2709 @@ + + + Usecase_2.topology + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + + bold + + + + + + + + + bold + + + + + + + + + bold + + + + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/loader/UC2/templates/iits_netmanager/src/config.py.hbs b/loader/UC2/templates/iits_netmanager/src/config.py.hbs new file mode 100644 index 0000000..928ae60 --- /dev/null +++ b/loader/UC2/templates/iits_netmanager/src/config.py.hbs @@ -0,0 +1,23 @@ +PROACTIVE = {{PROACTIVE}} + +ipp1 = '{{ipp1}}' +ipp2 = '{{ipp2}}' +ipp3 = '{{ipp3}}' +ipp4 = '{{ipp4}}' +ipp5 = '{{ipp5}}' + +SW1_ID = {{SW1_ID}} +SW2_ID = {{SW2_ID}} +SW3_ID = {{SW3_ID}} +SW4_ID = {{SW4_ID}} + +SW1b_ID = {{SW1b_ID}} +SW2b_ID = {{SW2b_ID}} +SW3b_ID = {{SW3b_ID}} +SW4b_ID = {{SW4b_ID}} + +HH1_ID = {{HH1_ID}} +HH2_ID = {{HH2_ID}} +HH3_ID = {{HH3_ID}} +HH4_ID = {{HH4_ID}} +HH5_ID = {{HH5_ID}} diff --git a/loader/loader/controllers.py b/loader/loader/controllers.py index cbcbb20..e302288 100644 --- a/loader/loader/controllers.py +++ b/loader/loader/controllers.py @@ -136,7 +136,6 @@ def start(self): for a in self.applications: - self.appNames.append(a.appName) appPath = os.path.join(a.path, a.entrypoint) @@ -278,7 +277,7 @@ def start(self): if "ODL" not in list: - call(['tmux', 'new-window', '-n', "ODL", '-t', 'NetIDE', '~/netide/distribution-karaf-0.4.0-Beryllium/bin/karaf']) + call(['tmux', 'new-window', '-n', "ODL", '-t', 'NetIDE', '~/netide/distribution-karaf-0.5.0-Boron/bin/karaf']) time.sleep(odlCommands['sleepafter']) else: diff --git a/loader/loader/package.py b/loader/loader/package.py index 5c0f15e..322ac00 100644 --- a/loader/loader/package.py +++ b/loader/loader/package.py @@ -40,7 +40,7 @@ class Package(object): extractPath = "" - def __init__(self, prefix, dataroot, paramPath=""): + def __init__(self, prefix, dataroot, paramPath="", file_type="json"): self.dataroot = dataroot self.path = os.path.abspath(prefix) print(self.path) @@ -91,7 +91,7 @@ def __init__(self, prefix, dataroot, paramPath=""): self.cksum = hash.hexdigest() - def load_apps_and_controller(self): + def load_apps_and_controller(self, file_type="json"): for d in self.appNames: nodes = [] @@ -107,7 +107,7 @@ def load_apps_and_controller(self): raise FileNotFoundError('Param file not found. Please use generate method first.') content = util.compileHandlebar(self.path, d, self.paramPath) - self.generateParamFile(content, d) + self.generateParamFile(content, d, file_type) for node, v in self.config.get("clients", {}).items(): @@ -120,7 +120,7 @@ def load_apps_and_controller(self): logging.debug("Checking hardware requirements for {}".format(d)) if not Application.check_hw_requirements(app): logging.error("Requirements for application {} not met".format(d)) - return False + return False #returns controller ctrl = Application.get_controller(app) @@ -145,7 +145,7 @@ def check_sysreq(self): logging.debug("Checking system requirements for {}".format(d)) if not Application.valid_requirements(app): logging.error("Requirements for application {} not met".format(d)) - return False + return False return True def check_no_hw_sysreq(self): @@ -155,7 +155,7 @@ def check_no_hw_sysreq(self): logging.debug("Checking system requirements for {}".format(d)) if not (Application.check_net_requirements(app) and Application.check_sw_requirements(app)): logging.error("Requirements for application {} not met".format(d)) - return False + return False return True def __del__(self): @@ -265,9 +265,26 @@ def generateParam(self, paramPath=""): content = util.compileHandlebar(self.path, name, paramPath) self.generateParamFile(content, name) - def generateParamFile(self, content, appName): + def generatePyParam(self, content, appName): + appPath = os.path.join(self.path, 'apps/' + appName + '/src/Configuration.py') + + with open(appPath, 'w') as paramFile: + paramFile.write(content) + + def generateParamFile(self, content, appName, file_type): + + if file_type == "json": + self.generateJsonParam(content, appName) + + if file_type == "py": + self.generatePyParam(content, appName) + + + + def generateJsonParam(self, content, appName): + content = content.lower() #gets dictionary from handlebars generated file dict = {} diff --git a/loader/loader/util.py b/loader/loader/util.py index 23b8b38..4308c9b 100644 --- a/loader/loader/util.py +++ b/loader/loader/util.py @@ -176,7 +176,7 @@ def compileHandlebar(path, appName, paramPath=""): output = template(appContent) - return output.lower() + return output class Chdir(object): @@ -385,5 +385,5 @@ def check_sw_version(sw_name, req_version): return False #if they're the same check subversion - #At this point the actual version is greateror equal to the requirement + #At this point the actual version is greateror equal to the requirement return True diff --git a/loader/netideloader.py b/loader/netideloader.py index 167a662..37de1db 100755 --- a/loader/netideloader.py +++ b/loader/netideloader.py @@ -64,7 +64,7 @@ def set_extraction_path(args): def createParam(args): p = Package(args.package, dataroot) - p.createParamFile(args.fp) + p.createParamFile(args.file) def start_package(args): @@ -73,7 +73,12 @@ def start_package(args): else: p = Package(args.package, dataroot) - if not p.load_apps_and_controller(): + + file_format = "json" + if not args.format == None: + file_format = args.format + + if not p.load_apps_and_controller(file_format): logging.error("There's something wrong with the package") return 2 @@ -88,10 +93,17 @@ def start_package(args): else: ODL("").start() + time.sleep(1) +###### workaround for demo - dirty ####### + if args.mininet == "on": + mnpath = "bash -c \' sudo mn -c && cd " + p.path + "/Topology && sudo chmod +x UC2_IITSystem.py && sudo ./UC2_IITSystem.py $1 && cd ../ \' " + call(['tmux', 'new-window', '-n', "mn", '-t', 'NetIDE', mnpath]) + time.sleep(1) +######## - for c in p.controllers_for_node().items(): + for c in p.controllers_for_node().items(): c[1].start() time.sleep(2) @@ -154,7 +166,7 @@ def generate(args): p = Package(args.package, dataroot, args.param) else: p = Package(args.package, dataroot) - if not p.load_apps_and_controller(): + if not p.load_apps_and_controller(args.format): logging.error("There's something wrong with the package") return 2 @@ -183,13 +195,16 @@ def check(args): parser_start = subparsers.add_parser("run", description="Load a NetIDE package and start its applications") parser_start.add_argument("package", type=str, help="Package to load") + parser_start.add_argument("--format", type=str, help="Enter py or json to define the created parameter file format") parser_start.add_argument("--server", type=str, help="Choose one of {ODL, ryu}") parser_start.add_argument("--ofport", type=str, help="Choose port for of.") parser_start.add_argument("--param", type=str, help="Path to Param File which should be used to configure the package.") + parser_start.add_argument("--mininet", type=str, help="enter on to use mininet") parser_start.set_defaults(func=start_package, mode="all") parser_createHandlebars = subparsers.add_parser("genconfig", description="Generates application configurations from a parameter file.") parser_createHandlebars.add_argument("package", type=str, help="Package to use") + parser_createHandlebars.add_argument("format", type=str, help="Enter py or json to define the created parameter file format") parser_createHandlebars.add_argument("--param", type=str, help="Path to Param File which should be used to configure the package.") parser_createHandlebars.set_defaults(func=generate, mode="all") diff --git a/loader/requirements.txt b/loader/requirements.txt index 7c1d3a9..bd17dfb 100644 --- a/loader/requirements.txt +++ b/loader/requirements.txt @@ -3,3 +3,4 @@ pyzmq pyyaml pybars3 psutil +ipaddr \ No newline at end of file