svn commit: r201614 - in stable/8: . contrib/top lib/libusb share/man/man4 sys/net sys/netinet sys/netinet6 tools/regression/lib/msun tools/regression/usr.bin/pkill tools/tools/ath/common tools/too...

Qing Li qingli at FreeBSD.org
Tue Jan 5 22:14:56 UTC 2010


Author: qingli
Date: Tue Jan  5 22:14:55 2010
New Revision: 201614
URL: http://svn.freebsd.org/changeset/base/201614

Log:
  MFC r201282, r201543
  
  r201282
  -------
  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.
  
  r201543
  -------
  The IFA_RTSELF address flag marks a loopback route has been installed
  for the interface address. This marker is necessary to properly support
  PPP types of links where multiple links can have the same local end
  IP address. The IFA_RTSELF flag bit maps to the RTF_HOST value, which
  was combined into the route flag bits during prefix installation in
  IPv6. This inclusion causing the prefix route to be unusable. This
  patch fixes this bug by excluding the IFA_RTSELF flag during route
  installation.
  
  PR:		ports/141342, kern/141134

Modified:
  stable/8/sys/net/if_llatbl.c
  stable/8/sys/net/if_llatbl.h
  stable/8/sys/net/if_var.h
  stable/8/sys/net/route.c
  stable/8/sys/net/route.h
  stable/8/sys/net/rtsock.c
  stable/8/sys/netinet/in.c
  stable/8/sys/netinet6/in6.c
  stable/8/sys/netinet6/nd6_rtr.c
  stable/8/usr.sbin/arp/arp.c
