svn commit: r257737 - head/sys/netinet

Gleb Smirnoff glebius at FreeBSD.org
Wed Nov 6 08:36:08 UTC 2013


Author: glebius
Date: Wed Nov  6 08:36:08 2013
New Revision: 257737
URL: http://svnweb.freebsd.org/changeset/base/257737

Log:
  Fix my braino in r257692. For SIOCG*ADDR we don't need exact match on
  specified address, actually in most cases the address isn't specified.
  
  Reported by:	peter

Modified:
  head/sys/netinet/in.c

Modified: head/sys/netinet/in.c
==============================================================================
--- head/sys/netinet/in.c	Wed Nov  6 07:46:10 2013	(r257736)
+++ head/sys/netinet/in.c	Wed Nov  6 08:36:08 2013	(r257737)
@@ -237,6 +237,7 @@ in_control(struct socket *so, u_long cmd
 {
 	struct ifreq *ifr = (struct ifreq *)data;
 	struct sockaddr_in *addr = (struct sockaddr_in *)&ifr->ifr_addr;
+	struct ifaddr *ifa;
 	struct in_ifaddr *ia;
 	int error;
 
@@ -279,19 +280,25 @@ in_control(struct socket *so, u_long cmd
 		return ((*ifp->if_ioctl)(ifp, cmd, data));
 	}
 
+	if (addr->sin_addr.s_addr != INADDR_ANY &&
+	    prison_check_ip4(td->td_ucred, &addr->sin_addr) != 0)
+		return (EADDRNOTAVAIL);
+
 	/*
-	 * Find address for this interface, if it exists.
+	 * For SIOCGIFADDR, pick the first address.  For the rest of
+	 * ioctls, try to find specified address.
 	 */
-	IN_IFADDR_RLOCK();
-	LIST_FOREACH(ia, INADDR_HASH(addr->sin_addr.s_addr), ia_hash) {
-		if (ia->ia_ifp == ifp &&
-		    ia->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr &&
-		    prison_check_ip4(td->td_ucred, &addr->sin_addr) == 0)
+	IF_ADDR_RLOCK(ifp);
+	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+		ia = (struct in_ifaddr *)ifa;
+		if (cmd == SIOCGIFADDR || addr->sin_addr.s_addr == INADDR_ANY)
+			break;
+		if (ia->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr)
 			break;
 	}
 
-	if (ia == NULL) {
-		IN_IFADDR_RUNLOCK();
+	if (ifa == NULL) {
+		IF_ADDR_RUNLOCK(ifp);
 		return (EADDRNOTAVAIL);
 	}
 
@@ -322,7 +329,7 @@ in_control(struct socket *so, u_long cmd
 		break;
 	}
 
-	IN_IFADDR_RUNLOCK();
+	IF_ADDR_RUNLOCK(ifp);
 
 	return (error);
 }


More information about the svn-src-all mailing list