deb-ryu/ryu/ofproto/ofproto_v1_2_parser.py
FUJITA Tomonori 6b99b1408b of1.2: handle unknown match field properly
Ryu crashes when it finds an unknown match field in OFPMatch. Instead,
Ryu should just ignore it and continue to parse.

With this patch, Ryu uses OFPmatchField class for an unknown match
field and continue to parse.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Tested-by: Simon Horman <horms@verge.net.au>
2012-07-30 11:58:23 +09:00

2374 lines
81 KiB
Python

# Copyright (C) 2012 Nippon Telegraph and Telephone Corporation.
# Copyright (C) 2012 Isaku Yamahata <yamahata at valinux co jp>
#
# 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):
assert 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, 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