svn commit: r197239 - in stable/8/sys: . amd64/include/xen cddl/contrib/opensolaris contrib/dev/acpica contrib/pf dev/xen/xenpci net netinet netinet6

Qing Li qingli at FreeBSD.org
Tue Sep 15 22:46:08 UTC 2009


Author: qingli
Date: Tue Sep 15 22:46:06 2009
New Revision: 197239
URL: http://svn.freebsd.org/changeset/base/197239

Log:
  MFC	r197227
  
  Self pointing routes are installed for configured interface addresses
  and address aliases. After an interface is brought down and brought
  back up again, those self pointing routes disappeared. This patch
  ensures after an interface is brought back up, the loopback routes
  are reinstalled properly.
  
  Reviewed by:	bz
  Approved by:	re

Modified:
  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/sys/net/if.c
  stable/8/sys/net/if_var.h
  stable/8/sys/netinet/in.c
  stable/8/sys/netinet/raw_ip.c
  stable/8/sys/netinet6/in6.c

Modified: stable/8/sys/net/if.c
==============================================================================
--- stable/8/sys/net/if.c	Tue Sep 15 22:37:17 2009	(r197238)
+++ stable/8/sys/net/if.c	Tue Sep 15 22:46:06 2009	(r197239)
@@ -1414,6 +1414,59 @@ ifa_free(struct ifaddr *ifa)
 	}
 }
 
