Example #1
0
    def switch_handler(self, address, fd, events):
        if events & io_loop.READ:
            data = self.sock_sw.recv(1024)
            if data == '':
                print "switch disconnected"
                io_loop.remove_handler(self.fd_sw)
                print "closing connection to controller"
                self.sock_con.close()
                io_loop.remove_handler(self.fd_con)
            else:
                rmsg = of.ofp_header(data[0:8])

                if rmsg.type == 6:
                    print "OFPT_FEATURES_REPLY"                                                  #Actually,we just need to change here.
                    header = of.ofp_header(data[0:8]) 
                    print "ofp_features_reply.xid ", header.xid
                    msg = of.ofp_features_reply(data[8:32])     #all sw type should make the convertion. Because our protocol need to use in all nets.
                    msg_port = data[32:]
                    msg = header/msg/msg_port                     
                    self.dpid=msg.datapath_id       #record the dpid
                    data = convert.of2ofc(msg, self.buffer, self.dpid)   
                    
                elif rmsg.type == 10:
                    pkt_in_msg = of.ofp_packet_in(data[8:18])
                    pkt_parsed = of.Ether(data[18:])
                    self.counter+=1
                    #[port + id+ dpid] --> [buffer_id + pkt_in_msg]
                    if isinstance(pkt_parsed.payload, of.IP) or isinstance(pkt_parsed.payload.payload, of.IP):
                        self.buffer[(pkt_in_msg.in_port, self.counter, self.dpid)] = [pkt_in_msg.buffer_id, rmsg/pkt_in_msg/pkt_parsed] # bind buffer id with in port 
                    rmsg.xid = self.counter                 # use the counter to check the buffer
                    data = rmsg/pkt_in_msg/pkt_parsed

                elif rmsg.type ==11:
                    match = ofc.ofp_match(data[12:48])                  #data[8:12]is wildcards
                    for flow in  self.flow_cache:
                        if match == ofc.ofp_match(str(flow[1])[12:48]):
                            self.flow_cache.remove(flow)                #delete the flow
                elif rmsg.type == 17:
                    print "stats_reply" ,len(data)
                    body = data[8:]
                    reply_header = of.ofp_stats_reply(body[:4])
                    if reply_header.type == 1 and len(data)>91:
                        reply_body_match = ofc.ofp_match(body[12:48])
                        reply_body_data2 = ofc.ofp_flow_stats_data(body[48:92])
                        if reply_body_data2.byte_count == 0 and reply_body_data2.packet_count == 0:  #it is a junck flow,delete it!
                            for flow in  self.flow_cache: 
                                if reply_body_match == ofc.ofp_match(str(flow[1])[12:48]):
                                    self.flow_cache.remove(flow)    
                io_loop.update_handler(self.fd_con, io_loop.WRITE)
                self.queue_con.put(str(data))
    
        if events & io_loop.WRITE:
            try:
                next_msg = self.queue_sw.get_nowait()
            except Queue.Empty:
                #print "%s queue empty" % str(address)
                io_loop.update_handler(self.fd_sw, io_loop.READ)
            else:
                #print 'sending "%s" to %s' % (of.ofp_type[of.ofp_header(next_msg).type], self.sock_sw.getpeername())
                self.sock_sw.send(next_msg)
Example #2
0
def features_reply_handler(data, fd):
    #print ">>>OFPT_FEATURES_REPLY"
    body = data[8:]
    msg = of.ofp_features_reply(body[0:24])  #length of reply msg
    sock_dpid[fd] = msg.datapath_id
    """
	port_info_raw = str(body[24:])                              #we change it into str so we can manipulate it.
	port_info = {}

	#print ">>>port number:",len(port_info_raw)/48, "total length:", len(port_info_raw)
	for i in range(len(port_info_raw)/48):
	    port= of.ofp_phy_port(port_info_raw[0+i*48:48+i*48])
	    #port.show()
	    #print port.port_no
	    port_info[port.port_no]= port                           #save port_info by port_no

	                         #sock_dpid[fd] comes from here.
	features_info[msg.datapath_id] =(msg, port_info)            #features_info[dpid] = (sw_features, port_info{})
	"""
    return None
