Beispiel #1
0
	def test_barrier_1(self):
		results = []
		
		sc, ss = self.sc, self.ss
		serv = TestChannel(socket=ss)
		serv.start()
		sc.send(sc.recv(1024)) # echo back HELLO
		serv.recv() # consume HELLO
		
		cb1 = lambda *a: results.append(("cb1", a))
		cb2 = lambda *a: results.append(("cb2", a))
		
		echo = b.ofp_header(version=4,type=2,xid=1,length=8)
		serv.send(echo, callback=cb1)
		pkt = sc.recv(1024)
		b1 = p.parse(pkt[:8])
		assert b1.header.type == ofp4.OFPT_BARRIER_REQUEST
		assert echo == pkt[8:], pkt[8:]

		echo = b.ofp_header(version=4,type=2,xid=2,length=8)
		serv.send(echo, callback=cb2)
		pkt = sc.recv(1024)
		b2 = p.parse(pkt[:8])
		assert b2.header.type == ofp4.OFPT_BARRIER_REQUEST
		assert echo == pkt[8:], pkt[8:]

		echo = b.ofp_header(version=4,type=2,xid=3,length=8)
		serv.send(echo, callback=cb1)
		pkt = sc.recv(1024)
		b3 = p.parse(pkt[:8])
		assert b3.header.type == ofp4.OFPT_BARRIER_REQUEST
		assert echo == pkt[8:], pkt[8:]

		sc.send(b.ofp_header(version=4,
			type=ofp4.OFPT_BARRIER_REPLY,
			xid=b1.header.xid,
			length=8))
		sc.send(b.ofp_header(version=4,type=3,xid=1,length=8))
		sc.send(b.ofp_header(version=4,
			type=ofp4.OFPT_BARRIER_REPLY,
			xid=b2.header.xid,
			length=8))
		sc.send(b.ofp_header(version=4,type=3,xid=2,length=8))
		sc.send(b.ofp_header(version=4,
			type=ofp4.OFPT_BARRIER_REPLY,
			xid=b3.header.xid,
			length=8))
		sc.send(b.ofp_header(version=4,type=3,xid=3,length=8))
		sc.close()

		serv.loop()
		assert [r[0] for r in results] == ["cb1", "cb2", "cb1"], [r[0] for r in results]
Beispiel #2
0
	def controller(self, message, channel):
		import twink.ofp4.parse as ofp4p
		import twink.ofp4.build as ofp4b
		msg = ofp4p.parse(message)
		if msg.header.type==0:
			assert len(channel.ports) == 0
			channel.close()
Beispiel #3
0
    def handleOFMessage(self, data):
        """
        Handles OpenFlow messages.
        """    

        # experimenter message -> ofx.
        version = ord(data[0])
        messageType = ord(data[1])
        mlen = len(data)
        # self.dprint ("version: %s type: %s len: %s"%(version, messageType, mlen))
        exp_id = None
        if messageType == 4:
            exp_id, exp_type = struct.unpack("!II", data[8:16])

        if exp_id == OFX_MESSAGE:
            contents = data[16::]
            self.handleOFXMessage(exp_id, exp_type, contents)
        else:
            ofMessage = ofparse.parse(data)
            ofMessageType = ofMessage.__class__.__name__
            # else, run it through all the registered interceptors.
            if ofMessageType in self.OFInterceptors:
                for fcn in self.OFInterceptors[ofMessageType]:
                    data = fcn(data)            
            return data
Beispiel #4
0
	def switch_reactor(self, message, channel):
		import twink.ofp4.parse as ofp4p
		import twink.ofp4.build as ofp4b
		msg = ofp4p.parse(message)
		if msg.header.type==18 and msg.type==13:
			channel.send(ofp4b.ofp_multipart_reply(ofp4b.ofp_header(4, 19, None, msg.header.xid),
				13, 0, ()))
	def handle(self, message, channel):
		msg = ofp4parse.parse(message)
		if msg.header.type == ofp4.OFPT_HELLO:
			self.ofctl("add-group", "group_id=1,type=all,"+",".join(["bucket=output:%d" % port.port_no for port in self.ports]))
			self.add_flow("table=0,priority=1,  actions=controller,goto_table:1")
			self.add_flow("table=1,priority=3,  dl_dst=01:00:00:00:00:00/01:00:00:00:00:00,  actions=group:1")
			self.add_flow("table=1,priority=1,  actions=group:1")
			self.init = True
