[U-Boot] [PATCH 1/1] net: avoid address-of-packed-member error

Simon Goldschmidt simon.k.r.goldschmidt at gmail.com
Mon Nov 4 20:28:51 UTC 2019


Am 04.11.2019 um 20:34 schrieb Heinrich Schuchardt:
> struct ip_udp_hdr is naturally packed. There is no point in adding a
> __packed attribute. With the attribute the network stack does not compile
> using GCC 9.2.1:

Is this commit message correct? In lwIP, we *do* need to pack all these 
network header structs as they can come in unaligned. Especially the IP 
header is normally 16-bit aligned if the incoming Ethernet frame is 
32-bit aligned (which is a must for many DMA engines).

This is also the reason why the below code works, I guess: it is rarely 
totally unaligned, but nearly always at least 16-bit aligned, so 
dereferencing the checksum pointer as aligned u16 just works.

Nevertheless, the code is formally wrong and your patch is correct. I 
just don't like the commit message saying 'packed' is not required.

> 
> net/net.c: In function ‘net_process_received_packet’:
> net/net.c:1288:23: error: taking address of packed member of ‘struct
> ip_udp_hdr’ may result in an unaligned pointer value
> [-Werror=address-of-packed-member]
>   1288 |    sumptr = (ushort *)&(ip->udp_src);
>        |                       ^~~~~~~~~~~~~~
> 
> Unfortunately there was a bug in GCC 7.1 which required __packed here.
> So let's avoid the error by using a uchar pointer instead of an u16
> pointer.
> 
> Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> ---
>   net/net.c | 10 ++++------
>   1 file changed, 4 insertions(+), 6 deletions(-)
> 
> diff --git a/net/net.c b/net/net.c
> index ded86e7456..e6f6d2cb45 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -1274,7 +1274,7 @@ void net_process_received_packet(uchar *in_packet, int len)
>   #ifdef CONFIG_UDP_CHECKSUM
>   		if (ip->udp_xsum != 0) {
>   			ulong   xsum;
> -			ushort *sumptr;
> +			uchar *sumptr;
>   			ushort  sumlen;
> 
>   			xsum  = ip->ip_p;
> @@ -1285,13 +1285,11 @@ void net_process_received_packet(uchar *in_packet, int len)
>   			xsum += (ntohl(ip->ip_dst.s_addr) >>  0) & 0x0000ffff;
> 
>   			sumlen = ntohs(ip->udp_len);
> -			sumptr = (ushort *)&(ip->udp_src);
> +			sumptr = (uchar *)&ip->udp_src;
> 
>   			while (sumlen > 1) {
> -				ushort sumdata;
> -
> -				sumdata = *sumptr++;
> -				xsum += ntohs(sumdata);
> +				xsum += (sumptr[0] << 8) + sumptr[1];

Do we need a comment here stating why we have an open-coded copy of 
ntohs? That could keep us from getting this bug back in the future...

Regards,
Simon

> +				sumptr += 2;
>   				sumlen -= 2;
>   			}
>   			if (sumlen > 0) {
> --
> 2.24.0.rc1
> 
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
> 



More information about the U-Boot mailing list