From Keith.White@site.uottawa.ca  Fri Apr 22 21:54:58 2005
Return-Path: <Keith.White@site.uottawa.ca>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 6136916A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 22 Apr 2005 21:54:58 +0000 (GMT)
Received: from mail.site.uottawa.ca (mailn.site.uottawa.ca [137.122.89.142])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 49CF843D1D
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 22 Apr 2005 21:54:57 +0000 (GMT)
	(envelope-from Keith.White@site.uottawa.ca)
Received: from admin16.site.uottawa.ca (admin16.site.uottawa.ca [137.122.90.250])
	by mail.site.uottawa.ca (8.9.3/8.9.3) with ESMTP id RAA01546
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 22 Apr 2005 17:54:55 -0400 (EDT)
Received: from admin16.site.uottawa.ca (localhost [127.0.0.1])
	by admin16.site.uottawa.ca (8.12.11/8.13.1) with ESMTP id j3MLoBcC066754
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 22 Apr 2005 17:50:11 -0400 (EDT)
	(envelope-from kwhite@admin16.site.uottawa.ca)
Received: (from kwhite@localhost)
	by admin16.site.uottawa.ca (8.12.11/8.13.1/Submit) id j3MLoBs3066753;
	Fri, 22 Apr 2005 17:50:11 -0400 (EDT)
	(envelope-from kwhite)
Message-Id: <200504222150.j3MLoBs3066753@admin16.site.uottawa.ca>
Date: Fri, 22 Apr 2005 17:50:11 -0400 (EDT)
From: Keith White <Keith.White@site.uottawa.ca>
Reply-To: Keith White <Keith.White@site.uottawa.ca>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: IPX routing doesn't work
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         80266
>Category:       kern
>Synopsis:       [ipx] [patch] IPX routing doesn't work
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    rwatson
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 22 22:00:43 GMT 2005
>Closed-Date:    Mon Aug 04 11:18:22 UTC 2008
>Last-Modified:  Mon Aug 04 11:18:22 UTC 2008
>Originator:     Keith White
>Release:        FreeBSD 5.4-RC3 i386
>Organization:
SITE, University of Ottawa
>Environment:
System: FreeBSD  5.4-RC3 FreeBSD 5.4-RC3 #3: Fri Apr 22 14:18:59 EDT 2005     root@:/usr/obj/usr/src/sys/NOSMPPAE  i386

>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.

>How-To-Repeat:

Find a busy IPX network.  Run "IPXrouted -q -t".  Notice misaligned
hostnames, invalid IPX network addresses, negative ticks and extreme
metric.

Run "netstat -rnf ipx".  Notice how all "Destinations" are "default"
rather than "network.*"

Run "ncplist s".  Wait for output (it'll likely timeout).

>Fix:

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 */
 	u_short		rip_metric;		/* cost of route */
 	u_short		rip_ticks;		/* cost of route */
-};
+} __packed;
 
 struct rip {
 	u_short	rip_cmd;		/* request/response */
 	struct netinfo rip_nets[1];	/* variable length */
-};
+} __packed;
  
 /*
  * Packet types.
--- usr/src/usr.sbin/IPXrouted/sap.h	Fri Aug 27 21:15:03 1999
+++ /usr/src/usr.sbin/IPXrouted/sap.h	Thu Apr 21 10:57:10 2005
@@ -47,19 +47,19 @@
 #define MAXSAPENTRIES		7
 #define SAP_WILDCARD		0xFFFF
 #define SERVNAMELEN		48
-typedef struct sap_info {
+typedef struct __attribute__ ((packed)) sap_info {
 	u_short ServType;
 	char    ServName[SERVNAMELEN];
 	struct ipx_addr ipx;
 	u_short hops;
-	}sap_info;  
+	}sap_info;
 
-typedef struct sap_packet {
+typedef struct __attribute__ ((packed)) sap_packet {
 	u_short sap_cmd;
 	sap_info sap[0]; /* Variable length. */
 	}sap_packet;
 
