Signed-off-by: Yuichi Ito <ito.yuic...@gmail.com>
---
 doc/source/library_packet_ref.rst |    3 +
 ryu/lib/packet/pbb.py             |   61 ++++++++++++++
 ryu/lib/packet/vlan.py            |    6 +-
 ryu/ofproto/ether.py              |    1 +
 ryu/tests/unit/packet/test_pbb.py |  167 +++++++++++++++++++++++++++++++++++++
 5 files changed, 237 insertions(+), 1 deletion(-)
 create mode 100644 ryu/lib/packet/pbb.py
 create mode 100644 ryu/tests/unit/packet/test_pbb.py

diff --git a/doc/source/library_packet_ref.rst 
b/doc/source/library_packet_ref.rst
index 13ceec6..4426cfd 100644
--- a/doc/source/library_packet_ref.rst
+++ b/doc/source/library_packet_ref.rst
@@ -29,6 +29,9 @@ Protocol Header classes
 .. automodule:: ryu.lib.packet.vlan
    :members:

+.. automodule:: ryu.lib.packet.pbb
+   :members:
+
 .. automodule:: ryu.lib.packet.mpls
    :members:

diff --git a/ryu/lib/packet/pbb.py b/ryu/lib/packet/pbb.py
new file mode 100644
index 0000000..3582f7f
--- /dev/null
+++ b/ryu/lib/packet/pbb.py
@@ -0,0 +1,61 @@
+# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
+#
+# 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 struct
+from ryu.lib.packet import packet_base
+from ryu.ofproto import ether
+
+
+class itag(packet_base.PacketBase):
+    """I-TAG (IEEE 802.1ah-2008) header encoder/decoder class.
+
+    An instance has the following attributes at least.
+    Most of them are same to the on-wire counterparts but in host byte order.
+    __init__ takes the correspondig args in this order.
+
+    ============== ====================
+    Attribute      Description
+    ============== ====================
+    pcp            Priority Code Point
+    dei            Drop Eligible Indication
+    uca            Use Customer Address
+    sid            Service Instance ID
+    ============== ====================
+    """
+
+    _PACK_STR = "!I"
+    _MIN_LEN = struct.calcsize(_PACK_STR)
+
+    def __init__(self, pcp=0, dei=0, uca=0, sid=0):
+        super(itag, self).__init__()
+        self.pcp = pcp
+        self.dei = dei
+        self.uca = uca
+        self.sid = sid
+
+    @classmethod
+    def parser(cls, buf):
+        (data, ) = struct.unpack_from(cls._PACK_STR, buf)
+        pcp = data >> 29
+        dei = data >> 28 & 1
+        uca = data >> 27 & 1
+        sid = data & 0x00ffffff
+        from ryu.lib.packet import ethernet
+        return (cls(pcp, dei, uca, sid), ethernet.ethernet,
+                buf[cls._MIN_LEN:])
+
+    def serialize(self, payload, prev):
+        data = self.pcp << 29 | self.dei << 28 | self.uca << 27 | self.sid
+        return struct.pack(self._PACK_STR, data)
diff --git a/ryu/lib/packet/vlan.py b/ryu/lib/packet/vlan.py
index e1360ee..5326f9a 100644
--- a/ryu/lib/packet/vlan.py
+++ b/ryu/lib/packet/vlan.py
@@ -21,6 +21,7 @@ from . import ipv6
 from . import lldp
 from . import slow
 from . import llc
+from . import pbb
 from ryu.ofproto import ether


@@ -89,7 +90,9 @@ class svlan(packet_base.PacketBase):
     Attribute      Description
     ============== ====================
     pcp            Priority Code Point
-    cfi            Canonical Format Indicator
+    cfi            Canonical Format Indicator.
+                   In a case to be used as B-TAG,
+                   this field means DEI(Drop Eligible Indication).
     vid            VLAN Identifier
     ethertype      EtherType
     ============== ====================
@@ -131,3 +134,4 @@ vlan.register_packet_type(slow.slow, ether.ETH_TYPE_SLOW)
 vlan.register_packet_type(llc.llc, ether.ETH_TYPE_IEEE802_3)

 svlan.register_packet_type(vlan, ether.ETH_TYPE_8021Q)
+svlan.register_packet_type(pbb.itag, ether.ETH_TYPE_8021AH)
diff --git a/ryu/ofproto/ether.py b/ryu/ofproto/ether.py
index 9e1539c..f17f7be 100644
--- a/ryu/ofproto/ether.py
+++ b/ryu/ofproto/ether.py
@@ -22,4 +22,5 @@ ETH_TYPE_SLOW = 0x8809
 ETH_TYPE_MPLS = 0x8847
 ETH_TYPE_8021AD = 0x88a8
 ETH_TYPE_LLDP = 0x88cc
+ETH_TYPE_8021AH = 0x88e7
 ETH_TYPE_IEEE802_3 = 0x05dc
