changeset 11430:7b1870d99874

6913366 Missing zones check for IP_BOUND_IF and IPV6_MULTICAST_IF 6913365 Should refuse adding routes that can't be used
author Erik Nordmark <Erik.Nordmark@Sun.COM>
date Mon, 04 Jan 2010 23:29:24 -0800
parents 3398895a8df2
children 753a00801df0
files usr/src/uts/common/inet/ip/conn_opt.c usr/src/uts/common/inet/ip/ip6_if.c usr/src/uts/common/inet/ip/ip_if.c usr/src/uts/common/inet/ip_if.h
diffstat 4 files changed, 49 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip/conn_opt.c	Mon Jan 04 23:03:14 2010 -0800
+++ b/usr/src/uts/common/inet/ip/conn_opt.c	Mon Jan 04 23:29:24 2010 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -1265,7 +1265,8 @@
 				return (EADDRNOTAVAIL);
 			}
 		}
-		if (!ip_ifindex_valid(pktinfo->ipi_ifindex, B_FALSE, ipst))
+		if (!ip_xmit_ifindex_valid(pktinfo->ipi_ifindex, zoneid,
+		    B_FALSE, ipst))
 			return (ENXIO);
 		break;
 	}
@@ -1273,7 +1274,7 @@
 		ifindex = *(uint_t *)i1;
 
 		/* Just check it is ok. */
-		if (!ip_ifindex_valid(ifindex, B_FALSE, ipst))
+		if (!ip_xmit_ifindex_valid(ifindex, zoneid, B_FALSE, ipst))
 			return (ENXIO);
 		break;
 	}
@@ -1523,8 +1524,8 @@
 		 */
 		ifindex = *(uint_t *)i1;
 
-		if (!ip_ifindex_valid(ifindex, B_TRUE, ipst) &&
-		    !ip_ifindex_valid(ifindex, B_FALSE, ipst))
+		if (!ip_xmit_ifindex_valid(ifindex, zoneid, B_TRUE, ipst) &&
+		    !ip_xmit_ifindex_valid(ifindex, zoneid, B_FALSE, ipst))
 			return (EINVAL);
 		break;
 	case IPV6_UNICAST_HOPS:
@@ -1544,7 +1545,7 @@
 	case IPV6_BOUND_IF:
 		ifindex = *(uint_t *)i1;
 
-		if (!ip_ifindex_valid(ifindex, B_TRUE, ipst))
+		if (!ip_xmit_ifindex_valid(ifindex, zoneid, B_TRUE, ipst))
 			return (ENXIO);
 		break;
 	case IPV6_PKTINFO: {
@@ -1600,7 +1601,8 @@
 			ixa->ixa_flags &= ~IXAF_VERIFY_SOURCE;
 		}
 		isv6 = !(IN6_IS_ADDR_V4MAPPED(&pkti->ipi6_addr));
-		if (!ip_ifindex_valid(pkti->ipi6_ifindex, isv6, ipst))
+		if (!ip_xmit_ifindex_valid(pkti->ipi6_ifindex, zoneid, isv6,
+		    ipst))
 			return (ENXIO);
 		break;
 	}
--- a/usr/src/uts/common/inet/ip/ip6_if.c	Mon Jan 04 23:03:14 2010 -0800
+++ b/usr/src/uts/common/inet/ip/ip6_if.c	Mon Jan 04 23:29:24 2010 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -687,20 +687,39 @@
 	 * Get an interface IRE for the specified gateway.
 	 * If we don't have an IRE_IF_NORESOLVER or IRE_IF_RESOLVER for the
 	 * gateway, it is currently unreachable and we fail the request
-	 * accordingly.
+	 * accordingly. We reject any RTF_GATEWAY routes where the gateway
+	 * is an IRE_LOCAL or IRE_LOOPBACK.
 	 * If RTA_IFP was specified we look on that particular ill.
 	 */
 	if (ill != NULL)
 		match_flags |= MATCH_IRE_ILL;
 
 	/* Check whether the gateway is reachable. */