-typedef struct sap_entry {
+typedef struct __attribute__ ((packed)) sap_entry {
 	struct sap_entry *forw;
 	struct sap_entry *back;
 	struct sap_entry *clone;
@@ -73,7 +73,7 @@
 
 #define SAPHASHSIZ		256		/* Should be a power of 2 */
 #define SAPHASHMASK		(SAPHASHSIZ-1)
-typedef struct sap_hash {
+typedef struct __attribute__ ((packed)) sap_hash {
 	struct sap_entry *forw;
 	struct sap_entry *back;
 	}sap_hash;
--- usr/src/usr.sbin/IPXrouted/trace.c	Sat Nov 15 12:10:56 2003
+++ /usr/src/usr.sbin/IPXrouted/trace.c	Thu Apr 21 12:45:04 2005
@@ -500,7 +500,7 @@
 {
 	static char buf[100];
 	net.net_e = val;
-	(void)sprintf(buf, "%u", ntohl(net.long_e));
+	(void)sprintf(buf, "%x", ntohl(net.long_e));
 	return (buf);
 }
 
--- usr/src/usr.sbin/IPXrouted/main.c	Sat Nov 15 12:10:56 2003
+++ /usr/src/usr.sbin/IPXrouted/main.c	Thu Apr 21 15:09:52 2005
@@ -77,7 +77,7 @@
 int	timeval;		/* local idea of time */
 int	noteremoterequests;	/* squawk on requests from non-local nets */
 int	r;			/* Routing socket to install updates with */
-struct	sockaddr_ipx ipx_netmask;	/* Used in installing routes */
+struct	__attribute__ ((packed)) sockaddr_ipx ipx_netmask;	/* Used in installing routes */
 
 char	packet[MAXRXPACKETSIZE+1];
 
--- usr/src/lib/libncp/ipxsap.h	Tue Oct 12 07:56:37 1999
+++ /usr/src/lib/libncp/ipxsap.h	Fri Apr 22 10:23:45 2005
@@ -58,7 +58,7 @@
 	u_char		server_name[IPX_SAP_SERVER_NAME_LEN];
 	struct ipx_addr	ipx;
 	u_short		hops;
-};
+} __packed;
 
 struct sap_packet {
 	u_short		operation;
--- 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


>Release-Note:
>Audit-Trail:

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

From: Keith White <Keith.White@site.uottawa.ca>
To: Bruce Evans <bde@zeta.org.au>
Cc: FreeBSD-gnats-submit@freebsd.org, bms@freebsd.org,
	rwatson@freebsd.org
Subject: Re: kern/80266: IPX routing doesn't work
Date: Sat, 23 Apr 2005 13:19:03 -0400 (EDT)

 On Sun, 24 Apr 2005, Bruce Evans wrote:
 
 >
 > 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.
 > ...
 
 Indeed.  If I try a fresh build of 5.4-RC3 with "union ipx_net"
 defined without "u_int u_net", both "IPXrouted" and
 "netstat -rnf ipx" work as expected.  No additional "packed"
 attributes are required.  Does the change to "src/sys/netipx/ipx.h"
 need to be reverted (again)?  I don't use the mars_nwe port so don't
 know the ramifications there.
 
 Thanks for the hint!
 
 ...keith
 
 The following patch against 5.4-RC3 "works for me":
 
 
 --- usr/src/sys/netipx/ipx.h	Mon Jan 31 18:26:42 2005
 +++ /usr/src/sys/netipx/ipx.h	Sat Apr 23 11:38:37 2005
 @@ -108,7 +108,7 @@
  union ipx_net {
  	u_char	c_net[4];
  	u_short	s_net[2];
 -	u_int	u_net;
 +/*	u_int	u_net; */
  };
 
  union ipx_net_u {
 
Responsible-Changed-From-To: freebsd-bugs->rwatson 
Responsible-Changed-By: kris 
Responsible-Changed-When: Sat Apr 23 20:14:13 GMT 2005 
Responsible-Changed-Why:  
rwatson worked on this code 

http://www.freebsd.org/cgi/query-pr.cgi?pr=80266 

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 10:41:44 +1000 (EST)

 On Sat, 23 Apr 2005, Keith White wrote:
 
 > On Sun, 24 Apr 2005, Bruce Evans wrote:
 >>
 >> 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.
 >> ...
 >
 > Indeed.  If I try a fresh build of 5.4-RC3 with "union ipx_net"
 > defined without "u_int u_net", both "IPXrouted" and
 > "netstat -rnf ipx" work as expected.  No additional "packed"
 > attributes are required.  Does the change to "src/sys/netipx/ipx.h"
 > need to be reverted (again)?  I don't use the mars_nwe port so don't
 > know the ramifications there.
 
 I think it is a very wrong way to go, so it should be reverted.  I
 think declaring only u_net as __packed would work.
 
 I said that the new u_net field becomes more bogus if all the structs
 containing it are packed because it becomes misaligned.  That is incorrect
 what actually happens (appart from the code being source-code uncompilable
 and binary-incompatible with compilers that don't support "packed") is that
 the compiler has to assume that everything is misaligned so it has to load
 access everything a byte at a time on machines that need strict alignment.
 So "packed" mainly gives large and slow code.
 
 An example of this affecting core code is "struct ip" in netinet.  This
 struct is naturally packed to give good alignment, so declaring it as
 "packed" seems to do nothing more than give large and slow code.  I
 checked that it gives large and slow code on ia64's:
 "struct in_addr ip_src" at the end of struct ip is naturally aligned
 (the struct size is 20, and ip_src is in 4 bytes at the end, and
 everything has good alignment provided the beginning of the struct
 does).  With the packed attribute, gcc has to access even this naturally
 aligned struct 1 byte at a type.  I checked that it does this for loads.
 It uses 4 1-byte loads, and some ORs and presumably some shifts to
 reassemble the 4 bytes.
 
 Bruce
State-Changed-From-To: open->feedback 
State-Changed-By: rwatson 
State-Changed-When: Thu Mar 6 09:25:50 UTC 2008 
State-Changed-Why:  
This is believed to have been fixed by this commit: 

revision 1.21 
date: 2005/05/27 12:25:42;  author: rwatson;  state: Exp;  lines: +0 -3 
Back out ipx.h:1.18, which introduced a Linux API compatibility field in 
the ipx_net data structure.  Doing so introduced a stronger alignment 
requirement for the address structure, which in turn propagated into 
other dependent data structures, which turns out not to be suported by 
the available IPX source code.  As a result, a number of user space 
applications, such as IPX routing components, failed to operate 
correctly. 

RELENG_5_3 candidate? 

PRs:            74059, 80266 
Pointy hat to:  bms 
Fix by:         bde 
Tested by:      Keith White <Keith dot White at site dot uottawa dot ca> 
MFC after:      1 week 
Suffering:      great 

Could you confirm that (i.e., that this is corrected in 5.4 and later?). 

Thanks, 


http://www.freebsd.org/cgi/query-pr.cgi?pr=80266 
State-Changed-From-To: feedback->closed 
State-Changed-By: rwatson 
State-Changed-When: Mon Aug 4 11:17:28 UTC 2008 
State-Changed-Why:  
Transition to closed as this problem is believed fixed in more recent 
FreeBSD versions.  If you are able to reproduce this problem still, 
please let me know and I can reopen the PR.  Thanks for the report! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=80266 
>Unformatted:
