kern/80266: IPX routing doesn't work

Bruce Evans bde at zeta.org.au
Sat Apr 23 07:20:24 PDT 2005


The following reply was made to PR kern/80266; it has been noted by GNATS.

From: Bruce Evans <bde at zeta.org.au>
To: Keith White <Keith.White at site.uottawa.ca>
Cc: FreeBSD-gnats-submit at freebsd.org, bms at freebsd.org,
	rwatson at 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


More information about the freebsd-bugs mailing list