From: Shaun Crampton <[email protected]>

Add support for ethernet padding.

* Add padding when serializing small packets.
* Modify packet.py to support adding a footer as well as header
  in back-compatible way.  If only header is returned, packet
  behaves as before.
* When packets supply a total_length field, truncate the packet
  to that length in order to remove any additional padding.
  When no total_length is specified, act as before.

Signed-off-by: Shaun Crampton <[email protected]>

---
Our use case was to interoperate with a switch that included the ethernet
padding when forwarding a packet to the controller.  We needed to remove
the padding before forwarding to our control plane software.

 ryu/lib/packet/ethernet.py |    9 +++++++--
 ryu/lib/packet/icmp.py     |    1 -
 ryu/lib/packet/packet.py   |   20 +++++++++++++++++++-
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/ryu/lib/packet/ethernet.py b/ryu/lib/packet/ethernet.py
index 7bc18ef..0d9c2a9 100644
--- a/ryu/lib/packet/ethernet.py
+++ b/ryu/lib/packet/ethernet.py
@@ -51,8 +51,13 @@ class ethernet(packet_base.PacketBase):
         return cls(dst, src, ethertype),
ethernet.get_packet_type(ethertype)
 
     def serialize(self, payload, prev):
-        return struct.pack(ethernet._PACK_STR, self.dst, self.src,
-                           self.ethertype)
+        header = struct.pack(ethernet._PACK_STR, self.dst, self.src,
+                             self.ethertype)
+        total_len = len(header) + len(payload)
+        # The minimum size of an ethernet frame is 64 bytes, including the
+        # 4-byte CRC, which is added by the hardware.  Pad the packet.
+        pad_len = max(60 - total_len, 0)
+        return header, "\0" * pad_len
 
 
 # copy vlan _TYPES
diff --git a/ryu/lib/packet/icmp.py b/ryu/lib/packet/icmp.py
index e42fa40..819e9ab 100644
--- a/ryu/lib/packet/icmp.py
+++ b/ryu/lib/packet/icmp.py
@@ -79,7 +79,6 @@ class icmp(packet_base.PacketBase):
                 msg.data = cls_.parser(buf, offset)
             else:
                 msg.data = buf[offset:]
-
         return msg, None
 
     def serialize(self, payload, prev):
diff --git a/ryu/lib/packet/packet.py b/ryu/lib/packet/packet.py
index f5fd82d..5602be2 100644
--- a/ryu/lib/packet/packet.py
+++ b/ryu/lib/packet/packet.py
@@ -44,6 +44,17 @@ class Packet(object):
         while cls:
             proto, cls = cls.parser(self.data[self.parsed_bytes:])
             if proto:
+                try:
+                    total_length = proto.total_length
+                except Exception:
+                    pass
+                else:
+                    if total_length + self.parsed_bytes < len(self.data):
+                        # The data remaining is longer that the header of
the
+                        # packet says it should be.  We likely have some
+                        # ethernet padding added.  Truncate it.
+                        truncation_length = total_length +
self.parsed_bytes
+                        self.data = self.data[:truncation_length]
                 self.parsed_bytes += proto.length
                 self.protocols.append(proto)
 
@@ -67,7 +78,14 @@ class Packet(object):
                 data = p.serialize(self.data, prev)
             else:
                 data = str(p)
-            self.data = data + self.data
+            try:
+                # Special-case: some protocols add a footer as well as a
+                # header.
+                prefix, suffix = data
+            except Exception:
+                prefix = data
+                suffix = ""
+            self.data = prefix + self.data + suffix
 
     def add_protocol(self, proto):
         """Register a protocol *proto* for this packet.
-- 
1.7.9.5


------------------------------------------------------------------------------
Try New Relic Now & We'll Send You this Cool Shirt
New Relic is the only SaaS-based application performance monitoring service 
that delivers powerful full stack analytics. Optimize and monitor your
browser, app, & servers with just a few lines of code. Try New Relic
and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_may
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to