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