Example #1
0
def runner():
    "Create and run a custom topo with adjustable link parameters"
    topo = CompleteGraphTopo( )
    c = RemoteController('c', '127.0.0.1', 6633)
    net = Mininet( topo=topo,
                   controller=None,
                              host=CPULimitedHost, link=TCLink ,waitConnected=True,autoSetMacs=True)

    net.addController(c)           
    net.start()
    enable_BFD(net)# enable bfd
    link_fail_dict=sw_link_map(net)
    edges=link_fail_dict.keys() # keys of link_fail_dict has all the edges of the graph
    edges=bi_direct_edges(edges) # make edges bi directional so that nx can find path
    graph=nx.DiGraph()
    graph.add_edges_from(edges) # construct graph from edges obtained from mininet net obj
    random.seed(30) # set seed for random number
    test_pair=[(0,7),(3,8),(0,9),(8,6),(9,1)] 
    result={'hop':[],'delay':[],'throughput':[]}
    time.sleep(8)
    for pair in test_pair:
        host1,host2=pair
        src=net.getNodeByName('h'+str(host1+1))
        dst=net.getNodeByName('h'+str(host2+1))
        path=nx.shortest_path(graph,host1+1,host2+1) # compute shortest path from graph
        links_between_pair=pairwise(path) # make links from path
        randindex=random.randint(0,len(links_between_pair)-1) # find random index  to be used to get failed link
        link_to_fail=links_between_pair[randindex] # get random link to be failed using random index
        print 'Failing link between',link_to_fail
        
        if link_fail_dict.has_key(link_to_fail):
           link_to_fail_obj=link_fail_dict[link_to_fail] # find the link obj to fail
        elif link_fail_dict.has_key(link_to_fail[::-1]): # link might be with reverse key
             link_to_fail_obj=link_fail_dict[link_to_fail[::-1]] # find the link obj to fail 
             link_to_fail= link_to_fail[::-1]  
        try:
           print ping(net,[src,dst],64,2)# send some packets before calculation
           net.delLink(link_to_fail_obj) # delete link to fail it
        except:
          import pdb;pdb.set_trace()
        time.sleep(5)        
        sent,received,min_,avg=ping(net,[src,dst],1024,5)
        print 'Delay ',avg,' for ',pair
        result['delay'].append(float(avg))
        hop=get_path_length(net,src,dst)
        print 'Hop ',hop,' for ',pair
        result['hop'].append(float(hop))
        time_perf,datasize_tx,bitrate=doIperf(net,src,dst)
        print 'Throughput ',bitrate,' for ',pair
        result['throughput'].append(float(bitrate))
        link_fail_dict[link_to_fail]=net.addLink("s%d" %link_to_fail[0],"s%d" %link_to_fail[1])
    print 'Average Number of Hop:', getavg(result['hop'])
    print 'Average Delay: ', getavg(result['delay'])
    print 'Throughput:',getavg(result['throughput'])
    CLI(net)
    net.stop()
