# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation. # Copyright (C) 2012 Isaku Yamahata # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or # implied. # See the License for the specific language governing permissions and # limitations under the License. import collections import struct import itertools from ryu.lib import mac from ryu import utils from ofproto_parser import MsgBase, msg_pack_into, msg_str_attr from . import ofproto_parser from . import ofproto_v1_2 import logging LOG = logging.getLogger('ryu.ofproto.ofproto_v1_2_parser') _MSG_PARSERS = {} def _set_msg_type(msg_type): def _set_cls_msg_type(cls): cls.cls_msg_type = msg_type return cls return _set_cls_msg_type def _register_parser(cls): '''class decorator to register msg parser''' assert cls.cls_msg_type is not None assert cls.cls_msg_type not in _MSG_PARSERS _MSG_PARSERS[cls.cls_msg_type] = cls.parser return cls @ofproto_parser.register_msg_parser(ofproto_v1_2.OFP_VERSION) def msg_parser(datapath, version, msg_type, msg_len, xid, buf): parser = _MSG_PARSERS.get(msg_type) return parser(datapath, version, msg_type, msg_len, xid, buf) @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_HELLO) class OFPHello(MsgBase): def __init__(self, datapath): super(OFPHello, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_ERROR) class OFPErrorMsg(MsgBase): def __init__(self, datapath): super(OFPErrorMsg, self).__init__(datapath) self.type = None self.code = None self.data = None @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPErrorMsg, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.type, msg.code = struct.unpack_from( ofproto_v1_2.OFP_ERROR_MSG_PACK_STR, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE) msg.data = msg.buf[ofproto_v1_2.OFP_ERROR_MSG_SIZE:] return msg def _serialize_body(self): assert self.data is not None msg_pack_into(ofproto_v1_2.OFP_ERROR_MSG_PACK_STR, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.type, self.code) self.buf += self.data @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_ECHO_REQUEST) class OFPEchoRequest(MsgBase): def __init__(self, datapath): super(OFPEchoRequest, self).__init__(datapath) self.data = None @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoRequest, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto_v1_2.OFP_HEADER_SIZE:] return msg def _serialize_body(self): if self.data is not None: self.buf += self.data @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_ECHO_REPLY) class OFPEchoReply(MsgBase): def __init__(self, datapath): super(OFPEchoReply, self).__init__(datapath) self.data = None @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPEchoReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.data = msg.buf[ofproto_v1_2.OFP_HEADER_SIZE:] return msg def _serialize_body(self): assert self.data is not None self.buf += self.data @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_EXPERIMENTER) class OFPExperimenter(MsgBase): def __init__(self, datapath): super(OFPExperimenter, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPExperimenter, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.experimenter, msg.exp_type) = struct.unpack_from( ofproto_v1_2.OFP_EXPERIMENTER_HEADER_PACK_STR, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE) return msg class OFPPort(collections.namedtuple('OFPPort', ( 'port_no', 'hw_addr', 'name', 'config', 'state', 'curr', 'advertised', 'supported', 'peer', 'curr_speed', 'max_speed'))): @classmethod def parser(cls, buf, offset): port = struct.unpack_from(ofproto_v1_2.OFP_PORT_PACK_STR, buf, offset) return cls(*port) @_set_msg_type(ofproto_v1_2.OFPT_FEATURES_REQUEST) class OFPFeaturesRequest(MsgBase): def __init__(self, datapath): super(OFPFeaturesRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_FEATURES_REPLY) class OFPSwitchFeatures(MsgBase): def __init__(self, datapath): super(OFPSwitchFeatures, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPSwitchFeatures, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.datapath_id, msg.n_buffers, msg.n_tables, msg.capabilities, msg.reserved) = struct.unpack_from( ofproto_v1_2.OFP_SWITCH_FEATURES_PACK_STR, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE) msg.ports = {} n_ports = ((msg_len - ofproto_v1_2.OFP_SWITCH_FEATURES_SIZE) / ofproto_v1_2.OFP_PORT_SIZE) offset = ofproto_v1_2.OFP_SWITCH_FEATURES_SIZE for i in range(n_ports): port = OFPPort.parser(msg.buf, offset) msg.ports[port.port_no] = port offset += ofproto_v1_2.OFP_PORT_SIZE return msg @_set_msg_type(ofproto_v1_2.OFPT_GET_CONFIG_REQUEST) class OFPGetConfigRequest(MsgBase): def __init__(self, datapath): super(OFPGetConfigRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_GET_CONFIG_REPLY) class OFPGetConfigReply(MsgBase): def __init__(self, datapath): super(OFPGetConfigReply, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPGetConfigReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.flags, msg.miss_send_len = struct.unpack_from( ofproto_v1_2.OFP_SWITCH_CONFIG_PACK_STR, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE) return msg @_set_msg_type(ofproto_v1_2.OFPT_SET_CONFIG) class OFPSetConfig(MsgBase): def __init__(self, datapath, flags=None, miss_send_len=None): super(OFPSetConfig, self).__init__(datapath) self.flags = flags self.miss_send_len = miss_send_len def _serialize_body(self): assert self.flags is not None assert self.miss_send_len is not None msg_pack_into(ofproto_v1_2.OFP_SWITCH_CONFIG_PACK_STR, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.flags, self.miss_send_len) @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_PACKET_IN) class OFPPacketIn(MsgBase): def __init__(self, datapath): super(OFPPacketIn, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPacketIn, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.buffer_id, msg.total_len, msg.reason, msg.table_id) = struct.unpack_from( ofproto_v1_2.OFP_PACKET_IN_PACK_STR, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE) msg.match = OFPMatch.parser(msg.buf, ofproto_v1_2.OFP_PACKET_IN_SIZE - ofproto_v1_2.OFP_MATCH_SIZE) match_len = utils.round_up(msg.match.length, 8) msg.data = msg.buf[(ofproto_v1_2.OFP_PACKET_IN_SIZE - ofproto_v1_2.OFP_MATCH_SIZE + match_len + 2):] if msg.total_len < len(msg.data): # discard padding for 8-byte alignment of OFP packet msg.data = msg.data[:msg.total_len] return msg @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_FLOW_REMOVED) class OFPFlowRemoved(MsgBase): def __init__(self, datapath): super(OFPFlowRemoved, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPFlowRemoved, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.cookie, msg.priority, msg.reason, msg.table_id, msg.duration_sec, msg.duration_nsec, msg.idle_timeout, msg.hard_timeout, msg.packet_count, msg.byte_count) = struct.unpack_from( ofproto_v1_2.OFP_FLOW_REMOVED_PACK_STR0, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE) offset = (ofproto_v1_2.OFP_FLOW_REMOVED_SIZE - ofproto_v1_2.OFP_MATCH_SIZE) msg.match = OFPMatch.parser(buf, offset) return msg @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_PORT_STATUS) class OFPPortStatus(MsgBase): def __init__(self, datapath): super(OFPPortStatus, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPPortStatus, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.reason = struct.unpack_from( ofproto_v1_2.OFP_PORT_STATUS_PACK_STR, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE)[0] msg.desc = OFPPort.parser(msg.buf, ofproto_v1_2.OFP_PORT_STATUS_DESC_OFFSET) return msg @_set_msg_type(ofproto_v1_2.OFPT_PACKET_OUT) class OFPPacketOut(MsgBase): def __init__(self, datapath, buffer_id=None, in_port=None, actions=None, data=None): # The in_port field is the ingress port that must be associated # with the packet for OpenFlow processing. assert in_port is not None super(OFPPacketOut, self).__init__(datapath) self.buffer_id = buffer_id self.in_port = in_port self.actions_len = 0 self.actions = actions self.data = data def _serialize_body(self): self.actions_len = 0 offset = ofproto_v1_2.OFP_PACKET_OUT_SIZE for a in self.actions: a.serialize(self.buf, offset) offset += a.len self.actions_len += a.len if self.data is not None: assert self.buffer_id == 0xffffffff self.buf += self.data msg_pack_into(ofproto_v1_2.OFP_PACKET_OUT_PACK_STR, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.buffer_id, self.in_port, self.actions_len) @_set_msg_type(ofproto_v1_2.OFPT_FLOW_MOD) class OFPFlowMod(MsgBase): def __init__(self, datapath, cookie, cookie_mask, table_id, command, idle_timeout, hard_timeout, priority, buffer_id, out_port, out_group, flags, match, instructions): super(OFPFlowMod, self).__init__(datapath) self.cookie = cookie self.cookie_mask = cookie_mask self.table_id = table_id self.command = command self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.priority = priority self.buffer_id = buffer_id self.out_port = out_port self.out_group = out_group self.flags = flags self.match = match self.instructions = instructions def _serialize_body(self): msg_pack_into(ofproto_v1_2.OFP_FLOW_MOD_PACK_STR0, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.cookie, self.cookie_mask, self.table_id, self.command, self.idle_timeout, self.hard_timeout, self.priority, self.buffer_id, self.out_port, self.out_group, self.flags) offset = (ofproto_v1_2.OFP_FLOW_MOD_SIZE - ofproto_v1_2.OFP_MATCH_SIZE) match_len = self.match.serialize(self.buf, offset) offset += match_len for inst in self.instructions: inst.serialize(self.buf, offset) offset += inst.len class OFPInstruction(object): _INSTRUCTION_TYPES = {} @staticmethod def register_instruction_type(types): def _register_instruction_type(cls): for type_ in types: OFPInstruction._INSTRUCTION_TYPES[type_] = cls return cls return _register_instruction_type @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from('!HH', buf, offset) cls_ = cls._INSTRUCTION_TYPES.get(type_) return cls_.parser(buf, offset) @OFPInstruction.register_instruction_type([ofproto_v1_2.OFPIT_GOTO_TABLE]) class OFPInstructionGotoTable(object): def __init__(self, table_id): super(OFPInstructionGotoTable, self).__init__() self.type = ofproto_v1_2.OFPIT_GOTO_TABLE self.len = ofproto_v1_2.OFP_INSTRUCTION_GOTO_TABLE_SIZE self.table_id = table_id @classmethod def parser(cls, buf, offset): (type_, len_, table_id) = struct.unpack_from( ofproto_v1_2.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset) return cls(table_id) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR, buf, offset, self.type, self.len, self.table_id) @OFPInstruction.register_instruction_type([ofproto_v1_2.OFPIT_WRITE_METADATA]) class OFPInstructionWriteMetadata(object): def __init__(self, metadata, metadata_mask): super(OFPInstructionWriteMetadata, self).__init__() self.type = ofproto_v1_2.OFPIT_WRITE_METADATA self.len = ofproto_v1_2.OFP_INSTRUCTION_WRITE_METADATA_SIZE self.metadata = metadata self.metadata_mask = metadata_mask @classmethod def parser(cls, buf, offset): (type_, len_, metadata, metadata_mask) = struct.unpack_from( ofproto_v1_2.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset) return cls(metadata, metadata_mask) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR, buf, offset, self.type, self.len, self.metadata, self.metadata_mask) @OFPInstruction.register_instruction_type([ofproto_v1_2.OFPIT_WRITE_ACTIONS, ofproto_v1_2.OFPIT_APPLY_ACTIONS, ofproto_v1_2.OFPIT_CLEAR_ACTIONS]) class OFPInstructionActions(object): def __init__(self, type_, actions=None): super(OFPInstructionActions, self).__init__() self.type = type_ self.actions = actions @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset) offset += ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_SIZE actions = [] actions_len = len_ - ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_SIZE while actions_len > 0: a = OFPAction.parser(buf, offset) actions.append(a) actions_len -= a.len offset += a.len inst = cls(type_, actions) inst.len = len_ return inst def serialize(self, buf, offset): action_offset = offset + ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_SIZE if self.actions: for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len self.len = action_offset - offset pad_len = utils.round_up(self.len, 8) - self.len ofproto_parser.msg_pack_into("%dx" % pad_len, buf, action_offset) self.len += pad_len msg_pack_into(ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_PACK_STR, buf, offset, self.type, self.len) class OFPActionHeader(object): def __init__(self, type_, len_): self.type = type_ self.len = len_ def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_HEADER_PACK_STR, buf, offset, self.type, self.len) class OFPAction(OFPActionHeader): _ACTION_TYPES = {} @staticmethod def register_action_type(type_, len_): def _register_action_type(cls): cls.cls_action_type = type_ cls.cls_action_len = len_ OFPAction._ACTION_TYPES[cls.cls_action_type] = cls return cls return _register_action_type def __init__(self): cls = self.__class__ super(OFPAction, self).__init__(cls.cls_action_type, cls.cls_action_len) @classmethod def parser(cls, buf, offset): type_, len_ = struct.unpack_from( ofproto_v1_2.OFP_ACTION_HEADER_PACK_STR, buf, offset) cls_ = cls._ACTION_TYPES.get(type_) assert cls_ is not None return cls_.parser(buf, offset) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_HEADER_PACK_STR, buf, offset, self.type, self.len) @OFPAction.register_action_type(ofproto_v1_2.OFPAT_OUTPUT, ofproto_v1_2.OFP_ACTION_OUTPUT_SIZE) class OFPActionOutput(OFPAction): def __init__(self, port, max_len): super(OFPActionOutput, self).__init__() self.port = port self.max_len = max_len @classmethod def parser(cls, buf, offset): type_, len_, port, max_len = struct.unpack_from( ofproto_v1_2.OFP_ACTION_OUTPUT_PACK_STR, buf, offset) return cls(port, max_len) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_OUTPUT_PACK_STR, buf, offset, self.type, self.len, self.port, self.max_len) @OFPAction.register_action_type(ofproto_v1_2.OFPAT_GROUP, ofproto_v1_2.OFP_ACTION_GROUP_SIZE) class OFPActionGroup(OFPAction): def __init__(self, group_id): super(OFPActionGroup, self).__init__() self.group_id = group_id @classmethod def parser(cls, buf, offset): (type_, len_, group_id) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_GROUP_PACK_STR, buf, offset) return cls(group_id) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_GROUP_PACK_STR, buf, offset, self.type, self.len, self.group_id) @OFPAction.register_action_type(ofproto_v1_2.OFPAT_SET_QUEUE, ofproto_v1_2.OFP_ACTION_SET_QUEUE_SIZE) class OFPActionSetQueue(OFPAction): def __init__(self, queue_id): super(OFPActionSetQueue, self).__init__() self.queue_id = queue_id @classmethod def parser(cls, buf, offset): (type_, len_, queue_id) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset) return cls(queue_id) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_SET_QUEUE_PACK_STR, buf, offset, self.type, self.len, self.queue_id) @OFPAction.register_action_type(ofproto_v1_2.OFPAT_SET_MPLS_TTL, ofproto_v1_2.OFP_ACTION_MPLS_TTL_SIZE) class OFPActionSetMplsTtl(OFPAction): def __init__(self, mpls_ttl): super(OFPActionSetMplsTtl, self).__init__() self.mpls_ttl = mpls_ttl @classmethod def parser(cls, buf, offset): (type_, len_, mpls_ttl) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset) return cls(mpls_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_MPLS_TTL_PACK_STR, buf, offset, self.type, self.len, self.mpls_ttl) @OFPAction.register_action_type(ofproto_v1_2.OFPAT_DEC_MPLS_TTL, ofproto_v1_2.OFP_ACTION_HEADER_SIZE) class OFPActionDecMplsTtl(OFPAction): def __init__(self): super(OFPActionDecMplsTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto_v1_2.OFPAT_SET_NW_TTL, ofproto_v1_2.OFP_ACTION_NW_TTL_SIZE) class OFPActionSetNwTtl(OFPAction): def __init__(self, nw_ttl): super(OFPActionSetNwTtl, self).__init__() self.nw_ttl = nw_ttl @classmethod def parser(cls, buf, offset): (type_, len_, nw_ttl) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_NW_TTL_PACK_STR, buf, offset) return cls(nw_ttl) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_NW_TTL_PACK_STR, buf, offset, self.type, self.len, self.nw_ttl) @OFPAction.register_action_type(ofproto_v1_2.OFPAT_DEC_NW_TTL, ofproto_v1_2.OFP_ACTION_HEADER_SIZE) class OFPActionDecNwTtl(OFPAction): def __init__(self): super(OFPActionDecNwTtl, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto_v1_2.OFPAT_COPY_TTL_OUT, ofproto_v1_2.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlOut(OFPAction): def __init__(self): super(OFPActionCopyTtlOut, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto_v1_2.OFPAT_COPY_TTL_IN, ofproto_v1_2.OFP_ACTION_HEADER_SIZE) class OFPActionCopyTtlIn(OFPAction): def __init__(self): super(OFPActionCopyTtlIn, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto_v1_2.OFPAT_PUSH_VLAN, ofproto_v1_2.OFP_ACTION_PUSH_SIZE) class OFPActionPushVlan(OFPAction): def __init__(self, ethertype): super(OFPActionPushVlan, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto_v1_2.OFPAT_PUSH_MPLS, ofproto_v1_2.OFP_ACTION_PUSH_SIZE) class OFPActionPushMpls(OFPAction): def __init__(self, ethertype): super(OFPActionPushMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_PUSH_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_PUSH_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto_v1_2.OFPAT_POP_VLAN, ofproto_v1_2.OFP_ACTION_HEADER_SIZE) class OFPActionPopVlan(OFPAction): def __init__(self): super(OFPActionPopVlan, self).__init__() @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_HEADER_PACK_STR, buf, offset) return cls() @OFPAction.register_action_type(ofproto_v1_2.OFPAT_POP_MPLS, ofproto_v1_2.OFP_ACTION_POP_MPLS_SIZE) class OFPActionPopMpls(OFPAction): def __init__(self, ethertype): super(OFPActionPopMpls, self).__init__() self.ethertype = ethertype @classmethod def parser(cls, buf, offset): (type_, len_, ethertype) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset) return cls(ethertype) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_POP_MPLS_PACK_STR, buf, offset, self.type, self.len, self.ethertype) @OFPAction.register_action_type(ofproto_v1_2.OFPAT_SET_FIELD, ofproto_v1_2.OFP_ACTION_SET_FIELD_SIZE) class OFPActionSetField(OFPAction): def __init__(self, field): super(OFPActionSetField, self).__init__() self.field = field @classmethod def parser(cls, buf, offset): (type_, len_) = struct.unpack_from('!HH', buf, offset) field = OFPMatchField.parser(buf, offset + 4) action = cls(field) action.len = len_ return action def serialize(self, buf, offset): len_ = ofproto_v1_2.OFP_ACTION_SET_FIELD_SIZE + self.field.oxm_len() self.len = utils.round_up(len_, 8) pad_len = self.len - len_ msg_pack_into('!HH', buf, offset, self.type, self.len) self.field.serialize(buf, offset + 4) offset += len_ ofproto_parser.msg_pack_into("%dx" % pad_len, buf, offset) @OFPAction.register_action_type( ofproto_v1_2.OFPAT_EXPERIMENTER, ofproto_v1_2.OFP_ACTION_EXPERIMENTER_HEADER_SIZE) class OFPActionExperimenter(OFPAction): def __init__(self, experimenter): super(OFPActionExperimenter, self).__init__() self.experimenter = experimenter @classmethod def parser(cls, buf, offset): (type_, len_, experimenter) = struct.unpack_from( ofproto_v1_2.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset) return cls(experimenter) def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_ACTION_EXPERIMENTER_HEADER_PACK_STR, buf, offset, self.type, self.len, self.experimenter) class OFPBucket(object): def __init__(self, len_, weight, watch_port, watch_group, actions): super(OFPBucket, self).__init__() self.len = len_ self.weight = weight self.watch_port = watch_port self.watch_group = watch_group self.actions = actions @classmethod def parser(cls, buf, offset): (len_, weigth, watch_port, watch_group) = struct.unpack_from( ofproto_v1_2.OFP_BUCKET_PACK_STR, buf, offset) length = ofproto_v1_2.OFP_BUCKET_SIZE offset += ofproto_v1_2.OFP_BUCKET_SIZE actions = [] while length < len_: action = OFPAction.parser(buf, offset) actions.append(action) offset += action.len length += action.len return cls(len_, weigth, watch_port, watch_group, actions) def serialize(self, buf, offset): action_offset = offset + ofproto_v1_2.OFP_BUCKET_SIZE action_len = 0 for a in self.actions: a.serialize(buf, action_offset) action_offset += a.len action_len += a.len self.len = utils.round_up(ofproto_v1_2.OFP_BUCKET_SIZE + action_len, 8) msg_pack_into(ofproto_v1_2.OFP_BUCKET_PACK_STR, buf, offset, self.len, self.weight, self.watch_port, self.watch_group) @_set_msg_type(ofproto_v1_2.OFPT_GROUP_MOD) class OFPGroupMod(MsgBase): def __init__(self, datapath, command, type_, group_id, buckets): super(OFPGroupMod, self).__init__(datapath) self.command = command self.type = type_ self.group_id = group_id self.buckets = buckets def _serialize_body(self): msg_pack_into(ofproto_v1_2.OFP_GROUP_MOD_PACK_STR, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.command, self.type, self.group_id) offset = ofproto_v1_2.OFP_GROUP_MOD_SIZE for b in self.buckets: b.serialize(self.buf, offset) offset += b.len @_set_msg_type(ofproto_v1_2.OFPT_PORT_MOD) class OFPPortMod(MsgBase): def __init__(self, datapath, port_no, hw_addr, config, mask, advertise): super(OFPPortMod, self).__init__(datapath) self.port_no = port_no self.hw_addr = hw_addr self.config = config self.mask = mask self.advertise = advertise def _serialize_body(self): msg_pack_into(ofproto_v1_2.OFP_PORT_MOD_PACK_STR, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.port_no, self.hw_addr, self.config, self.mask, self.advertise) @_set_msg_type(ofproto_v1_2.OFPT_TABLE_MOD) class OFPTableMod(MsgBase): def __init__(self, datapath, table_id, config): super(OFPTableMod, self).__init__(datapath) self.table_id = table_id self.config = config def _serialize_body(self): msg_pack_into(ofproto_v1_2.OFP_TABLE_MOD_PACK_STR, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.table_id, self.config) class OFPStatsRequest(MsgBase): def __init__(self, datapath, type_): super(OFPStatsRequest, self).__init__(datapath) self.type = type_ self.flags = 0 def _serialize_stats_body(self): pass def _serialize_body(self): msg_pack_into(ofproto_v1_2.OFP_STATS_REQUEST_PACK_STR, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.type, self.flags) self._serialize_stats_body() @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_STATS_REPLY) class OFPStatsReply(MsgBase): _STATS_TYPES = {} @staticmethod def register_stats_reply_type(type_, body_single_struct=False): def _register_stats_reply_type(cls): OFPStatsReply._STATS_TYPES[type_] = cls cls.cls_body_single_struct = body_single_struct return cls return _register_stats_reply_type def __init__(self, datapath): super(OFPStatsReply, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPStatsReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) msg.type, msg.flags = struct.unpack_from( ofproto_v1_2.OFP_STATS_REPLY_PACK_STR, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE) stats_type_cls = cls._STATS_TYPES.get(msg.type) offset = ofproto_v1_2.OFP_STATS_REPLY_SIZE body = [] while offset < msg_len: r = stats_type_cls.parser(msg.buf, offset) body.append(r) offset += r.length if stats_type_cls.cls_body_single_struct: msg.body = body[0] else: msg.body = body return msg @_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST) class OFPDescStatsRequest(OFPStatsRequest): def __init__(self, datapath): super(OFPDescStatsRequest, self).__init__(datapath, ofproto_v1_2.OFPST_DESC) @OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_DESC, body_single_struct=True) class OFPDescStats(collections.namedtuple('OFPDescStats', ('mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc'))): @classmethod def parser(cls, buf, offset): desc = struct.unpack_from(ofproto_v1_2.OFP_DESC_STATS_PACK_STR, buf, offset) stats = cls(*desc) stats.length = ofproto_v1_2.OFP_DESC_STATS_SIZE return stats @_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST) class OFPFlowStatsRequest(OFPStatsRequest): def __init__(self, datapath, table_id, out_port, out_group, cookie, cookie_mask, match): super(OFPFlowStatsRequest, self).__init__(datapath, ofproto_v1_2.OFPST_FLOW) self.table_id = table_id self.out_port = out_port self.out_group = out_group self.cookie = cookie self.cookie_mask = cookie_mask self.match = match def _serialize_stats_body(self): msg_pack_into(ofproto_v1_2.OFP_FLOW_STATS_REQUEST_PACK_STR, self.buf, ofproto_v1_2.OFP_STATS_REQUEST_SIZE, self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) offset = (ofproto_v1_2.OFP_STATS_REQUEST_SIZE + ofproto_v1_2.OFP_FLOW_STATS_REQUEST_SIZE - ofproto_v1_2.OFP_MATCH_SIZE) self.match.serialize(self.buf, offset) @OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_FLOW) class OFPFlowStats(object): def __init__(self, length, table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count, match, instructions=None): super(OFPFlowStats, self).__init__() self.length = length self.table_id = table_id self.duration_sec = duration_sec self.duration_nsec = duration_nsec self.priority = priority self.idle_timeout = idle_timeout self.hard_timeout = hard_timeout self.cookie = cookie self.packet_count = packet_count self.byte_count = byte_count self.match = match self.instructions = instructions @classmethod def parser(cls, buf, offset): (length, table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count) = struct.unpack_from( ofproto_v1_2.OFP_FLOW_STATS_PACK_STR, buf, offset) offset += (ofproto_v1_2.OFP_FLOW_STATS_SIZE - ofproto_v1_2.OFP_MATCH_SIZE) match = OFPMatch.parser(buf, offset) match_length = utils.round_up(match.length, 8) inst_length = (length - (ofproto_v1_2.OFP_FLOW_STATS_SIZE - ofproto_v1_2.OFP_MATCH_SIZE + match_length)) offset += match_length instructions = [] while inst_length > 0: inst = OFPInstruction.parser(buf, offset) instructions.append(inst) offset += inst.len inst_length -= inst.len return cls(length, table_id, duration_sec, duration_nsec, priority, idle_timeout, hard_timeout, cookie, packet_count, byte_count, match, instructions) @_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST) class OFPAggregateStatsRequest(OFPStatsRequest): def __init__(self, datapath, table_id, out_port, out_group, cookie, cookie_mask, match): super(OFPAggregateStatsRequest, self).__init__( datapath, ofproto_v1_2.OFPST_AGGREGATE) self.table_id = table_id self.out_port = out_port self.out_group = out_group self.cookie = cookie self.cookie_mask = cookie_mask self.match = match def _serialize_stats_body(self): msg_pack_into(ofproto_v1_2.OFP_AGGREGATE_STATS_REQUEST_PACK_STR, self.buf, ofproto_v1_2.OFP_STATS_REQUEST_SIZE, self.table_id, self.out_port, self.out_group, self.cookie, self.cookie_mask) offset = (ofproto_v1_2.OFP_STATS_REQUEST_SIZE + ofproto_v1_2.OFP_AGGREGATE_STATS_REQUEST_SIZE - ofproto_v1_2.OFP_MATCH_SIZE) self.match.serialize(self.buf, offset) @OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_AGGREGATE, body_single_struct=True) class OFPAggregateStatsReply(collections.namedtuple('OFPAggregateStats', ('packet_count', 'byte_count', 'flow_count'))): @classmethod def parser(cls, buf, offset): desc = struct.unpack_from( ofproto_v1_2.OFP_AGGREGATE_STATS_REPLY_PACK_STR, buf, offset) stats = cls(*desc) stats.length = ofproto_v1_2.OFP_AGGREGATE_STATS_REPLY_SIZE return stats @_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST) class OFPTableStatsRequest(OFPStatsRequest): def __init__(self, datapath): super(OFPTableStatsRequest, self).__init__(datapath, ofproto_v1_2.OFPST_TABLE) @OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_TABLE) class OFPTableStats( collections.namedtuple('OFPTableStats', ('table_id', 'name', 'match', 'wildcards', 'write_actions', 'apply_actions', 'write_setfields', 'apply_setfields', 'metadata_match', 'metadata_write', 'instructions', 'config', 'max_entries', 'active_count', 'lookup_count', 'matched_count'))): @classmethod def parser(cls, buf, offset): table = struct.unpack_from( ofproto_v1_2.OFP_TABLE_STATS_PACK_STR, buf, offset) stats = cls(*table) stats.length = ofproto_v1_2.OFP_TABLE_STATS_SIZE return stats @_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST) class OFPPortStatsRequest(OFPStatsRequest): def __init__(self, datapath, port_no): super(OFPPortStatsRequest, self).__init__(datapath, ofproto_v1_2.OFPST_PORT) self.port_no = port_no def _serialize_stats_body(self): msg_pack_into(ofproto_v1_2.OFP_PORT_STATS_REQUEST_PACK_STR, self.buf, ofproto_v1_2.OFP_STATS_REQUEST_SIZE, self.port_no) @OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_PORT) class OFPPortStats( collections.namedtuple('OFPPortStats', ('port_no', 'rx_packets', 'tx_packets', 'rx_bytes', 'tx_bytes', 'rx_dropped', 'tx_dropped', 'rx_errors', 'tx_errors', 'rx_frame_err', 'rx_over_err', 'rx_crc_err', 'collisions'))): @classmethod def parser(cls, buf, offset): port = struct.unpack_from(ofproto_v1_2.OFP_PORT_STATS_PACK_STR, buf, offset) stats = cls(*port) stats.length = ofproto_v1_2.OFP_PORT_STATS_SIZE return stats @_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST) class OFPQueueStatsRequest(OFPStatsRequest): def __init__(self, datapath, port_no, queue_id): super(OFPQueueStatsRequest, self).__init__(datapath, ofproto_v1_2.OFPST_QUEUE) self.port_no = port_no self.queue_id = queue_id def _serialize_stats_body(self): msg_pack_into(ofproto_v1_2.OFP_QUEUE_STATS_REQUEST_PACK_STR, self.buf, ofproto_v1_2.OFP_STATS_REQUEST_SIZE, self.port_no, self.queue_id) @OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_QUEUE) class OFPQueueStats( collections.namedtuple('OFPQueueStats', ('port_no', 'queue_id', 'tx_bytes', 'tx_packets', 'tx_errors'))): @classmethod def parser(cls, buf, offset): queue = struct.unpack_from(ofproto_v1_2.OFP_QUEUE_STATS_PACK_STR, buf, offset) stats = cls(*queue) stats.length = ofproto_v1_2.OFP_QUEUE_STATS_SIZE return stats class OFPBucketCounter(object): def __init__(self, packet_count, byte_count): super(OFPBucketCounter, self).__init__() self.packet_count = packet_count self.byte_count = byte_count @classmethod def parser(cls, buf, offset): packet, byte = struct.unpack_from( ofproto_v1_2.OFP_BUCKET_COUNTER_PACK_STR, buf, offset) return cls(packet, byte) @_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST) class OFPGroupStatsRequest(OFPStatsRequest): def __init__(self, datapath, group_id): super(OFPGroupStatsRequest, self).__init__(datapath, ofproto_v1_2.OFPST_GROUP) self.group_id = group_id def _serialize_stats_body(self): msg_pack_into(ofproto_v1_2.OFP_GROUP_STATS_REQUEST_PACK_STR, self.buf, ofproto_v1_2.OFP_STATS_REQUEST_SIZE, self.group_id) @OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_GROUP) class OFPGroupStats(object): def __init__(self, length, group_id, ref_count, packet_count, byte_count, bucket_counters): super(OFPGroupStats, self).__init__() self.length = length self.group_id = group_id self.ref_count = ref_count self.packet_count = packet_count self.byte_count = byte_count self.bucket_counters = bucket_counters @classmethod def parser(cls, buf, offset): (length, group_id, ref_count, packet_count, byte_count) = struct.unpack_from( ofproto_v1_2.OFP_GROUP_STATS_PACK_STR, buf, offset) bucket_len = length - ofproto_v1_2.OFP_GROUP_STATS_SIZE offset += ofproto_v1_2.OFP_GROUP_STATS_SIZE bucket_counters = [] while bucket_len > 0: bucket_counters.append(OFPBucketCounter.parser(buf, offset)) offset += ofproto_v1_2.OFP_BUCKET_COUNTER_SIZE bucket_len -= ofproto_v1_2.OFP_BUCKET_COUNTER_SIZE return cls(length, group_id, ref_count, packet_count, byte_count, bucket_counters) @_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST) class OFPGroupDescStatsRequest(OFPStatsRequest): def __init__(self, datapath): super(OFPGroupDescStatsRequest, self).__init__( datapath, ofproto_v1_2.OFPST_GROUP_DESC) @OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_GROUP_DESC) class OFPGroupDescStats(object): def __init__(self, length, type_, group_id, buckets): self.length = length self.type = type_ self.group_id = group_id self.buckets = buckets @classmethod def parser(cls, buf, offset): (length, type_, group_id) = struct.unpack_from( ofproto_v1_2.OFP_GROUP_DESC_STATS_PACK_STR, buf, offset) bucket_len = length - ofproto_v1_2.OFP_GROUP_DESC_STATS_SIZE offset += ofproto_v1_2.OFP_GROUP_DESC_STATS_SIZE buckets = [] while bucket_len > 0: buckets.append(OFPBucket.parser(buf, offset)) offset += ofproto_v1_2.OFP_BUCKET_SIZE bucket_len -= ofproto_v1_2.OFP_BUCKET_SIZE return cls(length, type_, group_id, buckets) @_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST) class OFPGroupFeaturesStatsRequest(OFPStatsRequest): def __init__(self, datapath): super(OFPGroupFeaturesStatsRequest, self).__init__( datapath, ofproto_v1_2.OFPST_GROUP_FEATURES) @OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_GROUP_FEATURES, body_single_struct=True) class OFPGroupFeaturesStats(object): def __init__(self, types, capabilities, max_groups, actions): self.types = types self.capabilities = capabilities self.max_groups = max_groups self.actions = actions @classmethod def parser(cls, buf, offset): stats = struct.unpack_from( ofproto_v1_2.OFP_GROUP_FEATURES_STATS_PACK_STR, buf, offset) types = stats[0] capabilities = stats[1] max_groups = stats[2:6] actions = stats[6:10] return cls(types, capabilities, max_groups, actions) @_set_msg_type(ofproto_v1_2.OFPT_QUEUE_GET_CONFIG_REQUEST) class OFPQueueGetConfigRequest(MsgBase): def __init__(self, datapath, port): super(OFPQueueGetConfigRequest, self).__init__(datapath) self.port = port def _serialize_body(self): msg_pack_into(ofproto_v1_2.OFP_QUEUE_GET_CONFIG_REQUEST_PACK_STR, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.port) class OFPQueuePropHeader(object): def __init__(self, property_, len_): self.property = property_ self.len = len_ def serialize(self, buf, offset): msg_pack_into(ofproto_v1_2.OFP_QUEUE_PROP_HEADER_PACK_STR, buf, offset, self.property, self.len) class OFPQueueProp(OFPQueuePropHeader): _QUEUE_PROP_PROPERTIES = {} @staticmethod def register_property(property_, len_): def _register_property(cls): cls.cls_property = property_ cls.cls_len = len_ OFPQueueProp._QUEUE_PROP_PROPERTIES[cls.cls_property] = cls return cls return _register_property def __init__(self): cls = self.__class__ super(OFPQueueProp, self).__init__(cls.cls_property, cls.cls_len) @classmethod def parser(cls, buf, offset): (property_, len_) = struct.unpack_from( ofproto_v1_2.OFP_QUEUE_PROP_HEADER_PACK_STR, buf, offset) cls_ = cls._QUEUE_PROP_PROPERTIES.get(property_) return cls_.parser(buf, offset) class OFPPacketQueue(object): def __init__(self, queue_id, port, len_, properties): super(OFPPacketQueue, self).__init__() self.queue_id = queue_id self.port = port self.len = len_ self.properties = properties @classmethod def parser(cls, buf, offset): (queue_id, port, len_) = struct.unpack_from( ofproto_v1_2.OFP_PACKET_QUEUE_PACK_STR, buf, offset) length = ofproto_v1_2.OFP_PACKET_QUEUE_SIZE offset += ofproto_v1_2.OFP_PACKET_QUEUE_SIZE properties = [] while length < len_: queue_prop = OFPQueueProp.parser(buf, offset) properties.append(queue_prop) offset += queue_prop.len length += queue_prop.len return cls(queue_id, port, len_, properties) @OFPQueueProp.register_property(ofproto_v1_2.OFPQT_MIN_RATE, ofproto_v1_2.OFP_QUEUE_PROP_MIN_RATE_SIZE) class OFPQueuePropMinRate(OFPQueueProp): def __init__(self, rate): super(OFPQueuePropMinRate, self).__init__() self.rate = rate @classmethod def parser(cls, buf, offset): (rate,) = struct.unpack_from( ofproto_v1_2.OFP_QUEUE_PROP_MIN_RATE_PACK_STR, buf, offset) return cls(rate) @OFPQueueProp.register_property(ofproto_v1_2.OFPQT_MAX_RATE, ofproto_v1_2.OFP_QUEUE_PROP_MAX_RATE_SIZE) class OFPQueuePropMaxRate(OFPQueueProp): def __init__(self, rate): super(OFPQueuePropMaxRate, self).__init__() self.rate = rate @classmethod def parser(cls, buf, offset): (rate,) = struct.unpack_from( ofproto_v1_2.OFP_QUEUE_PROP_MAX_RATE_PACK_STR, buf, offset) return cls(rate) @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_QUEUE_GET_CONFIG_REPLY) class OFPQueueGetConfigReply(MsgBase): def __init__(self, datapath): super(OFPQueueGetConfigReply, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPQueueGetConfigReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.port,) = struct.unpack_from( ofproto_v1_2.OFP_QUEUE_GET_CONFIG_REPLY_PACK_STR, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE) msg.queues = [] length = ofproto_v1_2.OFP_QUEUE_GET_CONFIG_REPLY_SIZE offset = ofproto_v1_2.OFP_QUEUE_GET_CONFIG_REPLY_SIZE while length < msg.msg_len: queue = OFPPacketQueue.parser(msg.buf, offset) msg.queues.append(queue) offset += queue.len length += queue.len return msg @_set_msg_type(ofproto_v1_2.OFPT_BARRIER_REQUEST) class OFPBarrierRequest(MsgBase): def __init__(self, datapath): super(OFPBarrierRequest, self).__init__(datapath) @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_BARRIER_REPLY) class OFPBarrierReply(MsgBase): def __init__(self, datapath): super(OFPBarrierReply, self).__init__(datapath) @_set_msg_type(ofproto_v1_2.OFPT_ROLE_REQUEST) class OFPRoleRequest(MsgBase): def __init__(self, datapath, role, generation_id): super(OFPRoleRequest, self).__init__(datapath) self.role = role self.generation_id = generation_id def _serialize_body(self): msg_pack_into(ofproto_v1_2.OFP_ROLE_REQUEST_PACK_STR, self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.role, self.generation_id) @_register_parser @_set_msg_type(ofproto_v1_2.OFPT_ROLE_REPLY) class OFPRoleReply(MsgBase): def __init__(self, datapath): super(OFPRoleReply, self).__init__(datapath) @classmethod def parser(cls, datapath, version, msg_type, msg_len, xid, buf): msg = super(OFPRoleReply, cls).parser(datapath, version, msg_type, msg_len, xid, buf) (msg.role, msg.generation_id) = struct.unpack_from( ofproto_v1_2.OFP_ROLE_REQUEST_PACK_STR, msg.buf, ofproto_v1_2.OFP_HEADER_SIZE) return msg UINT64_MAX = (1 << 64) - 1 UINT32_MAX = (1 << 32) - 1 UINT16_MAX = (1 << 16) - 1 class Flow(object): def __init__(self): self.in_port = 0 self.in_phy_port = 0 self.metadata = 0 self.dl_dst = mac.DONTCARE self.dl_src = mac.DONTCARE self.dl_type = 0 self.vlan_vid = 0 self.vlan_pcp = 0 self.ip_dscp = 0 self.ip_ecn = 0 self.ip_proto = 0 self.ipv4_src = 0 self.ipv4_dst = 0 self.tcp_src = 0 self.tcp_dst = 0 self.udp_src = 0 self.udp_dst = 0 self.sctp_src = 0 self.sctp_dst = 0 self.icmpv4_type = 0 self.icmpv4_code = 0 self.arp_op = 0 self.arp_spa = 0 self.arp_tpa = 0 self.arp_sha = 0 self.arp_tha = 0 self.ipv6_src = [] self.ipv6_dst = [] self.ipv6_flabel = 0 self.icmpv6_type = 0 self.icmpv6_code = 0 self.ipv6_nd_target = [] self.ipv6_nd_sll = 0 self.ipv6_nd_tll = 0 self.mpls_lable = 0 self.mpls_tc = 0 class FlowWildcards(object): def __init__(self): self.metadata_mask = 0 self.dl_dst_mask = 0 self.dl_src_mask = 0 self.vlan_vid_mask = 0 self.ipv4_src_mask = 0 self.ipv4_dst_mask = 0 self.arp_spa_mask = 0 self.arp_tpa_mask = 0 self.arp_sha_mask = 0 self.arp_tha_mask = 0 self.ipv6_src_mask = [] self.ipv6_dst_mask = [] self.ipv6_flabel_mask = 0 self.wildcards = (1 << 64) - 1 def ft_set(self, shift): self.wildcards &= ~(1 << shift) def ft_test(self, shift): return not self.wildcards & (1 << shift) class OFPMatch(object): def __init__(self): super(OFPMatch, self).__init__() self.wc = FlowWildcards() self.flow = Flow() self.fields = [] def append_field(self, header, value, mask=None): self.fields.append(OFPMatchField.make(header, value, mask)) def serialize(self, buf, offset): if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IN_PORT): self.append_field(ofproto_v1_2.OXM_OF_IN_PORT, self.flow.in_port) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IN_PHY_PORT): self.append_field(ofproto_v1_2.OXM_OF_IN_PHY_PORT, self.flow.in_phy_port) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_METADATA): if self.wc.metadata_mask == UINT64_MAX: header = ofproto_v1_2.OXM_OF_METADATA else: header = ofproto_v1_2.OXM_OF_METADATA_W self.append_field(header, self.flow.metadata, self.wc.metadata_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ETH_DST): if self.wc.dl_dst_mask: header = ofproto_v1_2.OXM_OF_ETH_DST_W else: header = ofproto_v1_2.OXM_OF_ETH_DST self.append_field(header, self.flow.dl_dst, self.wc.dl_dst_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ETH_SRC): if self.wc.dl_src_mask: header = ofproto_v1_2.OXM_OF_ETH_SRC_W else: header = ofproto_v1_2.OXM_OF_ETH_SRC self.append_field(header, self.flow.dl_src, self.wc.dl_src_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ETH_TYPE): self.append_field(ofproto_v1_2.OXM_OF_ETH_TYPE, self.flow.dl_type) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_VLAN_VID): if self.wc.vlan_vid_mask == UINT16_MAX: header = ofproto_v1_2.OXM_OF_VLAN_VID else: header = ofproto_v1_2.OXM_OF_VLAN_VID_W self.append_field(header, self.flow.vlan_vid, self.wc.vlan_vid_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_VLAN_PCP): self.append_field(ofproto_v1_2.OXM_OF_VLAN_PCP, self.flow.vlan_pcp) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IP_DSCP): self.append_field(ofproto_v1_2.OXM_OF_IP_DSCP, self.flow.ip_dscp) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IP_ECN): self.append_field(ofproto_v1_2.OXM_OF_IP_ECN, self.flow.ip_ecn) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IP_PROTO): self.append_field(ofproto_v1_2.OXM_OF_IP_PROTO, self.flow.ip_proto) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IPV4_SRC): if self.wc.ipv4_src_mask == UINT32_MAX: header = ofproto_v1_2.OXM_OF_IPV4_SRC else: header = ofproto_v1_2.OXM_OF_IPV4_SRC_W self.append_field(header, self.flow.ipv4_src, self.wc.ipv4_src_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IPV4_DST): if self.wc.ipv4_dst_mask == UINT32_MAX: header = ofproto_v1_2.OXM_OF_IPV4_DST else: header = ofproto_v1_2.OXM_OF_IPV4_DST_W self.append_field(header, self.flow.ipv4_dst, self.wc.ipv4_dst_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_TCP_SRC): self.append_field(ofproto_v1_2.OXM_OF_TCP_SRC, self.flow.tcp_src) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_TCP_DST): self.append_field(ofproto_v1_2.OXM_OF_TCP_DST, self.flow.tcp_dst) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_UDP_SRC): self.append_field(ofproto_v1_2.OXM_OF_UDP_SRC, self.flow.udp_src) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_UDP_DST): self.append_field(ofproto_v1_2.OXM_OF_UDP_DST, self.flow.udp_dst) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_SCTP_SRC): self.append_field(ofproto_v1_2.OXM_OF_SCTP_SRC, self.flow.sctp_src) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_SCTP_DST): self.append_field(ofproto_v1_2.OXM_OF_SCTP_DST, self.flow.sctp_dst) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ICMPV4_TYPE): self.append_field(ofproto_v1_2.OXM_OF_ICMPV4_TYPE, self.flow.icmpv4_type) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ICMPV4_CODE): self.append_field(ofproto_v1_2.OXM_OF_ICMPV4_CODE, self.flow.icmpv4_code) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ARP_OP): self.append_field(ofproto_v1_2.OXM_OF_ARP_OP, self.flow.arp_op) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ARP_SPA): if self.wc.arp_spa_mask == UINT32_MAX: header = ofproto_v1_2.OXM_OF_ARP_SPA else: header = ofproto_v1_2.OXM_OF_ARP_SPA_W self.append_field(header, self.flow.arp_spa, self.wc.arp_spa_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ARP_TPA): if self.wc.arp_tpa_mask == UINT32_MAX: header = ofproto_v1_2.OXM_OF_ARP_TPA else: header = ofproto_v1_2.OXM_OF_ARP_TPA_W self.append_field(header, self.flow.arp_tpa, self.wc.arp_tpa_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ARP_SHA): if self.wc.arp_sha_mask: header = ofproto_v1_2.OXM_OF_ARP_SHA_W else: header = ofproto_v1_2.OXM_OF_ARP_SHA self.append_field(header, self.flow.arp_sha, self.wc.arp_sha_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ARP_THA): if self.wc.arp_tha_mask: header = ofproto_v1_2.OXM_OF_ARP_THA_W else: header = ofproto_v1_2.OXM_OF_ARP_THA self.append_field(header, self.flow.arp_tha, self.wc.arp_tha_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IPV6_SRC): if len(self.wc.ipv6_src_mask): header = ofproto_v1_2.OXM_OF_IPV6_SRC_W else: header = ofproto_v1_2.OXM_OF_IPV6_SRC self.append_field(header, self.flow.ipv6_src, self.wc.ipv6_src_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IPV6_DST): if len(self.wc.ipv6_dst_mask): header = ofproto_v1_2.OXM_OF_IPV6_DST_W else: header = ofproto_v1_2.OXM_OF_IPV6_DST self.append_field(header, self.flow.ipv6_dst, self.wc.ipv6_dst_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IPV6_FLABEL): if self.wc.ipv6_flabel_mask == UINT32_MAX: header = ofproto_v1_2.OXM_OF_IPV6_FLABEL else: header = ofproto_v1_2.OXM_OF_IPV6_FLABEL_W self.append_field(header, self.flow.ipv6_flabel, self.wc.ipv6_flabel_mask) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ICMPV6_TYPE): self.append_field(ofproto_v1_2.OXM_OF_ICMPV6_TYPE, self.flow.icmpv6_type) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_ICMPV6_CODE): self.append_field(ofproto_v1_2.OXM_OF_ICMPV6_CODE, self.flow.icmpv6_code) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IPV6_ND_TARGET): self.append_field(ofproto_v1_2.OXM_OF_IPV6_ND_TARGET, self.flow.ipv6_nd_target) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IPV6_ND_SLL): self.append_field(ofproto_v1_2.OXM_OF_IPV6_ND_SLL, self.flow.ipv6_nd_sll) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_IPV6_ND_TLL): self.append_field(ofproto_v1_2.OXM_OF_IPV6_ND_TLL, self.flow.ipv6_nd_tll) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_MPLS_LABEL): self.append_field(ofproto_v1_2.OXM_OF_MPLS_LABEL, self.flow.mpls_label) if self.wc.ft_test(ofproto_v1_2.OFPXMT_OFB_MPLS_TC): self.append_field(ofproto_v1_2.OXM_OF_MPLS_TC, self.flow.mpls_tc) field_offset = offset + 4 for f in self.fields: f.serialize(buf, field_offset) field_offset += f.length length = field_offset - offset msg_pack_into('!HH', buf, offset, ofproto_v1_2.OFPMT_OXM, length) pad_len = utils.round_up(length, 8) - length ofproto_parser.msg_pack_into("%dx" % pad_len, buf, field_offset) return length + pad_len @classmethod def parser(cls, buf, offset): match = OFPMatch() type_, length = struct.unpack_from('!HH', buf, offset) match.type = type_ match.length = length # ofp_match adjustment offset += 4 length -= 4 while length > 0: field = OFPMatchField.parser(buf, offset) offset += field.length length -= field.length match.fields.append(field) return match def set_in_port(self, port): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IN_PORT) self.flow.in_port = port def set_in_phy_port(self, phy_port): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IN_PHY_PORT) self.flow.in_phy_port = phy_port def set_metadata(self, metadata): self.set_metadata_masked(metadata, UINT64_MAX) def set_metadata_masked(self, metadata, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_METADATA) self.wc.metadata_mask = mask self.flow.metadata = metadata & mask def set_dl_dst(self, dl_dst): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ETH_DST) self.flow.dl_dst = dl_dst def set_dl_dst_masked(self, dl_dst, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ETH_DST) self.wc.dl_dst_mask = mask # bit-wise and of the corresponding elements of dl_dst and mask self.flow.dl_dst = mac.haddr_bitand(dl_dst, mask) def set_dl_src(self, dl_src): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ETH_SRC) self.flow.dl_src = dl_src def set_dl_src_masked(self, dl_src, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ETH_SRC) self.wc.dl_src_mask = mask self.flow.dl_src = mac.haddr_bitand(dl_src, mask) def set_dl_type(self, dl_type): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ETH_TYPE) self.flow.dl_type = dl_type def set_vlan_vid(self, vid): self.set_vlan_vid_masked(vid, UINT16_MAX) def set_vlan_vid_masked(self, vid, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_VLAN_VID) self.wc.vlan_vid_mask = mask self.flow.vlan_vid = vid def set_vlan_pcp(self, pcp): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_VLAN_PCP) self.flow.vlan_pcp = pcp def set_ip_dscp(self, ip_dscp): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IP_DSCP) self.flow.ip_dscp = ip_dscp def set_ip_ecn(self, ip_ecn): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IP_ECN) self.flow.ip_ecn = ip_ecn def set_ip_proto(self, ip_proto): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IP_PROTO) self.flow.ip_proto = ip_proto def set_ipv4_src(self, ipv4_src): self.set_ipv4_src_masked(ipv4_src, UINT32_MAX) def set_ipv4_src_masked(self, ipv4_src, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV4_SRC) self.flow.ipv4_src = ipv4_src self.wc.ipv4_src_mask = mask def set_ipv4_dst(self, ipv4_dst): self.set_ipv4_dst_masked(ipv4_dst, UINT32_MAX) def set_ipv4_dst_masked(self, ipv4_dst, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV4_DST) self.flow.ipv4_dst = ipv4_dst self.wc.ipv4_dst_mask = mask def set_tcp_src(self, tcp_src): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_TCP_SRC) self.flow.tcp_src = tcp_src def set_tcp_dst(self, tcp_dst): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_TCP_DST) self.flow.tcp_dst = tcp_dst def set_udp_src(self, udp_src): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_UDP_SRC) self.flow.udp_src = udp_src def set_udp_dst(self, udp_dst): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_UDP_DST) self.flow.udp_dst = udp_dst def set_sctp_src(self, sctp_src): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_SCTP_SRC) self.flow.sctp_src = sctp_src def set_sctp_dst(self, sctp_dst): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_SCTP_DST) self.flow.sctp_dst = sctp_dst def set_icmpv4_type(self, icmpv4_type): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ICMPV4_TYPE) self.flow.icmpv4_type = icmpv4_type def set_icmpv4_code(self, icmpv4_code): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ICMPV4_CODE) self.flow.icmpv4_code = icmpv4_code def set_arp_opcode(self, arp_op): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ARP_OP) self.flow.arp_op = arp_op def set_arp_spa(self, arp_spa): self.set_arp_spa_masked(arp_spa, UINT32_MAX) def set_arp_spa_masked(self, arp_spa, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ARP_SPA) self.wc.arp_spa_mask = mask self.flow.arp_spa = arp_spa def set_arp_tpa(self, arp_tpa): self.set_arp_tpa_masked(arp_tpa, UINT32_MAX) def set_arp_tpa_masked(self, arp_tpa, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ARP_TPA) self.wc.arp_tpa_mask = mask self.flow.arp_tpa = arp_tpa def set_arp_sha(self, arp_sha): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ARP_SHA) self.flow.arp_sha = arp_sha def set_arp_sha_masked(self, arp_sha, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ARP_SHA) self.wc.arp_sha_mask = mask self.flow.arp_sha = mac.haddr_bitand(arp_sha, mask) def set_arp_tha(self, arp_tha): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ARP_THA) self.flow.arp_tha = arp_tha def set_arp_tha_masked(self, arp_tha, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ARP_THA) self.wc.arp_tha_mask = mask self.flow.arp_tha = mac.haddr_bitand(arp_tha, mask) def set_ipv6_src(self, src): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV6_SRC) self.flow.ipv6_src = src def set_ipv6_src_masked(self, src, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV6_SRC) self.wc.ipv6_src_mask = mask self.flow.ipv6_src = [x & y for (x, y) in itertools.izip(src, mask)] def set_ipv6_dst(self, dst): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV6_DST) self.flow.ipv6_dst = dst def set_ipv6_dst_masked(self, dst, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV6_DST) self.wc.ipv6_dst_mask = mask self.flow.ipv6_dst = [x & y for (x, y) in itertools.izip(dst, mask)] def set_ipv6_flabel(self, flabel): self.set_ipv6_flabel_masked(flabel, UINT32_MAX) def set_ipv6_flabel_masked(self, flabel, mask): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV6_FLABEL) self.wc.ipv6_flabel_mask = mask self.flow.ipv6_flabel = flabel def set_icmpv6_type(self, icmpv6_type): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ICMPV6_TYPE) self.flow.icmpv6_type = icmpv6_type def set_icmpv6_code(self, icmpv6_code): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_ICMPV6_CODE) self.flow.icmpv6_code = icmpv6_code def set_ipv6_nd_target(self, target): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV6_ND_TARGET) self.flow.ipv6_nd_target = target def set_ipv6_nd_sll(self, ipv6_nd_sll): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV6_ND_SLL) self.flow.ipv6_nd_sll = ipv6_nd_sll def set_ipv6_nd_tll(self, ipv6_nd_tll): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_IPV6_ND_TLL) self.flow.ipv6_nd_tll = ipv6_nd_tll def set_mpls_label(self, mpls_label): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_MPLS_LABEL) self.flow.mpls_label = mpls_label def set_mpls_tc(self, mpls_tc): self.wc.ft_set(ofproto_v1_2.OFPXMT_OFB_MPLS_TC) self.flow.mpls_tc = mpls_tc class OFPMatchField(object): _FIELDS_HEADERS = {} @staticmethod def register_field_header(headers): def _register_field_header(cls): for header in headers: OFPMatchField._FIELDS_HEADERS[header] = cls return cls return _register_field_header def __init__(self, header): self.header = header hasmask = (header >> 8) & 1 if hasmask: self.n_bytes = (header & 0xff) / 2 else: self.n_bytes = header & 0xff self.length = 0 @staticmethod def make(header, value, mask=None): cls_ = OFPMatchField._FIELDS_HEADERS.get(header) return cls_(header, value, mask) @classmethod def parser(cls, buf, offset): (header,) = struct.unpack_from('!I', buf, offset) cls_ = OFPMatchField._FIELDS_HEADERS.get(header) if cls_: field = cls_.field_parser(header, buf, offset) else: field = OFPMatchField(header) field.length = (header & 0xff) + 4 return field @classmethod def field_parser(cls, header, buf, offset): hasmask = (header >> 8) & 1 mask = None if hasmask: pack_str = '!' + cls.pack_str[1:] * 2 (value, mask) = struct.unpack_from(pack_str, buf, offset + 4) else: (value,) = struct.unpack_from(cls.pack_str, buf, offset + 4) return cls(header, value, mask) def serialize(self, buf, offset): hasmask = (self.header >> 8) & 1 if hasmask: self.put_w(buf, offset, self.value, self.mask) else: self.put(buf, offset, self.value) def _put_header(self, buf, offset): ofproto_parser.msg_pack_into('!I', buf, offset, self.header) self.length += 4 def _put(self, buf, offset, value): ofproto_parser.msg_pack_into(self.pack_str, buf, offset, value) self.length += self.n_bytes def put_w(self, buf, offset, value, mask): self._put_header(buf, offset) self._put(buf, offset + self.length, value) self._put(buf, offset + self.length, mask) def put(self, buf, offset, value): self._put_header(buf, offset) self._put(buf, offset + self.length, value) def _putv6(self, buf, offset, value): ofproto_parser.msg_pack_into(self.pack_str, buf, offset, *value) self.length += self.n_bytes def putv6(self, buf, offset, value, mask=None): self._put_header(buf, offset) self._putv6(buf, offset + self.length, value) if mask and len(mask): self._putv6(buf, offset + self.length, mask) def oxm_len(self): return self.header & 0xff @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IN_PORT]) class MTInPort(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTInPort, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_METADATA, ofproto_v1_2.OXM_OF_METADATA_W]) class MTMetadata(OFPMatchField): pack_str = '!Q' def __init__(self, header, value, mask=None): super(MTMetadata, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IN_PHY_PORT]) class MTInPhyPort(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTInPhyPort, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ETH_DST, ofproto_v1_2.OXM_OF_ETH_DST_W]) class MTEthDst(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTEthDst, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ETH_SRC, ofproto_v1_2.OXM_OF_ETH_SRC_W]) class MTEthSrc(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTEthSrc, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ETH_TYPE]) class MTEthType(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTEthType, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_VLAN_VID, ofproto_v1_2.OXM_OF_VLAN_VID_W]) class MTVlanVid(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTVlanVid, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_VLAN_PCP]) class MTVlanPcp(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTVlanPcp, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IP_DSCP]) class MTIPDscp(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTIPDscp, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IP_ECN]) class MTIPECN(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTIPECN, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IP_PROTO]) class MTIPProto(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTIPProto, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IPV4_SRC, ofproto_v1_2.OXM_OF_IPV4_SRC_W]) class MTIPV4Src(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTIPV4Src, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IPV4_DST, ofproto_v1_2.OXM_OF_IPV4_DST_W]) class MTIPV4Dst(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTIPV4Dst, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_TCP_SRC]) class MTTCPSrc(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTTCPSrc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_TCP_DST]) class MTTCPDst(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTTCPDst, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_UDP_SRC]) class MTUDPSrc(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTUDPSrc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_UDP_DST]) class MTUDPDst(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTUDPDst, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_SCTP_SRC]) class MTSCTPSrc(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTSCTPSrc, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_SCTP_DST]) class MTSCTPDst(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTSCTPDst, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ICMPV4_TYPE]) class MTICMPV4Type(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV4Type, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ICMPV4_CODE]) class MTICMPV4Code(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV4Code, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ARP_OP]) class MTArpOp(OFPMatchField): pack_str = '!H' def __init__(self, header, value, mask=None): super(MTArpOp, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ARP_SPA, ofproto_v1_2.OXM_OF_ARP_SPA_W]) class MTArpSpa(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTArpSpa, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ARP_TPA, ofproto_v1_2.OXM_OF_ARP_TPA_W]) class MTArpTpa(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTArpTpa, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ARP_SHA, ofproto_v1_2.OXM_OF_ARP_SHA_W]) class MTArpSha(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTArpSha, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ARP_THA, ofproto_v1_2.OXM_OF_ARP_THA_W]) class MTArpTha(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTArpTha, self).__init__(header) self.value = value self.mask = mask class MTIPv6(object): @classmethod def field_parser(cls, header, buf, offset): hasmask = (header >> 8) & 1 if hasmask: pack_str = '!' + cls.pack_str[1:] * 2 value = struct.unpack_from(pack_str, buf, offset + 4) return cls(header, list(value[:8]), list(value[8:])) else: value = struct.unpack_from(cls.pack_str, buf, offset + 4) return cls(header, list(value)) def serialize(self, buf, offset): self.putv6(buf, offset, self.value, self.mask) @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IPV6_SRC, ofproto_v1_2.OXM_OF_IPV6_SRC_W]) class MTIPv6Src(MTIPv6, OFPMatchField): pack_str = '!8H' def __init__(self, header, value, mask=None): super(MTIPv6Src, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IPV6_DST, ofproto_v1_2.OXM_OF_IPV6_DST_W]) class MTIPv6Dst(MTIPv6, OFPMatchField): pack_str = '!8H' def __init__(self, header, value, mask=None): super(MTIPv6Dst, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IPV6_FLABEL, ofproto_v1_2.OXM_OF_IPV6_FLABEL_W]) class MTIPv6Flabel(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTIPv6Flabel, self).__init__(header) self.value = value self.mask = mask @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_MPLS_LABEL]) class MTMplsLabel(OFPMatchField): pack_str = '!I' def __init__(self, header, value, mask=None): super(MTMplsLabel, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ICMPV6_TYPE]) class MTICMPV6Type(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV6Type, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_ICMPV6_CODE]) class MTICMPV6Code(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTICMPV6Code, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IPV6_ND_TARGET]) class MTIPv6NdTarget(MTIPv6, OFPMatchField): pack_str = '!8H' def __init__(self, header, value, mask=None): super(MTIPv6NdTarget, self).__init__(header) self.value = value def serialize(self, buf, offset): self.putv6(buf, offset, self.value) @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IPV6_ND_SLL]) class MTIPv6NdSll(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTIPv6NdSll, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_IPV6_ND_TLL]) class MTIPv6NdTll(OFPMatchField): pack_str = '!6s' def __init__(self, header, value, mask=None): super(MTIPv6NdTll, self).__init__(header) self.value = value @OFPMatchField.register_field_header([ofproto_v1_2.OXM_OF_MPLS_TC]) class MTMplsTc(OFPMatchField): pack_str = '!B' def __init__(self, header, value, mask=None): super(MTMplsTc, self).__init__(header) self.value = value