示例#1
0
 def __init__(self, *args, **kwargs):
     super(ResourceTracker, self).__init__(*args, **kwargs)
     self.mac_to_port = {}
     self.dpset = kwargs['dpset']
     self.datapaths = {}
     # create thread for traffic monitoring
     # self.monitor_thread = hub.spawn(self._monitor)
     self.hostname_list = {}
     self.dpid_datapathObj = {}
     self.ssh_learning = {}
     self.ssh_track_list = {}
     self.util = Utilites()
示例#2
0
 def __init__(self, *args, **kwargs):
     super(ICMPTrafficController, self).__init__(*args, **kwargs)
     self.datapaths = {}
     self.monitor_thread = hub.spawn(self._monitor)
     self.hostname_list = {}
     self.sleep = 10
     # length of saved dictionary value
     self.state_len = 3
     self.icmp_stats = {}
     self.iperf_stats = {}
     self.traffic_checked_list = []
     self.util = Utilites()
     self.dpid_datapathObj = {}
 def __init__(self, *args, **kwargs):
     super(ResourceScheduler, self).__init__(*args, **kwargs)
     self.mac_to_port = {}
     self.dpset = kwargs['dpset']
     self.datapaths = {}
     # create thread for traffic monitoring
     # self.monitor_thread = hub.spawn(self._monitor)
     self.hostname_list = {}
     self.dpid_datapathObj = {}
     self.ssh_learning = {}
     self.ssh_track_list = {}
     self.util = Utilites()
示例#4
0
 def __init__(self, *args, **kwargs):
     super(SimpleSwitch13, self).__init__(*args, **kwargs)
     self.mac_to_port = {}
     self.dpset = kwargs['dpset']
     self.datapaths = {}
     # create thread for traffic monitoring
     self.monitor_thread = hub.spawn(self._monitor)
     self.hostname_list = {}
     self.net = nx.DiGraph()
     self.nodes = {}
     self.links = {}
     self.no_of_nodes = 0
     self.no_of_links = 0
     self.topology_data_app = self
     # port number between two OVS
     self.link_port = {}
     # save OVS datapath Object for later reference
     self.dpid_datapathObj = {}
     self.icmp_count = 0
     self.icmp_track_list = {}
     self.icmp_path_list = {}
     self.util = Utilites()
