Apply by doing:
	cd /usr/src
	patch -p0 < 001_ndp.patch

Then build and install a new kernel.

Index: sys/netinet6/in6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6.c,v
retrieving revision 1.78
retrieving revision 1.78.2.1
diff -u -p -r1.78 -r1.78.2.1
--- sys/netinet6/in6.c	13 Jul 2008 20:41:39 -0000	1.78
+++ sys/netinet6/in6.c	2 Nov 2008 04:02:10 -0000	1.78.2.1
@@ -1941,6 +1941,31 @@ in6ifa_ifpwithaddr(struct ifnet *ifp, st
 	}
 
 	return ((struct in6_ifaddr *)ifa);
+}
+
+/*
+ * find the internet address on a given interface corresponding to a neighbor's
+ * address.
+ */
+struct in6_ifaddr *
+in6ifa_ifplocaladdr(const struct ifnet *ifp, const struct in6_addr *addr)
+{
+	struct ifaddr *ifa;
+	struct in6_ifaddr *ia;
+
+	TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+		if (ifa->ifa_addr == NULL)
+			continue;	/* just for safety */
+		if (ifa->ifa_addr->sa_family != AF_INET6)
+			continue;
+		ia = (struct in6_ifaddr *)ifa;
+		if (IN6_ARE_MASKED_ADDR_EQUAL(addr,
+				&ia->ia_addr.sin6_addr,
+				&ia->ia_prefixmask.sin6_addr))
+			return ia;
+	}
+
+	return NULL;
 }
 
 /*
Index: sys/netinet6/in6_var.h
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_var.h,v
retrieving revision 1.29
retrieving revision 1.29.2.1
diff -u -p -r1.29 -r1.29.2.1
--- sys/netinet6/in6_var.h	11 Jun 2008 06:30:36 -0000	1.29
+++ sys/netinet6/in6_var.h	2 Nov 2008 04:02:10 -0000	1.29.2.1
@@ -588,6 +588,8 @@ void	in6_createmkludge(struct ifnet *);
 void	in6_purgemkludge(struct ifnet *);
 struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int);
 struct in6_ifaddr *in6ifa_ifpwithaddr(struct ifnet *, struct in6_addr *);
+struct in6_ifaddr *in6ifa_ifplocaladdr(const struct ifnet *,
+	    const struct in6_addr *);
 char	*ip6_sprintf(struct in6_addr *);
 int	in6_addr2scopeid(struct ifnet *, struct in6_addr *);
 int	in6_matchlen(struct in6_addr *, struct in6_addr *);
Index: sys/netinet6/nd6_nbr.c
===================================================================
RCS file: /cvs/src/sys/netinet6/nd6_nbr.c,v
retrieving revision 1.51
retrieving revision 1.51.2.1
diff -u -p -r1.51 -r1.51.2.1
--- sys/netinet6/nd6_nbr.c	11 Jun 2008 19:00:50 -0000	1.51
+++ sys/netinet6/nd6_nbr.c	2 Nov 2008 04:02:10 -0000	1.51.2.1
@@ -132,8 +132,18 @@ nd6_ns_input(struct mbuf *m, int off, in
 			    "(wrong ip6 dst)\n"));
 			goto bad;
 		}
+	} else {
+		/*
+		 * Make sure the source address is from a neighbor's address.
+		 */
+		if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
+			nd6log((LOG_INFO, "nd6_ns_input: "
+			    "NS packet from non-neighbor\n"));
+			goto bad;
+		}
 	}
 
+
 	if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
 		nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n"));
 		goto bad;
@@ -540,9 +550,7 @@ nd6_na_input(struct mbuf *m, int off, in
 	struct ifnet *ifp = m->m_pkthdr.rcvif;
 	struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
 	struct nd_neighbor_advert *nd_na;
-#if 0
 	struct in6_addr saddr6 = ip6->ip6_src;
-#endif
 	struct in6_addr daddr6 = ip6->ip6_dst;
 	struct in6_addr taddr6;
 	int flags;
@@ -628,6 +636,14 @@ nd6_na_input(struct mbuf *m, int off, in
 		    "nd6_na_input: duplicate IP6 address %s\n",
 		    ip6_sprintf(&taddr6));
 		goto freeit;
+	}
+	/*
+	 * Make sure the source address is from a neighbor's address.
+	 */
+	if (in6ifa_ifplocaladdr(ifp, &saddr6) == NULL) {
+		nd6log((LOG_INFO, "nd6_na_input: "
+		    "ND packet from non-neighbor\n"));
+		goto bad;
 	}
 
 	if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {