Enhance os-ken to support Nicira PacketIn2
neutron ovs agent has to handle advanced packet_in with custom userdata which is necessary to openflow-based floating IP implementation, but current os-ken doesn't have such infrastructure. This story is to enhance os-ken in order that neutron ovs agent can act as an advanced SDN controller to handle advanced packet_in. Story: #2008964 Task: #42600 Related-Bug: #1931953 Signed-off-by: Yi Yang <yangyi01@inspur.com> Change-Id: I4f993be5dd4a5f48396c4be152da5b61ea92392f
This commit is contained in:
parent
5312d23b43
commit
bf25f07861
@ -143,6 +143,18 @@ NXT_PACKET_IN = 17
|
||||
NXT_FLOW_AGE = 18
|
||||
NXT_SET_ASYNC_CONFIG = 19
|
||||
NXT_SET_CONTROLLER_ID = 20
|
||||
NXT_PACKET_IN2 = 30
|
||||
|
||||
# nx_packet_in2_prop_type
|
||||
NXPINT_PACKET = 0
|
||||
NXPINT_FULL_LEN = 1
|
||||
NXPINT_BUFFER_ID = 2
|
||||
NXPINT_TABLE_ID = 3
|
||||
NXPINT_COOKIE = 4
|
||||
NXPINT_REASON = 5
|
||||
NXPINT_METADATA = 6
|
||||
NXPINT_USERDATA = 7
|
||||
NXPINT_CONTINUATION = 8
|
||||
|
||||
# enum nx_role
|
||||
NX_ROLE_OTHER = 0
|
||||
|
@ -1229,6 +1229,15 @@ oxm_types = [
|
||||
# EXT-233 Output match Extension
|
||||
# NOTE(yamamoto): The spec says uint64_t but I assume it's an error.
|
||||
oxm_fields.ONFExperimenter('actset_output', 43, type_desc.Int4),
|
||||
# Support for matching/setting xreg0-7
|
||||
oxm_fields.PacketRegs('xreg0', 0, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg1', 1, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg2', 2, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg3', 3, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg4', 4, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg5', 5, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg6', 6, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg7', 7, type_desc.Int8),
|
||||
] + nicira_ext.oxm_types
|
||||
|
||||
oxm_fields.generate(__name__)
|
||||
|
@ -53,6 +53,7 @@ from os_ken import exception
|
||||
from os_ken import utils
|
||||
from os_ken.ofproto.ofproto_parser import StringifyMixin, MsgBase
|
||||
from os_ken.ofproto import ether
|
||||
from os_ken.ofproto import nicira_ext
|
||||
from os_ken.ofproto import nx_actions
|
||||
from os_ken.ofproto import ofproto_parser
|
||||
from os_ken.ofproto import ofproto_common
|
||||
@ -6492,6 +6493,169 @@ class ONFBundleAddMsg(OFPExperimenter):
|
||||
self.buf += tail_buf
|
||||
|
||||
|
||||
@_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_SET_PACKET_IN_FORMAT)
|
||||
class NXTSetPacketInFormatMsg(OFPExperimenter):
|
||||
def __init__(self, datapath, packet_in_format):
|
||||
super(NXTSetPacketInFormatMsg, self).__init__(
|
||||
datapath, ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_SET_PACKET_IN_FORMAT)
|
||||
self.packet_in_format = packet_in_format
|
||||
|
||||
def _serialize_body(self):
|
||||
msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR,
|
||||
self.buf, ofproto.OFP_HEADER_SIZE,
|
||||
self.experimenter, self.exp_type)
|
||||
msg_pack_into(nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR,
|
||||
self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE,
|
||||
self.packet_in_format)
|
||||
|
||||
@classmethod
|
||||
def parser_subtype(cls, super_msg):
|
||||
packet_in_format = struct.unpack_from(
|
||||
nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR, super_msg.data)[0]
|
||||
msg = cls(super_msg.datapath, packet_in_format)
|
||||
msg.properties = []
|
||||
return msg
|
||||
|
||||
|
||||
@_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_PACKET_IN2)
|
||||
class NXTPacketIn2(OFPExperimenter):
|
||||
def __init__(self, datapath, properties=None):
|
||||
super(NXTPacketIn2, self).__init__(
|
||||
datapath, ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_PACKET_IN2)
|
||||
self.properties = properties or []
|
||||
self.data = None
|
||||
self.total_len = None
|
||||
self.buffer_id = None
|
||||
self.table_id = None
|
||||
self.cookie = None
|
||||
self.reason = None
|
||||
self.metadata = None
|
||||
self.userdata = None
|
||||
self.continuation = None
|
||||
|
||||
def _serialize_body(self):
|
||||
bin_props = bytearray()
|
||||
for p in self.properties:
|
||||
bin_props += p.serialize()
|
||||
|
||||
msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR,
|
||||
self.buf, ofproto.OFP_HEADER_SIZE,
|
||||
self.experimenter, self.exp_type)
|
||||
self.buf += bin_props
|
||||
|
||||
@classmethod
|
||||
def parser_subtype(cls, super_msg):
|
||||
msg = cls(super_msg.datapath)
|
||||
rest = super_msg.data
|
||||
while rest:
|
||||
p, rest = NXTPacketIn2Prop.parse(rest)
|
||||
msg.properties.append(p)
|
||||
msg._parse_property(p)
|
||||
|
||||
return msg
|
||||
|
||||
def _parse_property(self, p):
|
||||
if p.type == nicira_ext.NXPINT_PACKET:
|
||||
self.data = p.data
|
||||
# Note: here total_len is length of packet but not msg
|
||||
self.total_len = p.length
|
||||
elif p.type == nicira_ext.NXPINT_FULL_LEN:
|
||||
self.total_len = struct.unpack_from('!I', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_BUFFER_ID:
|
||||
self.buffer_id = struct.unpack_from('!I', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_TABLE_ID:
|
||||
self.table_id = struct.unpack_from('B', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_COOKIE:
|
||||
self.cookie = struct.unpack_from('!Q', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_REASON:
|
||||
self.reason = struct.unpack_from('!B', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_METADATA:
|
||||
self.metadata = p.data
|
||||
elif p.type == nicira_ext.NXPINT_USERDATA:
|
||||
self.userdata = p.data
|
||||
elif p.type == nicira_ext.NXPINT_CONTINUATION:
|
||||
self.continuation = p.data
|
||||
|
||||
|
||||
class NXTPacketIn2Prop(OFPPropBase):
|
||||
_TYPES = {}
|
||||
_PROP_TYPE = None
|
||||
|
||||
def __init__(self, type_=None, length=None, data=None):
|
||||
super(NXTPacketIn2Prop, self).__init__(type_, length)
|
||||
self.data = data
|
||||
|
||||
@classmethod
|
||||
def parse(cls, buf):
|
||||
(type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0)
|
||||
rest = buf[utils.round_up(length, 8):]
|
||||
try:
|
||||
subcls = cls._TYPES[type_]
|
||||
except KeyError:
|
||||
subcls = OFPPropUnknown
|
||||
prop = subcls.sub_parser(buf, type, length)
|
||||
prop.type = type_
|
||||
prop.length = length
|
||||
return prop, rest
|
||||
|
||||
def serialize_body(self):
|
||||
return self.data
|
||||
|
||||
@classmethod
|
||||
def sub_parser(cls, buf, type, length):
|
||||
p = cls(type, length - 4, buf[4:length])
|
||||
return p
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_PACKET)
|
||||
class NXTPacketIn2PropPacket(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_PACKET
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_FULL_LEN)
|
||||
class NXTPacketIn2PropFullLen(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_FULL_LEN
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_BUFFER_ID)
|
||||
class NXTPacketIn2PropBufferId(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_BUFFER_ID
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_TABLE_ID)
|
||||
class NXTPacketIn2PropTableId(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_TABLE_ID
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_COOKIE)
|
||||
class NXTPacketIn2PropCookie(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_COOKIE
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_REASON)
|
||||
class NXTPacketIn2PropReason(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_REASON
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_METADATA)
|
||||
class NXTPacketIn2PropMetadata(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_METADATA
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_USERDATA)
|
||||
class NXTPacketIn2PropUserData(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_USERDATA
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_CONTINUATION)
|
||||
class NXTPacketIn2PropContinuation(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_CONTINUATION
|
||||
|
||||
|
||||
nx_actions.generate(
|
||||
'os_ken.ofproto.ofproto_v1_3',
|
||||
'os_ken.ofproto.ofproto_v1_3_parser'
|
||||
|
@ -397,6 +397,15 @@ oxm_types = [
|
||||
# EXT-233 Output match Extension
|
||||
# NOTE(yamamoto): The spec says uint64_t but I assume it's an error.
|
||||
oxm_fields.ONFExperimenter('actset_output', 43, type_desc.Int4),
|
||||
# Support for matching/setting xreg0-7
|
||||
oxm_fields.PacketRegs('xreg0', 0, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg1', 1, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg2', 2, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg3', 3, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg4', 4, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg5', 5, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg6', 6, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg7', 7, type_desc.Int8),
|
||||
] + nicira_ext.oxm_types
|
||||
|
||||
oxm_fields.generate(__name__)
|
||||
|
@ -29,6 +29,7 @@ from os_ken.lib.packet import packet
|
||||
from os_ken import utils
|
||||
from os_ken.ofproto.ofproto_parser import StringifyMixin, MsgBase, MsgInMsgBase
|
||||
from os_ken.ofproto import ether
|
||||
from os_ken.ofproto import nicira_ext
|
||||
from os_ken.ofproto import nx_actions
|
||||
from os_ken.ofproto import ofproto_parser
|
||||
from os_ken.ofproto import ofproto_common
|
||||
@ -52,6 +53,15 @@ def _register_parser(cls):
|
||||
return cls
|
||||
|
||||
|
||||
def _register_exp_type(experimenter, exp_type):
|
||||
assert exp_type not in OFPExperimenter._subtypes
|
||||
|
||||
def _wrapper(cls):
|
||||
OFPExperimenter._subtypes[(experimenter, exp_type)] = cls
|
||||
return cls
|
||||
return _wrapper
|
||||
|
||||
|
||||
@ofproto_parser.register_msg_parser(ofproto.OFP_VERSION)
|
||||
def msg_parser(datapath, version, msg_type, msg_len, xid, buf):
|
||||
parser = _MSG_PARSERS.get(msg_type)
|
||||
@ -407,6 +417,7 @@ class OFPExperimenter(MsgBase):
|
||||
data Experimenter defined arbitrary additional data
|
||||
============= =========================================================
|
||||
"""
|
||||
_subtypes = {}
|
||||
|
||||
def __init__(self, datapath, experimenter=None, exp_type=None, data=None):
|
||||
super(OFPExperimenter, self).__init__(datapath)
|
||||
@ -423,6 +434,13 @@ class OFPExperimenter(MsgBase):
|
||||
ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, msg.buf,
|
||||
ofproto.OFP_HEADER_SIZE)
|
||||
msg.data = msg.buf[ofproto.OFP_EXPERIMENTER_HEADER_SIZE:]
|
||||
if (msg.experimenter, msg.exp_type) in cls._subtypes:
|
||||
new_msg = cls._subtypes[
|
||||
(msg.experimenter, msg.exp_type)].parser_subtype(msg)
|
||||
new_msg.set_headers(msg.version, msg.msg_type, msg.msg_len,
|
||||
msg.xid)
|
||||
new_msg.set_buf(msg.buf)
|
||||
return new_msg
|
||||
|
||||
return msg
|
||||
|
||||
@ -5833,6 +5851,169 @@ class OFPBundleAddMsg(MsgInMsgBase):
|
||||
self.buf += tail_buf
|
||||
|
||||
|
||||
@_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_SET_PACKET_IN_FORMAT)
|
||||
class NXTSetPacketInFormatMsg(OFPExperimenter):
|
||||
def __init__(self, datapath, packet_in_format):
|
||||
super(NXTSetPacketInFormatMsg, self).__init__(
|
||||
datapath, ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_SET_PACKET_IN_FORMAT)
|
||||
self.packet_in_format = packet_in_format
|
||||
|
||||
def _serialize_body(self):
|
||||
msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR,
|
||||
self.buf, ofproto.OFP_HEADER_SIZE,
|
||||
self.experimenter, self.exp_type)
|
||||
msg_pack_into(nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR,
|
||||
self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE,
|
||||
self.packet_in_format)
|
||||
|
||||
@classmethod
|
||||
def parser_subtype(cls, super_msg):
|
||||
packet_in_format = struct.unpack_from(
|
||||
nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR, super_msg.data)[0]
|
||||
msg = cls(super_msg.datapath, packet_in_format)
|
||||
msg.properties = []
|
||||
return msg
|
||||
|
||||
|
||||
@_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_PACKET_IN2)
|
||||
class NXTPacketIn2(OFPExperimenter):
|
||||
def __init__(self, datapath, properties=None):
|
||||
super(NXTPacketIn2, self).__init__(
|
||||
datapath, ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_PACKET_IN2)
|
||||
self.properties = properties or []
|
||||
self.data = None
|
||||
self.total_len = None
|
||||
self.buffer_id = None
|
||||
self.table_id = None
|
||||
self.cookie = None
|
||||
self.reason = None
|
||||
self.metadata = None
|
||||
self.userdata = None
|
||||
self.continuation = None
|
||||
|
||||
def _serialize_body(self):
|
||||
bin_props = bytearray()
|
||||
for p in self.properties:
|
||||
bin_props += p.serialize()
|
||||
|
||||
msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR,
|
||||
self.buf, ofproto.OFP_HEADER_SIZE,
|
||||
self.experimenter, self.exp_type)
|
||||
self.buf += bin_props
|
||||
|
||||
@classmethod
|
||||
def parser_subtype(cls, super_msg):
|
||||
msg = cls(super_msg.datapath)
|
||||
rest = super_msg.data
|
||||
while rest:
|
||||
p, rest = NXTPacketIn2Prop.parse(rest)
|
||||
msg.properties.append(p)
|
||||
msg._parse_property(p)
|
||||
|
||||
return msg
|
||||
|
||||
def _parse_property(self, p):
|
||||
if p.type == nicira_ext.NXPINT_PACKET:
|
||||
self.data = p.data
|
||||
# Note: here total_len is length of packet but not msg
|
||||
self.total_len = p.length
|
||||
elif p.type == nicira_ext.NXPINT_FULL_LEN:
|
||||
self.total_len = struct.unpack_from('!I', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_BUFFER_ID:
|
||||
self.buffer_id = struct.unpack_from('!I', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_TABLE_ID:
|
||||
self.table_id = struct.unpack_from('B', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_COOKIE:
|
||||
self.cookie = struct.unpack_from('!Q', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_REASON:
|
||||
self.reason = struct.unpack_from('!B', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_METADATA:
|
||||
self.metadata = p.data
|
||||
elif p.type == nicira_ext.NXPINT_USERDATA:
|
||||
self.userdata = p.data
|
||||
elif p.type == nicira_ext.NXPINT_CONTINUATION:
|
||||
self.continuation = p.data
|
||||
|
||||
|
||||
class NXTPacketIn2Prop(OFPPropBase):
|
||||
_TYPES = {}
|
||||
_PROP_TYPE = None
|
||||
|
||||
def __init__(self, type_=None, length=None, data=None):
|
||||
super(NXTPacketIn2Prop, self).__init__(type_, length)
|
||||
self.data = data
|
||||
|
||||
@classmethod
|
||||
def parse(cls, buf):
|
||||
(type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0)
|
||||
rest = buf[utils.round_up(length, 8):]
|
||||
try:
|
||||
subcls = cls._TYPES[type_]
|
||||
except KeyError:
|
||||
subcls = OFPPropUnknown
|
||||
prop = subcls.sub_parser(buf, type, length)
|
||||
prop.type = type_
|
||||
prop.length = length
|
||||
return prop, rest
|
||||
|
||||
def serialize_body(self):
|
||||
return self.data
|
||||
|
||||
@classmethod
|
||||
def sub_parser(cls, buf, type, length):
|
||||
p = cls(type, length - 4, buf[4:length])
|
||||
return p
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_PACKET)
|
||||
class NXTPacketIn2PropPacket(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_PACKET
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_FULL_LEN)
|
||||
class NXTPacketIn2PropFullLen(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_FULL_LEN
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_BUFFER_ID)
|
||||
class NXTPacketIn2PropBufferId(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_BUFFER_ID
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_TABLE_ID)
|
||||
class NXTPacketIn2PropTableId(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_TABLE_ID
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_COOKIE)
|
||||
class NXTPacketIn2PropCookie(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_COOKIE
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_REASON)
|
||||
class NXTPacketIn2PropReason(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_REASON
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_METADATA)
|
||||
class NXTPacketIn2PropMetadata(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_METADATA
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_USERDATA)
|
||||
class NXTPacketIn2PropUserData(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_USERDATA
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_CONTINUATION)
|
||||
class NXTPacketIn2PropContinuation(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_CONTINUATION
|
||||
|
||||
|
||||
nx_actions.generate(
|
||||
'os_ken.ofproto.ofproto_v1_4',
|
||||
'os_ken.ofproto.ofproto_v1_4_parser'
|
||||
|
@ -432,6 +432,15 @@ oxm_types = [
|
||||
oxm_fields.OpenFlowBasic('tcp_flags', 42, type_desc.Int2),
|
||||
oxm_fields.OpenFlowBasic('actset_output', 43, type_desc.Int4),
|
||||
oxm_fields.OpenFlowBasic('packet_type', 44, type_desc.Int4),
|
||||
# Support for matching/setting xreg0-7
|
||||
oxm_fields.PacketRegs('xreg0', 0, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg1', 1, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg2', 2, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg3', 3, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg4', 4, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg5', 5, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg6', 6, type_desc.Int8),
|
||||
oxm_fields.PacketRegs('xreg7', 7, type_desc.Int8),
|
||||
] + nicira_ext.oxm_types
|
||||
|
||||
oxm_fields.generate(__name__)
|
||||
|
@ -30,6 +30,7 @@ from os_ken import exception
|
||||
from os_ken import utils
|
||||
from os_ken.ofproto.ofproto_parser import StringifyMixin, MsgBase, MsgInMsgBase
|
||||
from os_ken.ofproto import ether
|
||||
from os_ken.ofproto import nicira_ext
|
||||
from os_ken.ofproto import nx_actions
|
||||
from os_ken.ofproto import ofproto_parser
|
||||
from os_ken.ofproto import ofproto_common
|
||||
@ -53,6 +54,15 @@ def _register_parser(cls):
|
||||
return cls
|
||||
|
||||
|
||||
def _register_exp_type(experimenter, exp_type):
|
||||
assert exp_type not in OFPExperimenter._subtypes
|
||||
|
||||
def _wrapper(cls):
|
||||
OFPExperimenter._subtypes[(experimenter, exp_type)] = cls
|
||||
return cls
|
||||
return _wrapper
|
||||
|
||||
|
||||
@ofproto_parser.register_msg_parser(ofproto.OFP_VERSION)
|
||||
def msg_parser(datapath, version, msg_type, msg_len, xid, buf):
|
||||
parser = _MSG_PARSERS.get(msg_type)
|
||||
@ -407,6 +417,7 @@ class OFPExperimenter(MsgBase):
|
||||
data Experimenter defined arbitrary additional data
|
||||
============= =========================================================
|
||||
"""
|
||||
_subtypes = {}
|
||||
|
||||
def __init__(self, datapath, experimenter=None, exp_type=None, data=None):
|
||||
super(OFPExperimenter, self).__init__(datapath)
|
||||
@ -423,6 +434,13 @@ class OFPExperimenter(MsgBase):
|
||||
ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR, msg.buf,
|
||||
ofproto.OFP_HEADER_SIZE)
|
||||
msg.data = msg.buf[ofproto.OFP_EXPERIMENTER_HEADER_SIZE:]
|
||||
if (msg.experimenter, msg.exp_type) in cls._subtypes:
|
||||
new_msg = cls._subtypes[
|
||||
(msg.experimenter, msg.exp_type)].parser_subtype(msg)
|
||||
new_msg.set_headers(msg.version, msg.msg_type, msg.msg_len,
|
||||
msg.xid)
|
||||
new_msg.set_buf(msg.buf)
|
||||
return new_msg
|
||||
|
||||
return msg
|
||||
|
||||
@ -6934,6 +6952,169 @@ class OFPBundleAddMsg(MsgInMsgBase):
|
||||
self.buf += tail_buf
|
||||
|
||||
|
||||
@_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_SET_PACKET_IN_FORMAT)
|
||||
class NXTSetPacketInFormatMsg(OFPExperimenter):
|
||||
def __init__(self, datapath, packet_in_format):
|
||||
super(NXTSetPacketInFormatMsg, self).__init__(
|
||||
datapath, ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_SET_PACKET_IN_FORMAT)
|
||||
self.packet_in_format = packet_in_format
|
||||
|
||||
def _serialize_body(self):
|
||||
msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR,
|
||||
self.buf, ofproto.OFP_HEADER_SIZE,
|
||||
self.experimenter, self.exp_type)
|
||||
msg_pack_into(nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR,
|
||||
self.buf, ofproto.OFP_EXPERIMENTER_HEADER_SIZE,
|
||||
self.packet_in_format)
|
||||
|
||||
@classmethod
|
||||
def parser_subtype(cls, super_msg):
|
||||
packet_in_format = struct.unpack_from(
|
||||
nicira_ext.NX_SET_PACKET_IN_FORMAT_PACK_STR, super_msg.data)[0]
|
||||
msg = cls(super_msg.datapath, packet_in_format)
|
||||
msg.properties = []
|
||||
return msg
|
||||
|
||||
|
||||
@_register_exp_type(ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_PACKET_IN2)
|
||||
class NXTPacketIn2(OFPExperimenter):
|
||||
def __init__(self, datapath, properties=None):
|
||||
super(NXTPacketIn2, self).__init__(
|
||||
datapath, ofproto_common.NX_EXPERIMENTER_ID,
|
||||
nicira_ext.NXT_PACKET_IN2)
|
||||
self.properties = properties or []
|
||||
self.data = None
|
||||
self.total_len = None
|
||||
self.buffer_id = None
|
||||
self.table_id = None
|
||||
self.cookie = None
|
||||
self.reason = None
|
||||
self.metadata = None
|
||||
self.userdata = None
|
||||
self.continuation = None
|
||||
|
||||
def _serialize_body(self):
|
||||
bin_props = bytearray()
|
||||
for p in self.properties:
|
||||
bin_props += p.serialize()
|
||||
|
||||
msg_pack_into(ofproto.OFP_EXPERIMENTER_HEADER_PACK_STR,
|
||||
self.buf, ofproto.OFP_HEADER_SIZE,
|
||||
self.experimenter, self.exp_type)
|
||||
self.buf += bin_props
|
||||
|
||||
@classmethod
|
||||
def parser_subtype(cls, super_msg):
|
||||
msg = cls(super_msg.datapath)
|
||||
rest = super_msg.data
|
||||
while rest:
|
||||
p, rest = NXTPacketIn2Prop.parse(rest)
|
||||
msg.properties.append(p)
|
||||
msg._parse_property(p)
|
||||
|
||||
return msg
|
||||
|
||||
def _parse_property(self, p):
|
||||
if p.type == nicira_ext.NXPINT_PACKET:
|
||||
self.data = p.data
|
||||
# Note: here total_len is length of packet but not msg
|
||||
self.total_len = p.length
|
||||
elif p.type == nicira_ext.NXPINT_FULL_LEN:
|
||||
self.total_len = struct.unpack_from('!I', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_BUFFER_ID:
|
||||
self.buffer_id = struct.unpack_from('!I', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_TABLE_ID:
|
||||
self.table_id = struct.unpack_from('B', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_COOKIE:
|
||||
self.cookie = struct.unpack_from('!Q', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_REASON:
|
||||
self.reason = struct.unpack_from('!B', p.data)[0]
|
||||
elif p.type == nicira_ext.NXPINT_METADATA:
|
||||
self.metadata = p.data
|
||||
elif p.type == nicira_ext.NXPINT_USERDATA:
|
||||
self.userdata = p.data
|
||||
elif p.type == nicira_ext.NXPINT_CONTINUATION:
|
||||
self.continuation = p.data
|
||||
|
||||
|
||||
class NXTPacketIn2Prop(OFPPropBase):
|
||||
_TYPES = {}
|
||||
_PROP_TYPE = None
|
||||
|
||||
def __init__(self, type_=None, length=None, data=None):
|
||||
super(NXTPacketIn2Prop, self).__init__(type_, length)
|
||||
self.data = data
|
||||
|
||||
@classmethod
|
||||
def parse(cls, buf):
|
||||
(type_, length) = struct.unpack_from(cls._PACK_STR, buf, 0)
|
||||
rest = buf[utils.round_up(length, 8):]
|
||||
try:
|
||||
subcls = cls._TYPES[type_]
|
||||
except KeyError:
|
||||
subcls = OFPPropUnknown
|
||||
prop = subcls.sub_parser(buf, type, length)
|
||||
prop.type = type_
|
||||
prop.length = length
|
||||
return prop, rest
|
||||
|
||||
def serialize_body(self):
|
||||
return self.data
|
||||
|
||||
@classmethod
|
||||
def sub_parser(cls, buf, type, length):
|
||||
p = cls(type, length - 4, buf[4:length])
|
||||
return p
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_PACKET)
|
||||
class NXTPacketIn2PropPacket(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_PACKET
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_FULL_LEN)
|
||||
class NXTPacketIn2PropFullLen(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_FULL_LEN
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_BUFFER_ID)
|
||||
class NXTPacketIn2PropBufferId(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_BUFFER_ID
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_TABLE_ID)
|
||||
class NXTPacketIn2PropTableId(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_TABLE_ID
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_COOKIE)
|
||||
class NXTPacketIn2PropCookie(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_COOKIE
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_REASON)
|
||||
class NXTPacketIn2PropReason(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_REASON
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_METADATA)
|
||||
class NXTPacketIn2PropMetadata(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_METADATA
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_USERDATA)
|
||||
class NXTPacketIn2PropUserData(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_USERDATA
|
||||
|
||||
|
||||
@NXTPacketIn2Prop.register_type(nicira_ext.NXPINT_CONTINUATION)
|
||||
class NXTPacketIn2PropContinuation(NXTPacketIn2Prop):
|
||||
_PROP_TYPE = nicira_ext.NXPINT_CONTINUATION
|
||||
|
||||
|
||||
nx_actions.generate(
|
||||
'os_ken.ofproto.ofproto_v1_5',
|
||||
'os_ken.ofproto.ofproto_v1_5_parser'
|
||||
|
Loading…
Reference in New Issue
Block a user