Subject: net/if.c fix for netatalk
To: None <tech-net@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-net
Date: 06/30/1999 18:39:47
--sdtB3X0nJg68CQEu
Content-Type: text/plain; charset=us-ascii

Hi,
some time ago I pointed out that our kernel does the wrong thing with
netatalk routes, refusing to add route through a gateway when the gateway
is not on the same net a the host, although it's on the local net block.
It turns out that if.c:ifa_ifwithnet() (returns the ifaddr of the interface
on the same net as the address passed in argument) only works for
networks where addr/netmask makes sense (as it uses
ifa->ifa_addr/ifa->ifa_netmask to find the rigth ifa).
Netatalk uses net ranges instead, where a physical network is designed by
a pair of low net/higth net (this is also why netatalk may use several
routing table entries for a physical link, to convert this low net/higth net
into a successtion of addr/netmask).

My first idea to fix this was to use the routing table instead of
ifa_ifwithnet() to check if a gateway is reachable when adding a route. But
this doesn't fix ifa_ifwithnet(), which is brocken for netatalk anyway.

So I fixed ifa_ifwithnet(), and for that I needed to add netatalk-specific
code (In fact if we are looking for a netatalk interface just use
at_ifawithnet() which does the rigth thing).

Diffs are attached. Does anyone object to this change ?
The only problem I can see is that if.c has now protocol-dependant sections,
but I don't see how to fix it better.

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
--

--sdtB3X0nJg68CQEu
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="atalk.diff"

Index: if.c
===================================================================
RCS file: /cvsroot/syssrc/sys/net/if.c,v
retrieving revision 1.48
diff -u -r1.48 if.c
--- if.c	1998/12/10 15:10:48	1.48
+++ if.c	1999/06/30 16:29:55
@@ -38,6 +38,7 @@
 #include "opt_compat_linux.h"
 #include "opt_compat_svr4.h"
 #include "opt_compat_43.h"
+#include "opt_atalk.h"
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -53,6 +54,10 @@
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/radix.h>
+#ifdef NETATALK
+#include <netatalk/at_extern.h>
+#include <netatalk/at.h>
+#endif
 
 int	ifqmaxlen = IFQ_MAXLEN;
 void	if_slowtimo __P((void *arg));
@@ -204,6 +209,17 @@
 	    if (sdl->sdl_index && sdl->sdl_index <= if_index)
 		return (ifnet_addrs[sdl->sdl_index - 1]);
 	}
+#ifdef NETATALK
+	if (af == AF_APPLETALK) {
+		for (ifp = ifnet.tqh_first; ifp != 0;
+		    ifp = ifp->if_list.tqe_next) {
+			ifa = at_ifawithnet((struct sockaddr_at *)addr, ifp);
+			if (ifa)
+				return ifa;
+		}
+		return NULL;
+	}
+#endif
 	for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next)
 		for (ifa = ifp->if_addrlist.tqh_first; ifa != 0; ifa = ifa->ifa_list.tqe_next) {
 			register char *cp, *cp2, *cp3;

--sdtB3X0nJg68CQEu--