def pop_out_tunnel(self, data): ''' tunnel->of ''' nccontainer = ncctunnel_pb2.nccontainer() nccontainer.ParseFromString(data) data = nccontainer.entry if nccontainer.instruction == "Centralized": # TODO self.echo += 1 ack_fromQueue.append( operation_entry(1, nccontainer.switch, nccontainer.op_id)) # self.checkPending() else: try: of_msg = unpack(data) except: logger.debug("Non OpenFlow Message" + str(len(data))) else: if of_msg.header.message_type == Type.OFPT_FEATURES_REPLY: switch_addr = of_msg.datapath_id.value self.tunnelIndex[switch_addr] = self.s self.tun2idx[self.s] = switch_addr self.ofchannelIndex[switch_addr] = self.tun2ofchannel[ self.s] if self.s in self.tun2idx.keys(): # logger.debug("datapath created id : %s" % self.tun2idx[self.s]) pass try: self.tun2ofchannel[self.s].send(data) except: pass
def push_in_tunnel(self, data): """ of -> tunnel """ global pendingBackAck if self.s in self.ofchaneldata.keys(): self.ofchaneldata[self.s] += data else: self.ofchaneldata[self.s] = data lenth = int.from_bytes(self.ofchaneldata[self.s][2:4], byteorder='big') if lenth > len(self.ofchaneldata[self.s]): logger.debug("not complicated packet") return else: data = self.ofchaneldata[self.s][:lenth] self.ofchaneldata[self.s] = self.ofchaneldata[self.s][lenth:] try: of_msg = unpack(data) logger.debug("OpenFlow Message Type: %s" % of_msg.header.message_type) if of_msg.header.message_type == Type.OFPT_FEATURES_REPLY: logger.debug("accept Type.OFPT_FEATURES_REPLY") self.bind_tun_ofchannel(of_msg) self.broadcast_ovs2sp(of_msg.datapath_id.value) elif of_msg.header.message_type == Type.OFPT_PORT_STATUS: # self.receievePortStatus(data) logger.debug(" ingore port status ") elif of_msg.header.message_type == Type.OFPT_ERROR: logger.debug(of_msg.error_type) except: logger.debug("Non OpenFlow Message") nccontainer = self.encapsulate(data) self.ofchaneldata[self.s] = bytes() size = nccontainer.ByteSize() nccontainer = nccontainer.SerializeToString() ver = 1 cmd = 101 header = [ver, size, cmd] headPack = struct.pack("!3I", *header) data = headPack + nccontainer if len(pendingBackAck): senderdata = {} for item in pendingBackAck: if item.sender in senderdata.keys(): senderdata[item.sender] += item.data else: senderdata[item.sender] = item.data for sender in senderdata.keys(): if sender == self.ofchannel2tun[self.s]: data += senderdata[sender] pendingBackAck = [ item for item in pendingBackAck if item.sender != self.s ] break self.ofchannel2tun[self.s].send(data)
def pop_out_tunnel(self, tunneldata): """ tunnel -> of """ global pendingBackAck nccontainer = ncctunnel_pb2.nccontainer() nccontainer.ParseFromString(tunneldata) data = nccontainer.entry if nccontainer.instruction == "TEST": self.block = True logger.debug(str(datetime.now())) newcontainer = container(nccontainer.op_id, nccontainer.instruction, nccontainer.switch, nccontainer.entry, nccontainer.ack_from, nccontainer.ack_to) logger.info("new container " + str(newcontainer)) self.pending_container.append(newcontainer) if newcontainer.state: self.__exec(newcontainer) # elif nccontainer.instruction == "Centralized": # size = nccontainer.ByteSize() # nccontainer = nccontainer.SerializeToString() # ver = 1 # cmd = 101 # header = [ver,size, cmd] # headPack = struct.pack("!3I", *header) # # pendingBackAck.append(backAck(self.s,headPack+nccontainer)) # # self.s.send(headPack+nccontainer) else: if self.s in self.senderdata.keys(): self.senderdata[self.s] += data else: self.senderdata[self.s] = data lenth = int.from_bytes(self.senderdata[self.s][2:4], byteorder='big') if lenth > len(self.senderdata[self.s]): logger.debug("not complicated packet") return else: data = self.senderdata[self.s][:lenth] self.senderdata[self.s] = self.senderdata[self.s][ lenth:] # NOTE buffer try: of_msg = unpack(data) except UnpackException: logger.debug("Non OpenFlow Message") self.tun2ofchannel[self.s].send(data) else: self.tun2ofchannel[self.s].send(data)
async def on_msg(self, msg_data): try: of_msg = unpack(msg_data) except UnpackException: self._connection.logger.debug( "can not unpack OpenFlow Message, %s", str(msg_data)) msg = TunnelMsg.construct(TunnelMsg.TYPE_PASS, msg_data) self._writer.write(msg.pack()) await self._writer.drain() else: await self._on_of_msg(of_msg, msg_data)
async def _on_pass_msg(self, msg): logger = self._connection.logger self._writer.write(msg.body) try: of_msg = unpack(msg.body) except UnpackException: logger.warn("can not unpack OpenFlow Message, %s", str(msg.body)) else: if of_msg.header.message_type == Type.OFPT_FEATURES_REPLY: dpid = of_msg.datapath_id.value logger.info("get OFPT_FEATURES_REPLY, dpid=%s" % dpid) self._connection.register_info(dpid, self._info) await self._writer.drain()
def encapsulate(self, data): """ encapsulate of_message with container_operation """ # TODO: encapsulate of_message with container_op nccontainer = ncctunnel_pb2.nccontainer() try: of_msg = unpack(data) except UnpackException: # logger.debug("Non OpenFlow Message") pass else: logger.debug("OpenFlow Message Type: %s" % of_msg.header.message_type) if of_msg.header.message_type == Type.OFPT_FLOW_MOD: id = str(random.random()) nccontainer.op_id = id nccontainer.entry = data return nccontainer
def test_unpack_v0x04_packet(self): """Test if the package in version v0x04 is properly unpacked.""" data = Hello_v0x04().pack() expected = unpack(data) self.assertEqual(expected.pack(), data)