Directory Properties:
  stable/8/   (props changed)
  stable/8/ObsoleteFiles.inc   (props changed)
  stable/8/UPDATING   (props changed)
  stable/8/bin/   (props changed)
  stable/8/bin/csh/   (props changed)
  stable/8/bin/pax/   (props changed)
  stable/8/bin/ps/   (props changed)
  stable/8/bin/sh/   (props changed)
  stable/8/cddl/compat/opensolaris/   (props changed)
  stable/8/cddl/contrib/opensolaris/   (props changed)
  stable/8/cddl/contrib/opensolaris/cmd/zdb/   (props changed)
  stable/8/cddl/contrib/opensolaris/cmd/zfs/   (props changed)
  stable/8/cddl/contrib/opensolaris/lib/libzfs/   (props changed)
  stable/8/cddl/lib/libnvpair/   (props changed)
  stable/8/contrib/bind9/   (props changed)
  stable/8/contrib/bsnmp/   (props changed)
  stable/8/contrib/bzip2/   (props changed)
  stable/8/contrib/cpio/   (props changed)
  stable/8/contrib/csup/   (props changed)
  stable/8/contrib/ee/   (props changed)
  stable/8/contrib/expat/   (props changed)
  stable/8/contrib/file/   (props changed)
  stable/8/contrib/gcc/   (props changed)
  stable/8/contrib/gdb/   (props changed)
  stable/8/contrib/gdtoa/   (props changed)
  stable/8/contrib/less/   (props changed)
  stable/8/contrib/libpcap/   (props changed)
  stable/8/contrib/ncurses/   (props changed)
  stable/8/contrib/netcat/   (props changed)
  stable/8/contrib/ntp/   (props changed)
  stable/8/contrib/openbsm/   (props changed)
  stable/8/contrib/openpam/   (props changed)
  stable/8/contrib/pf/   (props changed)
  stable/8/contrib/sendmail/   (props changed)
  stable/8/contrib/tcpdump/   (props changed)
  stable/8/contrib/tcsh/   (props changed)
  stable/8/contrib/top/   (props changed)
  stable/8/contrib/top/install-sh   (props changed)
  stable/8/contrib/traceroute/   (props changed)
  stable/8/contrib/wpa/   (props changed)
  stable/8/crypto/openssh/   (props changed)
  stable/8/crypto/openssl/   (props changed)
  stable/8/etc/   (props changed)
  stable/8/games/factor/   (props changed)
  stable/8/games/fortune/   (props changed)
  stable/8/games/fortune/datfiles/   (props changed)
  stable/8/gnu/usr.bin/groff/   (props changed)
  stable/8/gnu/usr.bin/patch/   (props changed)
  stable/8/include/   (props changed)
  stable/8/kerberos5/lib/libgssapi_krb5/   (props changed)
  stable/8/kerberos5/lib/libgssapi_spnego/   (props changed)
  stable/8/lib/bind/   (props changed)
  stable/8/lib/csu/   (props changed)
  stable/8/lib/libarchive/   (props changed)
  stable/8/lib/libc/   (props changed)
  stable/8/lib/libc/stdtime/   (props changed)
  stable/8/lib/libdevinfo/   (props changed)
  stable/8/lib/libdisk/   (props changed)
  stable/8/lib/libexpat/   (props changed)
  stable/8/lib/libfetch/   (props changed)
  stable/8/lib/libjail/   (props changed)
  stable/8/lib/libkvm/   (props changed)
  stable/8/lib/libpmc/   (props changed)
  stable/8/lib/libradius/   (props changed)
  stable/8/lib/libstand/   (props changed)
  stable/8/lib/libtacplus/   (props changed)
  stable/8/lib/libthr/   (props changed)
  stable/8/lib/libusb/   (props changed)
  stable/8/lib/libusb/usb.h   (props changed)
  stable/8/lib/libutil/   (props changed)
  stable/8/libexec/rtld-elf/   (props changed)
  stable/8/release/   (props changed)
  stable/8/release/doc/   (props changed)
  stable/8/release/doc/en_US.ISO8859-1/hardware/   (props changed)
  stable/8/sbin/   (props changed)
  stable/8/sbin/atacontrol/   (props changed)
  stable/8/sbin/bsdlabel/   (props changed)
  stable/8/sbin/camcontrol/   (props changed)
  stable/8/sbin/ddb/   (props changed)
  stable/8/sbin/dhclient/   (props changed)
  stable/8/sbin/fsck/   (props changed)
  stable/8/sbin/geom/   (props changed)
  stable/8/sbin/ifconfig/   (props changed)
  stable/8/sbin/ipfw/   (props changed)
  stable/8/sbin/mksnap_ffs/   (props changed)
  stable/8/sbin/mount/   (props changed)
  stable/8/sbin/mount_cd9660/   (props changed)
  stable/8/sbin/mount_msdosfs/   (props changed)
  stable/8/sbin/mount_nfs/   (props changed)
  stable/8/sbin/umount/   (props changed)
  stable/8/secure/usr.bin/bdes/   (props changed)
  stable/8/share/man/man3/   (props changed)
  stable/8/share/man/man4/   (props changed)
  stable/8/share/man/man4/de.4   (props changed)
  stable/8/share/man/man5/   (props changed)
  stable/8/share/man/man7/   (props changed)
  stable/8/share/man/man8/   (props changed)
  stable/8/share/man/man9/   (props changed)
  stable/8/share/misc/   (props changed)
  stable/8/share/timedef/   (props changed)
  stable/8/share/zoneinfo/   (props changed)
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/tools/kerneldoc/subsys/   (props changed)
  stable/8/tools/regression/bin/sh/   (props changed)
  stable/8/tools/regression/lib/libc/   (props changed)
  stable/8/tools/regression/lib/msun/test-conj.t   (props changed)
  stable/8/tools/regression/poll/   (props changed)
  stable/8/tools/regression/priv/   (props changed)
  stable/8/tools/regression/usr.bin/pkill/pgrep-_g.t   (props changed)
  stable/8/tools/regression/usr.bin/pkill/pgrep-_s.t   (props changed)
  stable/8/tools/regression/usr.bin/pkill/pkill-_g.t   (props changed)
  stable/8/tools/tools/ath/common/dumpregs.h   (props changed)
  stable/8/tools/tools/ath/common/dumpregs_5210.c   (props changed)
  stable/8/tools/tools/ath/common/dumpregs_5211.c   (props changed)
  stable/8/tools/tools/ath/common/dumpregs_5212.c   (props changed)
  stable/8/tools/tools/ath/common/dumpregs_5416.c   (props changed)
  stable/8/tools/tools/termcap/termcap.pl   (props changed)
  stable/8/tools/tools/vimage/   (props changed)
  stable/8/usr.bin/calendar/   (props changed)
  stable/8/usr.bin/calendar/calendars/calendar.freebsd   (props changed)
  stable/8/usr.bin/csup/   (props changed)
  stable/8/usr.bin/find/   (props changed)
  stable/8/usr.bin/finger/   (props changed)
  stable/8/usr.bin/fstat/   (props changed)
  stable/8/usr.bin/gcore/   (props changed)
  stable/8/usr.bin/gzip/   (props changed)
  stable/8/usr.bin/kdump/   (props changed)
  stable/8/usr.bin/locale/   (props changed)
  stable/8/usr.bin/look/   (props changed)
  stable/8/usr.bin/netstat/   (props changed)
  stable/8/usr.bin/perror/   (props changed)
  stable/8/usr.bin/procstat/   (props changed)
  stable/8/usr.bin/systat/   (props changed)
  stable/8/usr.bin/unifdef/   (props changed)
  stable/8/usr.bin/vmstat/   (props changed)
  stable/8/usr.bin/w/   (props changed)
  stable/8/usr.bin/whois/   (props changed)
  stable/8/usr.sbin/   (props changed)
  stable/8/usr.sbin/Makefile   (props changed)
  stable/8/usr.sbin/acpi/   (props changed)
  stable/8/usr.sbin/arp/   (props changed)
  stable/8/usr.sbin/bsnmpd/   (props changed)
  stable/8/usr.sbin/cdcontrol/   (props changed)
  stable/8/usr.sbin/crashinfo/   (props changed)
  stable/8/usr.sbin/cron/   (props changed)
  stable/8/usr.sbin/diskinfo/   (props changed)
  stable/8/usr.sbin/dumpcis/cardinfo.h   (props changed)
  stable/8/usr.sbin/dumpcis/cis.h   (props changed)
  stable/8/usr.sbin/freebsd-update/   (props changed)
  stable/8/usr.sbin/inetd/   (props changed)
  stable/8/usr.sbin/iostat/   (props changed)
  stable/8/usr.sbin/jail/   (props changed)
  stable/8/usr.sbin/jls/   (props changed)
  stable/8/usr.sbin/lpr/   (props changed)
  stable/8/usr.sbin/makefs/ffs/ffs_bswap.c   (props changed)
  stable/8/usr.sbin/makefs/ffs/ffs_subr.c   (props changed)
  stable/8/usr.sbin/makefs/ffs/ufs_bswap.h   (props changed)
  stable/8/usr.sbin/makefs/getid.c   (props changed)
  stable/8/usr.sbin/mfiutil/mfiutil.8   (props changed)
  stable/8/usr.sbin/ndp/   (props changed)
  stable/8/usr.sbin/ntp/   (props changed)
  stable/8/usr.sbin/ppp/   (props changed)
  stable/8/usr.sbin/pstat/   (props changed)
  stable/8/usr.sbin/service/   (props changed)
  stable/8/usr.sbin/sysinstall/   (props changed)
  stable/8/usr.sbin/syslogd/   (props changed)
  stable/8/usr.sbin/traceroute6/   (props changed)
  stable/8/usr.sbin/usbconfig/   (props changed)
  stable/8/usr.sbin/wpa/   (props changed)
  stable/8/usr.sbin/zic/   (props changed)

