def pack (self): """ Packs this object into its wire format. May normalize fields. NOTE: If "data" has been specified, this method may actually return *more than just a single ofp_flow_mod* in packed form. Specifically, it may also have a barrier and an ofp_packet_out. """ po = None if self.data: #TODO: It'd be nice to log and then ignore if not data_is_complete. # Unfortunately, we currently have no logging in here, so we # assert instead which is a either too drastic or too quiet. assert self.data.is_complete assert self.buffer_id is None self.buffer_id = self.data.buffer_id if self.buffer_id is None: po = ofp_packet_out(data=self.data) po.in_port = self.data.in_port po.actions.append(ofp_action_output(port = OFPP_TABLE)) # Should maybe check that packet hits the new entry... # Or just duplicate the actions? (I think that's the best idea) assert self._assert() match = self.match.pack() match_len = len(match) command = self.command command |= (self.table_id << 8) packed = b"" packed += ofp_header.pack(self) packed += struct.pack("!LL", self.vendor, self.subtype) packed += struct.pack("!QHHHHLHHH", self.cookie, command, self.idle_timeout, self.hard_timeout, self.priority, self._buffer_id, self.out_port, self.flags, match_len) packed += _PAD6 packed += match packed += _PAD * ((match_len + 7)/8*8 - match_len) for i in self.actions: packed += i.pack() if po: packed += ofp_barrier_request().pack() packed += po.pack() assert len(packed) == len(self) return packed
def pack (self): assert self._assert() match_len = len(self.match) packed = b"" packed += ofp_header.pack(self) packed += struct.pack("!LL", NX_VENDOR_ID, self.subtype) packed += struct.pack("!LHBBQH", self._buffer_id, self.total_len, self.reason, self.table_id, self.cookie, match_len) packed += _PAD6 packed += match.pack() packed += _PAD * ((match_len + 7)/8*8 - match_len) packed += _PAD2 packed += self.packed_data return packed