packet: Match userspace and kernel definition of ICMP header.
authorJesse Gross <jesse@nicira.com>
Tue, 27 Dec 2011 01:33:03 +0000 (17:33 -0800)
committerJesse Gross <jesse@nicira.com>
Tue, 27 Dec 2011 18:42:30 +0000 (10:42 -0800)
Current userspace considers an ICMP header to be 4 bytes consisting
of the type, code, and checksum.  The kernel considers it to be 8
bytes because it also counts the two data fields that contain
type-specific information (and are always present).  Since flow
extract will zero out headers that are not completely present this
means that an ICMP packet that has a header of 5-7 bytes will be
interpreted differently by userspace and kernel.  This fixes the
problem by adopting the kernel's version of the ICMP header in
userspace.

Signed-off-by: Jesse Gross <jesse@nicira.com>
lib/packets.h

index 19b7346baa9f10d47005f4e94b3a86f1499d3ac7..16834a8b72b28a6711d8245852bd95aa6f7ae368 100644 (file)
@@ -333,11 +333,23 @@ struct ip_header {
 };
 BUILD_ASSERT_DECL(IP_HEADER_LEN == sizeof(struct ip_header));
 
-#define ICMP_HEADER_LEN 4
+#define ICMP_HEADER_LEN 8
 struct icmp_header {
     uint8_t icmp_type;
     uint8_t icmp_code;
     ovs_be16 icmp_csum;
+    union {
+        struct {
+            ovs_be16 id;
+            ovs_be16 seq;
+        } echo;
+        struct {
+            ovs_be16 empty;
+            ovs_be16 mtu;
+        } frag;
+        ovs_be32 gateway;
+    } icmp_fields;
+    uint8_t icmp_data[0];
 };
 BUILD_ASSERT_DECL(ICMP_HEADER_LEN == sizeof(struct icmp_header));