>>>>> On Thu, 18 May 2006 01:35:35 +0900, 
>>>>> JINMEI Tatuya <[EMAIL PROTECTED]> 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<UP,POINTOPOINT,RUNNING,MULTICAST> 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.
                                        [EMAIL PROTECTED]

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;
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to