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]
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()
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
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
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"))
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
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)]), ]),]))
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"]
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
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"))
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])