示例#5
0
class ResourceTracker(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
    _CONTEXTS = {
        'dpset': dpset.DPSet,
    }

    def __init__(self, *args, **kwargs):
        super(ResourceTracker, self).__init__(*args, **kwargs)
        self.mac_to_port = {}
        self.dpset = kwargs['dpset']
        self.datapaths = {}
        # create thread for traffic monitoring
        # self.monitor_thread = hub.spawn(self._monitor)
        self.hostname_list = {}
        self.dpid_datapathObj = {}
        self.ssh_learning = {}
        self.ssh_track_list = {}
        self.util = Utilites()
        # self._update_switch_dpid_list()

    ###################################################################
    # ofp_event.EventOFPSwitchFeatures
    ####################################################################
    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        # self._update_switch_dpid_list()
        self.logger.debug("switch_features_handler: ")
        datapath = ev.msg.datapath
        dpid = datapath.id
        # save datapath object into dpid_datapath
        # here dpid is a integer, not Hex number
        self.dpid_datapathObj[dpid] = ev.msg.datapath

    ###################################################################
    # EventOFPPacketIn handler
    ####################################################################
    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        pkt = packet.Packet(data=msg.data)
        pkt_ethernet = pkt.get_protocol(ethernet.ethernet)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        dst_mac = eth.dst
        if dst_mac == LLDP_MAC_NEAREST_BRIDGE:
            return

        if not pkt_ethernet:
            return
        else:
            pass
            self.logger.debug("ResourceTracker: Packet-In:")
            # self.logger.info("\tether_packet: at %s %s " % (self.util.hostname_Check(datapath.id), pkt_ethernet))

        pkt_arp = pkt.get_protocol(arp.arp)
        if pkt_arp:
            return

        pkt_tcp = pkt.get_protocol(tcp.tcp)
        # pkt_udp = pkt.get_protocol(udp.udp)
        if pkt_tcp:
            # self.logger.info("\tTCP_packet: at %s %s " % (self.util.hostname_Check(datapath.id), pkt_tcp))
            pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
            src_ip = pkt_ipv4.src
            dst_ip = pkt_ipv4.dst
            in_port = msg.match['in_port']
            src_mac = eth.src
            # parser = datapath.ofproto_parser
            if pkt_tcp:
                src_port = pkt_tcp.src_port
                dst_port = pkt_tcp.dst_port
            if str(dst_port) == '8031' or str(dst_port) == '50010':
                key = (src_ip, dst_ip, src_mac, dst_mac, dst_port)
                self.logger.debug("ResourceTracker: Packet-In:")
                self.logger.info(
                    "\t############################# Resource_tracker Traffic #####################################"
                )
                self.logger.info(
                    "\tAt %s from %s to %s from src_port %s to dst_port %s from  port %s src_mac %s dst_mac %s"
                    % (self.util.hostname_Check(datapath.id), src_ip, dst_ip,
                       src_port, dst_port, in_port, src_mac, dst_mac))
                if key not in self.ssh_learning.keys():
                    # self.logger.info("\t############################# HDFS Traffic #####################################")
                    # self.logger.info("\tAt %s from %s to %s from src_port %s to dst_port %s from  port %s src_mac %s dst_mac %s" %
                    #                 (self.util.hostname_Check(datapath.id), src_ip, dst_ip, src_port, dst_port, in_port, src_mac, dst_mac))
                    # this valuw will be used at a timer, This entry will be cleard after 1 second
                    value = time.time()
                    self.ssh_learning[key] = value
                elif key in self.ssh_learning.keys():
                    if time.time(
                    ) - self.ssh_learning[key] >= SSH_KEY_LEARNING_TIMER:
                        self.logger.info(
                            "\t(src_ip, dst_ip, src_mac, dst_mac, dst_port, in_port) TIMEOUT from self.hdfs_learning dict!!!"
                        )
                        del self.ssh_learning[key]
                        self.ssh_learning[key] = time.time()
                    else:
                        return
                else:
                    return
                src_dpid_name = self.util.hostname_Check(datapath.id)
                # self.logger.info("\tInstall SSH flow between IP address %s and %s \n\tsleeping for 5 s ........................" % (src_ip, dst_ip))
                # time.sleep(5)
                # find dstination datapath id from host_tracker file
                dst_dpid_name = self.util.return_dst_dpid_hostname(
                    dst_ip, dst_mac)
                if dst_dpid_name == None:
                    self.logger.info(
                        "\tcould not find destination switch..............")
                    return

                self.logger.info(
                    "\tInstall Resource_tracker flow between %s and %s" %
                    (dst_dpid_name, src_dpid_name))

                # Now only consider two end hosts
                # hosts = [src_mac, dst_mac]
                hosts = [dst_mac, src_mac]
                # find shortest path between two switches, a list of hostnames ['s1','s2','s3']
                shortest_path = self.util.return_shortest_path(
                    dst_dpid_name, src_dpid_name)
                # install flows between hosts and switch
                # self.install_flows_for_hosts_and_attached_switches(hosts, shortest_path, src_ip, dst_ip, src_port, dst_port, src_mac, dst_mac, msg)

                if len(shortest_path) == 1:
                    self.util.install_flows_for_same_switch_v2(
                        shortest_path, 'TCP', src_ip, dst_ip, src_mac, dst_mac,
                        src_port, dst_port, self.dpid_datapathObj,
                        RESOURCE_TRACKER_IDLE_TIMER,
                        RESOURCE_TRACKER_HARD_TIMER, msg)
                else:
                    # install flows between hosts and switch
                    self.install_flows_for_hosts_and_attached_switches(
                        hosts, shortest_path, src_ip, dst_ip, src_port,
                        dst_port, src_mac, dst_mac, msg)

                # install flow for the rest of switches if the length of shortest path is greater than 2
                if len(shortest_path) > 2:
                    # self.util.install_flows_for_rest_of_switches(
                    #     shortest_path, 'TCP', SSH_PRIORITY, src_ip, dst_ip, src_mac, dst_mac, self.dpid_datapathObj, SSH_IDLE_TIMER, SSH_HARD_TIMER)
                    self.util.install_flows_for_rest_of_switches(
                        shortest_path, 'TCP', HDFS_PRIORITY, dst_ip, src_ip,
                        dst_mac, src_mac, self.dpid_datapathObj,
                        SSH_IDLE_TIMER, SSH_HARD_TIMER)

    def install_flows_for_hosts_and_attached_switches(self, hosts,
                                                      shortest_path, src_ip,
                                                      dst_ip, src_port,
                                                      dst_port, src_mac,
                                                      dst_mac, msg):
        count = 0
        for h_mac in hosts:
            if count < len(hosts) and count == 0:
                self.util.install_flow_between_host_and_switch_for_TCP_UDP(
                    h_mac, 'TCP', RESOURCE_TRACKER_PRIORITY,
                    shortest_path[count:count + 2], count, dst_ip, src_ip,
                    dst_port, src_port, dst_mac, src_mac,
                    self.dpid_datapathObj, SSH_IDLE_TIMER, SSH_HARD_TIMER, msg)
                count += 1
            elif count < len(hosts) and count == 1:
                self.util.install_flow_between_host_and_switch_for_TCP_UDP(
                    h_mac, 'TCP', RESOURCE_TRACKER_PRIORITY,
                    list([
                        shortest_path[len(shortest_path) - 1],
                        shortest_path[len(shortest_path) - 2]
                    ]), count, dst_ip, src_ip, dst_port, src_port, dst_mac,
                    src_mac, self.dpid_datapathObj, SSH_IDLE_TIMER,
                    SSH_HARD_TIMER, msg)
                count += 1
class ResourceScheduler(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
    _CONTEXTS = {
        'dpset': dpset.DPSet,
    }

    def __init__(self, *args, **kwargs):
        super(ResourceScheduler, self).__init__(*args, **kwargs)
        self.mac_to_port = {}
        self.dpset = kwargs['dpset']
        self.datapaths = {}
        # create thread for traffic monitoring
        # self.monitor_thread = hub.spawn(self._monitor)
        self.hostname_list = {}
        self.dpid_datapathObj = {}
        self.ssh_learning = {}
        self.ssh_track_list = {}
        self.util = Utilites()
        # self._update_switch_dpid_list()

    ###################################################################
    # ofp_event.EventOFPSwitchFeatures
    ####################################################################
    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        # self._update_switch_dpid_list()
        self.logger.debug("switch_features_handler: ")
        datapath = ev.msg.datapath
        dpid = datapath.id
        # save datapath object into dpid_datapath
        # here dpid is a integer, not Hex number
        self.dpid_datapathObj[dpid] = ev.msg.datapath

    ###################################################################
    # EventOFPPacketIn handler
    ####################################################################
    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        pkt = packet.Packet(data=msg.data)
        pkt_ethernet = pkt.get_protocol(ethernet.ethernet)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        dst_mac = eth.dst
        if dst_mac == LLDP_MAC_NEAREST_BRIDGE:
            return

        if not pkt_ethernet:
            return
        else:
            pass
            self.logger.debug("ResourceScheduler: Packet-In:")
            # self.logger.info("\tether_packet: at %s %s " % (self.util.hostname_Check(datapath.id), pkt_ethernet))

        pkt_arp = pkt.get_protocol(arp.arp)
        if pkt_arp:
            return

        pkt_tcp = pkt.get_protocol(tcp.tcp)
        # pkt_udp = pkt.get_protocol(udp.udp)
        if pkt_tcp:
            # self.logger.info("\tTCP_packet: at %s %s " % (self.util.hostname_Check(datapath.id), pkt_tcp))
            pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
            src_ip = pkt_ipv4.src
            dst_ip = pkt_ipv4.dst
            in_port = msg.match['in_port']
            src_mac = eth.src
            # parser = datapath.ofproto_parser
            if pkt_tcp:
                src_port = pkt_tcp.src_port
                dst_port = pkt_tcp.dst_port
            if str(dst_port) == '8030' or str(dst_port) == '54311':
                key = (src_ip, dst_ip, src_mac, dst_mac, dst_port)
                self.logger.debug("ResourceScheduler: Packet-In:")
                self.logger.info("\t############################# Resource_Scheduler Traffic #####################################")
                self.logger.info("\tAt %s from %s to %s from src_port %s to dst_port %s from  port %s src_mac %s dst_mac %s" %
                                 (self.util.hostname_Check(datapath.id), src_ip, dst_ip, src_port, dst_port, in_port, src_mac, dst_mac))
                if key not in self.ssh_learning.keys():
                    # self.logger.info("\t############################# HDFS Traffic #####################################")
                    # self.logger.info("\tAt %s from %s to %s from src_port %s to dst_port %s from  port %s src_mac %s dst_mac %s" %
                    #                 (self.util.hostname_Check(datapath.id), src_ip, dst_ip, src_port, dst_port, in_port, src_mac, dst_mac))
                    # this valuw will be used at a timer, This entry will be cleard after 1 second
                    value = time.time()
                    self.ssh_learning[key] = value
                elif key in self.ssh_learning.keys():
                    if time.time() - self.ssh_learning[key] >= SSH_KEY_LEARNING_TIMER:
                        self.logger.info("\t(src_ip, dst_ip, src_mac, dst_mac, dst_port, in_port) TIMEOUT from self.hdfs_learning dict!!!")
                        del self.ssh_learning[key]
                        self.ssh_learning[key] = time.time()
                    else:
                        return
                else:
                    return
                src_dpid_name = self.util.hostname_Check(datapath.id)
                # self.logger.info("\tInstall SSH flow between IP address %s and %s \n\tsleeping for 5 s ........................" % (src_ip, dst_ip))
                # time.sleep(5)
                # find dstination datapath id from host_tracker file
                dst_dpid_name = self.util.return_dst_dpid_hostname(dst_ip, dst_mac)
                if dst_dpid_name == None:
                    self.logger.info("\tcould not find destination switch..............")
                    return

                self.logger.info("\tInstall Resource_tracker flow between %s and %s" % (dst_dpid_name, src_dpid_name))

                # Now only consider two end hosts
                # hosts = [src_mac, dst_mac]
                hosts = [dst_mac, src_mac]
                # find shortest path between two switches, a list of hostnames ['s1','s2','s3']
                shortest_path = self.util.return_shortest_path(dst_dpid_name, src_dpid_name)
                # install flows between hosts and switch
                # self.install_flows_for_hosts_and_attached_switches(hosts, shortest_path, src_ip, dst_ip, src_port, dst_port, src_mac, dst_mac, msg)

                if len(shortest_path) == 1:
                    self.util.install_flows_for_same_switch_v2(
                        shortest_path, 'TCP', src_ip, dst_ip, src_mac, dst_mac,
                        src_port, dst_port, self.dpid_datapathObj, RESOURCE_TRACKER_IDLE_TIMER, RESOURCE_TRACKER_HARD_TIMER, msg)
                else:
                    # install flows between hosts and switch
                    self.install_flows_for_hosts_and_attached_switches(hosts, shortest_path, src_ip, dst_ip, src_port, dst_port, src_mac, dst_mac, msg)

                # install flow for the rest of switches if the length of shortest path is greater than 2
                if len(shortest_path) > 2:
                    # self.util.install_flows_for_rest_of_switches(
                    #     shortest_path, 'TCP', SSH_PRIORITY, src_ip, dst_ip, src_mac, dst_mac, self.dpid_datapathObj, SSH_IDLE_TIMER, SSH_HARD_TIMER)
                    self.util.install_flows_for_rest_of_switches(
                        shortest_path, 'TCP', HDFS_PRIORITY, dst_ip, src_ip, dst_mac, src_mac, self.dpid_datapathObj, SSH_IDLE_TIMER, SSH_HARD_TIMER)

    def install_flows_for_hosts_and_attached_switches(self, hosts, shortest_path, src_ip, dst_ip, src_port, dst_port, src_mac, dst_mac, msg):
        count = 0
        for h_mac in hosts:
            if count < len(hosts) and count == 0:
                self.util.install_flow_between_host_and_switch_for_TCP_UDP(
                    h_mac, 'TCP', RESOURCE_TRACKER_PRIORITY, shortest_path[count:count + 2],
                    count, dst_ip, src_ip, dst_port, src_port, dst_mac, src_mac, self.dpid_datapathObj, SSH_IDLE_TIMER, SSH_HARD_TIMER,  msg)
                count += 1
            elif count < len(hosts) and count == 1:
                self.util.install_flow_between_host_and_switch_for_TCP_UDP(
                    h_mac, 'TCP', RESOURCE_TRACKER_PRIORITY, list([shortest_path[len(shortest_path) - 1], shortest_path[len(shortest_path) - 2]]),
                    count, dst_ip, src_ip, dst_port, src_port, dst_mac, src_mac, self.dpid_datapathObj, SSH_IDLE_TIMER, SSH_HARD_TIMER, msg)
                count += 1
示例#7
0
class ICMPTrafficController(app_manager.RyuApp):

    def __init__(self, *args, **kwargs):
        super(ICMPTrafficController, self).__init__(*args, **kwargs)
        self.datapaths = {}
        self.monitor_thread = hub.spawn(self._monitor)
        self.hostname_list = {}
        self.sleep = 10
        # length of saved dictionary value
        self.state_len = 3
        self.icmp_stats = {}
        self.iperf_stats = {}
        self.traffic_checked_list = []
        self.util = Utilites()
        self.dpid_datapathObj = {}

    ###################################################################
    # ofp_event.EventOFPSwitchFeatures
    ####################################################################
    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        # self._update_switch_dpid_list()
        self.logger.debug("switch_features_handler: ")
        msg = ev.msg
        datapath = ev.msg.datapath
        dpid = datapath.id
        # save datapath object into dpid_datapath
        # here dpid is a integer, not Hex number
        self.dpid_datapathObj[dpid] = ev.msg.datapath
        # print self.dpid_datapathObj
        # ofproto = datapath.ofproto
        # parser = datapath.ofproto_parser

        # self.logger.debug(
        #     "   datapath in decimal %s,in hex %s",
        #     datapath.id, hex(int(datapath.id)))
        # self.logger.debug('   OFPSwitchFeatures received: '
        #                  'datapath_id=0x%016x n_buffers=%d '
        #                  'n_tables=%d auxiliary_id=%d '
        #                  'capabilities=0x%08x',
        #                  msg.datapath_id, msg.n_buffers, msg.n_tables,
        #                  msg.auxiliary_id, msg.capabilities)

    def _monitor(self):
        while True:
            self._request_stats()
            hub.sleep(STATS_UPDATE_TIMER)

    def _hostname_Check(self, datapath):
        # Given decimal datapath ID, return hostname
        if os.path.exists(os.path.abspath(OFP_SWITCHES_LIST_PREVIOUS)):
            f = os.path.abspath(OFP_SWITCHES_LIST_PREVIOUS)
        else:
            f = os.path.abspath(OFP_SWITCHES_LIST)
        with open(f, 'r') as iff:
            for line in iff:
                hostname, dpid = line.split()
                self.hostname_list[int(dpid, 16)] = hostname

        # print self.hostname_list
        # NEED add some datapath check later
        if datapath not in self.hostname_list.keys():
            return datapath
        else:
            return self.hostname_list[datapath]

    def _request_stats(self):
        self.logger.debug("icmpTrafficController: ")
        if(not os.path.exists(OFP_ICMP_LOG)):
            icmp_detail = ""
            icmp_path = []
        else:
            with open(OFP_ICMP_LOG, 'r') as inp:
                for line in inp:
                    # self.logger.debug("\t%s %s" % (line.strip(), type(line)))
                    icmp_path = line.split()[2:-1]
                    icmp_detail = line
                    self.logger.debug("\tICMP %s" % (icmp_path))

        if(not os.path.exists(OFP_IPERF_LOG)):
            iperf_detail = ""
            iperf_path = []
        else:
            with open(OFP_IPERF_LOG, 'r') as inp:
                for line in inp:
                    iperf_detail = line
                    # self.logger.debug("\t%s %s" % (line.strip(), type(line)))
                    iperf_path = line.split()[6:]
                    self.logger.debug("\tIPERF %s" % (iperf_path))

        # self.traffic_checked_list only save one icmp traffic and iperf traffic,
        # icmp/iperf detailed get update for every different ping/iperf_client
        if icmp_path and iperf_path:
            if len(self.traffic_checked_list) == 0:
                self.traffic_checked_list.insert(0, icmp_detail)
                self.traffic_checked_list.insert(1, iperf_detail)
                if self.check_if_path_overlape(icmp_path, iperf_path):
                    self.logger.debug("\t1. Path OVerlap, Now check if Iperf traffic is over 50Mbits/s~~~~~~~~~~~~~~~~~~~~~~~")
                    if self.check_iperf_traffic_on_path(iperf_path) > 50:
                        self.logger.debug("\t1. Install new flows for ICMP traffic from %s to %s" % (icmp_path[0], icmp_path[-1]))
                        if self.check_if_icmp_traffic_on(icmp_path):
                            self.icmp_reroute(icmp_path, icmp_detail)
                return
            elif(icmp_detail not in self.traffic_checked_list):
                self.traffic_checked_list.pop(0)
                self.traffic_checked_list.insert(0, icmp_detail)
                if self.check_if_path_overlape(icmp_path, iperf_path):
                    self.logger.debug("\t2. Path OVerlap, Now check if Iperf traffic is over 50Mbits/s~~~~~~~~~~~~~~~~~~~~~~~")
                    if self.check_iperf_traffic_on_path(iperf_path) > 50:
                        self.logger.debug("\t2. Install new flows for ICMP traffic from %s to %s" % (icmp_path[0], icmp_path[-1]))
                        if self.check_if_icmp_traffic_on(icmp_path):
                            self.icmp_reroute(icmp_path, icmp_detail)
                return
            elif(iperf_detail not in self.traffic_checked_list):
                self.traffic_checked_list.pop(1)
                self.traffic_checked_list.insert(1, iperf_detail)
                if self.check_if_path_overlape(icmp_path, iperf_path):
                    self.logger.debug("\t3. Path OVerlap, Now check if Iperf traffic is over 50Mbits/s~~~~~~~~~~~~~~~~~~~~~~~")
                    if self.check_iperf_traffic_on_path(iperf_path) > 50:
                        self.logger.debug("\t3. Install new flows for ICMP traffic from %s to %s" % (icmp_path[0], icmp_path[-1]))
                        if self.check_if_icmp_traffic_on(icmp_path):
                            self.icmp_reroute(icmp_path, icmp_detail)
                return

            # icmp and iperf happens at the same time

    def icmp_reroute(self, icmp_path, icmp_detail):
        self.logger.debug("ICMPTrafficController:")
        # find the current icmp_path flows
        # based on recored icmp packge information, find a new path which is different from the currernt one, install new flows, delete all the flows
        icmp_info = icmp_detail.split()[-1]
        src_mac, dst_mac, src_ip, dst_ip = icmp_info.split('-')[1], icmp_info.split('-')[2],\
            icmp_info.split('-')[3], icmp_info.split('-')[4]
        self.logger.debug("\tFinding the second shortest path for %s %s %s %s %s" % (icmp_path[0], src_mac, dst_mac, src_ip, dst_ip))
        src_dpid_name = icmp_path[0]
        dst_dpid_name = icmp_path[-1]
        all_shortest_path = self.util.return_all_shortest_paths(src_dpid_name, dst_dpid_name)
        self.logger.debug("\tAll all_shortest_path: %s", all_shortest_path)
        for path in all_shortest_path:
            if icmp_path != path:
                second_new_path = path

        self.logger.debug("\tFound the second new path %s" % second_new_path)
        hosts = [src_mac, dst_mac]
        # install flows bettween host and switches
        self.install_flows_for_hosts_and_attached_switches(hosts, second_new_path, src_ip, dst_ip, src_mac, dst_mac)
        # install flow for the rest of switches
        if len(second_new_path) > 2:
            self.util.install_flows_for_rest_of_switches(
              second_new_path, 'ICMP', ICMP_PRIORITY, src_ip, dst_ip, src_mac, dst_mac, self.dpid_datapathObj, ICMP_IDLE_TIMER, HARD_TIMER)

        # write to the icmp rereoute log
        with open(OFP_ICMP_REROUTE_LOG, 'w') as inp:
            inp.write("%s %s %s" % (src_mac, dst_mac, second_new_path))

        # delete previous flows
        self.logger.debug("delete old icmp flows along the prevous path")
        for node in icmp_path:
            self.logger.debug("\tDelete Flows From %s" % node)
            # match = parser.OFPMatch(in_port=in_port, eth_src=src, eth_dst=dst, eth_type=0x0800, ipv4_src=src_ip,
            #                                 ipv4_dst=dst_ip, ip_proto=1)
            previous_flows = self.util.return_flows_info_based_on_switch_name(node, 'ICMP', ICMP_PRIORITY)
            self.logger.debug("\t previous_flows details %s" % previous_flows)
            node_dpid = self.util.return_decimalDPID_baseON_swithName(node)
            node_datapath_obj = self.dpid_datapathObj[int(node_dpid)]
            for each_path in previous_flows:
                # in_port, src_mac, dst_mac, ip_proto, idle_timeout, src_ip, dst_ip, output_port, priorit
                # ['2', '02:26:11:36:df:68', '02:39:2f:fa:2f:a9', '1', '60', '192.168.1.9', '192.168.1.21', '3', '3']
                match = node_datapath_obj.ofproto_parser.OFPMatch(in_port=int(each_path[0]), eth_src=each_path[1], eth_dst=each_path[2], eth_type=0x0800, ipv4_src=each_path[5],
                                                                  ipv4_dst=each_path[6], ip_proto=1)
                actions = [node_datapath_obj.ofproto_parser.OFPActionOutput(int(each_path[7]))]
                self.util.del_flow(node_datapath_obj, ICMP_PRIORITY, match, actions, ICMP_IDLE_TIMER, HARD_TIMER, int(each_path[7]))
                self.logger.debug("\tDeleted at %s %s %s %s %s %s %s" % (node, each_path[0], each_path[1], each_path[2], each_path[5], each_path[6], each_path[7]))

    def install_flows_for_hosts_and_attached_switches(self, hosts, shortest_path, src_ip, dst_ip, src_mac, dst_mac):
        count = 0
        for h_mac in hosts:
            if count < len(hosts) and count == 0:
                self.util.install_flow_between_host_and_switch_for_ICMP(
                    h_mac, 'ICMP', shortest_path[count:count + 2], count, src_ip, dst_ip, src_mac, dst_mac, self.dpid_datapathObj)
                count += 1
            elif count < len(hosts) and count == 1:
                self.util.install_flow_between_host_and_switch_for_ICMP(
                     h_mac, 'ICMP', list([shortest_path[len(shortest_path) - 1], shortest_path[len(shortest_path) - 2]]),
                     count, src_ip, dst_ip, src_mac, dst_mac, self.dpid_datapathObj)
                count += 1

    def check_if_path_overlape(self, path1, path2):
        # return True is one of them is subset of another one
        # path1 and path2 are lists
        # path1 ('02:26:11:36:df:68', '02:39:2f:fa:2f:a9')  s1 s5 s4
        # path2 ('02:63:ff:a5:b1:0f', '02:a5:6e:49:09:5d', '192.168.1.25', '192.168.1.8', 47409, 5001)  s5 s1
        path1_set = set(path1)
        path2_set = set(path2)
        if path1_set.issubset(path2_set) or path2_set.issubset(path1_set):
            return True

    def check_iperf_traffic_on_path(self, iperf_path):
        # given a iperf path, return the size of the flow traffic on this path
        bandwidth_usage = 100  # for now we assume it always bigger than 100
        time.sleep(1)
        return bandwidth_usage

    def check_if_icmp_traffic_on(self, path1):
        # at this point, we assume icmp is always on
        return True