net: Use packed structures for networking
authorDenis Pynkin <denis.pynkin@collabora.com>
Fri, 21 Jul 2017 16:28:42 +0000 (19:28 +0300)
committerJoe Hershberger <joe.hershberger@ni.com>
Mon, 7 Aug 2017 20:18:31 +0000 (15:18 -0500)
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 2eaa88224c9050755330e67a57ae7b541cfaa3fa..e1269486ad9cf11562c5aa432a33527f894ce325 100644 (file)
@@ -308,7 +308,7 @@ struct ethernet_hdr {
        u8              et_dest[ARP_HLEN];      /* Destination node     */
        u8              et_src[ARP_HLEN];       /* Source node          */
        u16             et_protlen;             /* Protocol or length   */
-};
+} __attribute__((packed));
 
 /* Ethernet header size */
 #define ETHER_HDR_SIZE (sizeof(struct ethernet_hdr))
@@ -326,7 +326,7 @@ struct e802_hdr {
        u8              et_snap2;
        u8              et_snap3;
        u16             et_prot;                /* 802 protocol         */
-};
+} __attribute__((packed));
 
 /* 802 + SNAP + ethernet header size */
 #define E802_HDR_SIZE  (sizeof(struct e802_hdr))
@@ -340,7 +340,7 @@ struct vlan_ethernet_hdr {
        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))
@@ -369,7 +369,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 */
@@ -397,7 +397,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)
@@ -435,7 +435,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       */
 
@@ -470,7 +470,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 fcb0a64e6143c550e101e0fd7597a56804e1ef32..567340ec5d4a250498c7c8bdf30675552ab5b831 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 c4e96afa0621d783482f8f04865d6f576d5460bf..c55a5c1b04660ab4bf49a73d26a71f1005f2e2b3 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 45da246aa1e1bfa6ad8d7b267ab0a41fde8e231d..70a1a6d554be81390ac330a473c33be88baa32f0 100644 (file)
--- a/net/nfs.h
+++ b/net/nfs.h
@@ -79,7 +79,7 @@ struct rpc_t {
                        uint32_t data[NFS_READ_SIZE];
                } reply;
        } u;
-};
+} __attribute__((packed));
 void nfs_start(void);  /* Begin NFS */
 
 
index 6a9c6bb82fb9bbfe2235a232b29569ce2b85c113..c38bceed3f6a2044a91b970ada43eb2ef95d5889 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 */