Date: Sat, 23 Apr 2005 14:20:23 GMT From: Bruce Evans <bde@zeta.org.au> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/80266: IPX routing doesn't work Message-ID: <200504231420.j3NEKNTR057443@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/80266; it has been noted by GNATS. From: Bruce Evans <bde@zeta.org.au> To: Keith White <Keith.White@site.uottawa.ca> Cc: FreeBSD-gnats-submit@freebsd.org, bms@freebsd.org, rwatson@freebsd.org Subject: Re: kern/80266: IPX routing doesn't work Date: Sun, 24 Apr 2005 00:17:33 +1000 (EST) On Fri, 22 Apr 2005, Keith White wrote: >> Description: > > IPX routing in 5.4-RC3 doesn't work. > > See also: kern/74105 > > Some more structures need to be declared as "packed" for IPXrouted(8) > and kernel routines that use "struct sockaddr_ipx" so that > routes are created correctly. Fewer structures need to be declared as packed. "packed" is unportable and doesn't even work. > Patches against 5.4-RC3 > > --- usr/src/usr.sbin/IPXrouted/protocol.h Fri Aug 27 21:15:03 1999 > +++ /usr/src/usr.sbin/IPXrouted/protocol.h Fri Apr 22 11:30:40 2005 > @@ -49,12 +49,12 @@ > union ipx_net rip_dst; /* destination net */ The bug is that all (?) ipx structs were naturally packed, but this was broken by adding a "u_int u_net;" to union ipx_net. > ... > --- usr/src/sys/netipx/ipx.h Mon Jan 31 18:26:42 2005 > +++ /usr/src/sys/netipx/ipx.h Fri Apr 22 14:13:51 2005 > @@ -130,7 +130,7 @@ > u_char sipx_family; > struct ipx_addr sipx_addr; > char sipx_zero[2]; > -}; > +} __packed; > #define sipx_port sipx_addr.x_port > #define sipx_network sipx_addr.x_net.u_net > #define sipx_node sipx_addr.x_host.c_host Declaring this struct (struct sockaddr_ipx) as packed turns u_net into complete nonsense and shows why "packed" should never be used. struct sockaddr_ipx begins with 2 u_chars and struct ipx_addr begins with union ipx_net, so if the struct sockaddr_ipx is aligned to a 32-bit or stricter boundary, then if the struct is also packed then u_net is never properly aligned so it never works properly in the only place that it is used (in sipx_network. It works on machines that don't trap for misaligned accesses). Using "packed" causes this problem in general. Accesses to struct members except 8-bit ones tends to break unless "packed" had no effect. ipx.h has always had union ipx_net_u that was apparently intended to either handled alignment stuff or to make struct ipx_net's accessible via an integral type like u_net does: %%% union ipx_net { u_char c_net[4]; u_short s_net[2]; u_int u_net; }; union ipx_net_u { union ipx_net net_e; u_long long_e; }; %%% but neither ipx_net_u nor long_e seems to be actually used, so it is hard to tell whether they would work. They were cloned from similarly unused code in netns. long_e probably needs to be 32-bit (type n_long in netinet) to actually work. Any use would face the same alignment problems as does u_net, but putting the integral type in a separate stuct at least keeps it out of all the structs that use ipx_net and thus prevents alignment poisoning. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200504231420.j3NEKNTR057443>