-	type = IRE_INTERFACE;
+again:
+	type = IRE_INTERFACE | IRE_LOCAL | IRE_LOOPBACK;
 	if (flags & RTF_INDIRECT)
 		type |= IRE_OFFLINK;
 
 	gw_ire = ire_ftable_lookup_v6(gw_addr, 0, 0, type, ill,
 	    ALL_ZONES, NULL, match_flags, 0, ipst, NULL);
 	if (gw_ire == NULL) {
+		/*
+		 * With IPMP, we allow host routes to influence in.mpathd's
+		 * target selection.  However, if the test addresses are on
+		 * their own network, the above lookup will fail since the
+		 * underlying IRE_INTERFACEs are marked hidden.  So allow
+		 * hidden test IREs to be found and try again.
+		 */
+		if (!(match_flags & MATCH_IRE_TESTHIDDEN))  {
+			match_flags |= MATCH_IRE_TESTHIDDEN;
+			goto again;
+		}
+		if (ipif != NULL)
+			ipif_refrele(ipif);
+		return (ENETUNREACH);
+	}
+	if (gw_ire->ire_type & (IRE_LOCAL|IRE_LOOPBACK)) {
+		ire_refrele(gw_ire);
 		if (ipif != NULL)
 			ipif_refrele(ipif);
 		return (ENETUNREACH);
--- a/usr/src/uts/common/inet/ip/ip_if.c	Mon Jan 04 23:03:14 2010 -0800
+++ b/usr/src/uts/common/inet/ip/ip_if.c	Mon Jan 04 23:29:24 2010 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -3916,19 +3916,21 @@
 }
 
 /*
- * Verify whether or not an interface index is valid.
+ * Verify whether or not an interface index is valid for the specified zoneid
+ * to transmit packets.
  * It can be zero (meaning "reset") or an interface index assigned
  * to a non-VNI interface. (We don't use VNI interface to send packets.)
  */
 boolean_t
-ip_ifindex_valid(uint_t ifindex, boolean_t isv6, ip_stack_t *ipst)
+ip_xmit_ifindex_valid(uint_t ifindex, zoneid_t zoneid, boolean_t isv6,
+    ip_stack_t *ipst)
 {
 	ill_t		*ill;
 
 	if (ifindex == 0)
 		return (B_TRUE);
 
-	ill = ill_lookup_on_ifindex(ifindex, isv6, ipst);
+	ill = ill_lookup_on_ifindex_zoneid(ifindex, zoneid, isv6, ipst);
 	if (ill == NULL)
 		return (B_FALSE);
 	if (IS_VNI(ill)) {
@@ -5690,7 +5692,8 @@
 	 * Get an interface IRE for the specified gateway.
 	 * If we don't have an IRE_IF_NORESOLVER or IRE_IF_RESOLVER for the
 	 * gateway, it is currently unreachable and we fail the request
-	 * accordingly.
+	 * accordingly. We reject any RTF_GATEWAY routes where the gateway
+	 * is an IRE_LOCAL or IRE_LOOPBACK.
 	 * If RTA_IFP was specified we look on that particular ill.
 	 */
 	if (ill != NULL)
@@ -5698,7 +5701,7 @@
 
 	/* Check whether the gateway is reachable. */
 again:
-	type = IRE_INTERFACE;
+	type = IRE_INTERFACE | IRE_LOCAL | IRE_LOOPBACK;
 	if (flags & RTF_INDIRECT)
 		type |= IRE_OFFLINK;
 
@@ -5716,7 +5719,12 @@
 			match_flags |= MATCH_IRE_TESTHIDDEN;
 			goto again;
 		}
-
+		if (ipif != NULL)
+			ipif_refrele(ipif);
+		return (ENETUNREACH);
+	}
+	if (gw_ire->ire_type & (IRE_LOCAL|IRE_LOOPBACK)) {
+		ire_refrele(gw_ire);
 		if (ipif != NULL)
 			ipif_refrele(ipif);
 		return (ENETUNREACH);
--- a/usr/src/uts/common/inet/ip_if.h	Mon Jan 04 23:03:14 2010 -0800
+++ b/usr/src/uts/common/inet/ip_if.h	Mon Jan 04 23:29:24 2010 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* Copyright (c) 1990 Mentat Inc. */
@@ -172,7 +172,8 @@
     ip_stack_t *);
 extern	ill_t	*ill_lookup_on_name(char *, boolean_t,
     boolean_t, boolean_t *, ip_stack_t *);
-extern boolean_t ip_ifindex_valid(uint_t, boolean_t, ip_stack_t *);
+extern boolean_t ip_xmit_ifindex_valid(uint_t, zoneid_t, boolean_t,
+    ip_stack_t *);
 extern uint_t	ill_get_next_ifindex(uint_t, boolean_t, ip_stack_t *);
 extern uint_t	ill_get_ifindex_by_name(char *, ip_stack_t *);
 extern uint_t	ill_get_upper_ifindex(const ill_t *);