Example #3
0
def features_reply_handler(data,fd):
	#print ">>>OFPT_FEATURES_REPLY"
	body = data[8:]
	msg = of.ofp_features_reply(body[0:24])                     #length of reply msg
	sock_dpid[fd]=msg.datapath_id 
	"""
	port_info_raw = str(body[24:])                              #we change it into str so we can manipulate it.
	port_info = {}

	#print ">>>port number:",len(port_info_raw)/48, "total length:", len(port_info_raw)
	for i in range(len(port_info_raw)/48):
	    port= of.ofp_phy_port(port_info_raw[0+i*48:48+i*48])
	    #port.show()
	    #print port.port_no
	    port_info[port.port_no]= port                           #save port_info by port_no

	                         #sock_dpid[fd] comes from here.
	features_info[msg.datapath_id] =(msg, port_info)            #features_info[dpid] = (sw_features, port_info{})
	"""
	return None
Example #4
0
18   okay    "OFPT_BARRIER_REQUEST",
19   okay    "OFPT_BARRIER_REPLY",
20   okay    "OFPT_QUEUE_GET_CONFIG_REQUEST",
21   okay    "OFPT_QUEUE_GET_CONFIG_REPLY"
24   oaky    "OFPT_CFEATURES_REPLY"
0xfe oaky    "OFPT_CPORT_STATUS" 
0xff okay    "OFPT_CFLOW_MO
"""
    
if __name__ == '__main__':
    import convert
    import libopenflow as of 
    #a = ofp_cfeatures_reply()
    #b = ofp_phy_cport()
    #c = ofp_phy_cport()
    #d=ofp_header(type =24,length = 32+78*2)/ofp_cfeatures_reply(n_cports=2)/ofp_phy_cport()/sup_wave_port_bandwidth(num_lmda=4)/ofp_phy_cport()/sup_wave_port_bandwidth(num_lmda=5)

    #d.show()
    #a.n_cports=2
    #a.OFPC_TABLE_STATS=100
    #a.OFPST_T_OTN = 1
    #a.SUPP_SW_GRAN = 129
    #print a.SUPP_SW_GRAN
    buffer = {}
    dpid = 8

    e = of.ofp_header(type =6)/of.ofp_features_reply(datapath_id=1)/of.ofp_phy_port(port_no=1)/of.ofp_phy_port(port_no=2)\
                              /of.ofp_phy_port(port_no=3)/of.ofp_phy_port(port_no=4)/of.ofp_phy_port(port_no=5)
    f = convert.of2ofc(e, buffer, dpid)
    f.show()
    p = str(f)
Example #5
0
18   okay    "OFPT_BARRIER_REQUEST",
19   okay    "OFPT_BARRIER_REPLY",
20   okay    "OFPT_QUEUE_GET_CONFIG_REQUEST",
21   okay    "OFPT_QUEUE_GET_CONFIG_REPLY"
24   oaky    "OFPT_CFEATURES_REPLY"
0xfe oaky    "OFPT_CPORT_STATUS" 
0xff okay    "OFPT_CFLOW_MO
"""
    
if __name__ == '__main__':
    import convert
    import libopenflow as of 
    #a = ofp_cfeatures_reply()
    #b = ofp_phy_cport()
    #c = ofp_phy_cport()
    #d=ofp_header(type =24,length = 32+78*2)/ofp_cfeatures_reply(n_cports=2)/ofp_phy_cport()/sup_wave_port_bandwidth(num_lmda=4)/ofp_phy_cport()/sup_wave_port_bandwidth(num_lmda=5)

    #d.show()
    #a.n_cports=2
    #a.OFPC_TABLE_STATS=100
    #a.OFPST_T_OTN = 1
    #a.SUPP_SW_GRAN = 129
    #print a.SUPP_SW_GRAN
    buffer = {}
    dpid = 8

    e = of.ofp_header(type =6)/of.ofp_features_reply(datapath_id=1)/of.ofp_phy_port(port_no=1)/of.ofp_phy_port(port_no=2)\
                              /of.ofp_phy_port(port_no=3)/of.ofp_phy_port(port_no=4)/of.ofp_phy_port(port_no=5)
    f = convert.of2ofc(e, buffer, dpid)
    f.show()
    p = str(f)
