diff options
author | YAMAMOTO Takashi <yamamoto@valinux.co.jp> | 2013-07-23 16:03:26 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2013-07-31 21:06:38 +0900 |
commit | b7075a1e26579e4ed2e1b538b69eb0a0b0f48733 (patch) | |
tree | b4627f873395dc1459f9135cb3d7e46e61358ca4 | |
parent | 2ef6d905d9118fa4ab43eef419ae90d54b7bb1e4 (diff) |
of13: new OFPMatch composer api
a new api to compose matches. it looks like:
match = OFPMatch(in_port=1,
eth_type=0x86dd,
ipv6_src=('2001:db8:bd05:1d2:288a:1fc0:1:10ee',
'ffff:ffff:ffff:ffff::'),
ipv6_dst = '2001:db8:bd05:1d2:288a:1fc0:1:10ee')
the old match.set_foo and match.append_field methods are kept for now
but will be removed later.
Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/ofproto/ofproto_v1_3_parser.py | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/ryu/ofproto/ofproto_v1_3_parser.py b/ryu/ofproto/ofproto_v1_3_parser.py index 4ea91ff2..9a9f7bd3 100644 --- a/ryu/ofproto/ofproto_v1_3_parser.py +++ b/ryu/ofproto/ofproto_v1_3_parser.py @@ -349,7 +349,7 @@ class FlowWildcards(object): class OFPMatch(StringifyMixin): - def __init__(self, fields=[], type_=None): + def __init__(self, fields=[], type_=None, **kwargs): super(OFPMatch, self).__init__() self._wc = FlowWildcards() self._flow = Flow() @@ -379,10 +379,53 @@ class OFPMatch(StringifyMixin): f = cls(header, value, mask) self.fields.append(f) + # eg. + # OFPMatch(eth_src=('ff:ff:ff:00:00:00'), eth_type=0x800, + # ipv4_src='10.0.0.1') + self._fields2 = dict(ofproto_v1_3.oxm_normalize_user(k, uv) for (k, uv) + in kwargs.iteritems()) + def append_field(self, header, value, mask=None): self.fields.append(OFPMatchField.make(header, value, mask)) def serialize(self, buf, offset): + # XXX compat + if self.fields or self._wc.__dict__ != FlowWildcards().__dict__: + return self.serialize_old(buf, offset) + + fields = [ofproto_v1_3.oxm_from_user(k, v) for (k, v) + in self._fields2.iteritems()] + + # assumption: sorting by OXM type values makes fields + # meet ordering requirements (eg. eth_type before ipv4_src) + fields.sort() + + hdr_pack_str = '!HH' + field_offset = offset + struct.calcsize(hdr_pack_str) + for (n, value, mask) in fields: + if mask: + assert len(value) == len(mask) + pack_str = "!I%ds%ds" % (len(value), len(mask)) + msg_pack_into(pack_str, buf, field_offset, + (n << 9) | (1 << 8) | (len(value) * 2), + value, mask) + else: + pack_str = "!I%ds" % (len(value),) + msg_pack_into(pack_str, buf, field_offset, + (n << 9) | (0 << 8) | len(value), + value) + field_offset += struct.calcsize(pack_str) + + length = field_offset - offset + msg_pack_into(hdr_pack_str, buf, offset, + ofproto_v1_3.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 + + def serialize_old(self, buf, offset): if self._wc.ft_test(ofproto_v1_3.OFPXMT_OFB_IN_PORT): self.append_field(ofproto_v1_3.OXM_OF_IN_PORT, self._flow.in_port) |