From da7bba3b81c36cc1e16469c18b2575377a70b9eb Mon Sep 17 00:00:00 2001 From: "J.-N" Date: Wed, 30 Nov 2016 13:32:20 +0100 Subject: [PATCH 1/5] First version of uc2 for loader --- loader/UC2/Usecase_2.topology | 136 + loader/UC2/Usecase_2.wb | 218 ++ .../iits_netmanager/iits_netmanager.params | 3 + .../iits_netmanager/iits_netmanager.sysreq | 26 + .../iits_netmanager/src/IITS_NetManager.py | 540 ++++ .../iits_netmanager_13.params | 3 + .../iits_netmanager_13.sysreq | 26 + .../src/IITS_NetManager_13.py | 574 ++++ loader/UC2/composition/composition.xml | 20 + loader/UC2/controllers.json | 15 + loader/UC2/parameters.json | 4 + loader/UC2/representations.aird | 2709 +++++++++++++++++ .../iits_netmanager/src/config.py.hbs | 0 .../iits_netmanager_13/src/config.py.hbs | 0 loader/requirements.txt | 1 + 15 files changed, 4275 insertions(+) create mode 100644 loader/UC2/Usecase_2.topology create mode 100644 loader/UC2/Usecase_2.wb create mode 100644 loader/UC2/apps/iits_netmanager/iits_netmanager.params create mode 100644 loader/UC2/apps/iits_netmanager/iits_netmanager.sysreq create mode 100644 loader/UC2/apps/iits_netmanager/src/IITS_NetManager.py create mode 100644 loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.params create mode 100644 loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.sysreq create mode 100644 loader/UC2/apps/iits_netmanager_13/src/IITS_NetManager_13.py create mode 100644 loader/UC2/composition/composition.xml create mode 100644 loader/UC2/controllers.json create mode 100644 loader/UC2/parameters.json create mode 100644 loader/UC2/representations.aird create mode 100644 loader/UC2/templates/iits_netmanager/src/config.py.hbs create mode 100644 loader/UC2/templates/iits_netmanager_13/src/config.py.hbs 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..2c174c0 --- /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..2617868 --- /dev/null +++ b/loader/UC2/apps/iits_netmanager/src/IITS_NetManager.py @@ -0,0 +1,540 @@ +# 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.topology import event, switches +from ryu.topology.api import get_switch, get_link +from ipaddr import IPv4Address + +################### IP Setup ################## +# Hosts +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' + +############################################### + +# 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 +HH1_ID = 11 +HH2_ID = 12 +HH3_ID = 13 +HH4_ID = 14 +HH5_ID = 15 + +#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} + +#Boolean variable to determine proactive/reactive behavior +PROACTIVE = False + +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 + + out_port = self.mac_to_port[dpid][dst] + 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) + + 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) + elif reason == ofproto.OFPPR_MODIFY: + 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) \ No newline at end of file diff --git a/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.params b/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.params new file mode 100644 index 0000000..17ade9a --- /dev/null +++ b/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.params @@ -0,0 +1,3 @@ +{ + "parameters": {} +} \ No newline at end of file diff --git a/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.sysreq b/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.sysreq new file mode 100644 index 0000000..40f0303 --- /dev/null +++ b/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.sysreq @@ -0,0 +1,26 @@ +app: { + name: "Ryu IITS Netmanager 13", + version: "0.1", + controller: + { + name: "Ryu", + version: "3.30", + entrypoint: "src/iits_netmanager_13.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_13/src/IITS_NetManager_13.py b/loader/UC2/apps/iits_netmanager_13/src/IITS_NetManager_13.py new file mode 100644 index 0000000..480e115 --- /dev/null +++ b/loader/UC2/apps/iits_netmanager_13/src/IITS_NetManager_13.py @@ -0,0 +1,574 @@ +# Developed by Juan Manuel Sanchez, March 2016. + +""" +An OpenFlow 1.3 L2 static switching implementation. +""" + + +from ryu.base import app_manager +from ryu.controller import ofp_event +from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER +from ryu.controller.handler import set_ev_cls +from ryu.ofproto import ofproto_v1_3 +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.topology import event, switches +from ryu.topology.api import get_switch, get_link +from ipaddr import IPv4Address + +################### IP Setup ################## +# Hosts +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' + +############################################### + +# 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 +HH1_ID = 11 +HH2_ID = 12 +HH3_ID = 13 +HH4_ID = 14 +HH5_ID = 15 + +#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} + +#Boolean variable to determine proactive/reactive behavior +PROACTIVE = False + +class IITS_NetManager_13(app_manager.RyuApp): + OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] + + out_port_table = [[]] + + def __init__(self, *args, **kwargs): + super(IITS_NetManager_13, 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 + + @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) + def switch_features_handler(self, ev): + datapath = ev.msg.datapath + ofproto = datapath.ofproto + parser = datapath.ofproto_parser + + # install table-miss flow entry + # + # We specify NO BUFFER to max_len of the output action due to + # OVS bug. At this moment, if we specify a lesser number, e.g., + # 128, OVS will send Packet-In with invalid buffer_id and + # truncated packet data. In that case, we cannot output packets + # correctly. The bug has been fixed in OVS v2.1.0. + match = parser.OFPMatch() + actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] + self.add_flow(datapath, 0, match, actions) + + 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.match['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 + + out_port = self.mac_to_port[dpid][dst] + 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.match['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.match['in_port'] + + self.logger.info("ARP in %s %s", dpid, 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 + parser = datapath.ofproto_parser + in_port = msg.match['in_port'] + + 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.match['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 = [parser.OFPActionOutput(out_port)] + + # install a flow to avoid packet_in next time + if out_port != ofproto.OFPP_FLOOD: + match = parser.OFPMatch(in_port=in_port, ipv4_dst=dst) + # verify if we have a valid buffer_id, if yes avoid to send both + # flow_mod & packet_out + if msg.buffer_id != ofproto.OFP_NO_BUFFER: + self.add_flow(datapath, 1, match, actions, msg.buffer_id) + return + else: + self.add_flow(datapath, 1, match, actions) + data = None + if msg.buffer_id == ofproto.OFP_NO_BUFFER: + data = msg.data + + out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, + in_port=in_port, actions=actions, data=data) + datapath.send_msg(out) + + def add_flow(self, datapath, priority, match, actions, buffer_id=None): + ofproto = datapath.ofproto + parser = datapath.ofproto_parser + + inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, + actions)] + if buffer_id: + mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, + priority=priority, match=match, + instructions=inst) + else: + mod = parser.OFPFlowMod(datapath=datapath, priority=priority, + match=match, instructions=inst) + datapath.send_msg(mod) + + def add_priority_flow(self, datapath, dst, out_port, buffer_id=None): + self.logger.info("Added priority flow to %s in %s via %s", dst, datapath.id, out_port) + ofproto = datapath.ofproto + parser = datapath.ofproto_parser + match = datapath.ofproto_parser.OFPMatch( + eth_type=ether_types.ETH_TYPE_IP, ipv4_dst=IPv4Address(dst)) + actions = [parser.OFPActionOutput(out_port)] + priority = ofproto.OFP_DEFAULT_PRIORITY + 1 + + inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, + actions)] + if buffer_id: + mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, + priority=priority, match=match, + instructions=inst) + else: + mod = parser.OFPFlowMod(datapath=datapath, priority=priority, + match=match, instructions=inst) + datapath.send_msg(mod) + + def del_priority_flow(self, datapath, dst, out_port, buffer_id=None): + self.logger.info("Deleted priority flow to %s in %s via %s", dst, datapath.id, out_port) + ofproto = datapath.ofproto + parser = datapath.ofproto_parser + match = datapath.ofproto_parser.OFPMatch( + eth_type=ether_types.ETH_TYPE_IP, ipv4_dst=IPv4Address(dst)) + actions = [parser.OFPActionOutput(out_port)] + priority = ofproto.OFP_DEFAULT_PRIORITY + 1 + + inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, + actions)] + if buffer_id: + mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, priority=priority, + flags=ofproto.OFPFF_SEND_FLOW_REM, match=match, + instructions=inst) + else: + mod = parser.OFPFlowMod(datapath=datapath, priority=priority, flags=ofproto.OFPFF_SEND_FLOW_REM, + match=match, instructions=inst) + datapath.send_msg(mod) + + @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) + def _packet_in_handler(self, ev): + #self.logger.info("Packet In") + 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) + elif reason == ofproto.OFPPR_MODIFY: + 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/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..69f4f96 --- /dev/null +++ b/loader/UC2/parameters.json @@ -0,0 +1,4 @@ +{ + "iits_netmanager" :{}, + "iits_netmanager_13":{} +} 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..e69de29 diff --git a/loader/UC2/templates/iits_netmanager_13/src/config.py.hbs b/loader/UC2/templates/iits_netmanager_13/src/config.py.hbs new file mode 100644 index 0000000..e69de29 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 From 47cf1f79586e1b9b5b7b0c6a4978868882e4dd1f Mon Sep 17 00:00:00 2001 From: "J.-N" Date: Wed, 30 Nov 2016 16:09:12 +0100 Subject: [PATCH 2/5] added UC2 demo package. Small changes to loader to start mininet script. --- loader/UC2/Topology/UC2_IITSystem.py | 238 ++++++++ .../iits_netmanager/iits_netmanager.sysreq | 4 +- .../iits_netmanager_13.params | 3 - .../iits_netmanager_13.sysreq | 26 - .../src/IITS_NetManager_13.py | 574 ------------------ loader/UC2/parameters.json | 3 +- .../iits_netmanager_13/src/config.py.hbs | 0 loader/loader/controllers.py | 7 +- loader/loader/package.py | 6 +- loader/netideloader.py | 10 +- 10 files changed, 256 insertions(+), 615 deletions(-) create mode 100644 loader/UC2/Topology/UC2_IITSystem.py delete mode 100644 loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.params delete mode 100644 loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.sysreq delete mode 100644 loader/UC2/apps/iits_netmanager_13/src/IITS_NetManager_13.py delete mode 100644 loader/UC2/templates/iits_netmanager_13/src/config.py.hbs 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/apps/iits_netmanager/iits_netmanager.sysreq b/loader/UC2/apps/iits_netmanager/iits_netmanager.sysreq index 2c174c0..0b6b1f3 100644 --- a/loader/UC2/apps/iits_netmanager/iits_netmanager.sysreq +++ b/loader/UC2/apps/iits_netmanager/iits_netmanager.sysreq @@ -2,10 +2,10 @@ app: { name: "Ryu IITS Netmanager", version: "0.1", controller: - { + { name: "Ryu", version: "3.30", - entrypoint: "src/iits_netmanager.py", + entrypoint: "src/IITS_NetManager.py", port: 7733, }, hardwareReq: { diff --git a/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.params b/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.params deleted file mode 100644 index 17ade9a..0000000 --- a/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.params +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parameters": {} -} \ No newline at end of file diff --git a/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.sysreq b/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.sysreq deleted file mode 100644 index 40f0303..0000000 --- a/loader/UC2/apps/iits_netmanager_13/iits_netmanager_13.sysreq +++ /dev/null @@ -1,26 +0,0 @@ -app: { - name: "Ryu IITS Netmanager 13", - version: "0.1", - controller: - { - name: "Ryu", - version: "3.30", - entrypoint: "src/iits_netmanager_13.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_13/src/IITS_NetManager_13.py b/loader/UC2/apps/iits_netmanager_13/src/IITS_NetManager_13.py deleted file mode 100644 index 480e115..0000000 --- a/loader/UC2/apps/iits_netmanager_13/src/IITS_NetManager_13.py +++ /dev/null @@ -1,574 +0,0 @@ -# Developed by Juan Manuel Sanchez, March 2016. - -""" -An OpenFlow 1.3 L2 static switching implementation. -""" - - -from ryu.base import app_manager -from ryu.controller import ofp_event -from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER -from ryu.controller.handler import set_ev_cls -from ryu.ofproto import ofproto_v1_3 -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.topology import event, switches -from ryu.topology.api import get_switch, get_link -from ipaddr import IPv4Address - -################### IP Setup ################## -# Hosts -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' - -############################################### - -# 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 -HH1_ID = 11 -HH2_ID = 12 -HH3_ID = 13 -HH4_ID = 14 -HH5_ID = 15 - -#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} - -#Boolean variable to determine proactive/reactive behavior -PROACTIVE = False - -class IITS_NetManager_13(app_manager.RyuApp): - OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION] - - out_port_table = [[]] - - def __init__(self, *args, **kwargs): - super(IITS_NetManager_13, 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 - - @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER) - def switch_features_handler(self, ev): - datapath = ev.msg.datapath - ofproto = datapath.ofproto - parser = datapath.ofproto_parser - - # install table-miss flow entry - # - # We specify NO BUFFER to max_len of the output action due to - # OVS bug. At this moment, if we specify a lesser number, e.g., - # 128, OVS will send Packet-In with invalid buffer_id and - # truncated packet data. In that case, we cannot output packets - # correctly. The bug has been fixed in OVS v2.1.0. - match = parser.OFPMatch() - actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] - self.add_flow(datapath, 0, match, actions) - - 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.match['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 - - out_port = self.mac_to_port[dpid][dst] - 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.match['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.match['in_port'] - - self.logger.info("ARP in %s %s", dpid, 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 - parser = datapath.ofproto_parser - in_port = msg.match['in_port'] - - 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.match['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 = [parser.OFPActionOutput(out_port)] - - # install a flow to avoid packet_in next time - if out_port != ofproto.OFPP_FLOOD: - match = parser.OFPMatch(in_port=in_port, ipv4_dst=dst) - # verify if we have a valid buffer_id, if yes avoid to send both - # flow_mod & packet_out - if msg.buffer_id != ofproto.OFP_NO_BUFFER: - self.add_flow(datapath, 1, match, actions, msg.buffer_id) - return - else: - self.add_flow(datapath, 1, match, actions) - data = None - if msg.buffer_id == ofproto.OFP_NO_BUFFER: - data = msg.data - - out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, - in_port=in_port, actions=actions, data=data) - datapath.send_msg(out) - - def add_flow(self, datapath, priority, match, actions, buffer_id=None): - ofproto = datapath.ofproto - parser = datapath.ofproto_parser - - inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, - actions)] - if buffer_id: - mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, - priority=priority, match=match, - instructions=inst) - else: - mod = parser.OFPFlowMod(datapath=datapath, priority=priority, - match=match, instructions=inst) - datapath.send_msg(mod) - - def add_priority_flow(self, datapath, dst, out_port, buffer_id=None): - self.logger.info("Added priority flow to %s in %s via %s", dst, datapath.id, out_port) - ofproto = datapath.ofproto - parser = datapath.ofproto_parser - match = datapath.ofproto_parser.OFPMatch( - eth_type=ether_types.ETH_TYPE_IP, ipv4_dst=IPv4Address(dst)) - actions = [parser.OFPActionOutput(out_port)] - priority = ofproto.OFP_DEFAULT_PRIORITY + 1 - - inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, - actions)] - if buffer_id: - mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, - priority=priority, match=match, - instructions=inst) - else: - mod = parser.OFPFlowMod(datapath=datapath, priority=priority, - match=match, instructions=inst) - datapath.send_msg(mod) - - def del_priority_flow(self, datapath, dst, out_port, buffer_id=None): - self.logger.info("Deleted priority flow to %s in %s via %s", dst, datapath.id, out_port) - ofproto = datapath.ofproto - parser = datapath.ofproto_parser - match = datapath.ofproto_parser.OFPMatch( - eth_type=ether_types.ETH_TYPE_IP, ipv4_dst=IPv4Address(dst)) - actions = [parser.OFPActionOutput(out_port)] - priority = ofproto.OFP_DEFAULT_PRIORITY + 1 - - inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, - actions)] - if buffer_id: - mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id, priority=priority, - flags=ofproto.OFPFF_SEND_FLOW_REM, match=match, - instructions=inst) - else: - mod = parser.OFPFlowMod(datapath=datapath, priority=priority, flags=ofproto.OFPFF_SEND_FLOW_REM, - match=match, instructions=inst) - datapath.send_msg(mod) - - @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER) - def _packet_in_handler(self, ev): - #self.logger.info("Packet In") - 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) - elif reason == ofproto.OFPPR_MODIFY: - 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/parameters.json b/loader/UC2/parameters.json index 69f4f96..54ab94e 100644 --- a/loader/UC2/parameters.json +++ b/loader/UC2/parameters.json @@ -1,4 +1,3 @@ { - "iits_netmanager" :{}, - "iits_netmanager_13":{} + "iits_netmanager" :{} } diff --git a/loader/UC2/templates/iits_netmanager_13/src/config.py.hbs b/loader/UC2/templates/iits_netmanager_13/src/config.py.hbs deleted file mode 100644 index e69de29..0000000 diff --git a/loader/loader/controllers.py b/loader/loader/controllers.py index cbcbb20..006d265 100644 --- a/loader/loader/controllers.py +++ b/loader/loader/controllers.py @@ -63,7 +63,7 @@ def start(self): class RyuShim(Base): - def __init__(self, ofport="6633"): + def __init__(self, ofport="6644"): self.port = ofport def start(self): @@ -86,7 +86,7 @@ def start(self): list = util.getWindowList() if "RyuShim" not in list: - #6633 default for port listening + #6644 default for port listening newCmd = "bash -c \'cd ~/netide/Engine/ryu-shim/ && " + cmd + " --ofp-tcp-listen-port=" + self.port + " ryu-shim.py\'" call(['tmux', 'new-window', '-n', "RyuShim", '-t', 'NetIDE', newCmd]) @@ -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) @@ -147,7 +146,7 @@ def start(self): if a.appName not in windowNames: print(a.path) ryubackendpath = "bash -c \' cd ~/netide/Engine/ryu-backend/ && " + cmd + " --ofp-tcp-listen-port=" + str(Ryu.ryubackendport) + " ryu-backend.py " + os.path.join(a.path, a.entrypoint) + "\' " - + call(['tmux', 'new-window', '-n', a.appName, '-t', 'NetIDE', ryubackendpath]) Ryu.ryubackendport = Ryu.ryubackendport + 1 diff --git a/loader/loader/package.py b/loader/loader/package.py index 5c0f15e..901a946 100644 --- a/loader/loader/package.py +++ b/loader/loader/package.py @@ -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): diff --git a/loader/netideloader.py b/loader/netideloader.py index 167a662..5300793 100755 --- a/loader/netideloader.py +++ b/loader/netideloader.py @@ -89,9 +89,17 @@ def start_package(args): ODL("").start() +###### workaround for demo - dirty ####### - for c in p.controllers_for_node().items(): + 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(): + print(c) c[1].start() time.sleep(2) From 2b0eb8587eef0abfd04972a264f775596bb4dcbe Mon Sep 17 00:00:00 2001 From: "J.-N" Date: Sun, 4 Dec 2016 16:15:10 +0100 Subject: [PATCH 3/5] Fixed typo Added mininet option as a flag --- loader/loader/controllers.py | 4 ++-- loader/netideloader.py | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/loader/loader/controllers.py b/loader/loader/controllers.py index 006d265..cea597d 100644 --- a/loader/loader/controllers.py +++ b/loader/loader/controllers.py @@ -63,7 +63,7 @@ def start(self): class RyuShim(Base): - def __init__(self, ofport="6644"): + def __init__(self, ofport="6633"): self.port = ofport def start(self): @@ -146,7 +146,7 @@ def start(self): if a.appName not in windowNames: print(a.path) ryubackendpath = "bash -c \' cd ~/netide/Engine/ryu-backend/ && " + cmd + " --ofp-tcp-listen-port=" + str(Ryu.ryubackendport) + " ryu-backend.py " + os.path.join(a.path, a.entrypoint) + "\' " - + call(['tmux', 'new-window', '-n', a.appName, '-t', 'NetIDE', ryubackendpath]) Ryu.ryubackendport = Ryu.ryubackendport + 1 diff --git a/loader/netideloader.py b/loader/netideloader.py index 5300793..4f5d1c1 100755 --- a/loader/netideloader.py +++ b/loader/netideloader.py @@ -88,15 +88,15 @@ 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 ../ \' " - 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]) - + call(['tmux', 'new-window', '-n', "mn", '-t', 'NetIDE', mnpath]) + time.sleep(1) ######## - time.sleep(1) + for c in p.controllers_for_node().items(): print(c) @@ -194,6 +194,7 @@ def check(args): 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.") From 7effac087e69f42d5fcf2b0f1270efdcd5746651 Mon Sep 17 00:00:00 2001 From: "J.-N" Date: Wed, 7 Dec 2016 14:43:07 +0100 Subject: [PATCH 4/5] Typo in create Config param Updatet odl_karaf path --- loader/loader/controllers.py | 4 ++-- loader/netideloader.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/loader/loader/controllers.py b/loader/loader/controllers.py index cea597d..e302288 100644 --- a/loader/loader/controllers.py +++ b/loader/loader/controllers.py @@ -86,7 +86,7 @@ def start(self): list = util.getWindowList() if "RyuShim" not in list: - #6644 default for port listening + #6633 default for port listening newCmd = "bash -c \'cd ~/netide/Engine/ryu-shim/ && " + cmd + " --ofp-tcp-listen-port=" + self.port + " ryu-shim.py\'" call(['tmux', 'new-window', '-n', "RyuShim", '-t', 'NetIDE', newCmd]) @@ -277,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/netideloader.py b/loader/netideloader.py index 4f5d1c1..97a91ea 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): @@ -99,7 +99,6 @@ def start_package(args): for c in p.controllers_for_node().items(): - print(c) c[1].start() time.sleep(2) @@ -194,7 +193,7 @@ def check(args): 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.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.") From 4497c4158eca8335db4bb664a87e3df91f716dba Mon Sep 17 00:00:00 2001 From: "J.-N" Date: Mon, 19 Dec 2016 11:43:02 +0100 Subject: [PATCH 5/5] Updated the loader to support param generation for python config files --- .../iits_netmanager/src/IITS_NetManager.py | 68 ++-- .../iits_netmanager/src/pyretic/Commons.py | 56 +++ .../iits_netmanager/src/pyretic/Monitor.py | 142 +++++++ .../src/pyretic/RoutingSystem.py | 377 ++++++++++++++++++ .../src/pyretic/UC2_IITS_NetManager.py | 80 ++++ loader/UC2/parameters.json | 27 +- .../iits_netmanager/src/config.py.hbs | 23 ++ loader/loader/package.py | 25 +- loader/loader/util.py | 4 +- loader/netideloader.py | 11 +- 10 files changed, 773 insertions(+), 40 deletions(-) create mode 100644 loader/UC2/apps/iits_netmanager/src/pyretic/Commons.py create mode 100644 loader/UC2/apps/iits_netmanager/src/pyretic/Monitor.py create mode 100644 loader/UC2/apps/iits_netmanager/src/pyretic/RoutingSystem.py create mode 100644 loader/UC2/apps/iits_netmanager/src/pyretic/UC2_IITS_NetManager.py diff --git a/loader/UC2/apps/iits_netmanager/src/IITS_NetManager.py b/loader/UC2/apps/iits_netmanager/src/IITS_NetManager.py index 2617868..ee18c3d 100644 --- a/loader/UC2/apps/iits_netmanager/src/IITS_NetManager.py +++ b/loader/UC2/apps/iits_netmanager/src/IITS_NetManager.py @@ -16,42 +16,17 @@ 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 -################### IP Setup ################## -# Hosts -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' - -############################################### - -# 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 -HH1_ID = 11 -HH2_ID = 12 -HH3_ID = 13 -HH4_ID = 14 -HH5_ID = 15 +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} -#Boolean variable to determine proactive/reactive behavior -PROACTIVE = False - class IITS_NetManager(app_manager.RyuApp): OFP_VERSIONS = [ofproto_v1_0.OFP_VERSION] @@ -284,8 +259,11 @@ def arp_unicast(self, msg): # forward ARP if src not in self.mac_to_port[dpid]: self.mac_to_port[dpid][src] = in_port - - out_port = self.mac_to_port[dpid][dst] + 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: @@ -336,9 +314,32 @@ def forward_arp(self, msg): 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: @@ -462,7 +463,12 @@ def _port_status_handler(self, ev): 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, {}) @@ -537,4 +543,4 @@ def _port_status_handler(self, ev): 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) \ No newline at end of file + 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/parameters.json b/loader/UC2/parameters.json index 54ab94e..ec8c764 100644 --- a/loader/UC2/parameters.json +++ b/loader/UC2/parameters.json @@ -1,3 +1,28 @@ { - "iits_netmanager" :{} + "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/templates/iits_netmanager/src/config.py.hbs b/loader/UC2/templates/iits_netmanager/src/config.py.hbs index e69de29..928ae60 100644 --- a/loader/UC2/templates/iits_netmanager/src/config.py.hbs +++ 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/package.py b/loader/loader/package.py index 901a946..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(): @@ -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 97a91ea..37de1db 100755 --- a/loader/netideloader.py +++ b/loader/netideloader.py @@ -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 @@ -161,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 @@ -190,6 +195,7 @@ 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.") @@ -198,6 +204,7 @@ def check(args): 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")