On Wed, Nov 17, 2004 at 07:50:32PM +0300, Vladimir Grebenschikov wrote: > В чт, 11/11/2004 в 21:24 +0100, Max Laier пишет: > > All, > > > > I know I have sent this a couple of times before, but never got anywhere. > > This > > time I am set to commit! > > > > The attached patch (http://people.freebsd.org/~mlaier/in.c.patch) derived > > from > > WIDE via OpenBSD in.c, rev 1.21 improves the handling of automatic prefix > > routes. > > > > Right now you can't have two legs into the same network. If you want to, > > you > > must give on of the interfaces a host address only (netmask /32). This way > > it > > is not possible to hand over the route if one of the interfaces is > > "removed" (however this is done in the special case). > > > > The patch allows to add more than on IPv4 address with the same prefix. In > > the > > case that there is a route already, we leave it alone and add the new > > address > > without the IFA_ROUTE flag. When we remove an address later on, that has a > > route associated, we try to find an alternative address to use for the > > route > > and hand it over. > > > > This is required for CARP, but should be helpful for other situations as > > well. > > > > Any objections? > > This change actually broke one simple thing: > > # ifconfig lo0 alias 10.0.16.111/32 > # ping 10.0.16.111 > PING 10.0.16.111 (10.0.16.111): 56 data bytes > ping: sendto: No route to host > ^C > # > > You should (anyway should) add routing of interface address itself to > loop-back interface, like it usually done in all other cases. > > Please fix. > This bug was borrowed from OpenBSD (they still have it). The problem is that in "struct in_ifaddr", initially
ia_ifa.ifa_addr points to ia_addr - and - ia_ifa.ifa_dstaddr points to ia_dstaddr and the IFF_LOOPBACK code in in_ifinit() just resets the ia_ifa.ifa_dstaddr pointer to point to ia_ifa.ifa_addr. But new in_addprefix() code ignores this fact, and just uses INET fields directly, i.e., ia_dstaddr (which happens to be 0.0.0.0). Then all the havoc happens (it matches another interface address (ia_addr=127.0.0.1, ia_dstaddr=0) and refuses to install a host route. The fix is a one line change, and as I later found out, it also corresponds to NetBSD revision 1.83: http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/netinet/in.c.diff?r1=1.82&r2=1.83&cvsroot=netbsd %%% Index: in.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/in.c,v retrieving revision 1.78 diff -u -p -r1.78 in.c --- in.c 12 Nov 2004 20:53:51 -0000 1.78 +++ in.c 17 Nov 2004 21:42:44 -0000 @@ -759,7 +759,7 @@ in_ifinit(ifp, ia, sin, scrub) ia->ia_netbroadcast.s_addr = htonl(ia->ia_net | ~ ia->ia_netmask); } else if (ifp->if_flags & IFF_LOOPBACK) { - ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; + ia->ia_dstaddr = ia->ia_addr; flags |= RTF_HOST; } else if (ifp->if_flags & IFF_POINTOPOINT) { if (ia->ia_dstaddr.sin_family != AF_INET) %%% An alternative would be to fix in_addprefix() to pay attention to ia_ifa pointers, but as this bug shows, this is error prone. It's much easier to just initialize the ia_dstaddr as appropriate. Cheers, -- Ruslan Ermilov [EMAIL PROTECTED] FreeBSD committer
pgpTQciiFeYEy.pgp
Description: PGP signature