svn commit: r287851 - in head/sys: net netinet

Alexander V. Chernikov melifaro at FreeBSD.org
Wed Sep 16 06:23:17 UTC 2015


Author: melifaro
Date: Wed Sep 16 06:23:15 2015
New Revision: 287851
URL: https://svnweb.freebsd.org/changeset/base/287851

Log:
  Unify loopback route switching:
  * prepare gateway before insertion
  * use RTM_CHANGE instead of explicit find/change route
  * Remove fib argument from ifa_switch_loopback_route added in r264887:
    if old ifp fib differes from new one, that the caller
    is doing something wrong
  * Make ifa_*_loopback_route call single ifa_maintain_loopback_route().

Modified:
  head/sys/net/if.c
  head/sys/net/if_var.h
  head/sys/netinet/in.c

Modified: head/sys/net/if.c
==============================================================================
--- head/sys/net/if.c	Wed Sep 16 04:38:07 2015	(r287850)
+++ head/sys/net/if.c	Wed Sep 16 06:23:15 2015	(r287851)
@@ -1545,76 +1545,53 @@ ifa_free(struct ifaddr *ifa)
 	}
 }
 
-int
-ifa_add_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
+static int
+ifa_maintain_loopback_route(int cmd, const char *otype, struct ifaddr *ifa,
+    struct sockaddr *ia)
 {
-	int error = 0;
-	struct rtentry *rt = NULL;
+	int error;
 	struct rt_addrinfo info;
-	static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK};
+	struct sockaddr_dl null_sdl;
+	struct ifnet *ifp;
+
+	ifp = ifa->ifa_ifp;
 
 	bzero(&info, sizeof(info));
-	info.rti_ifp = V_loif;
+	if (cmd != RTM_DELETE)
+		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, ifa->ifa_ifp->if_fib);
+	link_init_sdl(ifp, (struct sockaddr *)&null_sdl, ifp->if_type);
+
+	error = rtrequest1_fib(cmd, &info, NULL, ifp->if_fib);
 
-	if (error == 0 && rt != NULL) {
-		RT_LOCK(rt);
-		((struct sockaddr_dl *)rt->rt_gateway)->sdl_type  =
-			ifa->ifa_ifp->if_type;
-		((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
-			ifa->ifa_ifp->if_index;
-		RT_REMREF(rt);
-		RT_UNLOCK(rt);
-	} else if (error != 0)
-		log(LOG_DEBUG, "%s: insertion failed: %u\n", __func__, error);
+	if (error != 0)
+		log(LOG_DEBUG, "%s: %s failed for interface %s: %u\n",
+		    __func__, otype, if_name(ifp), error);
 
 	return (error);
 }
 
 int
-ifa_del_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
+ifa_add_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, ifa->ifa_ifp->if_fib);
+	return (ifa_maintain_loopback_route(RTM_ADD, "insertion", ifa, ia));
+}
 
-	if (error != 0)
-		log(LOG_DEBUG, "%s: deletion failed: %u\n", __func__, error);
+int
+ifa_del_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
+{
 
-	return (error);
+	return (ifa_maintain_loopback_route(RTM_DELETE, "deletion", ifa, ia));
 }
 
 int
-ifa_switch_loopback_route(struct ifaddr *ifa, struct sockaddr *sa, int fib)
+ifa_switch_loopback_route(struct ifaddr *ifa, struct sockaddr *ia)
 {
-	struct rtentry *rt;
-
-	rt = rtalloc1_fib(sa, 0, 0, fib);
-	if (rt == NULL) {
-		log(LOG_DEBUG, "%s: fail", __func__);
-		return (EHOSTUNREACH);
-	}
-	((struct sockaddr_dl *)rt->rt_gateway)->sdl_type =
-	    ifa->ifa_ifp->if_type;
-	((struct sockaddr_dl *)rt->rt_gateway)->sdl_index =
-	    ifa->ifa_ifp->if_index;
-	RTFREE_LOCKED(rt);
 
-	return (0);
+	return (ifa_maintain_loopback_route(RTM_CHANGE, "switch", ifa, ia));
 }
 
 /*

Modified: head/sys/net/if_var.h
==============================================================================
--- head/sys/net/if_var.h	Wed Sep 16 04:38:07 2015	(r287850)
+++ head/sys/net/if_var.h	Wed Sep 16 06:23:15 2015	(r287851)
@@ -504,7 +504,7 @@ struct	ifnet *ifunit_ref(const char *);
 
 int	ifa_add_loopback_route(struct ifaddr *, struct sockaddr *);
 int	ifa_del_loopback_route(struct ifaddr *, struct sockaddr *);
-int	ifa_switch_loopback_route(struct ifaddr *, struct sockaddr *, int fib);
+int	ifa_switch_loopback_route(struct ifaddr *, struct sockaddr *);
 
 struct	ifaddr *ifa_ifwithaddr(const struct sockaddr *);
 int		ifa_ifwithaddr_check(const struct sockaddr *);

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Wed Sep 16 04:38:07 2015	(r287850)
+++ head/sys/netinet/in.c	Wed Sep 16 06:23:15 2015	(r287851)
@@ -776,13 +776,16 @@ in_scrubprefix(struct in_ifaddr *target,
 	    (flags & LLE_STATIC)) {
 		struct in_ifaddr *eia;
 
+		/*
+		 * XXXME: add fib-aware in_localip.
+		 * We definitely don't want to switch between
+		 * prefixes in different fibs.
+		 */
 		eia = in_localip_more(target);
 
 		if (eia != NULL) {
-			int fibnum = target->ia_ifp->if_fib;
-
 			error = ifa_switch_loopback_route((struct ifaddr *)eia,
-			    (struct sockaddr *)&target->ia_addr, fibnum);
+			    (struct sockaddr *)&target->ia_addr);
 			ifa_free(&eia->ia_ifa);
 		} else {
 			error = ifa_del_loopback_route((struct ifaddr *)target,


More information about the svn-src-all mailing list