From: Denis Pynkin <denis.pynkin@collabora.com>
Date: Fri, 21 Jul 2017 19:28:42 +0300
Subject: [PATCH] net: Use packed structures for networking

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>
Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
[backported from u-boot main]
---

--- a/include/net.h
+++ b/include/net.h
@@ -182,7 +182,7 @@ struct ethernet_hdr {
 	uchar		et_dest[6];	/* Destination node		*/
 	uchar		et_src[6];	/* Source node			*/
 	ushort		et_protlen;	/* Protocol or length		*/
-};
+} __attribute__((packed));
 
 /* Ethernet header size */
 #define ETHER_HDR_SIZE	(sizeof(struct ethernet_hdr))
@@ -198,7 +198,7 @@ struct e802_hdr {
 	uchar		et_snap2;
 	uchar		et_snap3;
 	ushort		et_prot;	/* 802 protocol			*/
-};
+} __attribute__((packed));
 
 /* 802 + SNAP + ethernet header size */
 #define E802_HDR_SIZE	(sizeof(struct e802_hdr))
@@ -212,7 +212,7 @@ struct vlan_ethernet_hdr {
 	ushort		vet_vlan_type;	/* PROT_VLAN			*/
 	ushort		vet_tag;	/* TAG of VLAN			*/
 	ushort		vet_type;	/* protocol type		*/
-};
+} __attribute__((packed));
 
 /* VLAN Ethernet header size */
 #define VLAN_ETHER_HDR_SIZE	(sizeof(struct vlan_ethernet_hdr))
@@ -239,7 +239,7 @@ struct ip_hdr {
 	ushort		ip_sum;		/* checksum			*/
 	IPaddr_t	ip_src;		/* Source IP address		*/
 	IPaddr_t	ip_dst;		/* Destination IP address	*/
-};
+} __attribute__((packed));
 
 #define IP_OFFS		0x1fff /* ip offset *= 8 */
 #define IP_FLAGS	0xe000 /* first 3 bits */
@@ -267,7 +267,7 @@ struct ip_udp_hdr {
 	ushort		udp_dst;	/* UDP destination port		*/
 	ushort		udp_len;	/* Length of UDP packet		*/
 	ushort		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)
@@ -306,7 +306,7 @@ struct arp_hdr {
 	uchar		ar_tha[];	/* Target hardware address	*/
 	uchar		ar_tpa[];	/* Target protocol address	*/
 #endif /* 0 */
-};
+} __attribute__((packed));
 
 #define ARP_HDR_SIZE	(8+20)		/* Size assuming ethernet	*/
 
@@ -341,7 +341,7 @@ struct icmp_hdr {
 		} frag;
 		uchar data[0];
 	} un;
-};
+} __attribute__((packed));
 
 #define ICMP_HDR_SIZE		(sizeof(struct icmp_hdr))
 #define IP_ICMP_HDR_SIZE	(IP_HDR_SIZE + ICMP_HDR_SIZE)
--- a/net/bootp.h
+++ b/net/bootp.h
@@ -49,7 +49,7 @@ struct Bootp_t {
 	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_t)
 
--- a/net/dns.h
+++ b/net/dns.h
@@ -32,7 +32,7 @@ struct header {
 	uint16_t	nauth;		/* Authority PRs */
 	uint16_t	nother;		/* Other PRs */
 	unsigned char	data[1];	/* Data, variable length */
-};
+} __attribute__((packed));
 
 extern void DnsStart(void);		/* Begin DNS */
 
--- a/net/nfs.h
+++ b/net/nfs.h
@@ -71,7 +71,7 @@ struct rpc_t {
 			uint32_t data[19];
 		} reply;
 	} u;
-};
+} __attribute__((packed));
 extern void NfsStart(void);	/* Begin NFS */
 
 
--- a/net/sntp.h
+++ b/net/sntp.h
@@ -54,7 +54,7 @@ struct sntp_pkt_t {
 	unsigned long long originate_timestamp;
 	unsigned long long receive_timestamp;
 	unsigned long long transmit_timestamp;
-};
+} __attribute__((packed));
 
 extern void SntpStart(void);	/* Begin SNTP */
 
