Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Jan 2012 02:13:28 +0000 (UTC)
From:      Qing Li <qingli@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r230604 - stable/9/sys/netinet6
Message-ID:  <201201270213.q0R2DS3x016063@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: qingli
Date: Fri Jan 27 02:13:27 2012
New Revision: 230604
URL: http://svn.freebsd.org/changeset/base/230604

Log:
  MFC 227460
  
  A default route learned from the RAs could be deleted manually
  after its installation. This removal may be accidental and can
  prevent the default route from being installed in the future if
  the associated default router has the best preference. The cause
  is the lack of status update in the default router on the state
  of its route installation in the kernel FIB. This patch fixes
  the described problem.
  
  Reviewed by:	hrs, discussed with hrs

Modified:
  stable/9/sys/netinet6/in6.c
  stable/9/sys/netinet6/nd6.c
  stable/9/sys/netinet6/nd6.h
  stable/9/sys/netinet6/nd6_rtr.c
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/amd64/include/xen/   (props changed)
  stable/9/sys/boot/   (props changed)
  stable/9/sys/boot/i386/efi/   (props changed)
  stable/9/sys/boot/ia64/efi/   (props changed)
  stable/9/sys/boot/ia64/ski/   (props changed)
  stable/9/sys/boot/powerpc/boot1.chrp/   (props changed)
  stable/9/sys/boot/powerpc/ofw/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/conf/   (props changed)
  stable/9/sys/contrib/dev/acpica/   (props changed)
  stable/9/sys/contrib/octeon-sdk/   (props changed)
  stable/9/sys/contrib/pf/   (props changed)
  stable/9/sys/contrib/x86emu/   (props changed)

Modified: stable/9/sys/netinet6/in6.c
==============================================================================
--- stable/9/sys/netinet6/in6.c	Thu Jan 26 22:01:05 2012	(r230603)
+++ stable/9/sys/netinet6/in6.c	Fri Jan 27 02:13:27 2012	(r230604)
@@ -152,7 +152,7 @@ in6_ifaddloop(struct ifaddr *ifa)
 	ia = ifa2ia6(ifa);
 	ifp = ifa->ifa_ifp;
 	IF_AFDATA_LOCK(ifp);
-	ifa->ifa_rtrequest = NULL;
+	ifa->ifa_rtrequest = nd6_rtrequest;
 
 	/* XXX QL
 	 * we need to report rt_newaddrmsg

Modified: stable/9/sys/netinet6/nd6.c
==============================================================================
--- stable/9/sys/netinet6/nd6.c	Thu Jan 26 22:01:05 2012	(r230603)
+++ stable/9/sys/netinet6/nd6.c	Fri Jan 27 02:13:27 2012	(r230604)
@@ -1174,6 +1174,46 @@ done:
 }
 
 
+/*
+ * Rejuvenate this function for routing operations related
+ * processing.
+ */
+void
+nd6_rtrequest(int req, struct rtentry *rt, struct rt_addrinfo *info)
+{
+	struct sockaddr_in6 *gateway = (struct sockaddr_in6 *)rt->rt_gateway;
+	struct nd_defrouter *dr;
+	struct ifnet *ifp = rt->rt_ifp;
+
+	RT_LOCK_ASSERT(rt);
+
+	switch (req) {
+	case RTM_ADD:
+		break;
+
+	case RTM_DELETE:
+		if (!ifp)
+			return;
+		/*
+		 * Only indirect routes are interesting.
+		 */
+		if ((rt->rt_flags & RTF_GATEWAY) == 0)
+			return;
+		/*
+		 * check for default route
+		 */
+		if (IN6_ARE_ADDR_EQUAL(&in6addr_any, 
+				       &SIN6(rt_key(rt))->sin6_addr)) {
+
+			dr = defrouter_lookup(&gateway->sin6_addr, ifp);
+			if (dr != NULL)
+				dr->installed = 0;
+		}
+		break;
+	}
+}
+
+
 int
 nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
 {

Modified: stable/9/sys/netinet6/nd6.h
==============================================================================
--- stable/9/sys/netinet6/nd6.h	Thu Jan 26 22:01:05 2012	(r230603)
+++ stable/9/sys/netinet6/nd6.h	Fri Jan 27 02:13:27 2012	(r230604)
@@ -406,6 +406,7 @@ void nd6_purge __P((struct ifnet *));
 void nd6_nud_hint __P((struct rtentry *, struct in6_addr *, int));
 int nd6_resolve __P((struct ifnet *, struct rtentry *, struct mbuf *,
 	struct sockaddr *, u_char *));
+void nd6_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *));
 int nd6_ioctl __P((u_long, caddr_t, struct ifnet *));
 struct llentry *nd6_cache_lladdr __P((struct ifnet *, struct in6_addr *,
 	char *, int, int, int));

Modified: stable/9/sys/netinet6/nd6_rtr.c
==============================================================================
--- stable/9/sys/netinet6/nd6_rtr.c	Thu Jan 26 22:01:05 2012	(r230603)
+++ stable/9/sys/netinet6/nd6_rtr.c	Fri Jan 27 02:13:27 2012	(r230604)
@@ -751,9 +751,10 @@ defrtrlist_update(struct nd_defrouter *n
 
 			/*
 			 * If the preference does not change, there's no need
-			 * to sort the entries.
+			 * to sort the entries. Also make sure the selected
+			 * router is still installed in the kernel.
 			 */
-			if (rtpref(new) == oldpref) {
+			if (dr->installed && rtpref(new) == oldpref) {
 				splx(s);
 				return (dr);
 			}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201270213.q0R2DS3x016063>