diff options
author | qingli <qingli@FreeBSD.org> | 2009-12-30 21:35:34 +0000 |
---|---|---|
committer | qingli <qingli@FreeBSD.org> | 2009-12-30 21:35:34 +0000 |
commit | ed965a92bc17f25c5049fbd529d10a9e94f8a3a7 (patch) | |
tree | 8e2dcb46479d9e8deaedba15ff39e4bf06edf8c9 /sys/netinet6 | |
parent | 05e668091314a2bdc6f8d36ac2e8abf4c424a09a (diff) | |
download | FreeBSD-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.c | 16 |
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); |