On Fri, 25 Oct 2013 17:59:21 +0900 Yuichi Ito <ito.yuic...@gmail.com> wrote:
> Signed-off-by: Yuichi Ito <ito.yuic...@gmail.com> > --- > ryu/lib/packet/ethernet.py | 1 + > ryu/lib/packet/vlan.py | 49 +++++++++++++++ > ryu/ofproto/ether.py | 3 +- > ryu/tests/unit/packet/test_vlan.py | 118 > ++++++++++++++++++++++++++++++++++++ > 4 files changed, 170 insertions(+), 1 deletion(-) > > diff --git a/ryu/lib/packet/ethernet.py b/ryu/lib/packet/ethernet.py > index 2b8c932..7170fce 100644 > --- a/ryu/lib/packet/ethernet.py > +++ b/ryu/lib/packet/ethernet.py > @@ -76,4 +76,5 @@ class ethernet(packet_base.PacketBase): > # copy vlan _TYPES > ethernet._TYPES = vlan.vlan._TYPES > ethernet.register_packet_type(vlan.vlan, ether.ETH_TYPE_8021Q) > +ethernet.register_packet_type(vlan.svlan, ether.ETH_TYPE_8021AD) > ethernet.register_packet_type(mpls.mpls, ether.ETH_TYPE_MPLS) > diff --git a/ryu/lib/packet/vlan.py b/ryu/lib/packet/vlan.py > index e672272..e1360ee 100644 > --- a/ryu/lib/packet/vlan.py > +++ b/ryu/lib/packet/vlan.py > @@ -76,9 +76,58 @@ class vlan(packet_base.PacketBase): > tci = self.pcp << 13 | self.cfi << 12 | self.vid > return struct.pack(vlan._PACK_STR, tci, self.ethertype) > > + > +class svlan(packet_base.PacketBase): > + """S-VLAN (IEEE 802.1ad) 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 > + cfi Canonical Format Indicator > + vid VLAN Identifier > + ethertype EtherType > + ============== ==================== > + """ > + > + _PACK_STR = "!HH" > + _MIN_LEN = struct.calcsize(_PACK_STR) > + > + def __init__(self, pcp=0, cfi=0, vid=0, ethertype=ether.ETH_TYPE_IP): > + super(svlan, self).__init__() > + self.pcp = pcp > + self.cfi = cfi > + self.vid = vid > + self.ethertype = ethertype > + > + @classmethod > + def get_packet_type(cls, type_): > + return cls._TYPES.get(type_) > + > + @classmethod > + def parser(cls, buf): > + tci, ethertype = struct.unpack_from(cls._PACK_STR, buf) > + pcp = tci >> 13 > + cfi = (tci >> 12) & 1 > + vid = tci & ((1 << 12) - 1) > + return (cls(pcp, cfi, vid, ethertype), > + cls.get_packet_type(ethertype), buf[cls._MIN_LEN:]) > + > + def serialize(self, payload, prev): > + tci = self.pcp << 13 | self.cfi << 12 | self.vid > + return struct.pack(self._PACK_STR, tci, self.ethertype) That code is identical to vlan class? We really need a new class for this protocol? > + > vlan.register_packet_type(arp.arp, ether.ETH_TYPE_ARP) > vlan.register_packet_type(ipv4.ipv4, ether.ETH_TYPE_IP) > vlan.register_packet_type(ipv6.ipv6, ether.ETH_TYPE_IPV6) > vlan.register_packet_type(lldp.lldp, ether.ETH_TYPE_LLDP) > 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) > diff --git a/ryu/ofproto/ether.py b/ryu/ofproto/ether.py > index f4883a3..9e1539c 100644 > --- a/ryu/ofproto/ether.py > +++ b/ryu/ofproto/ether.py > @@ -18,7 +18,8 @@ ETH_TYPE_IP = 0x0800 > ETH_TYPE_ARP = 0x0806 > ETH_TYPE_8021Q = 0x8100 > ETH_TYPE_IPV6 = 0x86dd > -ETH_TYPE_MPLS = 0x8847 > ETH_TYPE_SLOW = 0x8809 > +ETH_TYPE_MPLS = 0x8847 > +ETH_TYPE_8021AD = 0x88a8 > ETH_TYPE_LLDP = 0x88cc > ETH_TYPE_IEEE802_3 = 0x05dc > diff --git a/ryu/tests/unit/packet/test_vlan.py > b/ryu/tests/unit/packet/test_vlan.py > index 6983507..c9aa186 100644 > --- a/ryu/tests/unit/packet/test_vlan.py > +++ b/ryu/tests/unit/packet/test_vlan.py > @@ -26,6 +26,7 @@ from ryu.lib.packet.ethernet import ethernet > from ryu.lib.packet.packet import Packet > from ryu.lib.packet.ipv4 import ipv4 > from ryu.lib.packet.vlan import vlan > +from ryu.lib.packet.vlan import svlan > > > LOG = logging.getLogger('test_vlan') > @@ -136,3 +137,120 @@ class Test_vlan(unittest.TestCase): > def test_malformed_vlan(self): > m_short_buf = self.buf[1:vlan._MIN_LEN] > vlan.parser(m_short_buf) > + > + > +class Test_svlan(unittest.TestCase): > + > + pcp = 0 > + cfi = 0 > + vid = 32 > + tci = pcp << 15 | cfi << 12 | vid > + ethertype = ether.ETH_TYPE_8021Q > + > + buf = pack(svlan._PACK_STR, tci, ethertype) > + > + sv = svlan(pcp, cfi, vid, ethertype) > + > + def setUp(self): > + pass > + > + def tearDown(self): > + pass > + > + def find_protocol(self, pkt, name): > + for p in pkt.protocols: > + if p.protocol_name == name: > + return p > + > + def test_init(self): > + eq_(self.pcp, self.sv.pcp) > + eq_(self.cfi, self.sv.cfi) > + eq_(self.vid, self.sv.vid) > + eq_(self.ethertype, self.sv.ethertype) > + > + def test_parser(self): > + res, ptype, _ = self.sv.parser(self.buf) > + > + eq_(res.pcp, self.pcp) > + eq_(res.cfi, self.cfi) > + eq_(res.vid, self.vid) > + eq_(res.ethertype, self.ethertype) > + eq_(ptype, vlan) > + > + def test_serialize(self): > + data = bytearray() > + prev = None > + buf = self.sv.serialize(data, prev) > + > + fmt = svlan._PACK_STR > + res = struct.unpack(fmt, buf) > + > + eq_(res[0], self.tci) > + eq_(res[1], self.ethertype) > + > + def _build_svlan(self): > + src_mac = '00:07:0d:af:f4:54' > + dst_mac = '00:00:00:00:00:00' > + ethertype = ether.ETH_TYPE_8021AD > + e = ethernet(dst_mac, src_mac, ethertype) > + > + pcp = 0 > + cfi = 0 > + vid = 32 > + tci = pcp << 15 | cfi << 12 | vid > + ethertype = ether.ETH_TYPE_IP > + v = vlan(pcp, cfi, vid, 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(version, header_length, tos, total_length, identification, > + flags, offset, ttl, proto, csum, src, dst, option) > + > + p = Packet() > + > + p.add_protocol(e) > + p.add_protocol(self.sv) > + p.add_protocol(v) > + p.add_protocol(ip) > + p.serialize() > + > + return p > + > + def test_build_svlan(self): > + p = self._build_svlan() > + > + e = self.find_protocol(p, "ethernet") > + ok_(e) > + eq_(e.ethertype, ether.ETH_TYPE_8021AD) > + > + sv = self.find_protocol(p, "svlan") > + ok_(sv) > + eq_(sv.ethertype, ether.ETH_TYPE_8021Q) > + > + v = self.find_protocol(p, "vlan") > + ok_(v) > + eq_(v.ethertype, ether.ETH_TYPE_IP) > + > + ip = self.find_protocol(p, "ipv4") > + ok_(ip) > + > + eq_(sv.pcp, self.pcp) > + eq_(sv.cfi, self.cfi) > + eq_(sv.vid, self.vid) > + eq_(sv.ethertype, self.ethertype) > + > + @raises(Exception) > + def test_malformed_svlan(self): > + m_short_buf = self.buf[1:svlan._MIN_LEN] > + svlan.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 ------------------------------------------------------------------------------ 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