summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorqingli <qingli@FreeBSD.org>2009-12-30 21:35:34 +0000
committerqingli <qingli@FreeBSD.org>2009-12-30 21:35:34 +0000
commited965a92bc17f25c5049fbd529d10a9e94f8a3a7 (patch)
tree8e2dcb46479d9e8deaedba15ff39e4bf06edf8c9 /sys/netinet6
parent05e668091314a2bdc6f8d36ac2e8abf4c424a09a (diff)
downloadFreeBSD-src-ed965a92bc17f25c5049fbd529d10a9e94f8a3a7.zip
FreeBSD-src-ed965a92bc17f25c5049fbd529d10a9e94f8a3a7.tar.gz
The proxy arp entries could not be added into the system over the
IFF_POINTOPOINT link types. The reason was due to the routing entry returned from the kernel covering the remote end is of an interface type that does not support ARP. This patch fixes this problem by providing a hint to the kernel routing code, which indicates the prefix route instead of the PPP host route should be returned to the caller. Since a host route to the local end point is also added into the routing table, and there could be multiple such instantiations due to multiple PPP links can be created with the same local end IP address, this patch also fixes the loopback route installation failure problem observed prior to this patch. The reference count of loopback route to local end would be either incremented or decremented. The first instantiation would create the entry and the last removal would delete the route entry. MFC after: 5 days
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 7254c4d..c839efd 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1200,8 +1200,12 @@ in6_purgeaddr(struct ifaddr *ifa)
* The check for the current setting of "nd6_useloopback"
* is not needed.
*/
- error = ifa_del_loopback_route((struct ifaddr *)ia,
- (struct sockaddr *)&ia->ia_addr);
+ if (ia->ia_flags & IFA_RTSELF) {
+ error = ifa_del_loopback_route((struct ifaddr *)ia,
+ (struct sockaddr *)&ia->ia_addr);
+ if (error == 0)
+ ia->ia_flags &= ~IFA_RTSELF;
+ }
/* stop DAD processing */
nd6_dad_stop(ifa);
@@ -1762,6 +1766,8 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia,
|| (ifp->if_flags & IFF_LOOPBACK))) {
error = ifa_add_loopback_route((struct ifaddr *)ia,
(struct sockaddr *)&ia->ia_addr);
+ if (error == 0)
+ ia->ia_flags |= IFA_RTSELF;
}
/* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */
@@ -2347,7 +2353,9 @@ in6_lltable_prefix_free(struct lltable *llt,
}
static int
-in6_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr)
+in6_lltable_rtcheck(struct ifnet *ifp,
+ u_int flags,
+ const struct sockaddr *l3addr)
{
struct rtentry *rt;
char ip6buf[INET6_ADDRSTRLEN];
@@ -2415,7 +2423,7 @@ in6_lltable_lookup(struct lltable *llt, u_int flags,
* verify this.
*/
if (!(flags & LLE_IFADDR) &&
- in6_lltable_rtcheck(ifp, l3addr) != 0)
+ in6_lltable_rtcheck(ifp, flags, l3addr) != 0)
return NULL;
lle = in6_lltable_new(l3addr, flags);
OpenPOWER on IntegriCloud