Example #2
0
class Controller(app_manager.RyuApp):
    def __init__(self):
        super(Controller, self).__init__()

        self.switches = {}  # Switches
        self.num_switches = -1  # track that all switches have reported
        self.priority = 1100  # current max priority
        self.numH = None  # number of hosts
        self.verbose = 0  # reporting details

        self.network = self.initial_network1()
        self.mininet_from_network(self.network)
        self.wiring, self.agg_key, self.core_key = self.network.core_agg_wiring(
        )
        self.minwiring = MinimalRewiringILP(self.wiring)
        # wait a few secs and add new switch
        sleep(10)
        self.add_switch('spine', 5, 2)

    def mininet_from_network(self, network):
        """ Generate a mininet topology corresponding to the /network/ """
        self.topo = Topo()

        hosts = self.network.get_type('host')
        for sid in hosts:
            self.topo.addHost('s%d' % sid, dpid=("%0.2X" % sid))
        for sid in self.network.switches.keys():
            if sid not in hosts:
                self.topo.addSwitch('s%d' % sid,
                                    dpid=("%0.2X" % sid),
                                    protocols='OpenFlow10')

        for sid1, sid2 in self.network.edges.keys():
            self.addLink('s%d' % sid1, 's%d' % sid2)

        self.mininet = Mininet(self.topo)
        self.mininet.pingAll(timeout=1)

        return self.mininet

    @set_ev_cls(dpset.EventDP)
    def switchStatus(self, ev):
        print("S %s: %s!" %
              (ev.dp.id, "connected" if ev.enter else "disconnected"))
        sys.stdout.flush()
        self.prepareSwitch(ev.dp)

    def prepareSwitch(self, sw):
        hostIp = int(sw.id)
        self.switches[hostIp] = sw

        routes = self.network.route_ecmp()
        self.priority += 1
        for s_id in routes.keys():
            for h_id in routes[s_id].keys():
                self.install_flow(self.switches[s_id], (10 << 24) + h_id,
                                  routes[s_id][h_id],
                                  pr=self.priority)

    def install_flow(self, sw, dst, out, pr=1100, src=None):
        # Send the ARP/IP packets to the proper host
        ofproto = sw.ofproto
        action = sw.ofproto_parser.OFPActionOutput(out)
        if not src:
            match = sw.ofproto_parser.OFPMatch(dl_type=0x806, nw_dst=dst)
            match_arp = sw.ofproto_parser.OFPMatch(dl_type=0x800, nw_dst=dst)
        else:
            match = sw.ofproto_parser.OFPMatch(dl_type=0x806,
                                               nw_dst=dst,
                                               nw_src=src)
            match_arp = sw.ofproto_parser.OFPMatch(dl_type=0x800,
                                                   nw_dst=dst,
                                                   nw_src=src)
        mod = sw.ofproto_parser.OFPFlowMod(datapath=sw,
                                           match=match,
                                           cookie=0,
                                           command=ofproto.OFPFC_ADD,
                                           idle_timeout=0,
                                           hard_timeout=0,
                                           priority=pr,
                                           flags=ofproto.OFPFF_SEND_FLOW_REM,
                                           actions=[action])
        sw.send_msg(mod)

        mod = sw.ofproto_parser.OFPFlowMod(datapath=sw,
                                           match=match_arp,
                                           cookie=0,
                                           command=ofproto.OFPFC_ADD,
                                           idle_timeout=0,
                                           hard_timeout=0,
                                           priority=pr,
                                           flags=ofproto.OFPFF_SEND_FLOW_REM,
                                           actions=[action])
        sw.send_msg(mod)

    def add_switch(self, level, nports, pace=2):
        """ Add spine or server block switch with /nports/ complete with all 
    necessary rewiring and rerouting

    Args:
          level (string): "spine" or "server"
          nports (int): number of ports on switch
          pace (int): number of instructions to install before rerouting

    """
        self.network.max_sid += 1
        sid = self.network.max_sid
        self.mininet.addSwitch('s%d' % sid,
                               dpid=("%0.2X" % sid),
                               protocols='OpenFlow10')
        if level == 'spine':
            stype = 'core'
            self.core_key[len(self.core_key)] = sid
        else:
            stype = 'agg'
            self.agg_key[len(self.agg_key)] = sid

        self.network.add_switch(sid, nports, stype)

        instructions = self.minwiring.rewire(level, nports)
        for i, instr in enumerate(instructions):
            # add or delete link from network state and mininet topology
            a_id = self.agg_key[instr[1]]
            c_id = self.core_key[instr[2]]
            if instr[0] == "CONNECT":
                self.network.add_link(a_id, c_id, 1)
                self.mininet.addLink('s%d' % a_id, 's%d' % c_id)
                print("Adding 1 link between switch {} and {}".format(
                    a_id, c_id))
            elif instr[0] == "DISCONNECT":
                self.network.remove_link(a_id, c_id, 1)
                self.mininet.delLink('s%d' % a_id, 's%d' % c_id)
                print("Removing 1 link between switch {} and {}".format(
                    a_id, c_id))

            if i % pace == 0:
                # reroute every pace instructions
                routes = self.network.route_ecmp()
                self.priority += 1
                for s_id in routes.keys():
                    for h_id in routes[s_id].keys():
                        self.install_flow(self.switches[s_id],
                                          (10 << 24) + h_id,
                                          routes[s_id][h_id],
                                          pr=self.priority)

        # Final rerouting before exit
        routes = self.network.route_ecmp()
        self.priority += 1
        for s_id in routes.keys():
            for h_id in routes[s_id].keys():
                self.install_flow(self.switches[s_id], (10 << 24) + h_id,
                                  routes[s_id][h_id],
                                  pr=self.priority)

    def initial_network1(self):
        """ Sample starting network onto which we'll add nodes """
        net = Network()

        for i in range(1, 9):
            net.add_switch(i, 4, 'host')
        for i in range(9, 13):
            net.add_switch(i, 4, 'edge')
        for i in range(13, 17):
            net.add_switch(i, 5, 'agg')
        for i in range(17, 19):
            net.add_switch(i, 6, 'core')

        # host:edge links
        h_e = [(1, 9, 1), (2, 9, 1), (3, 10, 1), (4, 10, 1), (5, 11, 1),
               (6, 11, 1), (7, 12, 1), (8, 12, 1)]
        # edge:agg links
        e_a = [(13, 9, 1), (14, 9, 1), (13, 10, 1), (14, 10, 1), (15, 11, 1),
               (16, 11, 1), (15, 12, 1), (16, 12, 1)]
        # agg:core links
        a_c = [(13, 17, 2), (14, 17, 1), (13, 18, 1), (14, 18, 2), (15, 17, 2),
               (16, 17, 1), (15, 18, 1), (16, 18, 2)]

        for link in h_e + e_a + a_c:
            print(link)
            net.add_link(*link)
        return net