+int
+ifa_add_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
+{
+	int error = 0;
+	struct rtentry *rt = NULL;
+	struct rt_addrinfo info;
+	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
+
+	bzero(&info, sizeof(info));
+	info.rti_ifp = V_loif;
+	info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC;
+	info.rti_info[RTAX_DST] = ia;
+	info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
+	error = rtrequest1_fib(RTM_ADD, &info, &rt, 0);
+
+	if (error == 0 && rt != NULL) {
+		RT_LOCK(rt);
+		((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
+			rt->rt_ifp->if_type;
+		((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
+			rt->rt_ifp->if_index;
+		RT_REMREF(rt);
+		RT_UNLOCK(rt);
+	} else if (error != 0)
+		log(LOG_INFO, "ifa_add_loopback_route: insertion failed\n");
+
+	return (error);
+}
+
+int
+ifa_del_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
+{
+	int error = 0;
+	struct rt_addrinfo info;
+	struct sockaddr_dl null_sdl;
+
+	bzero(&null_sdl, sizeof(null_sdl));
+	null_sdl.sdl_len = sizeof(null_sdl);
+	null_sdl.sdl_family = AF_LINK;
+	null_sdl.sdl_type = ifa->ifa_ifp->if_type;
+	null_sdl.sdl_index = ifa->ifa_ifp->if_index;
+	bzero(&info, sizeof(info));
+	info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC;
+	info.rti_info[RTAX_DST] = ia;
+	info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
+	error = rtrequest1_fib(RTM_DELETE, &info, NULL, 0);
+
+	if (error != 0)
+		log(LOG_INFO, "ifa_del_loopback_route: deletion failed\n");
+
+	return (error);
+}
+
 /*
  * XXX: Because sockaddr_dl has deeper structure than the sockaddr
  * structs used to represent other address families, it is necessary

Modified: stable/8/sys/net/if_var.h
==============================================================================
--- stable/8/sys/net/if_var.h	Tue Sep 15 22:37:17 2009	(r197238)
+++ stable/8/sys/net/if_var.h	Tue Sep 15 22:46:06 2009	(r197239)
@@ -854,6 +854,9 @@ struct	ifnet *ifunit_ref(const char *);
 void	ifq_init(struct ifaltq *, struct ifnet *ifp);
 void	ifq_delete(struct ifaltq *);
 
+int	ifa_add_loopback_route(struct ifaddr *, struct sockaddr *);
+int	ifa_del_loopback_route(struct ifaddr *, struct sockaddr *);
+
 struct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
 int		ifa_ifwithaddr_check(struct sockaddr *);
 struct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);

Modified: stable/8/sys/netinet/in.c
==============================================================================
--- stable/8/sys/netinet/in.c	Tue Sep 15 22:37:17 2009	(r197238)
+++ stable/8/sys/netinet/in.c	Tue Sep 15 22:46:06 2009	(r197239)
@@ -827,9 +827,6 @@ in_ifinit(struct ifnet *ifp, struct in_i
 {
 	register u_long i = ntohl(sin->sin_addr.s_addr);
 	struct sockaddr_in oldaddr;
-	struct rtentry *rt = NULL;
-	struct rt_addrinfo info;
-	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
 	int s = splimp(), flags = RTF_UP, error = 0;
 
 	oldaddr = ia->ia_addr;
@@ -927,25 +924,9 @@ in_ifinit(struct ifnet *ifp, struct in_i
 	/*
 	 * add a loopback route to self
 	 */
-	if (V_useloopback && !(ifp->if_flags & IFF_LOOPBACK)) {
-		bzero(&info, sizeof(info));
-		info.rti_ifp = V_loif;
-		info.rti_flags = ia->ia_flags | RTF_HOST | RTF_STATIC;
-		info.rti_info[RTAX_DST] = (struct sockaddr *)&ia->ia_addr;
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
-		error = rtrequest1_fib(RTM_ADD, &info, &rt, 0);
-
-		if (error == 0 && rt != NULL) {
-			RT_LOCK(rt);
-			((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
-				rt->rt_ifp->if_type;
-			((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
-				rt->rt_ifp->if_index;
-			RT_REMREF(rt);
-			RT_UNLOCK(rt);
-		} else if (error != 0)
-			log(LOG_INFO, "in_ifinit: insertion failed\n");
-	}
+	if (V_useloopback && !(ifp->if_flags & IFF_LOOPBACK))
+		error = ifa_add_loopback_route((struct ifaddr *)ia, 
+				       (struct sockaddr *)&ia->ia_addr);
 
 	return (error);
 }
@@ -1064,8 +1045,6 @@ in_scrubprefix(struct in_ifaddr *target)
 	struct in_addr prefix, mask, p;
 	int error;
 	struct sockaddr_in prefix0, mask0;
-	struct rt_addrinfo info;
-	struct sockaddr_dl null_sdl;
 
 	/*
 	 * Remove the loopback route to the interface address.
@@ -1079,19 +1058,8 @@ in_scrubprefix(struct in_ifaddr *target)
 	 */
 	if ((target->ia_addr.sin_addr.s_addr != INADDR_ANY) &&
 	    !(target->ia_ifp->if_flags & IFF_LOOPBACK)) {
-		bzero(&null_sdl, sizeof(null_sdl));
-		null_sdl.sdl_len = sizeof(null_sdl);
-		null_sdl.sdl_family = AF_LINK;
-		null_sdl.sdl_type = V_loif->if_type;
-		null_sdl.sdl_index = V_loif->if_index;
-		bzero(&info, sizeof(info));
-		info.rti_flags = target->ia_flags | RTF_HOST | RTF_STATIC;
-		info.rti_info[RTAX_DST] = (struct sockaddr *)&target->ia_addr;
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
-		error = rtrequest1_fib(RTM_DELETE, &info, NULL, 0);
-
-		if (error != 0)
-			log(LOG_INFO, "in_scrubprefix: deletion failed\n");
+		error = ifa_del_loopback_route((struct ifaddr *)target,
+				       (struct sockaddr *)&target->ia_addr);
 	}
 
 	if ((target->ia_flags & IFA_ROUTE) == 0) {

Modified: stable/8/sys/netinet/raw_ip.c
==============================================================================
--- stable/8/sys/netinet/raw_ip.c	Tue Sep 15 22:37:17 2009	(r197238)
+++ stable/8/sys/netinet/raw_ip.c	Tue Sep 15 22:46:06 2009	(r197239)
@@ -715,6 +715,7 @@ rip_ctlinput(int cmd, struct sockaddr *s
 		err = rtinit(&ia->ia_ifa, RTM_ADD, flags);
 		if (err == 0)
 			ia->ia_flags |= IFA_ROUTE;
+		err = ifa_add_loopback_route((struct ifaddr *)ia, sa);
 		ifa_free(&ia->ia_ifa);
 		break;
 	}

Modified: stable/8/sys/netinet6/in6.c
==============================================================================
--- stable/8/sys/netinet6/in6.c	Tue Sep 15 22:37:17 2009	(r197238)
+++ stable/8/sys/netinet6/in6.c	Tue Sep 15 22:46:06 2009	(r197239)
@@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/syslog.h>
 
 #include <net/if.h>
+#include <net/if_var.h>
 #include <net/if_types.h>
 #include <net/route.h>
 #include <net/if_dl.h>
@@ -1195,24 +1196,8 @@ in6_purgeaddr(struct ifaddr *ifa)
 	 * The check for the current setting of "nd6_useloopback" 
 	 * is not needed.
 	 */
-	{
-		struct rt_addrinfo info;
-		struct sockaddr_dl null_sdl;
-
-		bzero(&null_sdl, sizeof(null_sdl));
-		null_sdl.sdl_len = sizeof(null_sdl);
-		null_sdl.sdl_family = AF_LINK;
-		null_sdl.sdl_type = ia->ia_ifp->if_type;
-		null_sdl.sdl_index = ia->ia_ifp->if_index;
-		bzero(&info, sizeof(info));
-		info.rti_flags = ia->ia_flags | RTF_HOST | RTF_STATIC;
-		info.rti_info[RTAX_DST] = (struct sockaddr *)&ia->ia_addr;
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
-		error = rtrequest1_fib(RTM_DELETE, &info, NULL, 0);
-
-		if (error != 0)
-			log(LOG_INFO, "in6_purgeaddr: deletion failed\n");
-	}
+	error = ifa_del_loopback_route((struct ifaddr *)ia,
+			       (struct sockaddr *)&ia->ia_addr);
 
 	/* stop DAD processing */
 	nd6_dad_stop(ifa);
@@ -1771,27 +1756,8 @@ in6_ifinit(struct ifnet *ifp, struct in6
 	if (!(ia->ia_flags & IFA_ROUTE)
 	    && (V_nd6_useloopback
 		|| (ifp->if_flags & IFF_LOOPBACK))) {
-		struct rt_addrinfo info;
-		struct rtentry *rt = NULL;
-		static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
-
-		bzero(&info, sizeof(info));
-		info.rti_ifp = V_loif;
-		info.rti_flags = ia->ia_flags | RTF_HOST | RTF_STATIC;
-		info.rti_info[RTAX_DST] = (struct sockaddr *)&ia->ia_addr;
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl;
-		error = rtrequest1_fib(RTM_ADD, &info, &rt, 0);
-
-		if (error == 0 && rt != NULL) {
-			RT_LOCK(rt);
-			((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
-				ifp->if_type;
-			((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
-				ifp->if_index;
-			RT_REMREF(rt);
-			RT_UNLOCK(rt);
-		} else if (error != 0)
-			log(LOG_INFO, "in6_ifinit: error = %d, insertion failed\n", error);
+		error = ifa_add_loopback_route((struct ifaddr *)ia,
+				       (struct sockaddr *)&ia->ia_addr);
 	}
 
 	/* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */


More information about the svn-src-all mailing list