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