On Wed, Jul 10, 2013 at 12:52:36PM +0900, YAMAMOTO Takashi wrote:
> 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')

How about allowing mask like CIDR notation?
e.g.. '2001:db8:bd05:1d2:288a:1fc0:1:10ee/64'


> the old match.set_foo and match.append_field methods are kept for now
> but will be removed later.
> 
> Signed-off-by: YAMAMOTO Takashi <[email protected]>
> ---
>  ryu/ofproto/ofproto_v1_3_parser.py | 56 +++++++++++++++++++++++++++++++++-
>  ryu/ofproto/oxm_fields.py          | 62 
> ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 117 insertions(+), 1 deletion(-)
> 
> diff --git a/ryu/ofproto/ofproto_v1_3_parser.py 
> b/ryu/ofproto/ofproto_v1_3_parser.py
> index 77af01f..2a4e472 100644
> --- a/ryu/ofproto/ofproto_v1_3_parser.py
> +++ b/ryu/ofproto/ofproto_v1_3_parser.py
> @@ -22,6 +22,7 @@ from ryu import utils
>  from ofproto_parser import StringifyMixin, MsgBase, msg_pack_into, 
> msg_str_attr
>  from . import ofproto_parser
>  from . import ofproto_v1_3
> +from . import oxm_fields
>  
>  import logging
>  LOG = logging.getLogger('ryu.ofproto.ofproto_v1_3_parser')
> @@ -349,7 +350,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 +380,63 @@ 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')
> +        fields2 = {}
> +        for k, uv in kwargs.iteritems():
> +            (n, v, m) = oxm_fields.from_user(k, uv)
> +            # apply mask
> +            if not m is None:
> +                v = ''.join(chr(ord(x) & ord(y)) for (x, y)
> +                    in itertools.izip(v, m))
> +            k2, uv2 = oxm_fields.to_user(n, v, m)

How about putting this kind of normalization into oxm_fields.py?


> +            assert k2 == k
> +            fields2[k2] = uv2
> +        self._fields2 = fields2
> +
>      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 = []
> +        for k, v in self._fields2.iteritems():
> +            fields.append(oxm_fields.from_user(k, v))

fields = [oxm_fields.from_user(k, v) for k, v in self._fields2.iteritems()]
Probably it's matter of taste, though.


> +
> +        # 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,
> +                              ofproto_v1_3.oxm_tlv_header_w(n, len(value)),
> +                              value, mask)
> +            else:
> +                pack_str = "!I%ds" % (len(value),)
> +                msg_pack_into(pack_str, buf, field_offset,
> +                              ofproto_v1_3.oxm_tlv_header(n, 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)
> diff --git a/ryu/ofproto/oxm_fields.py b/ryu/ofproto/oxm_fields.py
> index a7c319d..e44962c 100644
> --- a/ryu/ofproto/oxm_fields.py
> +++ b/ryu/ofproto/oxm_fields.py
> @@ -16,6 +16,8 @@
>  # See the License for the specific language governing permissions and
>  # limitations under the License.
>  
> +from ryu.lib import addrconv
> +
>  
>  class TypeDescr(object):
>      pass
> @@ -25,6 +27,21 @@ class IntDescr(TypeDescr):
>      def __init__(self, size):
>          self.size = size
>  
> +    def to_user(self, bin):
> +        i = 0
> +        for x in xrange(self.size):
> +            c = bin[:1]
> +            i = i * 256 + ord(c)
> +            bin = bin[1:]
> +        return i
> +
> +    def from_user(self, i):
> +        bin = ''
> +        for x in xrange(self.size):
> +            bin = chr(i & 255) + bin
> +            i /= 256
> +        return bin
> +
>  Int1 = IntDescr(1)
>  Int2 = IntDescr(2)
>  Int3 = IntDescr(3)
> @@ -34,14 +51,20 @@ Int8 = IntDescr(8)
>  
>  class MacAddr(TypeDescr):
>      size = 6
> +    to_user = addrconv.mac.bin_to_text
> +    from_user = addrconv.mac.text_to_bin
>  
>  
>  class IPv4Addr(TypeDescr):
>      size = 4
> +    to_user = addrconv.ipv4.bin_to_text
> +    from_user = addrconv.ipv4.text_to_bin
>  
>  
>  class IPv6Addr(TypeDescr):
>      size = 16
> +    to_user = addrconv.ipv6.bin_to_text
> +    from_user = addrconv.ipv6.text_to_bin
>  
>  
>  class D(object):
> @@ -111,3 +134,42 @@ def generate_constants(modname):
>          add_attr('OFPXMT_OFB_' + uk, ofpxmt)
>          add_attr('OXM_OF_' + uk, mod.oxm_tlv_header(ofpxmt, td.size))
>          add_attr('OXM_OF_' + uk + '_W', mod.oxm_tlv_header_w(ofpxmt, 
> td.size))
> +
> +
> +def find_field_by_name(name):
> +    for t in oxm_types:
> +        if t.name == name:
> +            return t
> +    raise KeyError

Can dict be used?
NAME_TO_FILED = dict((t.name, t) for t in oxm_types)


> +
> +
> +def from_user(name, user_value):
> +    f = find_field_by_name(name)
> +    t = f.type
> +    if isinstance(user_value, tuple):
> +        (value, mask) = user_value
> +    else:
> +        value = user_value
> +        mask = None
> +    value = t.from_user(value)
> +    if not mask is None:
> +        mask = t.from_user(mask)
> +    return f.num, value, mask
> +
> +
> +def find_field_by_num(n):
> +    for t in oxm_types:
> +        if t.num == n:
> +            return t
> +    raise KeyError

Can dict be used?
NUM_TO_FIELD = dict((t.num, t) for t in oxm_types)


> +
> +
> +def to_user(n, v, m):
> +    f = find_field_by_num(n)
> +    t = f.type
> +    value = t.to_user(v)
> +    if m is None:
> +        user_value = value
> +    else:
> +        user_value = (value, t.to_user(m))
> +    return f.name, user_value
> -- 
> 1.8.1.5
> 
> 
> ------------------------------------------------------------------------------
> See everything from the browser to the database with AppDynamics
> Get end-to-end visibility with application monitoring from AppDynamics
> Isolate bottlenecks and diagnose root cause in seconds.
> Start your free trial of AppDynamics Pro today!
> http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
> _______________________________________________
> Ryu-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ryu-devel
> 

-- 
yamahata

------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to