Beispiel #6
0
    def handleOFXMessage(self, data, datapathSendFcn):
        """
        Handles OFX messages (experimenter messages with appropriate 
        type code).
        """
        ofMessage = ofparse.parse(data)
        ofxModuleId = ofMessage.exp_type
        # if it goes to the OFX management module, send it there.
        if ofxModuleId==OFX_MANAGEMENT_MODULE:
            self.handleOFXManagementMessage(ofMessage.data, datapathSendFcn)

        # else, send it to whatever module's function is registered to handle the id.
        elif ofxModuleId in self.moduleHandlers:
            self.moduleHandlers[ofxModuleId](ofMessage.data, datapathSendFcn)
	def handle_async(self, message, channel):
		if not self.init:
			return
		
		msg = ofp4parse.parse(message)
		if msg.header.type == ofp4.OFPT_PACKET_IN:
			print(msg)
			in_port = [o for o in oxm.parse_list(msg.match.oxm_fields) if o.oxm_field==oxm.OXM_OF_IN_PORT][0].oxm_value
			src_mac = ":".join(["%02x" % ord(a) for a in msg.data[6:12]])
			channel.add_flow("table=0,priority=2,idle_timeout=300,  dl_src=%s,in_port=%d,  actions=goto_table:1" % (src_mac, in_port))
			channel.add_flow("table=1,priority=2,idle_timeout=300,  dl_dst=%s,  actions=output:%d" % (src_mac, in_port))
			channel.send(b.ofp_packet_out(None, msg.buffer_id, in_port, None, [], None))
			
			print(self.ofctl("dump-flows"))
Beispiel #8
0
 def handle(self, message, channel):
     msg = ofp4parse.parse(message)
     if msg.header.type == ofp4.OFPT_HELLO:
         self.ofctl(
             "add-group", "group_id=1,type=all," + ",".join(
                 ["bucket=output:%d" % port.port_no
                  for port in self.ports]))
         self.add_flow(
             "table=0,priority=1,  actions=controller,goto_table:1")
         self.add_flow(
             "table=1,priority=3,  dl_dst=01:00:00:00:00:00/01:00:00:00:00:00,  actions=group:1"
         )
         self.add_flow("table=1,priority=1,  actions=group:1")
         self.init = True
Beispiel #9
0
def switch_proc(message, channel):
	msg = p.parse(message)
	if msg.header.type == OFPT_FEATURES_REQUEST:
		channel.send(b.ofp_switch_features(b.ofp_header(4, OFPT_FEATURES_REPLY, 0, msg.header.xid), 1, 2, 3, 0, 0xF))
	elif msg.header.type == OFPT_GET_CONFIG_REQUEST:
		channel.send(b.ofp_switch_config(b.ofp_header(4, OFPT_GET_CONFIG_REPLY, 0, msg.header.xid), 0, 0xffe5))
	elif msg.header.type == OFPT_MULTIPART_REQUEST:
		if msg.type == OFPMP_FLOW:
			channel.send(b.ofp_multipart_reply(b.ofp_header(4, OFPT_MULTIPART_REPLY, 0, msg.header.xid),
				msg.type, 0, [
					b.ofp_flow_stats(None, 0, 10, 20, 30, 40, 50, 0, 1, 2, 3,
						b.ofp_match(None, None, "".join([
							oxm.build(None, oxm.OXM_OF_IN_PORT, None, None, 222),
							oxm.build(None, oxm.OXM_OF_ETH_SRC, None, None, binascii.a2b_hex("00112233"))])),
						[b.ofp_instruction_actions(OFPIT_APPLY_ACTIONS, None, [
							b.ofp_action_output(None, None, 1111, OFPCML_MAX)]),
						]),]))
