From owner-freebsd-net@FreeBSD.ORG Mon May 22 09:41:08 2006 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9727616A424; Mon, 22 May 2006 09:41:08 +0000 (UTC) (envelope-from jinmei@isl.rdc.toshiba.co.jp) Received: from shuttle.wide.toshiba.co.jp (shuttle.wide.toshiba.co.jp [202.249.10.124]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0AB5143D45; Mon, 22 May 2006 09:41:02 +0000 (GMT) (envelope-from jinmei@isl.rdc.toshiba.co.jp) Received: from impact.jinmei.org (unknown [3ffe:501:100f:1010:4fe:37e7:871c:4a5c]) by shuttle.wide.toshiba.co.jp (Postfix) with ESMTP id BF8FB15218; Mon, 22 May 2006 18:40:59 +0900 (JST) Date: Mon, 22 May 2006 18:40:48 +0900 Message-ID: From: JINMEI Tatuya / =?ISO-2022-JP?B?GyRCP0BMQEMjOkgbKEI=?= To: Ed Schouten , "Bruce A. Mah" In-Reply-To: References: <20060506172742.GM15353@hoeg.nl> <445EC341.60406@freebsd.org> <20060508065841.GN15353@hoeg.nl> User-Agent: Wanderlust/2.14.0 (Africa) Emacs/21.3 Mule/5.0 (SAKAKI) Organization: Research & Development Center, Toshiba Corp., Kawasaki, Japan. MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII Cc: FreeBSD Net Subject: Re: nd6_lookup prints bogus messages with point to point devices X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 May 2006 09:41:08 -0000 >>>>> On Thu, 18 May 2006 01:35:35 +0900, >>>>> JINMEI Tatuya said: >> I'm seeing the messages on the machine in Eindhoven (running RELENG_6 >> from a few days/weeks ago), but they also show up on my HEAD machine at >> home. Below is the output of `ifconfig gif0` on my machine at home: >> | gif0: flags=8051 mtu 1280 >> | tunnel inet 83.181.147.170 --> 193.109.122.244 >> | inet6 fe80::202:a5ff:fe58:4927%gif0 prefixlen 64 scopeid 0x7 >> | inet6 2001:7b8:310::1 --> 2001:7b8:2ff:a4::1 prefixlen 128 >> As far as I know, the latest FreeBSD releases show an error message when >> assigning an address with a non-128 prefixlen. > Sorry for not responding sooner, but I think I've figured out the > problem. I'm now testing a local patch to this problem, and will > report the details once I confirm the behavior. Could you try the patch attached below? It's for 6.1-RELEASE, but I guess it's pretty easy to apply to CURRENT. The essential reason of this problem is that the latest kernel regards the destination address of a point-to-point interface as a "neighbor" wrt Neighbor Discovery while a neighbor cache entry is not created on configuring the interface with the addresses. I believe it makes sense to treat the destination address as a neighbor, so the fix is to make sure that the cache entry is created when the interface is configured. Thanks, JINMEI, Tatuya Communication Platform Lab. Corporate R&D Center, Toshiba Corp. jinmei@isl.rdc.toshiba.co.jp Index: in6.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/in6.c,v retrieving revision 1.51.2.8 diff -u -r1.51.2.8 in6.c --- in6.c 9 Mar 2006 11:59:03 -0000 1.51.2.8 +++ in6.c 18 May 2006 05:27:07 -0000 @@ -1720,20 +1720,55 @@ /* we could do in(6)_socktrim here, but just omit it at this moment. */ + if (newhost && nd6_need_cache(ifp) != 0) { + /* set the rtrequest function to create llinfo */ + ia->ia_ifa.ifa_rtrequest = nd6_rtrequest; + } + /* * Special case: * If a new destination address is specified for a point-to-point * interface, install a route to the destination as an interface - * direct route. + * direct route. In addition, if the link is expected to have neighbor + * cache entries, specify RTF_LLINFO so that a cache entry for the + * destination address will be created. + * created * XXX: the logic below rejects assigning multiple addresses on a p2p - * interface that share a same destination. + * interface that share the same destination. */ plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */ if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 && ia->ia_dstaddr.sin6_family == AF_INET6) { - if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, - RTF_UP | RTF_HOST)) != 0) + int rtflags = RTF_UP | RTF_HOST; + struct rtentry *rt = NULL, **rtp = NULL; + + if (nd6_need_cache(ifp) != 0) { + rtflags |= RTF_LLINFO; + rtp = &rt; + } + + error = rtrequest(RTM_ADD, (struct sockaddr *)&ia->ia_dstaddr, + (struct sockaddr *)&ia->ia_addr, + (struct sockaddr *)&ia->ia_prefixmask, + ia->ia_flags | rtflags, rtp); + if (error != 0) return (error); + if (rt != NULL) { + struct llinfo_nd6 *ln; + + RT_LOCK(rt); + ln = (struct llinfo_nd6 *)rt->rt_llinfo; + if (ln != NULL) { + /* + * Set the state to STALE because we don't + * have to perform address resolution on this + * link. + */ + ln->ln_state = ND6_LLINFO_STALE; + } + RT_REMREF(rt); + RT_UNLOCK(rt); + } ia->ia_flags |= IFA_ROUTE; } if (plen < 128) { @@ -1744,11 +1779,8 @@ } /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */ - if (newhost) { - /* set the rtrequest function to create llinfo */ - ia->ia_ifa.ifa_rtrequest = nd6_rtrequest; + if (newhost) in6_ifaddloop(&(ia->ia_ifa)); - } return (error); } Index: nd6.c =================================================================== RCS file: /home/ncvs/src/sys/netinet6/nd6.c,v retrieving revision 1.48.2.12 diff -u -r1.48.2.12 nd6.c --- nd6.c 29 Mar 2006 21:05:11 -0000 1.48.2.12 +++ nd6.c 18 May 2006 05:27:08 -0000 @@ -512,6 +512,19 @@ ln->ln_asked++; nd6_llinfo_settimer(ln, (long)ndi->retrans * hz / 1000); nd6_ns_output(ifp, dst, dst, ln, 0); + } else if (rt->rt_ifa != NULL && + rt->rt_ifa->ifa_addr->sa_family == AF_INET6 && + (((struct in6_ifaddr *)rt->rt_ifa)->ia_flags & IFA_ROUTE)) { + /* + * This is an unreachable neighbor whose address is + * specified as the destination of a p2p interface + * (see in6_ifinit()). We should not free the entry + * since this is sort of a "static" entry generated + * via interface address configuration. + */ + ln->ln_asked = 0; + ln->ln_expire = 0; /* make it permanent */ + ln->ln_state = ND6_LLINFO_STALE; } else { (void)nd6_free(rt, 0); ln = NULL;