Modified: stable/8/sys/net/if_llatbl.c
==============================================================================
--- stable/8/sys/net/if_llatbl.c	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/sys/net/if_llatbl.c	Tue Jan  5 22:14:55 2010	(r201614)
@@ -274,7 +274,9 @@ lla_rt_output(struct rt_msghdr *rtm, str
 #ifdef INET
 			if (dst->sa_family == AF_INET && 
 			    ((struct sockaddr_inarp *)dst)->sin_other != 0) {
-				struct rtentry *rt = rtalloc1(dst, 0, 0);
+				struct rtentry *rt;
+				((struct sockaddr_inarp *)dst)->sin_other = 0;
+				rt = rtalloc1(dst, 0, 0);
 				if (rt == NULL || !(rt->rt_flags & RTF_HOST)) {
 					log(LOG_INFO, "%s: RTM_ADD publish "
 					    "(proxy only) is invalid\n",

Modified: stable/8/sys/net/if_llatbl.h
==============================================================================
--- stable/8/sys/net/if_llatbl.h	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/sys/net/if_llatbl.h	Tue Jan  5 22:14:55 2010	(r201614)
@@ -159,7 +159,7 @@ struct lltable {
 				    const struct sockaddr *mask);
 	struct llentry *	(*llt_lookup)(struct lltable *, u_int flags,
 				    const struct sockaddr *l3addr);
-	int			(*llt_rtcheck)(struct ifnet *,
+	int			(*llt_rtcheck)(struct ifnet *, u_int flags,
 				    const struct sockaddr *);
 	int			(*llt_dump)(struct lltable *,
 				     struct sysctl_req *);

Modified: stable/8/sys/net/if_var.h
==============================================================================
--- stable/8/sys/net/if_var.h	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/sys/net/if_var.h	Tue Jan  5 22:14:55 2010	(r201614)
@@ -712,6 +712,7 @@ struct ifaddr {
 	struct mtx ifa_mtx;
 };
 #define	IFA_ROUTE	RTF_UP		/* route installed */
+#define IFA_RTSELF	RTF_HOST	/* loopback route to self installed */
 
 /* for compatibility with other BSDs */
 #define	ifa_list	ifa_link

Modified: stable/8/sys/net/route.c
==============================================================================
--- stable/8/sys/net/route.c	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/sys/net/route.c	Tue Jan  5 22:14:55 2010	(r201614)
@@ -98,8 +98,6 @@ VNET_DEFINE(struct rtstat, rtstat);
 #define	V_rttrash	VNET(rttrash)
 #define	V_rtstat	VNET(rtstat)
 
-static void rt_maskedcopy(struct sockaddr *,
-	    struct sockaddr *, struct sockaddr *);
 
 /* compare two sockaddr structures */
 #define	sa_equal(a1, a2) (bcmp((a1), (a2), (a1)->sa_len) == 0)
@@ -1315,7 +1313,7 @@ rt_setgate(struct rtentry *rt, struct so
 	return (0);
 }
 
-static void
+void
 rt_maskedcopy(struct sockaddr *src, struct sockaddr *dst, struct sockaddr *netmask)
 {
 	register u_char *cp1 = (u_char *)src;

Modified: stable/8/sys/net/route.h
==============================================================================
--- stable/8/sys/net/route.h	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/sys/net/route.h	Tue Jan  5 22:14:55 2010	(r201614)
@@ -384,6 +384,7 @@ void	 rt_missmsg(int, struct rt_addrinfo
 void	 rt_newaddrmsg(int, struct ifaddr *, int, struct rtentry *);
 void	 rt_newmaddrmsg(int, struct ifmultiaddr *);
 int	 rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *);
+void 	 rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *);
 
 /*
  * Note the following locking behavior:

Modified: stable/8/sys/net/rtsock.c
==============================================================================
--- stable/8/sys/net/rtsock.c	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/sys/net/rtsock.c	Tue Jan  5 22:14:55 2010	(r201614)
@@ -60,6 +60,7 @@
 #include <net/vnet.h>
 
 #include <netinet/in.h>
+#include <netinet/if_ether.h>
 #ifdef INET6
 #include <netinet6/scope6_var.h>
 #endif
@@ -622,6 +623,27 @@ route_output(struct mbuf *m, struct sock
 			}
 		}
 #endif
+		/*
+		 * If performing proxied L2 entry insertion, and
+		 * the actual PPP host entry is found, perform
+		 * another search to retrieve the prefix route of
+		 * the local end point of the PPP link.
+		 */
+		if ((rtm->rtm_flags & RTF_ANNOUNCE) &&
+		    (rt->rt_ifp->if_flags & IFF_POINTOPOINT)) {
+			struct sockaddr laddr;
+			rt_maskedcopy(rt->rt_ifa->ifa_addr,
+				      &laddr,
+				      rt->rt_ifa->ifa_netmask);
+			/* 
+			 * refactor rt and no lock operation necessary
+			 */
+			rt = (struct rtentry *)rnh->rnh_matchaddr(&laddr, rnh);
+			if (rt == NULL) {
+				RADIX_NODE_HEAD_RUNLOCK(rnh);
+				senderr(ESRCH);
+			}
+		} 
 		RT_LOCK(rt);
 		RT_ADDREF(rt);
 		RADIX_NODE_HEAD_RUNLOCK(rnh);

Modified: stable/8/sys/netinet/in.c
==============================================================================
--- stable/8/sys/netinet/in.c	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/sys/netinet/in.c	Tue Jan  5 22:14:55 2010	(r201614)
@@ -924,9 +924,25 @@ in_ifinit(struct ifnet *ifp, struct in_i
 	/*
 	 * add a loopback route to self
 	 */
-	if (V_useloopback && !(ifp->if_flags & IFF_LOOPBACK))
-		error = ifa_add_loopback_route((struct ifaddr *)ia, 
+	if (V_useloopback && !(ifp->if_flags & IFF_LOOPBACK)) {
+		struct route ia_ro;
+
+		bzero(&ia_ro, sizeof(ia_ro));
+		*((struct sockaddr_in *)(&ia_ro.ro_dst)) = ia->ia_addr;
+		rtalloc_ign_fib(&ia_ro, 0, 0);
+		if ((ia_ro.ro_rt != NULL) && (ia_ro.ro_rt->rt_ifp != NULL) &&
+		    (ia_ro.ro_rt->rt_ifp == V_loif)) {
+			RT_LOCK(ia_ro.ro_rt);
+			RT_ADDREF(ia_ro.ro_rt);
+			RTFREE_LOCKED(ia_ro.ro_rt);
+		} else
+			error = ifa_add_loopback_route((struct ifaddr *)ia, 
 				       (struct sockaddr *)&ia->ia_addr);
+		if (error == 0)
+			ia->ia_flags |= IFA_RTSELF;
+		if (ia_ro.ro_rt != NULL)
+			RTFREE(ia_ro.ro_rt);
+	}
 
 	return (error);
 }
@@ -1043,7 +1059,7 @@ in_scrubprefix(struct in_ifaddr *target)
 {
 	struct in_ifaddr *ia;
 	struct in_addr prefix, mask, p;
-	int error;
+	int error = 0;
 	struct sockaddr_in prefix0, mask0;
 
 	/*
@@ -1057,9 +1073,28 @@ in_scrubprefix(struct in_ifaddr *target)
 	 * deletion is unconditional.
 	 */
 	if ((target->ia_addr.sin_addr.s_addr != INADDR_ANY) &&
-	    !(target->ia_ifp->if_flags & IFF_LOOPBACK)) {
-		error = ifa_del_loopback_route((struct ifaddr *)target,
+	    !(target->ia_ifp->if_flags & IFF_LOOPBACK) &&
+	    (target->ia_flags & IFA_RTSELF)) {
+		struct route ia_ro;
+		int freeit = 0;
+
+		bzero(&ia_ro, sizeof(ia_ro));
+		*((struct sockaddr_in *)(&ia_ro.ro_dst)) = target->ia_addr;
+		rtalloc_ign_fib(&ia_ro, 0, 0);
+		if ((ia_ro.ro_rt != NULL) && (ia_ro.ro_rt->rt_ifp != NULL) &&
+		    (ia_ro.ro_rt->rt_ifp == V_loif)) {
+			RT_LOCK(ia_ro.ro_rt);
+			if (ia_ro.ro_rt->rt_refcnt <= 1)
+				freeit = 1;
+			else
+				RT_REMREF(ia_ro.ro_rt);
+			RTFREE_LOCKED(ia_ro.ro_rt);
+		}
+		if (freeit)
+			error = ifa_del_loopback_route((struct ifaddr *)target,
 				       (struct sockaddr *)&target->ia_addr);
+		if (error == 0)
+			target->ia_flags &= ~IFA_RTSELF;
 		/* remove arp cache */
 		arp_ifscrub(target->ia_ifp, IA_SIN(target)->sin_addr.s_addr);
 	}
@@ -1317,7 +1352,7 @@ in_lltable_prefix_free(struct lltable *l
 
 
 static int
-in_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr)
+in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
 {
 	struct rtentry *rt;
 
@@ -1326,7 +1361,8 @@ in_lltable_rtcheck(struct ifnet *ifp, co
 
 	/* XXX rtalloc1 should take a const param */
 	rt = rtalloc1(__DECONST(struct sockaddr *, l3addr), 0, 0);
-	if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || rt->rt_ifp != ifp) {
+	if (rt == NULL || (rt->rt_flags & RTF_GATEWAY) || 
+	    ((rt->rt_ifp != ifp) && !(flags & LLE_PUB))) {
 #ifdef DIAGNOSTIC
 		log(LOG_INFO, "IPv4 address: \"%s\" is not on the network\n",
 		    inet_ntoa(((const struct sockaddr_in *)l3addr)->sin_addr));
@@ -1378,7 +1414,7 @@ in_lltable_lookup(struct lltable *llt, u
 		 * verify this.
 		 */
 		if (!(flags & LLE_IFADDR) &&
-		    in_lltable_rtcheck(ifp, l3addr) != 0)
+		    in_lltable_rtcheck(ifp, flags, l3addr) != 0)
 			goto done;
 
 		lle = in_lltable_new(l3addr, flags);

Modified: stable/8/sys/netinet6/in6.c
==============================================================================
--- stable/8/sys/netinet6/in6.c	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/sys/netinet6/in6.c	Tue Jan  5 22:14:55 2010	(r201614)
@@ -1196,8 +1196,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);
@@ -1758,6 +1762,8 @@ in6_ifinit(struct ifnet *ifp, struct in6
 		|| (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). */
@@ -2340,7 +2346,9 @@ in6_lltable_prefix_free(struct lltable *
 }
 
 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];
@@ -2408,7 +2416,7 @@ in6_lltable_lookup(struct lltable *llt, 
 		 * 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);

Modified: stable/8/sys/netinet6/nd6_rtr.c
==============================================================================
--- stable/8/sys/netinet6/nd6_rtr.c	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/sys/netinet6/nd6_rtr.c	Tue Jan  5 22:14:55 2010	(r201614)
@@ -1631,7 +1631,7 @@ nd6_prefix_onlink(struct nd_prefix *pr)
 	bzero(&mask6, sizeof(mask6));
 	mask6.sin6_len = sizeof(mask6);
 	mask6.sin6_addr = pr->ndpr_mask;
-	rtflags = ifa->ifa_flags | RTF_UP;
+	rtflags = (ifa->ifa_flags & ~IFA_RTSELF) | RTF_UP;
 	error = rtrequest(RTM_ADD, (struct sockaddr *)&pr->ndpr_prefix,
 	    ifa->ifa_addr, (struct sockaddr *)&mask6, rtflags, &rt);
 	if (error == 0) {

Modified: stable/8/usr.sbin/arp/arp.c
==============================================================================
--- stable/8/usr.sbin/arp/arp.c	Tue Jan  5 21:14:48 2010	(r201613)
+++ stable/8/usr.sbin/arp/arp.c	Tue Jan  5 22:14:55 2010	(r201614)
@@ -326,7 +326,6 @@ set(int argc, char **argv)
 			doing_proxy = 1;
 			if (argc && strncmp(argv[1], "only", 3) == 0) {
 				proxy_only = 1;
-				dst->sin_other = SIN_PROXY;
 				argc--; argv++;
 			}
 		} else if (strncmp(argv[0], "blackhole", 9) == 0) {
@@ -365,33 +364,30 @@ set(int argc, char **argv)
 			sdl_m.sdl_alen = ETHER_ADDR_LEN;
 		}
 	}
-	for (;;) {	/* try at most twice */
-		rtm = rtmsg(RTM_GET, dst, &sdl_m);
-		if (rtm == NULL) {
-			warn("%s", host);
-			return (1);
-		}
-		addr = (struct sockaddr_inarp *)(rtm + 1);
-		sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr);
-		if (addr->sin_addr.s_addr != dst->sin_addr.s_addr)	
-			break;
-		if (sdl->sdl_family == AF_LINK &&
-		    !(rtm->rtm_flags & RTF_GATEWAY) &&
-		    valid_type(sdl->sdl_type) )
-			break;
-		if (doing_proxy == 0) {
-			printf("set: can only proxy for %s\n", host);
-			return (1);
-		}
-		if (dst->sin_other & SIN_PROXY) {
-			printf("set: proxy entry exists for non 802 device\n");
-			return (1);
-		}
-		dst->sin_other = SIN_PROXY;
-		proxy_only = 1;
+
+	/*
+	 * In the case a proxy-arp entry is being added for
+	 * a remote end point, the RTF_ANNOUNCE flag in the 
+	 * RTM_GET command is an indication to the kernel
+	 * routing code that the interface associated with
+	 * the prefix route covering the local end of the
+	 * PPP link should be returned, on which ARP applies.
+	 */
+	rtm = rtmsg(RTM_GET, dst, &sdl_m);
+	if (rtm == NULL) {
+		warn("%s", host);
+		return (1);
+	}
+	addr = (struct sockaddr_inarp *)(rtm + 1);
+	sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr);
+	if (addr->sin_addr.s_addr == dst->sin_addr.s_addr) {
+		printf("set: proxy entry exists for non 802 device\n");
+		return (1);
 	}
 
-	if (sdl->sdl_family != AF_LINK) {
+	if ((sdl->sdl_family != AF_LINK) ||
+	    (rtm->rtm_flags & RTF_GATEWAY) ||
+	    !valid_type(sdl->sdl_type)) {
 		printf("cannot intuit interface index and type for %s\n", host);
 		return (1);
 	}
@@ -436,7 +432,11 @@ delete(char *host, int do_proxy)
 	dst = getaddr(host);
 	if (dst == NULL)
 		return (1);
-	dst->sin_other = do_proxy;
+
+	/*
+	 * Perform a regular entry delete first.
+	 */
+	flags &= ~RTF_ANNOUNCE;
 
 	/*
 	 * setup the data structure to notify the kernel
@@ -471,11 +471,16 @@ delete(char *host, int do_proxy)
 			break;
 		}
 
-		if (dst->sin_other & SIN_PROXY) {
+		/*
+		 * Regualar entry delete failed, now check if there
+		 * is a proxy-arp entry to remove.
+		 */
+		if (flags & RTF_ANNOUNCE) {
 			fprintf(stderr, "delete: cannot locate %s\n",host);
 			return (1);
 		}
-		dst->sin_other = SIN_PROXY;
+
+		flags |= RTF_ANNOUNCE;
 	}
 	rtm->rtm_flags |= RTF_LLDATA;
 	if (rtmsg(RTM_DELETE, dst, NULL) != NULL) {
@@ -485,6 +490,7 @@ delete(char *host, int do_proxy)
 	return (1);
 }
 
+
 /*
  * Search the arp table and do some action on matching entries
  */


More information about the svn-src-all mailing list