Beispiel #10
0
	def test_io(self):
		def handle(msg, ch):
			context["channel"] = ch

		# blocking server
		serv = twink.StreamServer(("localhost",0))
		serv.channel_cls = TestChannel
		serv_thread = twink.sched.spawn(serv.start)
		
		context["stop"] = serv.stop
		ch = None

		socket = twink.sched.socket
		s = socket.create_connection(serv.server_address[:2])
		ch = type("Client", (twink.OpenflowChannel, twink.LoggingChannel), {"accept_versions":[4,]})()
		ch.attach(s)
		msg = ch.recv()
		assert msg
		version, oftype, l, xid = twink.parse_ofp_header(msg)
		assert version==4

		twink.sched.Event().wait(0.3)

		mon = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
		mon.connect("unknown-%x.monitor" % id(context["channel"]))
		m = type("Client", (twink.OpenflowChannel, twink.LoggingChannel), {"accept_versions":[4,]})()
		m.attach(mon)
		assert p.parse(m.recv()).header.type == ofp4.OFPT_HELLO
		
		msg = b.ofp_header(version=4, type=2, xid=2, length=8)
		ch.send(msg)
		assert m.recv() == msg
		mon.close()
		ch.send(b.ofp_header(version=4, type=2, xid=3, length=8))
		assert m.recv() == b""
	
		ch.close()

		twink.sched.Event().wait(0.1) # wait for serv.loop reads the buffer
		serv.stop()
		serv_thread.join()

		assert context["loop_error"] is None, context["loop_error"]
Beispiel #11
0
	def test_add_flow(self):
		converted = rule2ofp("in_port=1,actions=drop")[0]
		flow = p.parse(converted)
		assert flow.header.type == OFPT_FLOW_MOD
		assert flow.match.oxm_fields
		assert not flow.instructions
		
		converted = rule2ofp("in_port=1,actions=drop", version=1)[0]
		v1msg = struct.unpack_from("!BBHI", converted)
		assert v1msg[0] == 1
		assert v1msg[1] == 14
		
		converted = rule2ofp("in_port=1,actions=drop", version=2)[0]
		v1msg = struct.unpack_from("!BBHI", converted)
		assert v1msg[0] == 2
		assert v1msg[1] == 14
		
		converted = rule2ofp("in_port=1,actions=drop", version=3)[0]
		v1msg = struct.unpack_from("!BBHI", converted)
		assert v1msg[0] == 3
		assert v1msg[1] == 14
Beispiel #12
0
    def test_add_flow(self):
        converted = rule2ofp("in_port=1,actions=drop")[0]
        flow = p.parse(converted)
        assert flow.header.type == OFPT_FLOW_MOD
        assert flow.match.oxm_fields
        assert not flow.instructions

        converted = rule2ofp("in_port=1,actions=drop", version=1)[0]
        v1msg = struct.unpack_from("!BBHI", converted)
        assert v1msg[0] == 1
        assert v1msg[1] == 14

        converted = rule2ofp("in_port=1,actions=drop", version=2)[0]
        v1msg = struct.unpack_from("!BBHI", converted)
        assert v1msg[0] == 2
        assert v1msg[1] == 14

        converted = rule2ofp("in_port=1,actions=drop", version=3)[0]
        v1msg = struct.unpack_from("!BBHI", converted)
        assert v1msg[0] == 3
        assert v1msg[1] == 14
Beispiel #13
0
    def handle_async(self, message, channel):
        if not self.init:
            return

        msg = ofp4parse.parse(message)
        if msg.header.type == ofp4.OFPT_PACKET_IN:
            print(msg)
            in_port = [
                o for o in oxm.parse_list(msg.match.oxm_fields)
                if o.oxm_field == oxm.OXM_OF_IN_PORT
            ][0].oxm_value
            src_mac = ":".join(["%02x" % ord(a) for a in msg.data[6:12]])
            channel.add_flow(
                "table=0,priority=2,idle_timeout=300,  dl_src=%s,in_port=%d,  actions=goto_table:1"
                % (src_mac, in_port))
            channel.add_flow(
                "table=1,priority=2,idle_timeout=300,  dl_dst=%s,  actions=output:%d"
                % (src_mac, in_port))
            channel.send(
                b.ofp_packet_out(None, msg.buffer_id, in_port, None, [], None))

            print(self.ofctl("dump-flows"))
