Ejemplo n.º 1
0
 def _route(self, req, **kwargs):
     srcdpid=dpid_lib.str_to_dpid(kwargs['srcdpid'])
     srcport=port_no_lib.str_to_port_no(kwargs['srcport'])
     dstdpid=dpid_lib.str_to_dpid(kwargs['dstdpid'])
     dstport=port_no_lib.str_to_port_no(kwargs['dstport'])
     links = get_link(self.topology_api_app, None)
     
     topology = nx.MultiDiGraph()
     for link in links:
         print link
         topology.add_edge(link.src.dpid, link.dst.dpid, src_port=link.src.port_no, dst_port=link.dst.port_no)
     
     try:    
         shortest_path = nx.shortest_path(topology, srcdpid, dstdpid)
     except (nx.NetworkXError, nx.NetworkXNoPath):
         body = json.dumps([])
         print "Error"
         return Response(content_type='application/json', body=body)
         
     ingressPort = NodePortTuple(srcdpid, srcport)
     egressPort = NodePortTuple(dstdpid, dstport)
     route = []
     route.append(ingressPort)
     
     for i in range(0, len(shortest_path)-1):
         link = topology[shortest_path[i]][shortest_path[i+1]]
         index = randrange(len(link))
         dstPort = NodePortTuple(shortest_path[i], link[index]['src_port'])
         srcPort = NodePortTuple(shortest_path[i+1], link[index]['dst_port'])
         route.append(dstPort)
         route.append(srcPort)
         
     route.append(egressPort)
     body = json.dumps([hop.to_dict() for hop in route])
     return Response(content_type='application/json', body=body)
Ejemplo n.º 2
0
 def get_topology_data(self, ev):
     switch_list = get_switch(self.topology_api_app, None)  
     switches=[switch.dp.id for switch in switch_list]
     self.net.add_nodes_from(switches)
     
     #print "**********List of switches"
     #for switch in switch_list:
       #self.ls(switch)
       #print switch
     #  self.nodes[self.no_of_nodes] = switch
     #  self.no_of_nodes += 1
    
     links_list = get_link(self.topology_api_app, None)
     #print links_list
     #links=[(link.src.dpid,link.dst.dpid,port=link.src.port_no) for link in links_list]
     #print links
     #self.net.add_edges_from(links)
     #links=[(link.dst.dpid,link.src.dpid,port=link.dst.port_no) for link in links_list]
     #print links
     #self.net.add_edges_from(links)
     for link in links_list:
         if (link.src.dpid,link.dst.dpid,link.src.port_no) not in list(self.net.edges_iter(data='port')):
             self.net.add_edge(link.src.dpid,link.dst.dpid,port=link.src.port_no)
         if (link.dst.dpid,link.src.dpid,link.dst.port_no) not in list(self.net.edges_iter(data='port')):
             self.net.add_edge(link.dst.dpid,link.src.dpid,port=link.dst.port_no)
     print "List of links"
     print self.net.edges(data=True, keys=True)
    def get_topology_data(self):
        if not self.topo_stable:
            return 
        self.topo_stable = False
        print 'get_topoloty_data'
        self.switch_list = get_switch(self.topology_api_app, None)
        self.mSwitches   = [switch.dp.id for switch in self.switch_list] # switch.dp.id
        self.mDataPaths  = [switch.dp for switch in self.switch_list]
        print type(self.mDataPaths[0])
        self.links_list = get_link(self.topology_api_app, None)
        self.links = [(1, link.src.dpid, link.dst.dpid, link.src.port_no, link.dst.port_no) for link in self.links_list]
        self.links.sort()
        # print 'links       : ', self.links
        print '\n\nlinks:'
        for lk in self.links:
            print 'switch ', lk[1], ', port ', lk[3],  '--> switch ', lk[2], ', port', lk[4] 
        print 'switches    : ', self.mSwitches
        self.constructing_stp_krustal()

        # Delete all flows in all datapaths
        for dpid in self.mSwitches:
            self.delete_flow(dpid)
        # Install new flows
        for block in self.ports_to_block:
            if block in self.ports_to_enable:
                continue
            dpid = block[0]
            port = block[1]
            self.block_port(dpid, port)
       # for enable in self.ports_to_enable:
       #     pass
        self.start_learning = True
Ejemplo n.º 4
0
    def get_topology_data(self, ev):
	switch_list = get_switch(self.topology_api_app, None)
	switches=[switch.dp.id for switch in switch_list]
	links_list = get_link(self.topology_api_app, None)
	links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
	print links
	print switches
Ejemplo n.º 5
0
 def _links(self, req, **kwargs):
     dpid = None
     if 'dpid' in kwargs:
         dpid = dpid_lib.str_to_dpid(kwargs['dpid'])
     links = get_link(self.topology_api_app, dpid)
     body = json.dumps([link.to_dict() for link in links])
     return Response(content_type='application/json', body=body)
Ejemplo n.º 6
0
 def get_topology_data(self,ev):
     switch_list = get_switch(self.topology_api_app, None)
     switches = [switch.dp.id for switch in switch_list]
     links_list = get_link(self.topology_api_app, None)
     links = [(link.src.dpid, link.dst.dpid, {'port':(link.src.hw_addr,link.dst.hw_addr)}) for link in links_list]
     print len(switches)
     print "total links",len(links)
Ejemplo n.º 7
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        in_port = msg.match['in_port']
        dpid = datapath.id
        ports = [int(link.to_dict()['src']['port_no'], 16)
                 for link in get_link(self, dpid)]

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocol(ethernet.ethernet)
        src = eth.src
        dst = eth.dst
        time_now = time.time()

        if in_port not in ports:
            self.hosts[src] = {'dpid': dpid, 'time': time_now}

        if eth.ethertype == 0x0806:  # ARP packet
            arp_p = pkt.get_protocol(arp.arp)
            if arp_p.src_mac != '00:00:00:00:00:00':
                self.arp[arp_p.src_mac] = {'dpid': dpid, 'ip': arp_p.src_ip,
                                           'time': time_now}
            if arp_p.dst_mac != '00:00:00:00:00:00':
                self.arp[arp_p.dst_mac] = {'dpid': dpid, 'ip': arp_p.dst_ip,
                                           'time': time_now}
        elif eth.ethertype == 0x0800:  # IPv4 packet
            ip_p = pkt.get_protocol(ipv4.ipv4)
            if ip_p.proto == 17:
                udp_p = pkt.get_protocol(udp.udp)
                if udp_p.dst_port == 67 and udp_p.src_port == 68:  # DHCP
                    return
            self.arp[src] = {'dpid': dpid, 'ip': ip_p.src, 'time': time_now}
            self.arp[dst] = {'dpid': dpid, 'ip': ip_p.dst, 'time': time_now}
    def _switch_enter_handler(self, ev):
        # get_switch(self, None) outputs the list of switches object.
        self.topo_switches = get_switch(self, None)
        # get_link(self, None) outputs the list of links object.
        self.topo_links = get_link(self, None)

        """
        Now you have saved the links and switches of the topo. But they are object, we need to use to_dict() to trans them  
        """
        # print '*'*40,"Switch_set",'*'*40
        for switch in self.topo_switches:
            dp = switch.dp
            dp_no = dpid_to_str(dp.id)
            if (Switch_set.has_key(dp_no) == False):
                ports = switch.ports
                Switch_set[dp_no] = [port.to_dict() for port in ports]
        # pprint.pprint(Switch_set)
        Switch_set_json = json.dumps(Switch_set, indent=4)
        Ssj_file = open('./Info/Static/Switch_json.json','w+')
        Ssj_file.write(Switch_set_json)
        Ssj_file.close()

        # print '*'*40,"Link_set",'*'*40
        Link_set = [ link.to_dict() for link in self.topo_links ]
        # pprint.pprint(Link_set)
        Link_set_json = json.dumps(Link_set, indent=4)
        Lsj_file = open('./Info/Static/Link_json.json','w+')
        Lsj_file.write(Link_set_json)
        Lsj_file.close()
        self.logger.info("******_switch_enter_handler, Switch_set & Link_set******")
Ejemplo n.º 9
0
    def get_topology_data(self, ev):
        switch_list = get_switch(self.topology_data_app, None)
        switches = [switch.dp.id for switch in switch_list]
        self.net.add_nodes_from(switches)

        with open(OFP_LINK_PORT, 'w') as outp:
            # src_dpid dst_dpid src_dpid_output_port dst_dpid_input_port
            links_list = get_link(self.topology_data_app, None)
            # print links_list

            # add link from one direction
            links = [(self._hostname_Check(link.src.dpid), self._hostname_Check(link.dst.dpid),
                      {'out_port': link.src.port_no})
                     for link in links_list]
            # print links
            self.net.add_edges_from(links)
            for link in links:
                outp.write("%s %s %s\n" % (self._hostname_Check(link[0]),
                                           self._hostname_Check(link[1]), link[2]['out_port']))

            # add links from oppsite direction
            links = [(link.dst.dpid, link.src.dpid,
                      {'out_port': link.dst.port_no}) for link in links_list]
            # print links
            self.net.add_edges_from(links)
            for link in links:
                outp.write("%s %s %s\n" % (self._hostname_Check(link[0]),
                                           self._hostname_Check(link[1]), link[2]['out_port']))
    def get_topology_data(self, ev):
        self.logger.info("get_topology_data()")
        self._update_switch_dpid_list()
        switch_list = get_switch(self.topology_data_app, None)
        switches = [switch.dp.id for switch in switch_list]
        # print "switches: ", switches
        self.net.add_nodes_from(switches)

        # print "~~~~~ FRONT ~~~~~~~"
        # print "switches:", [self._hostname_Check(s) for s in switches]
        # print "self.link_port: ", self.link_port
        # print "self.net.nodes():", self.net.nodes()
        # print "self.net.edges():", self.net.edges()

        # print "net nodes: ", self.net.nodes()
        for node in self.net.nodes():
            self.link_port.setdefault(node, {})

        # with open(OFP_LINK_PORT, 'w') as outp:
            # src_dpid dst_dpid src_dpid_output_port dst_dpid_input_port
        links_list = get_link(self.topology_data_app, None)
        # print "links_list: ", links_list

        # add link from one direction
        links = [(link.src.dpid, link.dst.dpid,
                  {'out_port': link.src.port_no}) for link in links_list]
        # print "links:", links
        self.net.add_edges_from(links)
        for link in links:
            # self.logger.info("%s %s %s\n" % (self._hostname_Check(link[0]),
            #                                  self._hostname_Check(link[1]), link[2]['out_port']))
            # self.logger.info("%s %s %s\n" % (link[0], link[1], link[2]['out_port']))
            # outp.write("%s %s %s\n" % (link[0], link[1], link[2]['out_port']))
            self.link_port[link[0]][link[1]] = link[2]['out_port']
Ejemplo n.º 11
0
 def get_topology(self, ev):
     switch_list = get_switch(self.topology_api_app, None)
     self.create_port_map(switch_list)
     self.switches = self.switch_port_table.keys()
     links = get_link(self.topology_api_app, None)
     self.create_inter_links(links)
     self.create_access_ports()
     self.get_graph(self.link_to_port.keys())
Ejemplo n.º 12
0
    def topology(self):
        #TODO add the topology collecting periodically
        self.edgenum=0
        start = time.time()
        print start
        self.switches = get_switch(self)
        self.links = get_link(self)
        self.topo_col_num = self.topo_col_num + 1
        end = time.time()
        print end
        print 'topology collecting time:'
        print end-start
        self.topo_col_period = self.topo_col_period + end-start

        #n=len(self.switches)
        #m=len(self.links)
##        self.startnum=0
##        self.dpids_to_nums={}
##        self.nums_to_dpids={}
        print 'dpids nums:'
        for switch in self.switches:#TODO this may has error
            if self.dpids_to_nums.get(switch.dp.id)==None:
                self.nums_to_dpids[self.startnum] = switch.dp.id
                self.dpids_to_nums[switch.dp.id] = self.startnum
                print str(switch.dp.id)+' '+str(self.startnum)
                self.startnum = self.startnum + 1
        print self.dpids_to_nums
        self.n=self.startnum
        print 'edges:'
        self.linkgraph=[]
        for i in xrange(self.switch_num):
            self.linkgraph.append([])
            for j in xrange(self.switch_num):
                self.linkgraph[i].append(0)
        for link in self.links:
            self.edgenum=self.edgenum+1
            srcnum = self.dpids_to_nums[link.src.dpid]
            dstnum = self.dpids_to_nums[link.dst.dpid]
            self.linkgraph[srcnum][dstnum]=1
            if self.graph[srcnum][dstnum]==0 and self.graph[dstnum][srcnum]==0:
                print str(srcnum)+' '+str(dstnum)
                self.dpid_to_port[(link.src.dpid, link.dst.dpid)] = (link.src.port_no, link.dst.port_no)
                self.dpid_to_port[(link.dst.dpid, link.src.dpid)]=(link.dst.port_no, link.src.port_no)
                #print>>devicegraph, str(srcnum)+' '+str(dstnum)
                self.graph[srcnum][dstnum] = 1
                self.graph[dstnum][srcnum] = 1
                self.undirected[srcnum][dstnum] = 1
                self.m=self.m+1
        self.G={}
        for i in xrange(self.switch_num):
            self.G[i]={}
            for j in xrange(self.switch_num):
                if self.linkgraph[i][j]==1 and self.linkgraph[j][i]==1:#TODO if only one way is ok then regard it as not ok
                    self.G[i][j]=1
        print self.G
        print self.linkgraph
        print self.graph
        print self.undirected
    def linkDeleteHandler(self, ev):
        link_list = get_link(self.topology_api_app, None)        
	self.debugfile.write("linkdelete events happened"+"\n")
	self.debugfile.flush()
        for link in link_list:
            self.debugfile.write(str(link)+"\n")
	    self.debugfile.flush()
	self.debugfile.write("the time is: "+str(time.time())+"\n")
	self.debugfile.flush()
Ejemplo n.º 14
0
 def get_topology_data(self, ev):
     switch_list = get_switch(self.my_topology_api_app, None)
     all_switches = [switch.dp.id for switch in switch_list]
     # links_list = get_link(self.topology_api_app, None)
     links_list = get_link(self.my_topology_api_app)
     links = [(link.src.dpid, link.dst.dpid,
               {'port': link.src.port_no}) for link in links_list]
     print ">> switches: ", all_switches
     print ">> links: ", links
Ejemplo n.º 15
0
 def get_topology(self, ev):
     switch_list = get_switch(self.topology_api_app, None)
     self.create_port_map(switch_list)
     self.switches = self.switch_port_table.keys()
     links = get_link(self.topology_api_app, None)
     self.create_interior_links(links)
     self.create_access_ports()
     self.get_graph(self.link_to_port.keys())
     self.shortest_paths = self.all_k_shortest_paths(
         self.graph, weight='weight', k=CONF.k_paths)
Ejemplo n.º 16
0
 def _new_link_event(self, ev):
     
     LOG.info('TOPO_EVENT: New link detected %s -> %s', ev.link.src.dpid, ev.link.dst.dpid)
     
     link_list = get_link(self.topology_api_app, None)
     links = [(link.src.dpid, link.dst.dpid, {'port':link.src.port_no, 'weight':self.DEF_EDGE_WEIGHT}) for link in link_list]
     self.net.add_edges_from(links)
     
     print '****List of links:'
     print links
Ejemplo n.º 17
0
 def get_topology(self, ev):
     print("HELLOOOOOO WORLD")
     switch_list = copy.copy(get_switch(self, None))
     links = copy.copy(get_link(self, None))
     edges_list=[]
     for link in links:
         src = link.src
         dst = link.src
         edges_list.append((src.dpid, dst.dpid, {'port': link.src.port_no}))
     print(links)
