net: Use packed structures for networking
authorDenis Pynkin <denis.pynkin@collabora.com>
Fri, 21 Jul 2017 16:28:42 +0000 (19:28 +0300)
committerLothar Waßmann <LW@KARO-electronics.de>
Tue, 16 Jun 2020 08:17:50 +0000 (10:17 +0200)
PXE boot is broken with GCC 7.1 due option '-fstore-merging' enabled
by default for '-O2':

BOOTP broadcast 1
data abort
pc : [<8ff8bb30>]          lr : [<00004f1f>]
reloc pc : [<17832b30>]    lr : [<878abf1f>]
sp : 8f558bc0  ip : 00000000     fp : 8ffef5a4
r10: 8ffed248  r9 : 8f558ee0     r8 : 8ffef594
r7 : 0000000e  r6 : 8ffed700     r5 : 00000000  r4 : 8ffed74e
r3 : 00060101  r2 : 8ffed230     r1 : 8ffed706  r0 : 00000ddd
Flags: nzcv  IRQs off  FIQs off  Mode SVC_32
Resetting CPU ...

Core reason is usage of structures for network headers without packed
attribute.

Reviewed-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
Signed-off-by: Denis Pynkin <denis.pynkin@collabora.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
include/net.h
net/bootp.h
net/dns.h
net/nfs.h
net/sntp.h

index af8617b..9a34360 100644 (file)
@@ -271,10 +271,10 @@ u32 ether_crc(size_t len, unsigned char const *p);
  */
 
 struct ethernet_hdr {
-       u8              et_dest[6];     /* Destination node             */
-       u8              et_src[6];      /* Source node                  */
-       u16             et_protlen;     /* Protocol or length           */
-};
+       u8              et_dest[6];     /* Destination node     */
+       u8              et_src[6];      /* Source node          */
+       u16             et_protlen;             /* Protocol or length   */
+} __attribute__((packed));
 
 /* Ethernet header size */
 #define ETHER_HDR_SIZE (sizeof(struct ethernet_hdr))
@@ -291,8 +291,8 @@ struct e802_hdr {
        u8              et_snap1;       /* SNAP                         */
        u8              et_snap2;
        u8              et_snap3;
-       u16             et_prot;        /* 802 protocol                 */
-};
+       u16             et_prot;                /* 802 protocol         */
+} __attribute__((packed));
 
 /* 802 + SNAP + ethernet header size */
 #define E802_HDR_SIZE  (sizeof(struct e802_hdr))
@@ -301,12 +301,12 @@ struct e802_hdr {
  *     Virtual LAN Ethernet header
  */
 struct vlan_ethernet_hdr {
-       u8              vet_dest[6];    /* Destination node             */
-       u8              vet_src[6];     /* Source node                  */
-       u16             vet_vlan_type;  /* PROT_VLAN                    */
-       u16             vet_tag;        /* TAG of VLAN                  */
-       u16             vet_type;       /* protocol type                */
-};
+       u8              vet_dest[6];    /* Destination node     */
+       u8              vet_src[6];     /* Source node          */
+       u16             vet_vlan_type;          /* PROT_VLAN            */
+       u16             vet_tag;                /* TAG of VLAN          */
+       u16             vet_type;               /* protocol type        */
+} __attribute__((packed));
 
 /* VLAN Ethernet header size */
 #define VLAN_ETHER_HDR_SIZE    (sizeof(struct vlan_ethernet_hdr))
@@ -333,7 +333,7 @@ struct ip_hdr {
        u16             ip_sum;         /* checksum                     */
        struct in_addr  ip_src;         /* Source IP address            */
        struct in_addr  ip_dst;         /* Destination IP address       */
-};
+} __attribute__((packed));
 
 #define IP_OFFS                0x1fff /* ip offset *= 8 */
 #define IP_FLAGS       0xe000 /* first 3 bits */
@@ -361,7 +361,7 @@ struct ip_udp_hdr {
        u16             udp_dst;        /* UDP destination port         */
        u16             udp_len;        /* Length of UDP packet         */
        u16             udp_xsum;       /* Checksum                     */
-};
+} __attribute__((packed));
 
 #define IP_UDP_HDR_SIZE                (sizeof(struct ip_udp_hdr))
 #define UDP_HDR_SIZE           (IP_UDP_HDR_SIZE - IP_HDR_SIZE)
@@ -400,7 +400,7 @@ struct arp_hdr {
        u8              ar_tha[];       /* Target hardware address      */
        u8              ar_tpa[];       /* Target protocol address      */
 #endif /* 0 */
-};
+} __attribute__((packed));
 
 #define ARP_HDR_SIZE   (8+20)          /* Size assuming ethernet       */
 
@@ -435,7 +435,7 @@ struct icmp_hdr {
                } frag;
                u8 data[0];
        } un;
-};
+} __attribute__((packed));
 
 #define ICMP_HDR_SIZE          (sizeof(struct icmp_hdr))
 #define IP_ICMP_HDR_SIZE       (IP_HDR_SIZE + ICMP_HDR_SIZE)
index fcb0a64..567340e 100644 (file)
@@ -49,7 +49,7 @@ struct bootp_hdr {
        char            bp_sname[64];   /* Server host name             */
        char            bp_file[128];   /* Boot file name               */
        char            bp_vend[OPT_FIELD_SIZE]; /* Vendor information  */
-};
+} __attribute__((packed));
 
 #define BOOTP_HDR_SIZE sizeof(struct bootp_hdr)
 
index c4e96af..c55a5c1 100644 (file)
--- a/net/dns.h
+++ b/net/dns.h
@@ -29,7 +29,7 @@ struct header {
        uint16_t        nauth;          /* Authority PRs */
        uint16_t        nother;         /* Other PRs */
        unsigned char   data[1];        /* Data, variable length */
-};
+} __attribute__((packed));
 
 void dns_start(void);          /* Begin DNS */
 
index d69b422..09b387e 100644 (file)
--- a/net/nfs.h
+++ b/net/nfs.h
@@ -68,7 +68,7 @@ struct rpc_t {
                        uint32_t data[19];
                } reply;
        } u;
-};
+} __attribute__((packed));
 void nfs_start(void);  /* Begin NFS */
 
 
index 6a9c6bb..c38bcee 100644 (file)
@@ -51,7 +51,7 @@ struct sntp_pkt_t {
        unsigned long long originate_timestamp;
        unsigned long long receive_timestamp;
        unsigned long long transmit_timestamp;
-};
+} __attribute__((packed));
 
 void sntp_start(void); /* Begin SNTP */