diff --git a/ryu/tests/unit/packet/test_pbb.py 
b/ryu/tests/unit/packet/test_pbb.py
new file mode 100644
index 0000000..891c09f
--- /dev/null
+++ b/ryu/tests/unit/packet/test_pbb.py
@@ -0,0 +1,167 @@
+# Copyright (C) 2013 Nippon Telegraph and Telephone Corporation.
+#
+# 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 logging
+import struct
+import unittest
+
+from nose.tools import eq_
+from nose.tools import ok_
+from nose.tools import raises
+from ryu.ofproto import ether
+from ryu.ofproto import inet
+from ryu.lib.packet import ethernet
+from ryu.lib.packet import packet
+from ryu.lib.packet import ipv4
+from ryu.lib.packet import vlan
+from ryu.lib.packet import pbb
+
+
+LOG = logging.getLogger(__name__)
+
+
+class Test_itag(unittest.TestCase):
+
+    pcp = 3
+    dei = 0
+    uca = 1
+    sid = 16770000
+    data = pcp << 29 | dei << 28 | uca << 27 | sid
+    buf = struct.pack(pbb.itag._PACK_STR, data)
+    it = pbb.itag(pcp, dei, uca, sid)
+
+    def setUp(self):
+        pass
+
+    def tearDown(self):
+        pass
+
+    def test_init(self):
+        eq_(self.pcp, self.it.pcp)
+        eq_(self.dei, self.it.dei)
+        eq_(self.uca, self.it.uca)
+        eq_(self.sid, self.it.sid)
+
+    def test_parser(self):
+        _res = pbb.itag.parser(self.buf)
+        if type(_res) is tuple:
+            res = _res[0]
+        else:
+            res = _res
+        eq_(res.pcp, self.pcp)
+        eq_(res.dei, self.dei)
+        eq_(res.uca, self.uca)
+        eq_(res.sid, self.sid)
+
+    def test_serialize(self):
+        data = bytearray()
+        prev = None
+        buf = self.it.serialize(data, prev)
+        res = struct.unpack(pbb.itag._PACK_STR, buf)
+        eq_(res[0], self.data)
+
+    def _build_itag(self):
+        b_src_mac = '00:07:0d:af:f4:54'
+        b_dst_mac = '00:00:00:00:00:00'
+        b_ethertype = ether.ETH_TYPE_8021AH
+        e1 = ethernet.ethernet(b_dst_mac, b_src_mac, b_ethertype)
+
+        b_pcp = 0
+        b_cfi = 0
+        b_vid = 32
+        b_ethertype = ether.ETH_TYPE_8021Q
+        bt = vlan.svlan(b_pcp, b_cfi, b_vid, b_ethertype)
+
+        c_src_mac = '11:11:11:11:11:11'
+        c_dst_mac = 'aa:aa:aa:aa:aa:aa'
+        c_ethertype = ether.ETH_TYPE_8021AH
+        e2 = ethernet.ethernet(c_dst_mac, c_src_mac, c_ethertype)
+
+        s_pcp = 0
+        s_cfi = 0
+        s_vid = 32
+        s_ethertype = ether.ETH_TYPE_8021Q
+        st = vlan.svlan(s_pcp, s_cfi, s_vid, s_ethertype)
+
+        c_pcp = 0
+        c_cfi = 0
+        c_vid = 32
+        c_ethertype = ether.ETH_TYPE_IP
+        ct = vlan.vlan(c_pcp, c_cfi, c_vid, c_ethertype)
+
+        version = 4
+        header_length = 20
+        tos = 0
+        total_length = 24
+        identification = 0x8a5d
+        flags = 0
+        offset = 1480
+        ttl = 64
+        proto = inet.IPPROTO_ICMP
+        csum = 0xa7f2
+        src = '131.151.32.21'
+        dst = '131.151.32.129'
+        option = 'TEST'
+        ip = ipv4.ipv4(version, header_length, tos, total_length,
+                       identification, flags, offset, ttl, proto, csum,
+                       src, dst, option)
+
+        p = packet.Packet()
+
+        p.add_protocol(e1)
+        p.add_protocol(bt)
+        p.add_protocol(self.it)
+        p.add_protocol(e2)
+        p.add_protocol(st)
+        p.add_protocol(ct)
+        p.add_protocol(ip)
+        p.serialize()
+
+        return p
+
+    def test_build_itag(self):
+        p = self._build_itag()
+
+        e = p.get_protocols(ethernet.ethernet)
+        ok_(e)
+        ok_(isinstance(e, list))
+        eq_(e[0].ethertype, ether.ETH_TYPE_8021AH)
+        eq_(e[1].ethertype, ether.ETH_TYPE_8021AH)
+
+        sv = p.get_protocols(vlan.svlan)
+        ok_(sv)
+        ok_(isinstance(sv, list))
+        eq_(sv[0].ethertype, ether.ETH_TYPE_8021Q)
+        eq_(sv[1].ethertype, ether.ETH_TYPE_8021Q)
+
+        it = p.get_protocol(pbb.itag)
+        ok_(it)
+
+        v = p.get_protocol(vlan.vlan)
+        ok_(v)
+        eq_(v.ethertype, ether.ETH_TYPE_IP)
+
+        ip = p.get_protocol(ipv4.ipv4)
+        ok_(ip)
+
+        eq_(it.pcp, self.pcp)
+        eq_(it.dei, self.dei)
+        eq_(it.uca, self.uca)
+        eq_(it.sid, self.sid)
+
+    @raises(Exception)
+    def test_malformed_itag(self):
+        m_short_buf = self.buf[1:pbb.itag._MIN_LEN]
+        pbb.itag.parser(m_short_buf)
-- 
1.7.10.4


------------------------------------------------------------------------------
October Webinars: Code for Performance
Free Intel webinars can help you accelerate application performance.
Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from 
the latest Intel processors and coprocessors. See abstracts and register >
http://pubads.g.doubleclick.net/gampad/clk?id=60135991&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to