Ejemplo n.º 18
0
 def get_topology_data(self, ev):
     switch_list = get_switch(self.topology_api_app, None)
     switches = [switch.dp.id for switch in switch_list]
     link_list = get_link(self.topology_api_app, None)
     self.net.add_nodes_from(switches)
     links=[(link.src.dpid,link.dst.dpid,
             {'port':link.src.port_no}) for link in links_list]
     self.ned_add_edges_from(links)
     self.logger.info('******************************** List of links')
     self.logger.info(self.net.edges())
Ejemplo n.º 19
0
 def get_topology_data(self, ev):
     print "Beep!"
     switch_list = get_switch(self.topology_api_app, None)
     switches = [switch.dp.id for switch in switch_list]
     links_list = get_link(self.topology_api_app, None)
     links = [(link.src.dpid, link.dst.dpid, {'port': link.src.port_no}) for link in links_list]
     # host_list = get_host(self.topology_api_app, None)
     # hosts = [host.dp.id for host in host_list]
     # print i
     print switches
     print links
Ejemplo n.º 20
0
    def get_topology_data(self, ev):
         switch_list = get_switch(self.topology_api_app, None)
         self.switches=[switch.dp.id for switch in switch_list]
         print '************Switch List*********************'
#         print self.switches
         links_list = get_link(self.topology_api_app, None)
         self.links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
         self.switches_nodes=[switch.dp for switch in switch_list]
         
         self.net.add_nodes_from(self.switches)
         self.net.add_edges_from(self.links)
    def get_topology_data(self,ev):
        time.sleep(0.01)
        switch_list = get_switch(self.topology_api_app, None)
        switches=[switch.dp.id for switch in switch_list]
        self.net.add_nodes_from(switches)
        links_list = get_link(self.topology_api_app, None)
        links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
        self.net.add_edges_from(links)
        links=[(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list]
        self.net.add_edges_from(links)
        print "**********List of links"
        print self.net.edges()
	'''while(self.limit>0):
    def get_topology_data(self, ev):
        switch_list = get_switch(self.topology_api_app, None)   
        switches=[switch.dp.id for switch in switch_list]
        self.net.add_nodes_from(switches)

        links_list = get_link(self.topology_api_app, None)
        #print links_list
        links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
        #print links
        self.net.add_edges_from(links)
        links=[(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list]
        #print links
        self.net.add_edges_from(links)
Ejemplo n.º 23
0
    def get_topology(self, ev):
        switch_list = get_switch(self.topology_api_app, None)
	#for val in switch_list:
	 #     self.file1.write("switch_list "+str(val)+"\n")

        self.create_port_map(switch_list)
        self.switches = self.switch_port_table.keys()
        links = get_link(self.topology_api_app, dpid=None)

	#self.file1.write("links "+str(links)+"\n")

        self.create_interior_links(links)
        self.create_access_ports()
        self.get_graph(self.link_to_port.keys())
Ejemplo n.º 24
0
    def get_topology(self, ev):
        # get switches and store them into self.network
        switch_list = get_switch(self.topology_api_app, None)   
        switches=[switch.dp.id for switch in switch_list]
        self.network.add_nodes_from(switches)
    
        # get links and store them into self.network
        links_list = get_link(self.topology_api_app, None)
        links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
        self.network.add_edges_from(links)

        # reverse link.
        links=[(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list]
        self.network.add_edges_from(links)
Ejemplo n.º 25
0
    def _get_sws_links(self):

        sws_list = get_switch(self, None)
        sws = [switch.dp.id for switch in sws_list]

        links_list = get_link(self, None)

        links = []
        for link in links_list:
            links.append({'src': link.src.dpid,
                          'dst': link.dst.dpid,
                          'port': link.dst.port_no})

        return sws, links
Ejemplo n.º 26
0
    def get_topology(self, ev):
        switch_list = get_switch(self.topology_api_app, None)	
        self.switches = [switch.dp.id for switch in switch_list]
	print "--------------------------the num of switches is %d---------------------------------------" %len(self.switches)
	print self.switches
	links_list = get_link(self.topology_api_app, None)
	links = [(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list] 
	#print links  
	if len(self.switches) == 26:
            #self.switches = self.switch_port_table.keys()
            #links = get_link(self.topology_api_app, None)
	    self.create_port_map(switch_list)
            self.create_interior_links(links_list)
            self.create_access_ports()
            #self.get_graph(self.link_to_port.keys())	
	    self.get_graph(self.link_to_port.keys())
Ejemplo n.º 27
0
    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()
Ejemplo n.º 28
0
    def get_topology_data(self):
        self.threadLock.acquire()

        #Delay a second for the LLDP to propagate
        time.sleep(1)

        switch_list = get_switch(self, None)
        GlobalTables.switch_list = [switch.dp.id for switch in switch_list]
        links_list = get_link(self, None)
        GlobalTables.sw_links = [(link.src.dpid, link.dst.dpid, {'port': link.src.port_no}) for link in links_list]

        self.threadLock.release()

        self.logger.info("sw_links: %s", GlobalTables.sw_links)
        self.logger.info("hosts: %s", GlobalTables.hosts)
        self.logger.info("mac_to_port: %s", GlobalTables.mac_to_port)
Ejemplo n.º 29
0
    def datapath_change_handler(self, ev):

        if ev.enter:
            print "Datapath entered, id %s" % ev.dp.id
            switch = api.get_switch(self, ev.dp.id)[0]
            self.switches.append(switch)
            ports = switch.ports

            print "Switch : %s" % switch
            print "Ports :"
            for port in ports:
                print port.to_dict()

            print "Links :"
            links = api.get_link(self, ev.dp.id)
            for link in links:
                print link.to_dict()
Ejemplo n.º 30
0
 def get_topology_data(self):
     if not self.topo_stable:
         return False
     self.topo_stable = False
     print 'Geting  topology data'
     self.switch_list = get_switch(self.topology_api_app, None)
     self.mSwitches   = [switch.dp.id for switch in self.switch_list] # switch.dp.id
     self.mDataPaths  = [switch.dp for switch in self.switch_list]
     # print type(self.mDataPaths[0])
     self.links_list = get_link(self.topology_api_app, None)
     self.links = [(1, link.src.dpid, link.dst.dpid, link.src.port_no, link.dst.port_no) for link in self.links_list]
     self.links.sort()
     print '\n\nlinks:'
     for lk in self.links:
         print 'switch ', lk[1], ', port ', lk[3],  '--> switch ', lk[2], ', port', lk[4]
     print '\nswitches    : ', self.mSwitches
     return True
Ejemplo n.º 31
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(array.array('B', msg.data))
        eth_pkt = pkt.get_protocol(ethernet.ethernet)
        arp_pkt = pkt.get_protocol(arp.arp)

        if arp_pkt:
            links = get_link(self, None)
            self.data = [link.to_dict() for link in links]
            for i in self.data:
                src = int(i['src']['dpid'], 16)
                dst = int(i['dst']['dpid'], 16)
                self.portmap.setdefault(src, {})
                self.portmap.setdefault(dst, {})
                self.portmap[src][dst] = int(i['src']['port_no'])
                self.portmap[dst][src] = int(i['dst']['port_no'])
                try:
                    self.graph[src][dst]
                except:
                    self.graph.add_weighted_edges_from([(src, dst,
                                                         self.default_weight)])

            # path calculation
            src = int(arp_pkt.src_ip.split('.')[-1])
            dst = int(arp_pkt.dst_ip.split('.')[-1])
            cur = datapath.id
            path = nx.shortest_path(self.graph, source=cur, target=dst)

            for i in xrange(len(path) - 1):
                src = path[i]
                dst = path[i + 1]

                # forward
                out_port = self.portmap[src][dst]
                self._add_dynamic_flow(self.datapaths[src],
                                       1,
                                       out_port,
                                       2048,
                                       nw_src=arp_pkt.src_ip,
                                       nw_dst=arp_pkt.dst_ip,
                                       soft_timeout=2)
                self._add_dynamic_flow(self.datapaths[src],
                                       1,
                                       out_port,
                                       2054,
                                       arp_spa=arp_pkt.src_ip,
                                       arp_tpa=arp_pkt.dst_ip,
                                       soft_timeout=2)

                # backward
                out_port = self.portmap[dst][src]
                self._add_dynamic_flow(self.datapaths[dst],
                                       1,
                                       out_port,
                                       2048,
                                       nw_src=arp_pkt.dst_ip,
                                       nw_dst=arp_pkt.src_ip,
                                       soft_timeout=2)
                self._add_dynamic_flow(self.datapaths[dst],
                                       1,
                                       out_port,
                                       2054,
                                       arp_spa=arp_pkt.dst_ip,
                                       arp_tpa=arp_pkt.src_ip,
                                       soft_timeout=2)

            src = path[0]
            dst = path[1]
            out_port = self.portmap[src][dst]
            actions = [parser.OFPActionOutput(out_port)]
            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)

        elif eth_pkt:
            if eth_pkt.dst.split(':')[1] == '00' and eth_pkt.src.split(
                    ':')[1] == '00':
                self.logger.info("packet in %s %s %s %s", datapath.id,
                                 eth_pkt.src, eth_pkt.dst, in_port)
                links = get_link(self, None)
                self.data = [link.to_dict() for link in links]
                for i in self.data:
                    src = int(i['src']['dpid'], 16)
                    dst = int(i['dst']['dpid'], 16)
                    self.portmap.setdefault(src, {})
                    self.portmap.setdefault(dst, {})
                    self.portmap[src][dst] = int(i['src']['port_no'])
                    self.portmap[dst][src] = int(i['dst']['port_no'])
                    try:
                        self.graph[src][dst]
                    except:
                        self.graph.add_weighted_edges_from([
                            (src, dst, self.default_weight)
                        ])

                # path calculation
                src = int(eth_pkt.src.split(':')[-1], 16)
                dst = int(eth_pkt.dst.split(':')[-1], 16)
                cur = datapath.id
                path = nx.dijkstra_path(self.graph, source=cur, target=dst)

                for i in xrange(len(path) - 1):
                    src = path[i]
                    dst = path[i + 1]

                    # forward
                    out_port = self.portmap[src][dst]
                    self._add_dynamic_flow(self.datapaths[src],
                                           1,
                                           out_port,
                                           None,
                                           eth_src=eth_pkt.src,
                                           eth_dst=eth_pkt.dst,
                                           soft_timeout=2)

                    # backward
                    out_port = self.portmap[dst][src]
                    self._add_dynamic_flow(self.datapaths[dst],
                                           1,
                                           out_port,
                                           None,
                                           eth_src=eth_pkt.dst,
                                           eth_dst=eth_pkt.src,
                                           soft_timeout=2)

                src = path[0]
                dst = path[1]
                out_port = self.portmap[src][dst]
                actions = [parser.OFPActionOutput(out_port)]
                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 _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
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        dst = eth.dst
        src = eth.src
        dpid_src = datapath.id

        # TOPOLOGY DISCOVERY------------------------------------------

        switch_list = get_switch(self.topology_api_app, None)
        switches = [switch.dp.id for switch in switch_list]
        if self.GLOBAL_VARIABLE == 0:
            for s in switches:
                for switch_port in range(1, NUMBER_OF_SWITCH_PORTS + 1):
                    self.port_occupied.setdefault(s, {})
                    self.port_occupied[s][switch_port] = 0
            self.GLOBAL_VARIABLE = 1
        self.net.add_nodes_from(switches)
        links_list = get_link(self.topology_api_app, None)
        links = [(link.src.dpid, link.dst.dpid, {
            'port': link.src.port_no
        }) for link in links_list]
        self.net.add_edges_from(links)
        links = [(link.dst.dpid, link.src.dpid, {
            'port': link.dst.port_no
        }) for link in links_list]
        self.net.add_edges_from(links)
        links_ = [(link.dst.dpid, link.src.dpid, link.dst.port_no)
                  for link in links_list]
        for l in links_:
            self.port_occupied[l[0]][l[2]] = 1

    # MAC LEARNING-------------------------------------------------

        self.mac_to_port.setdefault(dpid_src, {})
        self.port_to_mac.setdefault(dpid_src, {})
        self.mac_to_port[dpid_src][src] = in_port
        self.mac_to_dpid[src] = dpid_src
        self.port_to_mac[dpid_src][in_port] = src

        # HANDLE ARP PACKETS--------------------------------------------

        if eth.ethertype == ether_types.ETH_TYPE_ARP:
            arp_packet = pkt.get_protocol(arp.arp)
            arp_dst_ip = arp_packet.dst_ip
            arp_src_ip = arp_packet.src_ip
            # self.logger.info("It is an ARP packet")
            # If it is an ARP request
            if arp_packet.opcode == 1:
                # self.logger.info("It is an ARP request")
                if arp_dst_ip in self.ip_to_mac:
                    # self.logger.info("The address is inside the IP TO MAC table")
                    srcIp = arp_dst_ip
                    dstIp = arp_src_ip
                    srcMac = self.ip_to_mac[arp_dst_ip]
                    dstMac = src
                    outPort = in_port
                    opcode = 2
                    self.send_arp(datapath, opcode, srcMac, srcIp, dstMac,
                                  dstIp, outPort)
                    # self.logger.info("packet in %s %s %s %s", srcMac, srcIp, dstMac, dstIp)
                else:
                    # self.logger.info("The address is NOT inside the IP TO MAC table")
                    srcIp = arp_src_ip
                    dstIp = arp_dst_ip
                    srcMac = src
                    dstMac = dst
                    # learn the new IP address
                    self.ip_to_mac.setdefault(srcIp, {})
                    self.ip_to_mac[srcIp] = srcMac
                    # Send and ARP request to all the switches
                    opcode = 1
                    for id_switch in switches:
                        #if id_switch != dpid_src:
                        datapath_dst = get_datapath(self, id_switch)
                        for po in range(1,
                                        len(self.port_occupied[id_switch]) +
                                        1):
                            if self.port_occupied[id_switch][po] == 0:
                                outPort = po
                                if id_switch == dpid_src:
                                    if outPort != in_port:
                                        self.send_arp(datapath_dst, opcode,
                                                      srcMac, srcIp, dstMac,
                                                      dstIp, outPort)
                                else:
                                    self.send_arp(datapath_dst, opcode, srcMac,
                                                  srcIp, dstMac, dstIp,
                                                  outPort)

            else:
                srcIp = arp_src_ip
                dstIp = arp_dst_ip
                srcMac = src
                dstMac = dst
                if arp_dst_ip in self.ip_to_mac:
                    # learn the new IP address
                    self.ip_to_mac.setdefault(srcIp, {})
                    self.ip_to_mac[srcIp] = srcMac
                    # Send and ARP reply to the switch
                opcode = 2
                outPort = self.mac_to_port[self.mac_to_dpid[dstMac]][dstMac]
                datapath_dst = get_datapath(self, self.mac_to_dpid[dstMac])
                self.send_arp(datapath_dst, opcode, srcMac, srcIp, dstMac,
                              dstIp, outPort)

        # HANDLE IP PACKETS-----------------------------------------------

        ip4_pkt = pkt.get_protocol(ipv4.ipv4)
        if ip4_pkt:
            src_ip = ip4_pkt.src
            dst_ip = ip4_pkt.dst
            src_MAC = src
            dst_MAC = dst
            proto = str(ip4_pkt.proto)
            sport = "0"
            dport = "0"
            if proto == "6":
                tcp_pkt = pkt.get_protocol(tcp.tcp)
                sport = str(tcp_pkt.src_port)
                dport = str(tcp_pkt.dst_port)

            if proto == "17":
                udp_pkt = pkt.get_protocol(udp.udp)
                sport = str(udp_pkt.src_port)
                dport = str(udp_pkt.dst_port)

            self.logger.info(
                "Packet in switch: %s, source IP: %s, destination IP: %s, From the port: %s",
                dpid_src, src_ip, dst_ip, in_port)
            # self.logger.info("Packet in switch: %s, source MAC: %s, destination MAC: %s, From the port: %s", dpid_src, src, dst, in_port)

            datapath_dst = get_datapath(self, self.mac_to_dpid[dst_MAC])
            dpid_dst = datapath_dst.id
            self.logger.info(" --- Destination present on switch: %s",
                             dpid_dst)

            # Shortest path computation
            path = nx.shortest_path(self.net, dpid_src, dpid_dst)
            self.logger.info(" --- Shortest path: %s", path)

            # Set the flows for different cases
            if len(path) == 1:
                In_Port = self.mac_to_port[dpid_src][src]
                Out_Port = self.mac_to_port[dpid_dst][dst]
                actions_1 = [datapath.ofproto_parser.OFPActionOutput(Out_Port)]
                actions_2 = [datapath.ofproto_parser.OFPActionOutput(In_Port)]
                match_1 = parser.OFPMatch(in_port=In_Port, eth_dst=dst)
                match_2 = parser.OFPMatch(in_port=Out_Port, eth_dst=src)
                self.add_flow(datapath, 1, match_1, actions_1)
                self.add_flow(datapath, 1, match_2, actions_2)

                actions = [datapath.ofproto_parser.OFPActionOutput(Out_Port)]
                data = msg.data
                pkt = packet.Packet(data)
                eth = pkt.get_protocols(ethernet.ethernet)[0]
                # self.logger.info(" --- Changing destination mac to %s" % (eth.dst))
                pkt.serialize()
                out = datapath.ofproto_parser.OFPPacketOut(
                    datapath=datapath,
                    buffer_id=0xffffffff,
                    in_port=datapath.ofproto.OFPP_CONTROLLER,
                    actions=actions,
                    data=pkt.data)
                datapath.send_msg(out)

            elif len(path) >= 2:
                datapath_src = get_datapath(self, path[0])
                datapath_dst = get_datapath(self, path[len(path) - 1])
                dpid_src = datapath_src.id
                #self.logger.info("dpid_src  %s", dpid_src)
                dpid_dst = datapath_dst.id
                #self.logger.info("dpid_dst  %s", dpid_dst)
                In_Port_src = self.mac_to_port[dpid_src][src]
                #self.logger.info("In_Port_src  %s", In_Port_src)
                In_Port_dst = self.mac_to_port[dpid_dst][dst]
                #self.logger.info("In_Port_dst  %s", In_Port_dst)
                Out_Port_src = self.net[path[0]][path[1]]['port']
                #self.logger.info("Out_Port_src  %s", Out_Port_src)
                Out_Port_dst = self.net[path[len(path) - 1]][path[len(path) -
                                                                  2]]['port']
                #self.logger.info("Out_Port_dst  %s", Out_Port_dst)

                actions_1_src = [
                    datapath.ofproto_parser.OFPActionOutput(Out_Port_src)
                ]
                match_1_src = parser.OFPMatch(in_port=In_Port_src,
                                              eth_type=0x0800,
                                              ipv4_src=src_ip,
                                              ipv4_dst=dst_ip)
                self.add_flow(datapath_src, 1, match_1_src, actions_1_src)

                actions_2_src = [
                    datapath.ofproto_parser.OFPActionOutput(In_Port_src)
                ]
                match_2_src = parser.OFPMatch(in_port=Out_Port_src,
                                              eth_type=0x0800,
                                              ipv4_src=dst_ip,
                                              ipv4_dst=src_ip)
                self.add_flow(datapath_src, 1, match_2_src, actions_2_src)
                self.logger.info("Install the flow on switch %s", path[0])

                actions_1_dst = [
                    datapath.ofproto_parser.OFPActionOutput(Out_Port_dst)
                ]
                match_1_dst = parser.OFPMatch(in_port=In_Port_dst,
                                              eth_type=0x0800,
                                              ipv4_src=dst_ip,
                                              ipv4_dst=src_ip)
                self.add_flow(datapath_dst, 1, match_1_dst, actions_1_dst)

                actions_2_dst = [
                    datapath.ofproto_parser.OFPActionOutput(In_Port_dst)
                ]
                match_2_dst = parser.OFPMatch(in_port=Out_Port_dst,
                                              eth_type=0x0800,
                                              ipv4_src=src_ip,
                                              ipv4_dst=dst_ip)
                self.add_flow(datapath_dst, 1, match_2_dst, actions_2_dst)
                self.logger.info("Install the flow on switch %s",
                                 path[len(path) - 1])

                if len(path) > 2:
                    for i in range(1, len(path) - 1):
                        self.logger.info("Install the flow on switch %s",
                                         path[i])
                        In_Port_temp = self.net[path[i]][path[i - 1]]['port']
                        Out_Port_temp = self.net[path[i]][path[i + 1]]['port']
                        dp = get_datapath(self, path[i])
                        actions_1 = [
                            dp.ofproto_parser.OFPActionOutput(Out_Port_temp)
                        ]
                        actions_2 = [
                            dp.ofproto_parser.OFPActionOutput(In_Port_temp)
                        ]
                        match_1 = parser.OFPMatch(in_port=In_Port_temp,
                                                  eth_type=0x0800,
                                                  ipv4_src=src_ip,
                                                  ipv4_dst=dst_ip)
                        match_2 = parser.OFPMatch(in_port=Out_Port_temp,
                                                  eth_type=0x0800,
                                                  ipv4_src=dst_ip,
                                                  ipv4_dst=src_ip)
                        self.add_flow(dp, 1, match_1, actions_1)
                        self.add_flow(dp, 1, match_2, actions_2)

            # Send the packet to the original switch
                path_port = self.net[path[0]][path[1]]['port']
                actions = [datapath.ofproto_parser.OFPActionOutput(path_port)]
                data = msg.data
                pkt = packet.Packet(data)
                eth = pkt.get_protocols(ethernet.ethernet)[0]
                # change the mac address of packet
                eth.src = self.ip_to_mac[src_ip]
                eth.dst = self.ip_to_mac[dst_ip]
                # self.logger.info(" --- Changing destination mac to %s" % (eth.dst))
                pkt.serialize()
                out = datapath.ofproto_parser.OFPPacketOut(
                    datapath=datapath,
                    buffer_id=0xffffffff,
                    in_port=datapath.ofproto.OFPP_CONTROLLER,
                    actions=actions,
                    data=pkt.data)
                datapath.send_msg(out)
Ejemplo n.º 33
0
 def get_topology_data(self, ev):
     switch_list = get_switch(self.topology_api_app, None)
     switches=[switch.dp.id for switch in switch_list]
     links_list = get_link(self.topology_api_app, None)
     links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
Ejemplo n.º 34
0
 def get_links(self, ev):
     links = get_link(self.topology_api_app, None)
     self.create_interior_links(links)
     self.create_access_ports()
     self.logger.info("*********************************************************************************************")
Ejemplo n.º 35
0
    def get_topology_data(self):
        """Topology Info Handling."""

        net_sp = nx.Graph()

        self.net = nx.DiGraph()

        switch_list = get_switch(self.topology_api_app, None)
        switches = [switch.dp.id for switch in switch_list]
        self.net.add_nodes_from(switches)

        net_sp.add_nodes_from(switches)

        for switch in switch_list:
            print switch.dp.id

        links_list = get_link(self.topology_api_app, None)

        links = [(link.src.dpid, link.dst.dpid, {
            'port': link.src.port_no
        }) for link in links_list]

        print links

        self.net.add_edges_from(links)

        links = [(link.dst.dpid, link.src.dpid, {
            'port': link.dst.port_no
        }) for link in links_list]
        self.net.add_edges_from(links)

        group = collection.Group('whole')
        group.topology = self.net
        group.switches = switches
        group.links = links

        links = [(link.src.dpid, link.dst.dpid) for link in links_list]
        net_sp.add_edges_from(links)
        constant.ccc = nx.minimum_spanning_tree(net_sp)

        data_collection.switch_inner_port = []
        for link in links_list:
            inner_port1 = (link.src.dpid, link.src.port_no)
            inner_port2 = (link.dst.dpid, link.dst.port_no)

            if inner_port1 not in data_collection.switch_inner_port:
                data_collection.switch_inner_port.append(inner_port1)
            if inner_port2 not in data_collection.switch_inner_port:
                data_collection.switch_inner_port.append(inner_port2)

        if data_collection.group_list.get('whole') is not None:
            # print 'a'
            g = data_collection.group_list.get('whole')

            g.switches = group.switches
            g.topology = group.topology
            g.links = group.links
            # print g.switches, g.topology, g.links
        else:
            # print 'b'
            data_collection.group_list.update({'whole': group})
Ejemplo n.º 36
0
	def _packet_in_handler(self, ev):
        
		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
		ofproto = datapath.ofproto
		parser = datapath.ofproto_parser
		in_port = msg.match['in_port']		

		pkt = packet.Packet(msg.data)
		eth = pkt.get_protocols(ethernet.ethernet)[0]

		if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
			return
		dst = eth.dst
		src = eth.src
		
		dpid_src = datapath.id
		
		# TOPOLOGY DISCOVERY------------------------------------------
		
		switch_list = get_switch(self.topology_api_app, None)   
		switches=[switch.dp.id for switch in switch_list]		
		self.net.add_nodes_from(switches)
		links_list = get_link(self.topology_api_app, None)
		links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
		self.net.add_edges_from(links)
		links=[(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list]
		self.net.add_edges_from(links)
		# print links
		
		# MAC LEARNING-------------------------------------------------
		
		self.mac_to_port.setdefault(dpid_src, {})
		self.mac_to_port.setdefault(src, {})
		self.port_to_mac.setdefault(dpid_src, {})
		self.mac_to_port[dpid_src][src] = in_port	
		self.mac_to_dpid[src] = dpid_src
		self.port_to_mac[dpid_src][in_port] = src
		self.logger.info("Packet in the controller from switch: %s", dpid_src)
		#print self.mac_to_port
		
		# HANDLE ARP PACKETS--------------------------------------------
		
		if eth.ethertype == ether_types.ETH_TYPE_ARP:
			arp_packet = pkt.get_protocol(arp.arp)
			arp_dst_ip = arp_packet.dst_ip
			arp_src_ip = arp_packet.src_ip
			# self.logger.info("ARP packet from switch: %s source IP: %s destination IP: %s from port: %s", dpid_src, arp_src_ip, arp_dst_ip, in_port)
			# self.logger.info("ARP packet from switch: %s source MAC: %s destination MAC:%s from port: %s", dpid_src, src, dst, in_port)
			
			if arp_dst_ip in self.ip_to_mac:
				if arp_packet.opcode == 1:
					# send arp reply (SAME SUBNET)
					dstIp = arp_src_ip
					srcIp = arp_dst_ip
					dstMac = src
					srcMac = self.ip_to_mac[arp_dst_ip]
					outPort = in_port
					opcode = 2 # arp reply packet
					self.send_arp(datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort)
			else:
				if arp_packet.opcode == 1:
					# send arp reply (GATEWAY)
					dstIp = arp_src_ip
					srcIp = arp_dst_ip
					dstMac = src
					srcMac = self.port_to_mac[dpid_src][in_port]
					outPort = in_port
					opcode = 2 # arp reply packet
					self.send_arp(datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort)
		
		# HANDLE IP PACKETS----------------------------------------------- 	
		
		ip4_pkt = pkt.get_protocol(ipv4.ipv4)
		if ip4_pkt:
			src_ip = ip4_pkt.src
			dst_ip = ip4_pkt.dst
			proto  = str(ip4_pkt.proto)
			sport = "0"
			dport = "0" 
			if proto == "6":
				tcp_pkt = pkt.get_protocol(tcp.tcp)
				sport = str(tcp_pkt.src_port)
				dport = str(tcp_pkt.dst_port)
			   
			if proto == "17":
				udp_pkt = pkt.get_protocol(udp.udp)
				sport = str(udp_pkt.src_port)
				dport = str(udp_pkt.dst_port)
				
			self.logger.info("Packet from the switch: %s, source IP: %s, destination IP: %s, From the port: %s", dpid_src, src_ip, dst_ip, in_port)
########################################################################################################################
			# PACKET CLASSIFICATION FUNCTION: it returns action: "allow" or "deny"
			# action_rule = self.linear_classification(src_ip, dst_ip, proto, sport, dport)
			action_rule = "allow"	
			
			if action_rule == "allow":			
				# IP LOOKUP FUNCTION: it is zero if it didn't find a solution
				destination_switch_IP = self.binary_trie_search(dst_ip)
########################################################################################################################
				if destination_switch_IP != "0":
					datapath_dst = get_datapath(self,int(self.switch[destination_switch_IP][DPID]))
					dpid_dst = datapath_dst.id			
					self.logger.info(" --- Destination present on switch: %s", dpid_dst)
					
					# Shortest path computation
					path = nx.shortest_path(self.net,dpid_src,dpid_dst)
					self.logger.info(" --- Shortest path: %s", path)
					
					if len(path) == 1:
						In_Port = self.mac_to_port[dpid_src][src]
						Out_Port = self.mac_to_port[dpid_dst][dst]	
						actions_1 = [datapath.ofproto_parser.OFPActionOutput(Out_Port)]
						actions_2 = [datapath.ofproto_parser.OFPActionOutput(In_Port)]
						match_1 = parser.OFPMatch(in_port=In_Port, eth_dst=dst)
						self.add_flow(datapath, 1, match_1, actions_1)

						actions = [datapath.ofproto_parser.OFPActionOutput(Out_Port)]
						data = msg.data
						pkt = packet.Packet(data)
						eth = pkt.get_protocols(ethernet.ethernet)[0]
						# self.logger.info(" --- Changing destination mac to %s" % (eth.dst))
						pkt.serialize()
						out = datapath.ofproto_parser.OFPPacketOut(
							datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER,
							actions=actions, data=pkt.data)
						datapath.send_msg(out)
						
						
					elif len(path) == 2:				
						path_port = self.net[path[0]][path[1]]['port']
						actions = [datapath.ofproto_parser.OFPActionOutput(path_port)]
						data = msg.data
						pkt = packet.Packet(data)
						eth = pkt.get_protocols(ethernet.ethernet)[0]
						eth.src = self.ip_to_mac[src_ip] 
						eth.dst = self.ip_to_mac[dst_ip] 
						# self.logger.info(" --- Changing destination mac to %s" % (eth.dst))
						pkt.serialize()
						out = datapath.ofproto_parser.OFPPacketOut(
						datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER,
							actions=actions, data=pkt.data)
						datapath.send_msg(out)	
						
					elif len(path) > 2:
						# Add flows in the middle of the network path 
						for i in range(1, len(path)-1):							
							In_Port = self.net[path[i]][path[i-1]]['port']
							Out_Port = self.net[path[i]][path[i+1]]['port']
							dp = get_datapath(self, path[i])
							# self.logger.info("Matched OpenFlow Rule = switch: %s, from in port: %s, to out port: %s, source IP: %s, and destination IP: %s", path[i], In_Port, Out_Port, src_ip, dst_ip)
						
							actions_1 = [dp.ofproto_parser.OFPActionOutput(Out_Port)]
							match_1 = parser.OFPMatch(in_port=In_Port, eth_type = 0x0800, ipv4_src=src_ip, ipv4_dst=dst_ip)
							self.add_flow(dp, 1, match_1, actions_1)
						
						path_port = self.net[path[0]][path[1]]['port']
						actions = [datapath.ofproto_parser.OFPActionOutput(path_port)]
						data = msg.data
						pkt = packet.Packet(data)
						eth = pkt.get_protocols(ethernet.ethernet)[0]
						# change the mac address of packet
						eth.src = self.ip_to_mac[src_ip] 
						eth.dst = self.ip_to_mac[dst_ip] 
						# self.logger.info(" --- Changing destination mac to %s" % (eth.dst))
						pkt.serialize()
						out = datapath.ofproto_parser.OFPPacketOut(
						datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER,
							actions=actions, data=pkt.data)
						datapath.send_msg(out)
Ejemplo n.º 37
0
            out_port = p[0][2]
        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, eth_src=src, eth_dst=dst)
        
        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)
    
    @set_ev_cls(event.EventSwitchEnter)
    def get_topology_data(self, ev):
        global switches
        switch_list = get_switch(self.topology_api_app, None)  
        switches=[switch.dp.id for switch in switch_list]
        self.datapath_list=[switch.dp for switch in switch_list]
        #print "self.datapath_list=", self.datapath_list
        print "switches=", switches
        links_list = get_link(self.topology_api_app, None)
        mylinks=[(link.src.dpid,link.dst.dpid,link.src.port_no,link.dst.port_no) for link in links_list]
    
        for s1,s2,port1,port2 in mylinks:
            adjacency[s1][s2]=port1
            adjacency[s2][s1]=port2
            #print s1,s2,port1,port2
Ejemplo n.º 38
0
    def handler_switch_enter(self, ev):
        self.topo_shape.topo_raw_switches = copy.copy(get_switch(self, None))
        self.topo_shape.topo_raw_links = copy.copy(get_link(self, None))

        self.topo_shape.print_links("EventSwitchEnter")
        self.topo_shape.print_switches("EventSwitchEnter")
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch

        msg = ev.msg
        datapath = msg.datapath

        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        src = eth.src
        dst = eth.dst

        dpid = datapath.id


        self.S = list(set(self.S + [s.dp.id for s in get_switch(self, None)]))
        self.L = list(set(self.L + [(l.src.dpid, l.dst.dpid, l.src.port_no) for l in get_link(self, None)]))

        if self.tr_send_time<time.time():
            self.trac_send()

        if self.tr_start_time>0 and time.time()-self.tr_start_time>1:
            self.tr_result=False
            self.trac()

        if dpid in self.fe and len([0 for a in self.fe[dpid] if a[0]==in_port and a[1]==dst])>0:
            pkt_ipv4=pkt.get_protocol(ipv4.ipv4)
            if pkt_ipv4 and pkt_ipv4.src=='10.7.10.7':
                self.tr_result=True
                self.trac()
            return


        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)

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            return

        if src[:2] != '00' and dst[:2] != '00':
            return

        
        self.mac_to_port.setdefault(dpid, {})

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][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:

            self.add_flow_path(dpid, src, dst)

            match = parser.OFPMatch(in_port=in_port, eth_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 event_switch_enter_handler(self, ev):
     self.switch = [s.dp.id for s in get_switch(self, None)]
     self.link = [(l.src.dpid, l.dst.dpid, {'port': l.src.port_no}) for l in get_link(self, None)]
Ejemplo n.º 41
0
    def topology(self):
        #TODO add the topology collecting periodically
        self.edgenum = 0
        start = time.time()
        print start
        self.switches = get_switch(self)
        self.links = get_link(self)
        self.topo_col_num = self.topo_col_num + 1
        end = time.time()
        print end
        print 'topology collecting time:'
        print end - start
        self.topo_col_period = self.topo_col_period + end - start

        #n=len(self.switches)
        #m=len(self.links)
        ##        self.startnum=0
        ##        self.dpids_to_nums={}
        ##        self.nums_to_dpids={}
        print 'dpids nums:'
        for switch in self.switches:  #TODO this may has error
            if self.dpids_to_nums.get(switch.dp.id) == None:
                self.nums_to_dpids[self.startnum] = switch.dp.id
                self.dpids_to_nums[switch.dp.id] = self.startnum
                print str(switch.dp.id) + ' ' + str(self.startnum)
                self.startnum = self.startnum + 1
        print self.dpids_to_nums
        self.n = self.startnum
        print 'edges:'
        self.linkgraph = []
        for i in xrange(self.switch_num):
            self.linkgraph.append([])
            for j in xrange(self.switch_num):
                self.linkgraph[i].append(0)
        for link in self.links:
            self.edgenum = self.edgenum + 1
            srcnum = self.dpids_to_nums[link.src.dpid]
            dstnum = self.dpids_to_nums[link.dst.dpid]
            self.linkgraph[srcnum][dstnum] = 1
            if self.graph[srcnum][dstnum] == 0 and self.graph[dstnum][
                    srcnum] == 0:
                print str(srcnum) + ' ' + str(dstnum)
                self.dpid_to_port[(link.src.dpid,
                                   link.dst.dpid)] = (link.src.port_no,
                                                      link.dst.port_no)
                self.dpid_to_port[(link.dst.dpid,
                                   link.src.dpid)] = (link.dst.port_no,
                                                      link.src.port_no)
                #print>>devicegraph, str(srcnum)+' '+str(dstnum)
                self.graph[srcnum][dstnum] = 1
                self.graph[dstnum][srcnum] = 1
                self.undirected[srcnum][dstnum] = 1
                self.m = self.m + 1
        self.G = {}
        for i in xrange(self.switch_num):
            self.G[i] = {}
            for j in xrange(self.switch_num):
                if self.linkgraph[i][j] == 1 and self.linkgraph[j][
                        i] == 1:  #TODO if only one way is ok then regard it as not ok
                    self.G[i][j] = 1
        print self.G
        print self.linkgraph
        print self.graph
        print self.undirected
Ejemplo n.º 42
0
    def get_links(self):

        return list(get_link(self, None).keys())
Ejemplo n.º 43
0
 def handler_switch_enter(self, ev):
     for link in copy.copy(get_link(self)):
         self.link_repository.register_link(link.src.dpid, link.src.port_no,
                                            link.dst.dpid, link.dst.port_no)
Ejemplo n.º 44
0
    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
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return
        dst = eth.dst
        src = eth.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        #self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        self.i = self.i + 1
        if self.i == 500:
            host_list = get_host(self, None)
            hosts = [host.mac for host in host_list]
            switch_list = get_switch(self, None)
            switches = [switch.dp.id for switch in switch_list]
            links_list = get_link(self, None)
            link_port = {(link.src.dpid, link.dst.dpid): link.src.port_no
                         for link in links_list}
            links = [(link.src.dpid, link.dst.dpid) for link in links_list]

            print('hosts: ', hosts)
            print('switches: ', switches)
            print('link_port: ', link_port)
            print('switch_links: ', links)

            output = subprocess.Popen([
                "/home/mininet/mininet/util/m", "h2", "iperf", "-c", "10.0.0.1"
            ],
                                      stdout=subprocess.PIPE,
                                      stdin=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
            string = str(output.communicate(input="mininet"))
            string = string[len(string) - 22:len(string) - 8]
            self.bw[("S1", "S2")] = string

            output = subprocess.Popen([
                "/home/mininet/mininet/util/m", "h3", "iperf", "-c", "10.0.0.1"
            ],
                                      stdout=subprocess.PIPE,
                                      stdin=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
            string = str(output.communicate(input="mininet"))
            string = string[len(string) - 22:len(string) - 8]
            self.bw[("S1", "S3")] = string

            output = subprocess.Popen([
                "/home/mininet/mininet/util/m", "h4", "iperf", "-c", "10.0.0.1"
            ],
                                      stdout=subprocess.PIPE,
                                      stdin=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
            string = str(output.communicate(input="mininet"))
            string = string[len(string) - 22:len(string) - 8]
            self.bw[("S1", "S4")] = string

            output = subprocess.Popen([
                "/home/mininet/mininet/util/m", "h5", "iperf", "-c", "10.0.0.1"
            ],
                                      stdout=subprocess.PIPE,
                                      stdin=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
            string = str(output.communicate(input="mininet"))
            string = string[len(string) - 22:len(string) - 8]
            self.bw[("S1", "S5")] = string

            output = subprocess.Popen([
                "/home/mininet/mininet/util/m", "h6", "iperf", "-c", "10.0.0.1"
            ],
                                      stdout=subprocess.PIPE,
                                      stdin=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
            string = str(output.communicate(input="mininet"))
            string = string[len(string) - 22:len(string) - 8]
            self.bw[("S1", "S6")] = string

            print self.bw

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][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, eth_dst=dst, eth_src=src)
            # 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)
Ejemplo n.º 45
0
 def getLinkPort(self, srcDpid, dstDpid):
     links = get_link(self)
     for link in links:
         if link.src.dpid == srcDpid and link.dst.dpid == dstDpid:
             return link.src.port_no
 def getLinksByDatapathID(self, dpid):
     """ Get datapath links by object ID """
     #dp = self.getDatapathByID(dpid)
     #link = get_link(self, dp.id)
     link = get_link(self, dpid)
     return link
Ejemplo n.º 47
0
	def _packet_in_handler(self, ev):
        
		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
		ofproto = datapath.ofproto
		parser = datapath.ofproto_parser
		in_port = msg.match['in_port']		

		pkt = packet.Packet(msg.data)
		eth = pkt.get_protocols(ethernet.ethernet)[0]

		if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
			return
		dst = eth.dst
		src = eth.src
		
		dpid_src = datapath.id
		
		# TOPOLOGY DISCOVERY------------------------------------------
		
		switch_list = get_switch(self.topology_api_app, None)   
		switches=[switch.dp.id for switch in switch_list]		
		self.net.add_nodes_from(switches)
		links_list = get_link(self.topology_api_app, None)
		links=[(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
		self.net.add_edges_from(links)
		links=[(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no}) for link in links_list]
		self.net.add_edges_from(links)
		# print links
		
		# MAC LEARNING-------------------------------------------------
		
		self.mac_to_port.setdefault(dpid_src, {})
		self.mac_to_port.setdefault(src, {})
		self.port_to_mac.setdefault(dpid_src, {})
		self.mac_to_port[dpid_src][src] = in_port	
		self.mac_to_dpid[src] = dpid_src
		self.port_to_mac[dpid_src][in_port] = src
		self.logger.info("Packet in the controller from switch: %s", dpid_src)
		#print self.mac_to_port
		
		# HANDLE ARP PACKETS--------------------------------------------
		
		if eth.ethertype == ether_types.ETH_TYPE_ARP:
			arp_packet = pkt.get_protocol(arp.arp)
			arp_dst_ip = arp_packet.dst_ip
			arp_src_ip = arp_packet.src_ip
			# self.logger.info("ARP packet from switch: %s source IP: %s destination IP: %s from port: %s", dpid_src, arp_src_ip, arp_dst_ip, in_port)
			# self.logger.info("ARP packet from switch: %s source MAC: %s destination MAC:%s from port: %s", dpid_src, src, dst, in_port)
			
			if arp_dst_ip in self.ip_to_mac:
				if arp_packet.opcode == 1:
					# send arp reply (SAME SUBNET)
					dstIp = arp_src_ip
					srcIp = arp_dst_ip
					dstMac = src
					srcMac = self.ip_to_mac[arp_dst_ip]
					outPort = in_port
					opcode = 2 # arp reply packet
					self.send_arp(datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort)
			else:
				if arp_packet.opcode == 1:
					# send arp reply (GATEWAY)
					dstIp = arp_src_ip
					srcIp = arp_dst_ip
					dstMac = src
					srcMac = self.port_to_mac[dpid_src][in_port]
					outPort = in_port
					opcode = 2 # arp reply packet
					self.send_arp(datapath, opcode, srcMac, srcIp, dstMac, dstIp, outPort)
		
		# HANDLE IP PACKETS----------------------------------------------- 	
		
		ip4_pkt = pkt.get_protocol(ipv4.ipv4)
		if ip4_pkt:
			src_ip = ip4_pkt.src
			dst_ip = ip4_pkt.dst
			proto  = str(ip4_pkt.proto)
			sport = "0"
			dport = "0" 
			if proto == "6":
				tcp_pkt = pkt.get_protocol(tcp.tcp)
				sport = str(tcp_pkt.src_port)
				dport = str(tcp_pkt.dst_port)
			   
			if proto == "17":
				udp_pkt = pkt.get_protocol(udp.udp)
				sport = str(udp_pkt.src_port)
				dport = str(udp_pkt.dst_port)
				
			self.logger.info("Packet from the switch: %s, source IP: %s, destination IP: %s, From the port: %s", dpid_src, src_ip, dst_ip, in_port)
#############################################################################################################################			
			





























			# PACKET CLASSIFICATION FUNCTION: it returns action: "allow" or "deny"
			#here we call our tree and function which were defined below of script 
			#class TREE and NODE are out of Class SIMPLEswitch
			#if here put code of call , the program will be called iteratively

			action_rule = self.linear_classification(src_ip, dst_ip, proto, sport, dport)
			#action_rule = "allow"	
			#keep in mind that u need follow the order of calling the function based on your f****n logic and script
			##############################################
			#last issue 30.03.20 how obtain all rule from finding_prefix	
			
			############################################## here handle F1 field source ip ################################
			

			

####################################################################################################
			
			print "proto of pkt", proto
			print "sport of pkt", sport
			print "dport of pkt", dport

			binn_scr_ip=fromIPtoBinary(src_ip)
			

			#here convert all set of SRC_ip into binary version and append them in nod[] vector 
			nod=[]
			for rule in self.classify:
				k=fromIPtoBinary_1(self.classify[rule][SRC_IP])
				nod.append(k)
			
			#here call Tree() which wrote below, in creation tree we put all brahches in list and after handle them in order to create tree
			f1=Tree()
			i=0
			while i<=len(nod[1]):
				k=0
				tupl=[]
				while k<len(nod):
					
					tupl.append(nod[k][:i])
					
					
					k+=1
				#this checks similar branches and delete the duplicates 	
				tupl=list(dict.fromkeys(tupl))
				for ke in tupl:
					#here we assign nodes 
					f1.add_node(str(ke))
				

				i+=1

			
			
			
			# here is important part for Set-prunning tree algoritm , we check if node is ancestor of another nodes and assign ancestor's rules to their children
			for rule in self.classify:
				
				for i in self.classify:
					if self.classify[i][SRC_IP] in self.classify[rule][SRC_IP]:
						#this is row to assign rule in Tree
						f1.add_rule(fromIPtoBinary_rule(self.classify[rule][SRC_IP]),0,i,None)
						


			#this is commented PrintTree function , just  to check the tree decommnet it and run
			
			#f1.print_tree(f1.root)

			#Here we search based on binary version of src_ip best prefix match in the Tree
			ff=f1.finding_prefix(src_ip,f1.root,0)
			#this is additional func just to clean duplicates
			ff=list(dict.fromkeys(ff))
			#here we see best prefix match
			print "\n\n\nBest prefix match for SRC_IP:",ff

		
			
			


################################## Destination of IP address  handling                 #######################################
			
			#Here we create vector nod2[] and append into this all binary version dst_ip 
			nod2=[]
			for rule in self.classify:
				k=fromIPtoBinary_1(self.classify[rule][DST_IP])
				nod2.append(k)

			f2=Tree()
			i=0
			while i<=len(nod2[1]):
				k=0
				tupl=[]
				while k<len(nod2):
					
					tupl.append(nod2[k][:i])
					
					
					k+=1
				#this checks similar branches and delete the duplicates 	
				tupl=list(dict.fromkeys(tupl))
				for ke in tupl:
					#here we assign nodes 
					f2.add_node(str(ke))
				

				i+=1


			for rule in self.classify:
				
				for i in self.classify:
					if self.classify[i][DST_IP] in self.classify[rule][DST_IP]:
						#this is row to assign rule in Tree
						f2.add_rule(fromIPtoBinary_rule(self.classify[rule][DST_IP]),0,i,None)



			ff2=f2.finding_prefix(dst_ip,f2.root,0)
			#this is additional func just to clean duplicates
			ff2=list(dict.fromkeys(ff2))
			#here we see best prefix match
			print "\n\n\nBest prefix match for DST_IP:",ff2
			




			
			
#############################################handling protocol of packet  filed 3 ######################################################
			#Here we conwert proto in binary
			bin_proto=str(bin(int(proto))[2:])
			
			#Here we convert all proto in rules into binary versions and append them in vector prep[]
			prep=[]
			for i in self.classify:
				prt=str(bin(int(self.classify[i][PROTO]))[2:])
				prep.append(prt)
			
			

			
			#here we "fix" binary version:we align them and made them similiar size it is neccesary to create Tree
			chunk3=[]
			for i in prep:
				chunk3.append(i.ljust(len( max(prep,key=len)),'0'))
			
			#Here we create third tree for Proto 
			f3=Tree()
			
			
			i=0
			while i<=len(chunk3[1]):
				k=0
				tupl=[]
				while k<len(chunk3):
					
					tupl.append(chunk3[k][:i])
					
					
					k+=1
				tupl=list(dict.fromkeys(tupl))
				for ke in tupl:
					
					
					f3.add_node(str(ke))
					
				

				i+=1





			for rule in sorted(self.classify):
				
				f3.add_rule(str(bin(int(self.classify[rule][PROTO]))[2:]),0,rule,None)
			#Here we also have print tree func for proto , it is neccessary to check the correctness of tree 
			#f3.print_tree(f3.root)
			
			#Here we find best prefix math for proto in Tree
			ff3=f3.finding_prefix_one(bin_proto,f3.root,0)
			
			print "Best prefix match for PROTO:", ff3

			

			




################################## source port of packet handling filed 4   #####################################################
			#here we handle source port of packet , the implementation a little bit different then for SRC,DST
			
			#Here we append all source port of rule in all_sport[] vector, we need it for further computation and creation the tree
			all_sport=[]
			
			for i in self.classify:
				
				all_sport.append(self.classify[i][SPORT])

			#here we clean duplicates	
			all_sport=list(dict.fromkeys(all_sport))
			

			
			#here we sort and append into data[ ] only non star=="*" source port , bcz "star" source port goes to root of the Tree 
			data=[]
			
			for i in all_sport:
				if i!="*":
					
					k=str(bin(int(i))[2:])
					data.append(k)
				
			
			#Here also we align all branches, we alligned them with zeros, and it doesnt impact to correctness of Tree
			same_sport=[]
			for i in data:
				
				same_sport.append(i.ljust(len( max(data,key=len)),'0'))
			
			#Here we create tree for source port and assign nodes
			f4=Tree()
			i=0
			while i<=len(same_sport[1]):
				k=0
				tupl=[]
				while k<len(same_sport):
					
					tupl.append(same_sport[k][:i])
					
					
					k+=1
				tupl=list(dict.fromkeys(tupl))
				for ke in tupl:
					
					f4.add_node(str(ke))
					
				
				i+=1

			
			#Here we assign rule regarding of set-prunning algorithm
			
			for rule in self.classify:
				for i in self.classify:
					if fromIPtoBinary_port(self.classify[i][SPORT]) in fromIPtoBinary_port(self.classify[rule][SPORT]):
						#assign the rule in the Tree 
						f4.add_rule(fromIPtoBinary_port(self.classify[rule][SPORT]),0,i,None)
						


			#Also here we have print tree check (commented), we need print tree func to check the correctness tree at each field
			#f4.print_tree(f4.root)
			

			#we convert source ip in binary and use finding prefix function to find best prefix match
			bin_sport=fromIPtoBinary_port(sport)

			fsport=f4.finding_prefix_one(bin_sport,f4.root,0)
			#here we clean duplicates, it occurs bcz in add_rule function we use iteration and append result into vector iteratively
			fsport=list(dict.fromkeys(fsport))
			print "Best prefix match S_PORT", fsport


			

			





########################################## destination port of packet :handling field 5############# handling destination port#################################
			#handlig for dest port the same as for source port
			all_dport=[]
			bin_dport=fromIPtoBinary_port(dport)
			for i in self.classify:
				
				all_dport.append(self.classify[i][DPORT])

			all_dport=list(dict.fromkeys(all_dport))
			

			
			data=[]
			
			for i in all_dport:
				if i!="*":
					
					k=str(bin(int(i))[2:])
					data.append(k)
				
			

			same_dport=[]
			for i in data:
				
				same_dport.append(i.ljust(len( max(data,key=len)),'0'))
			

			f5=Tree()
			i=0
			while i<=len(same_dport[1]):
				k=0
				tupl=[]
				while k<len(same_dport):
					
					tupl.append(same_dport[k][:i])
					
					
					k+=1
				tupl=list(dict.fromkeys(tupl))
				for ke in tupl:
					
					f5.add_node(str(ke))
					
				
#
				i+=1

			
			
			
			for rule in self.classify:
				for i in self.classify:
					if fromIPtoBinary_port(self.classify[i][DPORT]) in fromIPtoBinary_port(self.classify[rule][DPORT]):
						
						f5.add_rule(fromIPtoBinary_port(self.classify[rule][DPORT]),0,i,None)
						



			#f4.print_tree(f4.root)
			

			
			

			fdport=f5.finding_prefix_one(bin_dport,f5.root,0)
			fdport=list(dict.fromkeys(fdport))
			print "Best prefix match D_PORT:", fdport
			
###############################################################################################################################
			
			#Here we call set_prunning function in order to analyze prefixes and obtain result action and it's rule





			#here we call Set-prunning function

			action_rule=self.set_prunning_tree(ff,ff2,ff3,fsport,fdport)
			

















			action_rule="deny"
			if action_rule == "allow":			
				# IP LOOKUP FUNCTION: it is zero if it didn't find a solution
				destination_switch_IP = self.linear_search(dst_ip)
				
				if destination_switch_IP != "0":
					datapath_dst = get_datapath(self,int(self.switch[destination_switch_IP][DPID]))
					dpid_dst = datapath_dst.id			
					self.logger.info(" --- Destination present on switch: %s", dpid_dst)
					
					# Shortest path computation
					path = nx.shortest_path(self.net,dpid_src,dpid_dst)
					self.logger.info(" --- Shortest path: %s", path)
					
					if len(path) == 1:
						In_Port = self.mac_to_port[dpid_src][src]
						Out_Port = self.mac_to_port[dpid_dst][dst]	
						actions_1 = [datapath.ofproto_parser.OFPActionOutput(Out_Port)]
						actions_2 = [datapath.ofproto_parser.OFPActionOutput(In_Port)]
						match_1 = parser.OFPMatch(in_port=In_Port, eth_dst=dst)
						self.add_flow(datapath, 1, match_1, actions_1)

						actions = [datapath.ofproto_parser.OFPActionOutput(Out_Port)]
						data = msg.data
						pkt = packet.Packet(data)
						eth = pkt.get_protocols(ethernet.ethernet)[0]
						# self.logger.info(" --- Changing destination mac to %s" % (eth.dst))
						pkt.serialize()
						out = datapath.ofproto_parser.OFPPacketOut(
							datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER,
							actions=actions, data=pkt.data)
						datapath.send_msg(out)
						
						
					elif len(path) == 2:				
						path_port = self.net[path[0]][path[1]]['port']
						actions = [datapath.ofproto_parser.OFPActionOutput(path_port)]
						data = msg.data
						pkt = packet.Packet(data)
						eth = pkt.get_protocols(ethernet.ethernet)[0]
						eth.src = self.ip_to_mac[src_ip] 
						eth.dst = self.ip_to_mac[dst_ip] 
						# self.logger.info(" --- Changing destination mac to %s" % (eth.dst))
						pkt.serialize()
						out = datapath.ofproto_parser.OFPPacketOut(
						datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER,
							actions=actions, data=pkt.data)
						datapath.send_msg(out)	
						
					elif len(path) > 2:
						# Add flows in the middle of the network path 
						for i in range(1, len(path)-1):							
							In_Port = self.net[path[i]][path[i-1]]['port']
							Out_Port = self.net[path[i]][path[i+1]]['port']
							dp = get_datapath(self, path[i])
							# self.logger.info("Matched OpenFlow Rule = switch: %s, from in port: %s, to out port: %s, source IP: %s, and destination IP: %s", path[i], In_Port, Out_Port, src_ip, dst_ip)
						
							actions_1 = [dp.ofproto_parser.OFPActionOutput(Out_Port)]
							match_1 = parser.OFPMatch(in_port=In_Port, eth_type = 0x0800, ipv4_src=src_ip, ipv4_dst=dst_ip)
							self.add_flow(dp, 1, match_1, actions_1)
						
						path_port = self.net[path[0]][path[1]]['port']
						actions = [datapath.ofproto_parser.OFPActionOutput(path_port)]
						data = msg.data
						pkt = packet.Packet(data)
						eth = pkt.get_protocols(ethernet.ethernet)[0]
						# change the mac address of packet
						eth.src = self.ip_to_mac[src_ip] 
						eth.dst = self.ip_to_mac[dst_ip] 
						# self.logger.info(" --- Changing destination mac to %s" % (eth.dst))
						pkt.serialize()
						out = datapath.ofproto_parser.OFPPacketOut(
						datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER,
							actions=actions, data=pkt.data)
						datapath.send_msg(out)
Ejemplo n.º 48
0
 def handler_switch_enter(self, ev):
     self.logger.info('switch entered')
     # The Function get_switch(self, None) outputs the list of switches.
     self.topo_raw_switches = copy.copy(get_switch(self, None))
     # The Function get_link(self, None) outputs the list of links.
     self.topo_raw_links = copy.copy(get_link(self, None))
    def _packet_in_handler(self, ev):
        """
		Executes everytime a packet arrives on a controller
		"""
        # 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
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return

        dst = eth.dst
        src = eth.src

        self.logger.info(
            "Na controller dorazi paket. Predtym prisiel na Switch cislo %s, na port %s. Dst: %s, Src: %s",
            datapath.id, in_port, dst, src)

        t = pkt.get_protocol(ipv4.ipv4)

        if t:
            print 'zdrojova ip: ', t.src
            print 'dest ip: ', t.dst

        ht = pkt.get_protocol(tcp.tcp)
        mam = 0
        found_path = 0
        random_path = ()
        # If TCP
        if ht:
            print 'zdrojovy port: ', ht.src_port
            print 'destination port: ', ht.dst_port
            mam = 1
            options = ht.option
            # Parse TCP options
            if options and len(options) > 0:
                for opt in options:
                    # Parse MPTCP options
                    if opt.kind == 30:
                        # Parse MPTCP subtype. 00 = MP_CAPABLE. 01 = MP_JOIN. 11 = MP_JOIN
                        hexopt = binascii.hexlify(opt.value)
                        subtype = hexopt[:2]
                        # MP CAPABLE
                        if subtype == "00":
                            # MP CAPABLE SYN
                            if ht.bits == 2:
                                self.logger.info("MP_CAPABLE SYN")
                                dpid = datapath.id
                                if src not in self.net:
                                    self.net.add_node(src)
                                    self.net.add_edge(dpid, src, port=in_port)
                                    self.net.add_edge(src, dpid)

                                # Send A->B traffic to controller
                                match = parser.OFPMatch(eth_type=0x0800,
                                                        ip_proto=6,
                                                        ipv4_src=t.src,
                                                        ipv4_dst=t.dst,
                                                        tcp_src=ht.src_port,
                                                        tcp_dst=ht.dst_port)
                                actions = [
                                    parser.OFPActionOutput(
                                        ofproto.OFPP_CONTROLLER,
                                        ofproto.OFPCML_NO_BUFFER)
                                ]
                                self.add_flow(datapath, 3, match, actions)

                                # Send B->A traffic to controller
                                match = parser.OFPMatch(eth_type=0x0800,
                                                        ip_proto=6,
                                                        ipv4_src=t.dst,
                                                        ipv4_dst=t.src,
                                                        tcp_src=ht.dst_port,
                                                        tcp_dst=ht.src_port)
                                actions = [
                                    parser.OFPActionOutput(
                                        ofproto.OFPP_CONTROLLER,
                                        ofproto.OFPCML_NO_BUFFER)
                                ]
                                self.add_flow(datapath, 3, match, actions)

                                # Sender's key.
                                keya = hexopt[4:]

                                # Sender's token is a SHA1 truncated hash of the key.
                                tokena = int(
                                    hashlib.sha1(binascii.unhexlify(
                                        hexopt[4:])).hexdigest()[:8], 16)

                                # Store IPs, ports, sender's key and sender's token.
                                values = {
                                    'tsrc': t.src,
                                    'tdst': t.dst,
                                    'keya': keya,
                                    'tokena': tokena,
                                    'htsrc_port': ht.src_port,
                                    'htdst_port': ht.dst_port,
                                    'src': src,
                                    'dst': dst
                                }
                                query = "replace INTO mptcp.conn (ip_src,ip_dst,keya,tokena,tcp_src,tcp_dst,src,dst) values('{tsrc}','{tdst}','{keya}',{tokena},{htsrc_port},{htdst_port},'{src}','{dst}');"
                                self.executeInsert(query.format(**values))
                            # MP_CAPABLE SYN-ACK
                            elif ht.bits == 18:
                                self.logger.info("MP_CAPABLE SYN-ACK")

                                dpid = datapath.id
                                if src not in self.net:
                                    self.net.add_node(src)
                                    self.net.add_edge(dpid, src, port=in_port)
                                    self.net.add_edge(src, dpid)

                                # Change out_port so traffic does not go to controller anymore
                                match = parser.OFPMatch(eth_type=0x0800,
                                                        ip_proto=6,
                                                        ipv4_src=t.src,
                                                        ipv4_dst=t.dst,
                                                        tcp_src=ht.src_port,
                                                        tcp_dst=ht.dst_port)
                                # All shortest paths between srcmac and dst mac
                                paths = list(
                                    nx.all_shortest_paths(self.net, src, dst))
                                print("Found path for SYN-ACK. %s to %s Its:",
                                      src, dst)

                                # Random index in list of paths
                                path_index = randrange(0, len(paths))
                                print(
                                    "Volim random index z 0 az do %d. Zvolil som: %d'",
                                    len(paths), path_index)
                                # Select random path
                                path = paths[path_index]
                                print(path)

                                macs = dst + '-' + src
                                self.connpaths[macs] = path_index
                                print(
                                    "Zlozil som kluc do connpaths: %s. Pridelil som path_index %d. Obsah conppaths:",
                                    macs, path_index)
                                print(self.connpaths)
                                next = path[path.index(dpid) + 1]

                                out_port = self.net[dpid][next]['port']
                                print("Out_port: %d", out_port)
                                actions = [parser.OFPActionOutput(out_port)]
                                self.add_flow(datapath, 3, match, actions)

                                # Receiver's key.
                                keyb = hexopt[4:]

                                # Receiver's token is a SHA1 truncated hash of the key.
                                tokenb = int(
                                    hashlib.sha1(binascii.unhexlify(
                                        hexopt[4:])).hexdigest()[:8], 16)

                                # Store receiver's key and receiver's token to the appropriate connection.
                                values = {
                                    'tsrc': t.src,
                                    'tdst': t.dst,
                                    'htsrc_port': ht.src_port,
                                    'htdst_port': ht.dst_port,
                                    'keyb': keyb,
                                    'tokenb': tokenb
                                }
                                query = "UPDATE mptcp.conn SET keyb='{keyb}',tokenb={tokenb} WHERE ip_src='{tdst}' AND ip_dst='{tsrc}' AND tcp_src={htdst_port} AND tcp_dst={htsrc_port};"
                                self.executeInsert(query.format(**values))

                            # MP_CAPABLE ACK
                            elif ht.bits == 16:
                                self.logger.info("MP_CAPABLE ACK")

                                # Change out_port so traffic does not go to controller anymore
                                dpid = datapath.id
                                match = parser.OFPMatch(eth_type=0x0800,
                                                        ip_proto=6,
                                                        ipv4_src=t.src,
                                                        ipv4_dst=t.dst,
                                                        tcp_src=ht.src_port,
                                                        tcp_dst=ht.dst_port)

                                # Construct key in connpaths
                                macs = src + '-' + dst
                                print('Som v ACK. macs: %s', macs)

                                # Get all shortest paths
                                paths = list(
                                    nx.all_shortest_paths(self.net, src, dst))
                                path = paths[self.connpaths[macs]]

                                print('Random index v ACK: ',
                                      self.connpaths[macs])
                                print("Found path for ACK. %s to %s Its:", src,
                                      dst)
                                print(path)
                                next = path[path.index(dpid) + 1]

                                out_port = self.net[dpid][next]['port']

                                print("Out_port: %d", out_port)
                                actions = [parser.OFPActionOutput(out_port)]
                                self.add_flow(datapath, 3, match, actions)

                                command = 'ovs-ofctl -OOpenFlow13 del-flows s1 "eth_dst=' + dst + ',tcp,tcp_flags=0x010"'
                                os.system(command)

                        # MP_JOIN
                        elif subtype == "10" or subtype == "11":

                            # MP_JOIN SYN
                            if ht.bits == 2:
                                self.logger.info("MP_JOIN SYN")
                                dpid = datapath.id
                                if src not in self.net:
                                    self.net.add_node(src)
                                    self.net.add_edge(dpid, src, port=in_port)
                                    self.net.add_edge(src, dpid)

                                # Send A->B traffic to controller
                                match = parser.OFPMatch(eth_type=0x0800,
                                                        ip_proto=6,
                                                        ipv4_src=t.src,
                                                        ipv4_dst=t.dst,
                                                        tcp_src=ht.src_port,
                                                        tcp_dst=ht.dst_port)
                                actions = [
                                    parser.OFPActionOutput(
                                        ofproto.OFPP_CONTROLLER,
                                        ofproto.OFPCML_NO_BUFFER)
                                ]
                                self.add_flow(datapath, 3, match, actions)

                                # Send B->A traffic to controller
                                match = parser.OFPMatch(eth_type=0x0800,
                                                        ip_proto=6,
                                                        ipv4_src=t.dst,
                                                        ipv4_dst=t.src,
                                                        tcp_src=ht.dst_port,
                                                        tcp_dst=ht.src_port)
                                actions = [
                                    parser.OFPActionOutput(
                                        ofproto.OFPP_CONTROLLER,
                                        ofproto.OFPCML_NO_BUFFER)
                                ]
                                self.add_flow(datapath, 3, match, actions)

                                # Receiver's token. From the MPTCP connection.
                                tokenb = int(hexopt[4:][:8], 16)

                                # Sender's nonce.
                                noncea = hexopt[12:]

                                # Store IPs, ports, sender's nonce into subflow table.
                                values = {
                                    'tsrc': t.src,
                                    'tdst': t.dst,
                                    'tokenb': tokenb,
                                    'noncea': noncea,
                                    'htsrc_port': ht.src_port,
                                    'htdst_port': ht.dst_port
                                }
                                query = "replace INTO mptcp.subflow (ip_src,ip_dst,tokenb,noncea,tcp_src,tcp_dst) values('{tsrc}','{tdst}',{tokenb},'{noncea}',{htsrc_port},{htdst_port});"
                                self.executeInsert(query.format(**values))

                            # MP_JOIN SYN-ACK
                            elif ht.bits == 18:
                                self.logger.info("MP_JOIN SYN-ACK.")

                                # Change out_port so traffic does not go to controller anymore
                                dpid = datapath.id
                                match = parser.OFPMatch(eth_type=0x0800,
                                                        ip_proto=6,
                                                        ipv4_src=t.src,
                                                        ipv4_dst=t.dst,
                                                        tcp_src=ht.src_port,
                                                        tcp_dst=ht.dst_port)

                                if src not in self.net:
                                    self.net.add_node(src)
                                    self.net.add_edge(dpid, src, port=in_port)
                                    self.net.add_edge(src, dpid)

                                paths = list(
                                    nx.all_shortest_paths(self.net, src, dst))
                                print("Found path for SYN-ACK. %s to %s Its:",
                                      src, dst)
                                # Random index in list of paths
                                path_index = randrange(0, len(paths))
                                print(
                                    "JOIN volim random index z 0 az do %d. Zvolil som: %d'",
                                    len(paths), path_index)
                                # Select random path
                                path = paths[path_index]
                                print(path)

                                macs = dst + '-' + src
                                self.connpaths[macs] = path_index
                                print(
                                    "Zlozil som kluc do connpaths: %s. Pridelil som path_index %d. Obsah conppaths:",
                                    macs, path_index)
                                print(self.connpaths)
                                next = path[path.index(dpid) + 1]

                                out_port = self.net[dpid][next]['port']
                                print("Out_port: %d", out_port)
                                actions = [parser.OFPActionOutput(out_port)]
                                self.add_flow(datapath, 3, match, actions)

                                # Receiver's truncated HASH.
                                trunhash = int(hexopt[4:][:16], 16)

                                # Receiver's nonce.
                                nonceb = hexopt[20:]

                                # Store truncated HASH and receiver's nonce into appropriate subflow.
                                values = {
                                    'tsrc': t.src,
                                    'tdst': t.dst,
                                    'htsrc_port': ht.src_port,
                                    'htdst_port': ht.dst_port,
                                    'trunhash': trunhash,
                                    'nonceb': nonceb
                                }
                                query = "UPDATE mptcp.subflow SET trunhash={trunhash},nonceb='{nonceb}' WHERE ip_src='{tdst}' AND ip_dst='{tsrc}' AND tcp_src={htdst_port} AND tcp_dst={htsrc_port};"
                                self.executeInsert(query.format(**values))

                            # MP_JOIN ACK
                            elif ht.bits == 16:
                                self.logger.info("MP_JOIN ACK.")

                                # Change out_port so traffic does not go to controller anymore
                                dpid = datapath.id
                                match = parser.OFPMatch(eth_type=0x0800,
                                                        ip_proto=6,
                                                        ipv4_src=t.src,
                                                        ipv4_dst=t.dst,
                                                        tcp_src=ht.src_port,
                                                        tcp_dst=ht.dst_port)

                                # Construct key in connpaths
                                macs = src + '-' + dst
                                print('Som v  JOIN ACK. macs: %s', macs)

                                # Get all paths
                                paths = list(
                                    nx.all_shortest_paths(self.net, src, dst))
                                path = paths[self.connpaths[macs]]
                                print('Random index v ACK: ',
                                      self.connpaths[macs])
                                print("Found path for ACK. %s to %s Its:", src,
                                      dst)
                                print(path)
                                next = path[path.index(dpid) + 1]

                                out_port = self.net[dpid][next]['port']

                                print("Out_port: %d", out_port)
                                actions = [parser.OFPActionOutput(out_port)]
                                self.add_flow(datapath, 3, match, actions)

                                # Sender's HASH.
                                hmachash = hexopt[4:]

                                # Store sender's HASH to appropriate subflow.
                                values = {
                                    'tsrc': t.src,
                                    'tdst': t.dst,
                                    'htsrc_port': ht.src_port,
                                    'htdst_port': ht.dst_port,
                                    'hmachash': hmachash
                                }
                                query = "UPDATE mptcp.subflow SET hash='{hmachash}' WHERE ip_src='{tsrc}' AND ip_dst='{tdst}' AND tcp_src={htsrc_port} AND tcp_dst={htdst_port};"
                                self.executeInsert(query.format(**values))

                                # Select keys from appropriate connection based on receiver's token.
                                values = {
                                    'tsrc': t.src,
                                    'tdst': t.dst,
                                    'htsrc_port': ht.src_port,
                                    'htdst_port': ht.dst_port
                                }
                                query = "SELECT keya,keyb from conn where tokenb in (SELECT tokenb from subflow where ip_src='{tsrc}' and ip_dst='{tdst}' and tcp_src={htsrc_port} and tcp_dst={htdst_port});"
                                keys = self.executeSelect(
                                    query.format(**values))

                                # Select nonces for current subflow.
                                values = {
                                    'tsrc': t.src,
                                    'tdst': t.dst,
                                    'htsrc_port': ht.src_port,
                                    'htdst_port': ht.dst_port
                                }
                                query = "SELECT noncea,nonceb from subflow where ip_src='{tsrc}' AND ip_dst='{tdst}' AND tcp_src={htsrc_port} AND tcp_dst={htdst_port};"
                                nonces = self.executeSelect(
                                    query.format(**values))

                                # Key for generating HMAC is a concatenation of two keys. Message is a concatenation of two nonces.
                                keyhmac = binascii.unhexlify(keys[0] + keys[1])
                                message = binascii.unhexlify(nonces[0] +
                                                             nonces[1])

                                # Generate hash.
                                vysledok = hmac.new(keyhmac, message,
                                                    hashlib.sha1).hexdigest()
                                print(vysledok)

                                # Compare generated HASH to the one from MP_JOIN ACK.
                                if vysledok == hmachash:

                                    # Get connection ID based on tokens.
                                    values = {
                                        'tsrc': t.src,
                                        'tdst': t.dst,
                                        'htsrc_port': ht.src_port,
                                        'htdst_port': ht.dst_port
                                    }
                                    query = "SELECT id from conn where tokenb in (SELECT tokenb from subflow where ip_src='{tsrc}' and ip_dst='{tdst}' and tcp_src={htsrc_port} and tcp_dst={htdst_port});"
                                    ids = self.executeSelect(
                                        query.format(**values))[0]

                                    # Insert connection ID to a current subflow.
                                    values = {
                                        'tsrc': t.src,
                                        'tdst': t.dst,
                                        'htsrc_port': ht.src_port,
                                        'htdst_port': ht.dst_port,
                                        'id': ids
                                    }
                                    query = "update subflow set connid = {id} where ip_src='{tsrc}' and ip_dst='{tdst}' and tcp_src={htsrc_port} and tcp_dst={htdst_port};"
                                    self.executeInsert(query.format(**values))

                                    query = "select src,dst from conn join subflow on subflow.connid=conn.id where conn.id=(select connid from subflow where ip_src='{tsrc}' and ip_dst='{tdst}' and tcp_src={htsrc_port} and tcp_dst={htdst_port}) group by src;"

                                    result = self.executeSelect(
                                        query.format(**values))
                                    srcmac = result[0]
                                    dstmac = result[1]
                                    print('srcmac = %s', srcmac)
                                    print('dstmac = %s', dstmac)

                                #	paths = list(nx.all_shortest_paths(self.net,srcmac,dstmac))
                                #	print ("Available paths: ")
                                #	for p in paths:
                                #		print p

                                #	print ("Random_path: ")
                                #	random_path = random.choice(paths)
                                #	print (random_path)
                                #	found_path = 1
                                #	print ("Found_path: %d",found_path)

            # Learn MAC addresses to avoid FLOOD.
        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})
        self.mac_to_port[dpid][src] = in_port

        # Shortest path forwarding
        #		for f in msg.match.fields:
        #			if f.header == ofproto_v1_3.OXM_OF_IN_PORT:
        #				in_port = f.value
        #
        #		if src not in self.net:
        #			self.net.add_node(src)
        #			self.net.add_edge(dpid,src,port=in_port)
        #			self.net.add_edge(src,dpid)
        #		if dst in self.net:
        #			print("Som v rozhodovani.")
        #			if found_path == 1:
        #				print ("Assingin random path.")
        #				path = random_path
        #				next = path[path.index(dpid) + 1]
        #				out_port = self.net[dpid][next]['port']
        #			else:
        #				print ("Assining not random path.")
        #				path = nx.shortest_path(self.net,src,dst)
        #				next = path[path.index(dpid) + 1]
        #				out_port = self.net[dpid][next]['port']
        #		else:
        #			out_port = ofproto.OFPP_FLOOD

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # Install flow to avoid FLOOD next time.
        if out_port != ofproto.OFPP_FLOOD:
            match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
            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)
        """
		Get topology data. Links and switches.
		"""
        switch_list = get_switch(self.topology_api_app, None)
        switches = [switch.dp.id for switch in switch_list]
        self.net.add_nodes_from(switches)

        links_list = get_link(self.topology_api_app, None)
        links = [(link.src.dpid, link.dst.dpid, {
            'port': link.src.port_no
        }) for link in links_list]
        print("Linky: ", links)
        self.net.add_edges_from(links)
        links = [(link.dst.dpid, link.src.dpid, {
            'port': link.dst.port_no
        }) for link in links_list]
        print("Linky znova: ", links)
        self.net.add_edges_from(links)
        print("Linky z programu: ", self.net.edges())
        print("Nodes z programu: ", self.net.nodes())
Ejemplo n.º 50
0
 def handler_link_add(self, ev):
     self.logger.info("Link detected")
     self.topo_blueprint.topo_raw_links = get_link(self, None)
Ejemplo n.º 51
0
 def get_topology(self, ev):
     self.create_map(get_switch(self.topology_api_app))
     # print get_host(self.topology_api_app)
     # print type(get_host(self.topology_api_app))
     self.create_link_port(get_link(self.topology_api_app),
                           get_host(self.topology_api_app))
Ejemplo n.º 52
0
    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
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        if eth.ethertype == ether_types.ETH_TYPE_LLDP:
            # ignore lldp packet
            return

        src = eth.src
        dst = eth.dst
        if str(dst) in ("00:00:00:00:00:01", "00:00:00:00:00:02",
                        "00:00:00:00:00:03", "00:00:00:00:00:04",
                        "00:00:00:00:00:05", "00:00:00:00:00:06"):
            msg = ev.msg

            dpid = datapath.id
            self.mac_to_port.setdefault(dpid, {})

            self.logger.info("packet from Source: %s to Destination: %s", src,
                             dst)

            if dst in self.mac_to_port[dpid]:
                out_port = self.mac_to_port[dpid][dst]
            else:
                out_port = ofproto.OFPP_FLOOD
            actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

            switch_list = get_switch(self, None)
            switches = [switch.dp.id for switch in switch_list]
            links_list = get_link(self, None)
            link_port = {(link.src.dpid, link.dst.dpid): link.src.port_no
                         for link in links_list}

            self.g.add_nodes_from(switches)
            links = [(link.src.dpid, link.dst.dpid, {
                'port': link.src.port_no
            }) for link in links_list]

            self.g.add_edges_from(links)
            links = [(link.dst.dpid, link.src.dpid, {
                'port': link.dst.port_no
            }) for link in links_list]

            topo = {
                '1': {
                    '3': 10,
                    '2': 10,
                    '5': 15
                },
                '2': {
                    '1': 10,
                    '3': 15,
                    '4': 15
                },
                '3': {
                    '1': 10,
                    '2': 15,
                    '4': 5
                },
                '4': {
                    '2': 15,
                    '3': 5,
                    '6': 10
                },
                '5': {
                    '1': 15,
                    '6': 15
                },
                '6': {
                    '4': 10,
                    '5': 15
                }
            }
            dst_dpid = dpid_hostLookup(self, dst)

            path3 = []
            src = str(src)
            dst = str(dst)

            dijkstra(topo, str(dpid), str(dst_dpid))

            global path2
            path3 = list(map(int, path2))

            path3.reverse()

            if not self.g.has_node(eth.src):

                self.g.add_node(eth.src)
                self.g.add_edge(eth.src, datapath.id)
                self.g.add_edge(datapath.id, eth.src, port=in_port)

            if not self.g.has_node(eth.dst):

                self.g.add_node(eth.dst)
                self.g.add_edge(eth.dst, datapath.id)
                self.g.add_edge(datapath.id, eth.dst, port=in_port)

            if (path3 != []):
                if self.g.has_node(eth.dst):
                    next_match = parser.OFPMatch(eth_dst=eth.dst)
                    back_match = parser.OFPMatch(eth_dst=eth.src)

                    for on_path_switch in range(1, len(path3) - 1):

                        now_switch = path3[on_path_switch]
                        next_switch = path3[on_path_switch + 1]
                        back_switch = path3[on_path_switch - 1]
                        next_port = link_port[(now_switch, next_switch)]
                        back_port = link_port[(now_switch, back_switch)]

                        new_dp = get_datapath(self, next_switch)
                        action = parser.OFPInstructionActions(
                            ofproto.OFPIT_APPLY_ACTIONS,
                            [parser.OFPActionOutput(next_port)])

                        inst = [action]
                        actions = [parser.OFPActionOutput(next_port)]
                        self.add_flow(datapath=new_dp,
                                      priority=1,
                                      actions=actions,
                                      match=next_match,
                                      buffer_id=0)
                        action = parser.OFPInstructionActions(
                            ofproto.OFPIT_APPLY_ACTIONS,
                            [parser.OFPActionOutput(back_port)])
                        inst = [action]
                        actions = [parser.OFPActionOutput(back_port)]
                        new_dp = get_datapath(self, back_switch)
                        self.add_flow(datapath=new_dp,
                                      match=back_match,
                                      priority=1,
                                      actions=actions,
                                      buffer_id=0)

                        out = datapath.ofproto_parser.OFPPacketOut(
                            datapath=datapath,
                            buffer_id=msg.buffer_id,
                            in_port=in_port,
                            actions=actions)
                        datapath.send_msg(out)

                else:
                    return
            else:
                if out_port != ofproto.OFPP_FLOOD:
                    self.add_flow(datapath, msg.in_port, dst, actions)

                out = datapath.ofproto_parser.OFPPacketOut(
                    datapath=datapath,
                    buffer_id=msg.buffer_id,
                    in_port=in_port,
                    actions=actions)
                datapath.send_msg(out)
Ejemplo n.º 53
0
    def push_flow(self, req, source_dpid_int, destn_dpid_int, mac, **_kwargs):
        path = self.shortest_route(source_dpid_int, destn_dpid_int)

        source_dpid = self.append(source_dpid_int)
        destn_dpid = self.append(destn_dpid_int)
        source_dpid1 = dpid_lib.str_to_dpid(source_dpid)
        destn_dpid1 = dpid_lib.str_to_dpid(destn_dpid)
        source_dp = self.dpset.get(source_dpid1)
        destn_dp = self.dpset.get(destn_dpid1)

        if source_dp is None:
            return Response(status=404)

        for node in range(len(path) - 1):
            tsrc_dpid = int(path[node].replace("dpid=", ""))
            tdst_dpid = int(path[node + 1].replace("dpid=", ""))
            tsrc_dpid = self.append(tsrc_dpid)
            tdst_dpid = self.append(tdst_dpid)
            tsrc_dpid = dpid_lib.str_to_dpid(tsrc_dpid)
            tdst_dpid = dpid_lib.str_to_dpid(tdst_dpid)
            tsrc_dp = self.dpset.get(tsrc_dpid)

            links = get_link(self.topology_api_app, tsrc_dpid)

            if links is None:
                return Response(status=404)
            for i in range(len(links)):
                links_dpid = dpid_lib.str_to_dpid(
                    links[i].to_dict()["dst"]["dpid"])
                if links_dpid == tdst_dpid:
                    str_port = links[i].to_dict()["src"]["port_no"]
                    break
            port = port_lib.str_to_port_no(str_port)
            actions = [tsrc_dp.ofproto_parser.OFPActionOutput(int(port))]
            # pushing flows
            ofproto = tsrc_dp.ofproto

            match = tsrc_dp.ofproto_parser.OFPMatch(dl_dst=haddr_to_bin(mac))
            mod = tsrc_dp.ofproto_parser.OFPFlowMod(
                datapath=tsrc_dp,
                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)
            tsrc_dp.send_msg(mod)

        ofproto = destn_dp.ofproto

        if (destn_dpid1 == 0000000000000001):
            logging.debug("PORT")
            out_port = 1
            logging.debug(out_port)
            logging.debug("PORT")
        if (destn_dpid1 == 0000000000000002):
            out_port = 3
        if (destn_dpid1 == 0000000000000003):
            out_port = 2
        actions1 = [destn_dp.ofproto_parser.OFPActionOutput(1)]
        match1 = destn_dp.ofproto_parser.OFPMatch(dl_dst=haddr_to_bin(mac))

        mod1 = destn_dp.ofproto_parser.OFPFlowMod(
            datapath=destn_dp,
            match=match1,
            cookie=0,
            command=ofproto.OFPFC_ADD,
            idle_timeout=0,
            hard_timeout=0,
            priority=ofproto.OFP_DEFAULT_PRIORITY,
            flags=ofproto.OFPFF_SEND_FLOW_REM,
            actions=actions1)
        destn_dp.send_msg(mod1)

        body = json.dumps([link.to_dict() for link in links])
        return Response(content_type='application/json', body=body)
Ejemplo n.º 54
0
    def _packet_in_handler(self, ev):

        pkt = packet.Packet(ev.msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]
        arp_pkt = pkt.get_protocol(arp.arp)
        ip4_pkt = pkt.get_protocol(ipv4.ipv4)
        if arp_pkt:
            pak = arp_pkt
        elif ip4_pkt:
            pak = ip4_pkt
        else:
            pak = eth

        self.logger.info('  _packet_in_handler: src_mac -> %s' % eth.src)
        self.logger.info('  _packet_in_handler: dst_mac -> %s' % eth.dst)
        self.logger.info('  _packet_in_handler: %s' % pak)
        self.logger.info('  ------')

        if eth.ethertype == ether_types.ETH_TYPE_LLDP or eth.ethertype == ether_types.ETH_TYPE_IPV6:
            # ignore lldp packet
            return

        dst = eth.src
        src = eth.dst
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']
        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info(">>>>>>> packet in %s %s %s %s", dpid, src, dst, in_port)
        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port
        print(src)
        print(dst)

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD
        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]


        switch_list = get_switch(self, None)
        switches = [switch.dp.id for switch in switch_list]
        links_list = get_link(self, None)
        link_port={(link.src.dpid,link.dst.dpid):link.src.port_no for link in links_list}
        # g = nx.DiGraph()
        self.g.add_nodes_from(switches)
        links = [(link.src.dpid,link.dst.dpid,{'port':link.src.port_no}) for link in links_list]
        print(links)
        self.g.add_edges_from(links)
        links = [(link.dst.dpid,link.src.dpid,{'port':link.dst.port_no})  for link in links_list]
        self.g.add_edges_from(links)
        #print(links)
        #print(self.g)

        topo = {'1': {'3': 50, '4': 100}, '2': {'3': 100, '4': 50}, '3': {'1': 50, '2': 100, '13': 15, '14': 100},
                '4': {'1': 100, '2': 50, '14': 5}, '5': {'7': 50, '8': 100}, '6': {'7': 100, '8': 50},
                '7': {'5': 50, '6': 100, '13': 15, '14': 20, '15': 5}, '8': {'5': 100, '6': 50, '15': 10, '16': 15},
                '9': {'11': 50, '12': 100}, '10': {'11': 100, '12': 50},
                '11': {'9': 50, '10': 100, '14': 10}, '12': {'9': 100, '10': 50, '15': 15, '16': 10},
                '13': {'3': 15, '7': 15}, '14': {'3': 10, '4': 5, '7': 20, '11': 10}, '15': {'7': 5, '8': 10, '12': 15},
                '16': {'8': 15, '12': 10}}

        dst_dpid = dpid_hostLookup(self, dst)
        print("dpid",str(dpid))
        print("dst",dst)
        # if(dst=='ff:ff:ff:ff:ff:ff'):
        #     return()
        path3=[]
        src=str(src)
        dst=str(dst)
        print("dst dpid",str(dst_dpid))
        if ((src == '00:00:00:00:00:01' and dst == '00:00:00:00:00:13') or (src == '00:00:00:00:00:01' and dst == '00:00:00:00:00:23') or (
            src == '00:00:00:00:00:01' and dst == '00:00:00:00:00:33') or(src == '00:00:00:00:00:02' and dst == '00:00:00:00:00:12') or (
            src == '00:00:00:00:00:02' and dst == '00:00:00:00:00:22') or (src == '00:00:00:00:00:02' and dst == '00:00:00:00:00:32') or
            (src == '00:00:00:00:00:03' and dst == '00:00:00:00:00:14') or (src == '00:00:00:00:00:03' and dst == '00:00:00:00:00:24') or (
                        src == '00:00:00:00:00:03' and dst == '00:00:00:00:00:34')):
         dijkstra(topo, str(dpid), str(dst_dpid))
         global path2
         path3= list(map(int, path2))
         print(path3)
         path3.reverse()

        elif ((src == '00:00:00:00:00:01' and (dst == '00:00:00:00:00:11' or dst == '00:00:00:00:00:12' or dst == '00:00:00:00:00:14' or dst == '00:00:00:00:00:21' or dst == '00:00:00:00:00:22' or dst == '00:00:00:00:00:24' or dst == '00:00:00:00:00:31' or dst == '00:00:00:00:00:32' or dst == '00:00:00:00:00:34'))
              or (src == '00:00:00:00:00:02' and (dst == '00:00:00:00:00:11' or dst == '00:00:00:00:00:13' or dst == '00:00:00:00:00:14' or dst == '00:00:00:00:00:21' or dst == '00:00:00:00:00:23' or dst == '00:00:00:00:00:24' or dst == '00:00:00:00:00:31' or dst == '00:00:00:00:00:33' or dst == '00:00:00:00:00:34'))
              or (src == '00:00:00:00:00:03' and (dst == '00:00:00:00:00:11' or dst == '00:00:00:00:00:12' or dst == '00:00:00:00:00:13' or dst == '00:00:00:00:00:21' or dst == '00:00:00:00:00:22' or dst == '00:00:00:00:00:23' or dst == '00:00:00:00:00:31' or dst == '00:00:00:00:00:32' or dst == '00:00:00:00:00:33'))):
            dijkstra_longestpath(topo, str(dpid), str(dst_dpid))
            path3 = list(map(int, path2))
            print(path3)
            path3.reverse()


        if not self.g.has_node(eth.src):
            print("add %s in self.net" % eth.src)
            self.g.add_node(eth.src)
            self.g.add_edge(eth.src, datapath.id)
            self.g.add_edge(datapath.id, eth.src, {'port': in_port})
            print(self.g.node)

        if not self.g.has_node(eth.dst):
            print("add %s in self.net" % eth.dst)
            self.g.add_node(eth.dst)
            self.g.add_edge(eth.dst, datapath.id)
            self.g.add_edge(datapath.id, eth.dst, {'port': in_port})
            print(self.g.node)

       # path3=[13,3,1]
        print("before loop")
        if(path3!=[]):
         if self.g.has_node(eth.dst):
            next_match = parser.OFPMatch(eth_dst=eth.dst)
            back_match = parser.OFPMatch(eth_dst=eth.src)
            print(path3)
            for on_path_switch in range(1, len(path3) - 1):
                print("hi in loop")
                now_switch = path3[on_path_switch]
                next_switch = path3[on_path_switch + 1]
                back_switch = path3[on_path_switch - 1]
                next_port = link_port[(now_switch,next_switch)]
                back_port = link_port[(now_switch,back_switch)]
                print("next_port",next_port)
                print("back_port",back_port)
                new_dp=get_datapath(self, next_switch)
                action = parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                                          [parser.OFPActionOutput(next_port)])
                inst = [action]
                self.add_flow(datapath=new_dp, match=next_match, inst=inst, table=0)

                action = parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                                          [parser.OFPActionOutput(back_port)])
                inst = [action]
                actions = [parser.OFPActionOutput(next_port)]
                new_dp = get_datapath(self, back_switch)
                self.add_flow(datapath=new_dp, match=back_match, inst=inst,actions=action, table=0)
                print ("now switch:%s",now_switch)
                out = datapath.ofproto_parser.OFPPacketOut(
                    datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port,
                    actions=actions)
                datapath.send_msg(out)
                print("final")

            else:
                return
        else:
            if out_port != ofproto.OFPP_FLOOD:
                self.add_flow(datapath, msg.in_port, dst, actions)

            out = datapath.ofproto_parser.OFPPacketOut(
                datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port,
                actions=actions)
            datapath.send_msg(out)
Ejemplo n.º 55
0
    def update_topology(self, ev):
        # clear graph and precomputed paths
        self.net.clear()
        self.labels = {}
        self.mac_to_port = {}

        # wait a moment for ryu's topology info to update
        sleep(0.05)

        # get switches and links from ryu.topology
        switch_list = get_switch(self.topology_api_app, None)
        switches = [switch.dp.id for switch in switch_list]
        links_list = get_link(self.topology_api_app, None)
        links = [(link.src.dpid, link.dst.dpid, {'port':link.src.port_no})
                for link in links_list]

        # remove all the flows in the switches
        for switch in switch_list:
            self.remove_flows(switch.dp)

        # add switches and links to graph
        self.net.add_nodes_from(switches)
        self.net.add_edges_from(links)
        #self.logger.info("switches: %s", str(switches))
        #self.logger.info("links: %s", str(links))
        # get link bandwidth info from file and add it to the graph
        bw_list = open('bandwidths.edgelist', 'rb')
        bw_graph = nx.read_edgelist(bw_list, nodetype=int, data=(('bw', float),) )
        bw_list.close()
        #self.logger.info("bw_graph.edges(): %s", str(bw_graph.edges()))

        for edge in bw_graph.edges(): # .edges() only returns ends, not data
            #self.logger.info("edge = %s", str(edge))
            # if the edge is not in the edgelist of known/expected edges or
            # the bw field for the edge is missing, use a default bandwidth
            link_bw = 1
            if edge in self.net.edges():
                #self.logger.info("edge %s in self.net.edges()", str(edge))
                try:
                    link_bw = bw_graph[edge[0]][edge[1]]['bw']
                    #self.logger.info("link_bw = %f", link_bw)
                except:
                    #self.logger.info("no link_bw found")
                    pass
            try:
                port01 = self.net[edge[0]][edge[1]]['port']
                port10 = self.net[edge[1]][edge[0]]['port']
                self.net.add_edge(edge[0],edge[1], {'port': port01,
                    'bw': link_bw})
                self.net.add_edge(edge[1],edge[0], {'port': port10,
                    'bw': link_bw})
            except KeyError:
                #self.logger.info("KeyError for edge %s", str(edge))
                continue

        # calculate labels
        #self.logger.info("calculating labels")
        self.labels = compute_mpls_labels(self.net)

        # add label-swapping flows to the switches
	for switch in switch_list:
            switch_id = switch.dp.id
            ofproto = self.switch_ofprotos[switch_id]
            parser = self.switch_parsers[switch_id]
            for dst in self.labels[switch_id].keys():
                for path in range(len(self.labels[switch_id][dst])):
                    # create a match for the path using its label
                    match = parser.OFPMatch(eth_type=ether_types.ETH_TYPE_MPLS,
                            mpls_label=self.labels[switch_id][dst][path][3])
                    # determine actions the switch_id should take
                    if switch_id == dst:
                        # check if this is the ARP path or not
                        if self.labels[switch_id][dst][path][3] < 1000:
                            packet_ethertype = ether_types.ETH_TYPE_ARP
                        else:
                            packet_ethertype = ether_types.ETH_TYPE_IP
                        # create an instruction to pop the MPLS header
                        actions = [parser.OFPActionPopMpls(packet_ethertype)]
                        # create an instruction to go to the next table
                        table_instruction = parser.OFPInstructionGotoTable(
                                       self.mpls_dst_table)
                        instructions = [parser.OFPInstructionActions(
                                ofproto.OFPIT_APPLY_ACTIONS, actions),
                                table_instruction]

                    else:
                        next_hop = self.labels[switch_id][dst][path][2][1]
                        next_hop_label = self.labels[switch_id][dst][path][4]
                        out_port = self.net[switch_id][next_hop]['port']
                        actions = [parser.OFPActionSetField(
                                        mpls_label = next_hop_label),
                                    parser.OFPActionDecMplsTtl(),
                                    parser.OFPActionOutput(out_port)
                                  ]
                        instructions = [parser.OFPInstructionActions(
                                ofproto.OFPIT_APPLY_ACTIONS, actions)]

                    # now add the flow
                    self.add_flow(switch.dp, 1200, match, instructions,
                            self.routing_table)
        self.print_graph()
        self.print_labels()
        print("")
Ejemplo n.º 56
0
    def _monitor(self):
        hub.sleep(200)  # Wait for the topology discovery

        host_list = get_host(self, None)
        switch_list = get_switch(self, None)
        link_list = get_link(self, None).keys()

        # Add missing backward links
        link_pairs = set([(link.src.dpid, link.dst.dpid)
                          for link in link_list])
        missing_links = [
            Link(link.dst, link.src) for link in link_list
            if not (link.dst.dpid, link.src.dpid) in link_pairs
        ]
        link_list.extend(missing_links)

        H, S = (len(host_list), len(switch_list))

        # The number of nodes, the number of flows and the number of links respectively
        # +2*H is for the links connecting switches and hosts (bidrectional)
        N, H2, L = (H + S, H * (H - 1), len(link_list) + 2 * H)

        # Gather Flow Table Rules
        self.port_dst_to_rule = {}
        self.R, self.t = (0, None)
        for dp in self.datapaths.values():
            self._request_stats(dp)
        hub.sleep(5)

        # self.port_to_link[switch_id][port_no] gives the corresponding link id
        # of the port of the switch
        self.port_to_link = {}

        # self.port_to_host[switch_id][port_no] gives the corresponding host of
        # the port of the switch
        self.port_to_host = {}

        # switch_to_links[switch_id] provides the id list of the links
        # connected to the switch
        switch_to_links = {}

        # switch_to_rules[switch_id] provides the id list of the rules
        # in the switch
        switch_to_rules = {}

        # Populate the dictionaries
        for link_id, link in enumerate(link_list):
            self.port_to_link.setdefault(link.src.dpid, {})
            self.port_to_link[link.src.dpid][link.src.port_no] = link_id, link

            switch_to_links.setdefault(link.src.dpid, [])
            switch_to_links[link.src.dpid].append(link_id)
            switch_to_links.setdefault(link.dst.dpid, [])
            switch_to_links[link.dst.dpid].append(link_id)

        # Add hosts with the links
        for host_id, host in enumerate(host_list):
            rlink_id = len(link_list) + host_id  # (Host -> Switch)
            tlink_id = rlink_id + H  # (Switch -> Host)
            switch_to_links[host.port.dpid].extend([rlink_id, tlink_id])

            self.port_to_host.setdefault(host.port.dpid, {})
            self.port_to_host[host.port.dpid][
                host.port.port_no] = rlink_id, tlink_id, host

        for switch_id in self.port_dst_to_rule:
            switch_to_rules[switch_id] = [
                rule_id for rule_id, port_no in
                self.port_dst_to_rule[switch_id].values()
            ]

        # Create the routing matricess
        A = np.zeros((L, H2))
        B = np.zeros((self.R, H2))
        flow_id = 0
        for src_id, src in enumerate(host_list):
            for dst_id, dst in enumerate(host_list):
                if src_id != dst_id:

                    # Outgoing link id of src host (Host -> Switch)
                    link_id = len(link_list) + src_id
                    A[link_id, flow_id] = 1

                    # The first switch on the path
                    switch_id = src.port.dpid

                    # The corresponding rule and out port
                    rule_id, port_no = self.port_dst_to_rule[switch_id][
                        src.port.port_no, dst.mac]
                    B[rule_id, flow_id] = 1

                    # Populate through the switches on the path
                    while port_no in self.port_to_link[switch_id]:

                        # Next Link
                        link_id, link = self.port_to_link[switch_id][port_no]
                        A[link_id, flow_id] = 1

                        # Next Switch
                        switch_id = link.dst.dpid

                        rule_id, port_no = self.port_dst_to_rule[switch_id][
                            link.dst.port_no, dst.mac]
                        B[rule_id, flow_id] = 1

                    # Incoming link id of the dst host (Switch -> Host)
                    link_id = len(link_list) + H + dst_id
                    A[link_id, flow_id] = 1

                    flow_id += 1

        im = InferenceModule(A, links=switch_to_links)
        im2 = InferenceModule(B, links=switch_to_rules)

        # Start monitoring
        T = 1000  # The number of time steps
        self.trace = np.zeros((T, L))  # Time Step x Link ID
        self.trace2 = np.zeros((T, self.R))  # Time Step x Link ID
        for self.t in range(T):
            self.logger.info('Time Step: ' + str(self.t))
            for dp in self.datapaths.values():  # Complete measurement
                self._request_stats(dp)  # See SimpleMonitor13._request_stats
            hub.sleep(1)

        # Save
        with open(
                'trace_' + datetime.now().strftime('%Y-%m-%d_%H:%M:%S') +
                '.pkl', 'w') as trace_file:
            pickle.dump(
                {
                    'im':
                    im,
                    'im2':
                    im2,
                    'A':
                    A,
                    'B':
                    B,
                    'trace':
                    self.trace,
                    'trace2':
                    self.trace2,
                    'port_dst_to_rule':
                    self.port_dst_to_rule,
                    'switch_links': [(link.src.dpid, link.dst.dpid)
                                     for link in link_list],
                    'host_links': [(host.mac, host.port.dpid)
                                   for host in host_list],
                    'switch_to_links':
                    switch_to_links,
                    'switch_to_rules':
                    switch_to_rules,
                    'H':
                    H,
                    'S':
                    S,
                    'N':
                    N,
                    'H2':
                    H2,
                    'L':
                    L,
                    'R':
                    self.R,
                    'T':
                    T
                }, trace_file)
Ejemplo n.º 57
0
    def _packet_in_handler(self, ev):
        #TODO using two methods to do two things respectively ?
        #TODO using server MAC learning period T to separate the two methods ?
##        end=time.time()
##        if (end-start)*1000 < self.T:
##            #TODO compute the route
##            print (end-start)*1000
##            self.MACLearning(ev)
##        else:
##            print (end-start)*1000
##            #TODO learning server MAC
##            self.Routing(ev)
        
        #TODO add the topology collecting periodically
        self.edgenum=0
        start = time.time()
        print start
        self.switches = get_switch(self)
        self.links = get_link(self)
        self.topo_col_num = self.topo_col_num + 1
        end = time.time()
        print end
        print 'topology collecting time:'
        print end-start
        self.topo_col_period = self.topo_col_period + end-start

        #n=len(self.switches)
        #m=len(self.links)
##        self.startnum=0
##        self.dpids_to_nums={}
##        self.nums_to_dpids={}
        print 'dpids nums:'
        for switch in self.switches:#TODO this may has error
            if self.dpids_to_nums.get(switch.dp.id)==None:
                self.nums_to_dpids[self.startnum] = switch.dp.id
                self.dpids_to_nums[switch.dp.id] = self.startnum
                print str(switch.dp.id)+' '+str(self.startnum)
                self.startnum = self.startnum + 1
        print self.dpids_to_nums
        self.n=self.startnum
        print 'edges:'
        self.linkgraph=[]
        for i in xrange(self.switch_num):
            self.linkgraph.append([])
            for j in xrange(self.switch_num):
                self.linkgraph[i].append(0)
        for link in self.links:
            self.edgenum=self.edgenum+1
            srcnum = self.dpids_to_nums[link.src.dpid]
            dstnum = self.dpids_to_nums[link.dst.dpid]
            self.linkgraph[srcnum][dstnum]=1
            if self.graph[srcnum][dstnum]==0 and self.graph[dstnum][srcnum]==0:
                print str(srcnum)+' '+str(dstnum)
                self.dpid_to_port[(link.src.dpid, link.dst.dpid)] = (link.src.port_no, link.dst.port_no)
                self.dpid_to_port[(link.dst.dpid, link.src.dpid)]=(link.dst.port_no, link.src.port_no)
                #print>>devicegraph, str(srcnum)+' '+str(dstnum)
                self.graph[srcnum][dstnum] = 1
                self.graph[dstnum][srcnum] = 1
                self.undirected[srcnum][dstnum] = 1
                self.m=self.m+1
        self.G={}
        for i in xrange(self.switch_num):
            self.G[i]={}
            for j in xrange(self.switch_num):
                if self.linkgraph[i][j]==1 and self.linkgraph[j][i]==1:#TODO if only one way is ok then regard it as not ok
                    self.G[i][j]=1
        print self.G
        flag=0
        if self.n<4 or self.m<4 or self.topo_col_num<self.topo_col_num_max or self.topo_col_period<self.topo_col_period_max:#TODO test,but when the edge is error, then it will not be ok
            flag=1#TODO
        print 'topology ok'
        if self.servernum<2:
            self.MACLearning(ev)
            if 2==self.servernum: #and 0==flag:
                src=self.server1
                dst=self.server2
                self.short(ev, src, dst, self.G)#add the flow entries of FF:FF:FF:FF:FF:FF
                src=self.server2
                dst=self.server1
                self.short(ev, src, dst, self.G)                
        elif 2==self.servernum or self.edgenum!=8: #and 0==flag:
            #it means that two servers' MAC have been added, then add the
            src=self.server1
            dst=self.server2
            self.short(ev, src, dst, self.G)#add the flow entries of FF:FF:FF:FF:FF:FF
            src=self.server2
            dst=self.server1
            self.short(ev, src, dst, self.G)
Ejemplo n.º 58
0
 def get_topo(self, ev):
     links_list = get_link(self.topology_get, None)
     for link in links_list:
         self.net.add_edge(link.src.dpid, link.dst.dpid, port=link.src.port_no)
Ejemplo n.º 59
0
    def AAR(self, h1, h2):
        count = 0
        count_flow = 0
        start_time = time.time()
        net = nx.DiGraph()
        print "----------------------------------"
        print "Failure link:(", h1, ",", h2, ")"

        links = copy.copy(get_link(self, None))
        edges_list = []  # extra list item for constructing nx graph
        if len(links) > 0:
            for link in links:
                src = link.src
                dst = link.dst
                edges_list.append((src.dpid, dst.dpid, {'port': src.port_no}))
        net.add_edges_from(edges_list)

        for key in self.all_pair_shortest_path.keys():
            path = self.all_pair_shortest_path[key][0]
            back_path = self.all_pair_shortest_path[key][1]
            anchor_nodes = self.all_pair_shortest_path[key][2]
            src, dst = key
            if src in [19, 21, 22, 23, 24] and dst in [9, 10, 11, 18, 17]:
                pass
            else:
                continue
            if h1 in path and h2 in path:
                count_flow = count_flow + 1
                index = path.index(h1)
                index2 = path.index(h2)
                if index != index2 - 1 and index != index2 + 1:
                    continue
                print "Original path:", path
                if index2 < index:
                    index = index2
                new_path = None
                while index != -1:
                    if path[index] in anchor_nodes:
                        count += 1
                        try:
                            new_path = nx.shortest_path(
                                net, path[index], path[-1])
                            for sw in path[:index]:
                                if sw in new_path:
                                    continue
                            break
                        except:
                            log = "do nothing"
                    index = index - 1
                old_path = path[:index]
                if new_path == None:
                    try:
                        count += 1
                        new_path = nx.shortest_path(net, path[0], path[-1])
                        old_path = []
                    except:
                        print "no alternative path found"
                        continue
                print "change to:", old_path, "+", new_path

                path = old_path
                path.extend(new_path)

                if path == back_path:
                    print 'new path is already existed in backup path'
                else:
                    # update monitoring list
                    spath = set(path)
                    ss = set(self.monitoring_list)
                    if (spath & ss):
                        pass
                    else:
                        self.monitoring_list.append(path[-1])
                    # update anchor nodes
                    anchor_nodes = []
                    for sw in path:
                        if len(list(set(nx.all_neighbors(net, sw)))) > 2:
                            anchor_nodes.append(sw)
                    self.all_pair_shortest_path[key][0] = path
                    self.all_pair_shortest_path[key][2] = anchor_nodes

                    # add new flow entry for anchor node
                    datapath = self.dp_list[new_path[0]]
                    out_port = self.net[new_path[0]][new_path[1]]['port']
                    ofp_parser = datapath.ofproto_parser
                    actions = [ofp_parser.OFPActionOutput(out_port)]
                    src, dst = key
                    src = "10.0.0.%s" % (str(src))
                    dst = "10.0.0.%s" % (str(dst))
                    match = ofp_parser.OFPMatch(eth_type=self.eth_type,
                                                ipv4_dst=dst,
                                                ipv4_src=src)
                    self.add_flow(datapath, 1000, match, actions, table=0)

        print "Compute time:", (time.time() - start_time) * 1000, "ms"
        print "Number of computation:", count
        print "Number of flow change:", count_flow
        print "-----------------------------------\n"
        print self.monitoring_list
        print "Total ", len(self.monitoring_list), " switches"
Ejemplo n.º 60
0
    def dpi_init(self, req, **kwargs):

        # get post data
        post_data = req.text.split(",")
        try:
            hw_addr = post_data[0]
            ip_addr = post_data[1]
            dpi_port = post_data[2]
        except:
            return "DPI_POST_ERROR"

        if self.response_app.dpi_info['mac']:
            return "DPI_ALREADY_EXIST"
        else:
            # set dpi_info
            self.response_app.dpi_info['mac'] = hw_addr
            self.response_app.dpi_info['ip'] = ip_addr
            self.response_app.dpi_info['port'] = dpi_port

            # check whether the dpi is in network
            for host in get_host(self.response_app):
                host_dict = host.to_dict()
                if host_dict['mac'] == hw_addr:
                    self.response_app.dpi_info['dpid'] = host_dict['port'][
                        'dpid']
                    self.response_app.dpi_info['port_no'] = host_dict['port'][
                        'port_no']
                    self.response_app.dpi_info['name'] = host_dict['port'][
                        'name']
                    break
            else:
                print "DPI server not found??!"
                return "DPI_INIT_FAIL"

        # XXX: remove all datapaths' table. It's better to remove datapath which dpi server attached to.
        for dp in self.response_app.datapaths.values():
            ofproto = dp.ofproto
            parser = dp.ofproto_parser
            match = parser.OFPMatch()
            # remove all flows
            self.response_app.del_flows(dp, match)
            # add table miss
            actions = [
                parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                       ofproto.OFPCML_NO_BUFFER)
            ]
            inst = [
                parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                             actions)
            ]
            self.response_app.add_flow(dp, 0, match, actions)

        ### Create dpi tree when the dpi server connects to the Ryu controller
        # XXX: only for tree topology. It's better to resolve cyclic topology too.
        # XXX: not consider switch leave and enter situation
        # create the topology tree only with links data
        links = get_link(self.response_app, None)
        links = [link.to_dict() for link in links]
        links_r = []
        for x in links:
            a = int(x['src']['dpid'])
            b = int(x['dst']['dpid'])
            t = ()
            if a < b:
                t = (a, b)
            else:
                t = (b, a)
            if t in links_r:
                continue
            else:
                links_r.append(t)
        #  print links_r

        rdpid = int(self.response_app.dpi_info['dpid'])
        tree = {rdpid: {'parent': None, 'child': []}}

        # tn_check is a list matains the dpid in the tree already
        tn_check = [rdpid]

        # try to create the tree
        while len(links_r) > 0:
            for x in links_r:
                p = None
                if x[0] in tn_check:
                    p = x[0]
                    c = x[1]
                if p is not None and x[1] in tn_check:
                    c = x[0]
                    p = x[1]
                if p is not None:
                    tn_check.append(c)
                    tree[p]['child'].append(c)
                    tree[c] = {'parent': None, 'child': []}  # init child node
                    tree[c]['parent'] = p  # only one parent currently
                    links_r.remove(x)
                    break
            else:
                print "Link wrong in dpi tree: " + str(x)
                break
        print tree
        self.response_app.dpi_info['tree'] = tree
        print self.response_app.dpi_info['tree']

        # start dpi monitor

        # print "dpi monitor thread: start"
        # self.dpi_thread = hub.spawn(self.response_app._dpi_monitor)

        # add dpi to query queue
        # XXX: handle Full exception
        self.response_app.dpiq.put(self.response_app.dpi_info)

        # add trace flow and update hosts' data
        self.trace_flow(None)

        return "DPI_INIT_OK"