summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorgnn <gnn@FreeBSD.org>2006-06-08 00:31:17 +0000
committergnn <gnn@FreeBSD.org>2006-06-08 00:31:17 +0000
commit3b364427e5617217905e74b60e4576f9a1af18a4 (patch)
tree949b9634b02f7c8aac16dccd42686e8e083dc6ab /sys
parentb2f065226110fdafc15d7abf538c9944b3ff7d6f (diff)
downloadFreeBSD-src-3b364427e5617217905e74b60e4576f9a1af18a4.zip
FreeBSD-src-3b364427e5617217905e74b60e4576f9a1af18a4.tar.gz
Fix spurious warnings from neighbor discovery when working with IPv6 over
point to point tunnels (gif). PR: 93220 Submitted by: Jinmei Tatuya MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet6/in6.c48
-rw-r--r--sys/netinet6/nd6.c13
2 files changed, 53 insertions, 8 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index c775aec..fcc3080 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1720,20 +1720,55 @@ in6_ifinit(ifp, ia, sin6, newhost)
/* 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 @@ in6_ifinit(ifp, ia, sin6, newhost)
}
/* 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);
}
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 3ff8b22..ad7e079 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -512,6 +512,19 @@ nd6_llinfo_timer(arg)
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;
OpenPOWER on IntegriCloud