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) + + 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