mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-05-10 14:56:11 +02:00
Add OF1.4 OFPMatchField support
This covers fields that are also present in OF1.3. In particular it does not cover PBB_UCA. I plan to address this in a subsequent patch. Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
4a52daee65
commit
ec18b3f0f1
@ -314,6 +314,9 @@ OFPXMC_NXM_1 = 0x0001 # Backward compatibility with NXM
|
||||
OFPXMC_OPENFLOW_BASIC = 0x8000 # Basic class for OpenFlow
|
||||
OFPXMC_EXPERIMENTER = 0xFFFF # Experimenter class
|
||||
|
||||
# enum ofp_vlan_id
|
||||
OFPVID_PRESENT = 0x1000 # bit that indicate that a VLAN id is set.
|
||||
|
||||
|
||||
def _oxm_tlv_header(class_, field, hasmask, length):
|
||||
return (class_ << 16) | (field << 9) | (hasmask << 8) | length
|
||||
|
||||
@ -568,6 +568,564 @@ class OFPPortDescPropEthernet(StringifyMixin):
|
||||
return ether
|
||||
|
||||
|
||||
class OFPMatchField(StringifyMixin):
|
||||
_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
|
||||
self.n_bytes = ofproto.oxm_tlv_header_extract_length(header)
|
||||
self.length = 0
|
||||
|
||||
@classmethod
|
||||
def cls_to_header(cls, cls_, hasmask):
|
||||
# XXX efficiency
|
||||
inv = dict((v, k) for k, v in cls._FIELDS_HEADERS.iteritems()
|
||||
if (((k >> 8) & 1) != 0) == hasmask)
|
||||
return inv[cls_]
|
||||
|
||||
@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 ofproto.oxm_tlv_header_extract_hasmask(header):
|
||||
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):
|
||||
if ofproto.oxm_tlv_header_extract_hasmask(self.header):
|
||||
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
|
||||
|
||||
def to_jsondict(self):
|
||||
# remove some redundant attributes
|
||||
d = super(OFPMatchField, self).to_jsondict()
|
||||
v = d[self.__class__.__name__]
|
||||
del v['header']
|
||||
del v['length']
|
||||
del v['n_bytes']
|
||||
return d
|
||||
|
||||
@classmethod
|
||||
def from_jsondict(cls, dict_):
|
||||
# just pass the dict around.
|
||||
# it will be converted by OFPMatch.__init__().
|
||||
return {cls.__name__: dict_}
|
||||
|
||||
def stringify_attrs(self):
|
||||
f = super(OFPMatchField, self).stringify_attrs
|
||||
if not ofproto.oxm_tlv_header_extract_hasmask(self.header):
|
||||
# something like the following, but yield two values (k,v)
|
||||
# return itertools.ifilter(lambda k, v: k != 'mask', iter())
|
||||
def g():
|
||||
for k, v in f():
|
||||
if k != 'mask':
|
||||
yield (k, v)
|
||||
return g()
|
||||
else:
|
||||
return f()
|
||||
|
||||
|
||||
@OFPMatchField.register_field_header([ofproto.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.OXM_OF_METADATA,
|
||||
ofproto.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.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.OXM_OF_ETH_DST,
|
||||
ofproto.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.OXM_OF_ETH_SRC,
|
||||
ofproto.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.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.OXM_OF_VLAN_VID,
|
||||
ofproto.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
|
||||
|
||||
@classmethod
|
||||
def field_parser(cls, header, buf, offset):
|
||||
m = super(MTVlanVid, cls).field_parser(header, buf, offset)
|
||||
m.value &= ~ofproto.OFPVID_PRESENT
|
||||
return m
|
||||
|
||||
def serialize(self, buf, offset):
|
||||
self.value |= ofproto.OFPVID_PRESENT
|
||||
super(MTVlanVid, self).serialize(buf, offset)
|
||||
|
||||
|
||||
@OFPMatchField.register_field_header([ofproto.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.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.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.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.OXM_OF_IPV4_SRC,
|
||||
ofproto.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.OXM_OF_IPV4_DST,
|
||||
ofproto.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.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.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.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.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.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.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.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.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.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.OXM_OF_ARP_SPA,
|
||||
ofproto.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.OXM_OF_ARP_TPA,
|
||||
ofproto.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.OXM_OF_ARP_SHA,
|
||||
ofproto.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.OXM_OF_ARP_THA,
|
||||
ofproto.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(StringifyMixin):
|
||||
@classmethod
|
||||
def field_parser(cls, header, buf, offset):
|
||||
if ofproto.oxm_tlv_header_extract_hasmask(header):
|
||||
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.OXM_OF_IPV6_SRC,
|
||||
ofproto.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.OXM_OF_IPV6_DST,
|
||||
ofproto.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.OXM_OF_IPV6_FLABEL,
|
||||
ofproto.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.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.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.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.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.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.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.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
|
||||
|
||||
|
||||
@OFPMatchField.register_field_header([ofproto.OXM_OF_MPLS_BOS])
|
||||
class MTMplsBos(OFPMatchField):
|
||||
pack_str = '!B'
|
||||
|
||||
def __init__(self, header, value, mask=None):
|
||||
super(MTMplsBos, self).__init__(header)
|
||||
self.value = value
|
||||
|
||||
|
||||
@OFPMatchField.register_field_header([ofproto.OXM_OF_PBB_ISID,
|
||||
ofproto.OXM_OF_PBB_ISID_W])
|
||||
class MTPbbIsid(OFPMatchField):
|
||||
pack_str = '!3B'
|
||||
|
||||
def __init__(self, header, value, mask=None):
|
||||
super(MTPbbIsid, self).__init__(header)
|
||||
self.value = value
|
||||
self.mask = mask
|
||||
|
||||
@classmethod
|
||||
def field_parser(cls, header, buf, offset):
|
||||
hasmask = (header >> 8) & 1
|
||||
mask = None
|
||||
if ofproto.oxm_tlv_header_extract_hasmask(header):
|
||||
pack_str = '!' + cls.pack_str[1:] * 2
|
||||
(v1, v2, v3, m1, m2, m3) = struct.unpack_from(pack_str, buf,
|
||||
offset + 4)
|
||||
value = v1 << 16 | v2 << 8 | v3
|
||||
mask = m1 << 16 | m2 << 8 | m3
|
||||
else:
|
||||
(v1, v2, v3,) = struct.unpack_from(cls.pack_str, buf, offset + 4)
|
||||
value = v1 << 16 | v2 << 8 | v3
|
||||
return cls(header, value, mask)
|
||||
|
||||
def _put(self, buf, offset, value):
|
||||
ofproto_parser.msg_pack_into(self.pack_str, buf, offset,
|
||||
(value >> 16) & 0xff,
|
||||
(value >> 8) & 0xff,
|
||||
(value >> 0) & 0xff)
|
||||
self.length += self.n_bytes
|
||||
|
||||
|
||||
@OFPMatchField.register_field_header([ofproto.OXM_OF_TUNNEL_ID,
|
||||
ofproto.OXM_OF_TUNNEL_ID_W])
|
||||
class MTTunnelId(OFPMatchField):
|
||||
pack_str = '!Q'
|
||||
|
||||
def __init__(self, header, value, mask=None):
|
||||
super(MTTunnelId, self).__init__(header)
|
||||
self.value = value
|
||||
self.mask = mask
|
||||
|
||||
|
||||
@OFPMatchField.register_field_header([ofproto.OXM_OF_IPV6_EXTHDR,
|
||||
ofproto.OXM_OF_IPV6_EXTHDR_W])
|
||||
class MTIPv6ExtHdr(OFPMatchField):
|
||||
pack_str = '!H'
|
||||
|
||||
def __init__(self, header, value, mask=None):
|
||||
super(MTIPv6ExtHdr, self).__init__(header)
|
||||
self.value = value
|
||||
self.mask = mask
|
||||
|
||||
|
||||
@_register_parser
|
||||
@_set_msg_type(ofproto.OFPT_PACKET_IN)
|
||||
class OFPPacketIn(MsgBase):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user