changeset 12997:82a41a56372e

6966758 ire generation numbers changes on shared IP zone boot throws off uperf numbers 6972874 zone shutdown can fail when resetting link protection on datalinks created inside a NGZ
author Sowmini Varadhan <Sowmini.Varadhan@oracle.COM>
date Mon, 02 Aug 2010 08:40:07 -0400
parents be896e318721
children 04c3fb904c79
files usr/src/cmd/zoneadmd/vplat.c usr/src/uts/common/inet/ip/ip.c usr/src/uts/common/inet/ip/ip6_ire.c usr/src/uts/common/inet/ip/ip_ftable.c usr/src/uts/common/inet/ip_ire.h
diffstat 5 files changed, 85 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/zoneadmd/vplat.c	Mon Aug 02 16:27:00 2010 +0530
+++ b/usr/src/cmd/zoneadmd/vplat.c	Mon Aug 02 08:40:07 2010 -0400
@@ -3107,17 +3107,25 @@
 	}
 
 	for (i = 0, dllink = dllinks; i < dlnum; i++, dllink++) {
+		char dlerr[DLADM_STRSIZE];
+
 		dlstatus = dladm_set_linkprop(dld_handle, *dllink,
 		    "protection", NULL, 0, DLADM_OPT_ACTIVE);
+		if (dlstatus == DLADM_STATUS_NOTFOUND) {
+			/* datalink does not belong to the GZ */
+			continue;
+		}
 		if (dlstatus != DLADM_STATUS_OK) {
-			zerror(zlogp, B_TRUE, "could not reset protection\n");
+			zerror(zlogp, B_FALSE,
+			    dladm_status2str(dlstatus, dlerr));
 			free(dllinks);
 			return (-1);
 		}
 		dlstatus = dladm_set_linkprop(dld_handle, *dllink,
 		    "allowed-ips", NULL, 0, DLADM_OPT_ACTIVE);
 		if (dlstatus != DLADM_STATUS_OK) {
-			zerror(zlogp, B_TRUE, "could not reset allowed-ips\n");
+			zerror(zlogp, B_FALSE,
+			    dladm_status2str(dlstatus, dlerr));
 			free(dllinks);
 			return (-1);
 		}
--- a/usr/src/uts/common/inet/ip/ip.c	Mon Aug 02 16:27:00 2010 +0530
+++ b/usr/src/uts/common/inet/ip/ip.c	Mon Aug 02 08:40:07 2010 -0400
@@ -9378,7 +9378,7 @@
 			 */
 			if (optval == IPOPT_SSRR) {
 				ire = ire_ftable_lookup_v4(dst, 0, 0,
-				    IRE_IF_ALL, NULL, ALL_ZONES,
+				    IRE_INTERFACE, NULL, ALL_ZONES,
 				    ira->ira_tsl,
 				    MATCH_IRE_TYPE | MATCH_IRE_SECATTR, 0, ipst,
 				    NULL);
@@ -12915,7 +12915,8 @@
 			 */
 			if (optval == IPOPT_SSRR) {
 				ire = ire_ftable_lookup_v4(dst, 0, 0,
-				    IRE_IF_ALL, NULL, ALL_ZONES, ixa->ixa_tsl,
+				    IRE_INTERFACE, NULL, ALL_ZONES,
+				    ixa->ixa_tsl,
 				    MATCH_IRE_TYPE | MATCH_IRE_SECATTR, 0, ipst,
 				    NULL);
 				if (ire == NULL) {
--- a/usr/src/uts/common/inet/ip/ip6_ire.c	Mon Aug 02 16:27:00 2010 +0530
+++ b/usr/src/uts/common/inet/ip/ip6_ire.c	Mon Aug 02 08:40:07 2010 -0400
@@ -1218,6 +1218,15 @@
 			goto error;
 
 		ASSERT(!(ire->ire_type & IRE_MULTICAST)); /* Not in ftable */
+		/*
+		 * Verify that the IRE_IF_CLONE has a consistent generation
+		 * number.
+		 */
+		if ((ire->ire_type & IRE_IF_CLONE) && !ire_clone_verify(ire)) {
+			ire_refrele(ire);
+			ire = NULL;
+			continue;
+		}
 
 		/*
 		 * Don't allow anything unusual past the first iteration.
@@ -1477,26 +1486,28 @@
 	ASSERT(ire != NULL);
 
 	/*
-	 * If this type should have an ire_nce_cache (even if it
-	 * doesn't yet have one) then we are done. Includes
-	 * IRE_INTERFACE with a full 128 bit mask.
-	 */
-	if (ire->ire_nce_capable)
-		return (ire);
-
-	/*
 	 * If the IRE has a current cached parent we know that the whole
 	 * parent chain is current, hence we don't need to discover and
 	 * build any dependencies by doing a recursive lookup.
 	 */
 	mutex_enter(&ire->ire_lock);
-	if (ire->ire_dep_parent != NULL &&
-	    ire->ire_dep_parent->ire_generation ==
-	    ire->ire_dep_parent_generation) {
+	if (ire->ire_dep_parent != NULL) {
+		if (ire->ire_dep_parent->ire_generation ==
+		    ire->ire_dep_parent_generation) {
+			mutex_exit(&ire->ire_lock);
+			return (ire);
+		}
+		mutex_exit(&ire->ire_lock);
+	} else {
 		mutex_exit(&ire->ire_lock);
-		return (ire);
+		/*
+		 * If this type should have an ire_nce_cache (even if it
+		 * doesn't yet have one) then we are done. Includes
+		 * IRE_INTERFACE with a full 128 bit mask.
+		 */
+		if (ire->ire_nce_capable)
+			return (ire);
 	}
-	mutex_exit(&ire->ire_lock);
 
 	/*
 	 * Fallback to loop in the normal code starting with the ire
--- a/usr/src/uts/common/inet/ip/ip_ftable.c	Mon Aug 02 16:27:00 2010 +0530
+++ b/usr/src/uts/common/inet/ip/ip_ftable.c	Mon Aug 02 08:40:07 2010 -0400
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -1446,6 +1445,15 @@
 			goto error;
 
 		ASSERT(!(ire->ire_type & IRE_MULTICAST)); /* Not in ftable */
+		/*
+		 * Verify that the IRE_IF_CLONE has a consistent generation
+		 * number.
+		 */
+		if ((ire->ire_type & IRE_IF_CLONE) && !ire_clone_verify(ire)) {
+			ire_refrele(ire);
+			ire = NULL;
+			continue;
+		}
 
 		/*
 		 * Don't allow anything unusual past the first iteration.
@@ -1713,28 +1721,29 @@
 	ire = ire_ftable_lookup_simple_v4(nexthop, xmit_hint, ipst,
 	    &generation);
 	ASSERT(ire != NULL);
-
-	/*
-	 * If this type should have an ire_nce_cache (even if it
-	 * doesn't yet have one) then we are done. Includes
-	 * IRE_INTERFACE with a full 32 bit mask.
-	 */
-	if (ire->ire_nce_capable)
-		return (ire);
-
 	/*
 	 * If the IRE has a current cached parent we know that the whole
 	 * parent chain is current, hence we don't need to discover and
 	 * build any dependencies by doing a recursive lookup.
 	 */
 	mutex_enter(&ire->ire_lock);
-	if (ire->ire_dep_parent != NULL &&
-	    ire->ire_dep_parent->ire_generation ==
-	    ire->ire_dep_parent_generation) {
+	if (ire->ire_dep_parent != NULL) {
+		if (ire->ire_dep_parent->ire_generation ==
+		    ire->ire_dep_parent_generation) {
+			mutex_exit(&ire->ire_lock);
+			return (ire);
+		}
+		mutex_exit(&ire->ire_lock);
+	} else {
 		mutex_exit(&ire->ire_lock);
-		return (ire);
+		/*
+		 * If this type should have an ire_nce_cache (even if it
+		 * doesn't yet have one) then we are done. Includes
+		 * IRE_INTERFACE with a full 32 bit mask.
+		 */
+		if (ire->ire_nce_capable)
+			return (ire);
 	}
-	mutex_exit(&ire->ire_lock);
 
 	/*
 	 * Fallback to loop in the normal code starting with the ire
@@ -1746,3 +1755,24 @@
 	ire_refrele(ire);
 	return (ire1);
 }
+
+/*
+ * Verify that the generation numbers in the chain leading to an IRE_IF_CLONE
+ * are consistent. Return FALSE (and delete the IRE_IF_CLONE) if they
+ * are not consistent, and TRUE otherwise.
+ */
+boolean_t
+ire_clone_verify(ire_t *ire)
+{
+	ASSERT((ire->ire_type & IRE_IF_CLONE) != 0);
+	mutex_enter(&ire->ire_lock);
+	if (ire->ire_dep_parent != NULL &&
+	    ire->ire_dep_parent->ire_generation !=
+	    ire->ire_dep_parent_generation) {
+		mutex_exit(&ire->ire_lock);
+		ire_delete(ire);
+		return (B_FALSE);
+	}
+	mutex_exit(&ire->ire_lock);
+	return (B_TRUE);
+}
--- a/usr/src/uts/common/inet/ip_ire.h	Mon Aug 02 16:27:00 2010 +0530
+++ b/usr/src/uts/common/inet/ip_ire.h	Mon Aug 02 08:40:07 2010 -0400
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 /* Copyright (c) 1990 Mentat Inc. */
 
@@ -346,6 +345,7 @@
 extern  void ire_increment_generation(ire_t *);
 extern  void ire_increment_multicast_generation(ip_stack_t *, boolean_t);
 extern	void ire_rebind(ire_t *);
+extern	boolean_t ire_clone_verify(ire_t *);
 
 #endif /* _KERNEL */