Beispiel #14
0
def switch_proc(message, ofchannel):

    msg = p.parse(message)

    # TODO: Acquire lock

    if msg.header.type == OFPT_FEATURES_REQUEST:
        channel.send(b.ofp_switch_features(b.ofp_header(4, OFPT_FEATURES_REPLY, 0, msg.header.xid), 1, 2, 3, 0, 0xF))

    elif msg.header.type == OFPT_GET_CONFIG_REQUEST:
        channel.send(b.ofp_switch_config(b.ofp_header(4, OFPT_GET_CONFIG_REPLY, 0, msg.header.xid), 0, 0xffe5))

    elif msg.header.type == OFPT_ROLE_REQUEST:
        channel.send(b.ofp_role_request(b.ofp_header(4, OFPT_ROLE_REPLY, 0, msg.header.xid), msg.role, msg.generation_id))

    elif msg.header.type == OFPT_FLOW_MOD:
        if msg.cookie not in flows:
            flows[msg.cookie] = msg
        else:
            print "I already have this FlowMod: Cookie", \
                msg.cookie, oxm.parse_list(flows[msg.cookie].match), (flows[msg.cookie].instructions)

    elif msg.header.type == OFPT_MULTIPART_REQUEST:
        if msg.type == OFPMP_FLOW:
            channel.send(b.ofp_multipart_reply(b.ofp_header(4, OFPT_MULTIPART_REPLY, 0, msg.header.xid),
                         msg.type, 0, ["".join(b.ofp_flow_stats(None, f.table_id, 1, 2, f.priority,
                                                                f.idle_timeout, f.hard_timeout, f.flags, f.cookie, 0, 0,
                                                                f.match, f.instructions)
                                               for f in flows.itervalues())]))
        elif msg.type == OFPMP_PORT_DESC:
            channel.send(b.ofp_multipart_reply(b.ofp_header(4, OFPT_MULTIPART_REPLY, 0, msg.header.xid),
                         msg.type, 0, ["".join(b.ofp_port(ofp.port_no, ofp.hw_addr, ofp.name, ofp.config, ofp.state,
                                                          ofp.curr, ofp.advertised, ofp.supported, ofp.peer, ofp.curr_speed, ofp.max_speed)
                                               for ofp in of_ports.itervalues())]))
        elif msg.type == OFPMP_DESC:
            channel.send(b.ofp_multipart_reply(b.ofp_header(4, OFPT_MULTIPART_REPLY, 0, msg.header.xid),
                         msg.type, 0, 
                         b.ofp_desc("UC Berkeley", "Intel Xeon", "BESS", "commit-6e343", None)))

    elif msg.header.type ==  OFPT_PACKET_OUT:
        index = msg.actions[0].port
        print "Packet out OF Port %d, Len:%d" % (index, len(msg.data))
        sock = of_ports[index].pkt_inout_socket
        if sock is not None:
            sent = sock.send(msg.data)
            if sent != len(msg.data):
                print "Incomplete Transmission Sent:%d, Len:%d" % (sent, len(msg.data))
        else:
            print "Packet out OF Port %d, Len:%d. Failed - Null socket" % (index, len(msg.data))

    elif msg.header.type == OFPT_HELLO:
        pass

    elif msg.header.type == OFPT_SET_CONFIG:
        pass

    elif msg.header.type == OFPT_BARRIER_REQUEST:
        pass

    else:
        print msg
        assert 0
    try:

        temp = testFile.read(8)
        if temp is None:
            break
        start = struct.unpack("d", temp)[0]
        temp = testFile.read(4)
        length = struct.unpack("i", temp)[0]
        msg = testFile.read(length)
        data.append((start, length, msg))
    except:
        traceback.print_exc()
        break

for (start, length, msg) in data:
    pkt = parse.parse(msg)
    print "working start%s" % start
    if pkt.__class__.__name__ == "ofp_packet_in":
        ether_pkt = Ether(pkt.data)
        if UDP in ether_pkt:
            udp_sport = ether_pkt[UDP].sport
            start_time = start
            udp_start_time[udp_sport] = start_time

    elif pkt.__class__.__name__ == "ofp_packet_out":
        ether_pkt = Ether(pkt.data)
        if UDP in ether_pkt:
            stop_time = start
            udp_sport = ether_pkt[UDP].sport
            udp_stop_time.append(stop_time - udp_start_time[udp_sport])