Example #6
0
def client_handler(address, fd, events):
    sock = fd_map[fd]
    #print sock, sock.getpeername(), sock.getsockname()
    if events & io_loop.READ:
        data = sock.recv(1024)
        if data == '':
            """
            According to stackoverflow(http://stackoverflow.com/questions/667640/how-to-tell-if-a-connection-is-dead-in-python)
            When a socket is closed, the server will receive a EOF. In python, however, server will
            receive a empty string(''). So, when a switch disconnected, the server will find out
            at once. But, if you do not react on this incident, there will be always a ``ioloop.read``
            event. And the loop will run forever, thus, the CPU useage will be pretty high.
            """
            print "connection dropped"
            io_loop.remove_handler(fd)
        if len(data)<8:
            print "not a openflow message"
        else:
            #print len(data)
            #if the data length is 8, then only of header
            #else, there are payload after the header
            if len(data)>8:
                rmsg = of.ofp_header(data[0:8])
                body = data[8:]
            else:
                rmsg = of.ofp_header(data)
            #rmsg.show()
            if rmsg.type == 0:
                print "OFPT_HELLO"
                msg = of.ofp_header(type = 5)
                io_loop.update_handler(fd, io_loop.WRITE)
                message_queue_map[sock].put(data)
                message_queue_map[sock].put(str(msg))
            elif rmsg.type == 1:
                print "OFPT_ERROR"
            elif rmsg.type == 5:
                print "OFPT_FEATURES_REQUEST"
            elif rmsg.type == 6:
                print "OFPT_FEATURES_REPLY"
                #print "rmsg.load:",len(body)/48
                msg = of.ofp_features_reply(body[0:24])#length of reply msg
                #msg.show()
                port_info_raw = body[24:]
                port_info = {}
                print "port number:",len(port_info_raw)/48, "total length:", len(port_info_raw)
                for i in range(len(port_info_raw)/48):
                    #print "port", i, ",len:", len(port_info_raw[0+i*48:48+i*48]) 
                    """The port structure has a length of 48 bytes.
                       so when receiving port info, first split the list
                       into port structure length and then analysis
                    """
                    port_info[i] = of.ofp_phy_port(port_info_raw[0+i*48:48+i*48])
                    #print port_info[i].port_name
                    #port_info[i].show()
                    #print port_info[i].OFPPC_PORT_DOWN

            elif rmsg.type == 2:
                print "OFPT_ECHO_REQUEST"
                msg = of.ofp_header(type=3, xid=rmsg.xid)
                
                #test for status request [which is good]
                global exe_id
                global ofp_match_obj
                if exe_id>1:
                    #len = 8+4+44
                    stat_req = of.ofp_header(type=16,length=56)\
                               /of.ofp_stats_request(type=1)\
                               /of.ofp_flow_wildcards()\
                               /ofp_match_obj\
                               /of.ofp_flow_stats_request()
                    #stat_req.show()
                
                message_queue_map[sock].put(str(msg))
                if exe_id>1:
                    message_queue_map[sock].put(str(stat_req))
                io_loop.update_handler(fd, io_loop.WRITE)
                #end of test
                
                #io_loop.update_handler(fd, io_loop.WRITE)
                #message_queue_map[sock].put(str(msg))
            elif rmsg.type == 3:
                print "OFPT_ECHO_REPLY"
            elif rmsg.type == 4:
                print "OFPT_VENDOR"
            elif rmsg.type == 6:
                print "OFPT_FEATURES_REPLY"
            elif rmsg.type == 7:
                print "OFPT_GET_CONFIG_REQUEST"
            elif rmsg.type == 8:
                print "OFPT_GET_CONFIG_REPLY"
            elif rmsg.type == 9:
                print "OFPT_SET_CONFIG"
            elif rmsg.type == 10:
                #print "OFPT_PACKET_IN"
                #rmsg.show()
                pkt_in_msg = of.ofp_packet_in(body)
                #pkt_in_msg.show()
                raw = pkt_in_msg.load
                pkt_parsed = of.Ether(raw)
                #pkt_parsed.payload.show()
                #print "to see if the payload of ether is IP"
                #if isinstance(pkt_parsed.payload, of.IP):
                    #pkt_parsed.show()
                if isinstance(pkt_parsed.payload, of.ARP):
                    #pkt_parsed.show()
                    #pkt_out = of.ofp_header()/of.ofp_pktout_header()/of.ofp_action_output()
                    pkt_out.payload.payload.port = 0xfffb
                    pkt_out.payload.buffer_id = pkt_in_msg.buffer_id
                    pkt_out.payload.in_port = pkt_in_msg.in_port
                    pkt_out.length = 24
                    #pkt_out.show()
                    io_loop.update_handler(fd, io_loop.WRITE)
                    message_queue_map[sock].put(str(pkt_out))
                if isinstance(pkt_parsed.payload, of.IP):
                    if isinstance(pkt_parsed.payload.payload, of.ICMP):
                        #print "from", pkt_parsed.src, "to", pkt_parsed.dst 
                        
                        """
                        When receive a OPF_PACKET_IN message, you can caculate a path, and then
                        use OFP_FLOW_MOD message to install path. Also, you can find out the exact
                        port to send the message, then you can use the following code to send a
                        OFP_PACKET_OUT message and send the packet to destination.
                        """
                        
                        #pkt_parsed.show()
                        #pkt_out = of.ofp_header()/of.ofp_pktout_header()/of.ofp_action_output()
                        pkt_out.payload.payload.port = 0xfffb
                        pkt_out.payload.buffer_id = pkt_in_msg.buffer_id
                        pkt_out.payload.in_port = pkt_in_msg.in_port
                        pkt_out.length = 24
                        
                        """
                        io_loop.update_handler(fd, io_loop.WRITE)
                        message_queue_map[sock].put(str(pkt_out))
                        """
                        
                        #print pkt_parsed.payload.proto
                        #pkt_parsed.show()
                        #print "ICMP protocol"
                        #pkt_out.show()
                        #usually don't have to fill in ``wilecards`` area
                        
                        global cookie
                        global exe_id
                        exe_id += 1
                        cookie += 1
                        flow_mod_msg = of.ofp_header(type=14,
                                                     length=80,
                                                     xid=exe_id)/\
                        of.ofp_flow_wildcards()\
                        /of.ofp_match(in_port=pkt_in_msg.in_port,
                                      dl_src=pkt_parsed.src,
                                      dl_dst=pkt_parsed.dst,
                                      dl_type=pkt_parsed.type,
                                      nw_tos=pkt_parsed.payload.tos,
                                      nw_proto=pkt_parsed.payload.proto,
                                      nw_src=pkt_parsed.payload.src,
                                      nw_dst=pkt_parsed.payload.dst,
                                      tp_src = pkt_parsed.payload.payload.type,
                                      tp_dst = pkt_parsed.payload.payload.code)\
                        /of.ofp_flow_mod(cookie=cookie,
                                         command=0,
                                         idle_timeout=60,
                                         buffer_id=pkt_in_msg.buffer_id,#icmp type 8: request, 0: reply
                                         flags=1)\
                        /of.ofp_action_output(type=0, 
                                              port=0xfffb,
                                              len=8)
                        
                        #flow_mod_msg.show()
                        global ofp_match_obj
                        ofp_match_obj = of.ofp_match(in_port=pkt_in_msg.in_port,
                                      dl_src=pkt_parsed.src,
                                      dl_dst=pkt_parsed.dst,
                                      dl_type=pkt_parsed.type,
                                      nw_tos=pkt_parsed.payload.tos,
                                      nw_proto=pkt_parsed.payload.proto,
                                      nw_src=pkt_parsed.payload.src,
                                      nw_dst=pkt_parsed.payload.dst,
                                      tp_src = pkt_parsed.payload.payload.type,
                                      tp_dst = pkt_parsed.payload.payload.code)
                        
                        exe_id += 1
                        """
                        
                        print "--------------------------------------------------------------------------------------"
                        print "len of flow_mod_msg        :", len(str(flow_mod_msg))
                        print "len of of_header()         :", len(str(of.ofp_header()))
                        print "len of ofp_flow_wildcards():", len(str(of.ofp_flow_wildcards()))
                        print "len of ofp_match()         :", len(str(of.ofp_match()))
                        print "len of ofp_flow_mod()      :", len(str(of.ofp_flow_mod(command=0,idle_timeout=60,buffer_id=pkt_in_msg.buffer_id)))
                        print "len of ofp_action_output() :", len(str(of.ofp_action_output(type=0,port=0xfffb,len=8)))
                        print "--------------------------------------------------------------------------------------"
                        """
                        io_loop.update_handler(fd, io_loop.WRITE)
                        #message_queue_map[sock].put(str(pkt_out))
                        message_queue_map[sock].put(str(flow_mod_msg))
                        message_queue_map[sock].put(str(of.ofp_header(type=18,xid=exe_id))) #send a barrier request msg.

            elif rmsg.type == 11: 
                print "OFPT_FLOW_REMOVED"
            elif rmsg.type == 12:
                print "OFPT_PORT_STATUS"
            elif rmsg.type == 13:
                print "OFPT_PACKET_OUT"
            elif rmsg.type == 14:
                print "OFPT_FLOW_MOD"
            elif rmsg.type == 15:
                print "OFPT_PORT_MOD"
            elif rmsg.type == 16:
                print "OFPT_STATS_REQUEST"
                
            elif rmsg.type == 17:
                print "OFPT_STATS_REPLY"
                # 1. parsing ofp_stats_reply
                reply_header = of.ofp_stats_reply(body[:4])
                
                # 2.parsing ofp_flow_stats msg
                reply_body_data1 = of.ofp_flow_stats(body[4:8])
                # match field in ofp_flow_stats
                reply_body_wildcards = of.ofp_flow_wildcards(body[8:12])
                reply_body_match = of.ofp_match(body[12:48])
                # second part in ofp_flow_stats
                reply_body_data2 = of.ofp_flow_stats_data(body[48:92])
                
                # 3.parsing actions
                # should first judge action type 
                i = 0
                reply_body_action = []
                #print len(body[92:])
                while i<len(body[92:]):
                    if body[95+i:96+i]==0x08:
                        print "0x08"
                    i+=8
                    if body[95+i:96+i] == 0x08:
                        reply_body_action.append(of.ofp_action_output(body[92+i:100+i]))
                        #i+=8
                # 4.show msg
                msg = reply_header/reply_body_data1/reply_body_wildcards/reply_body_match/reply_body_data2
                msg.show()
                print reply_body_action
            
            # no message body
            elif rmsg.type == 18:
                print "OFPT_BARRIER_REQUEST"
            
            #no message body, the xid is the previous barrier request xid
            elif rmsg.type == 19:
                print "OFPT_BARRIER_REPLY: ", rmsg.xid, "Successful"
            elif rmsg.type == 20:
                print "OFPT_QUEUE_GET_CONFIG_REQUEST"
            elif rmsg.type == 21:
                print "OFPT_QUEUE_GET_CONFIG_REPLY"

    if events & io_loop.WRITE:
        try:
            next_msg = message_queue_map[sock].get_nowait()
        except Queue.Empty:
            #print "%s queue empty" % str(address)
            io_loop.update_handler(fd, io_loop.READ)
        else:
            #print 'sending "%s" to %s' % (of.ofp_header(next_msg).type, address)
            sock.send(next_msg)