changeset 2894:464fc76e8ce1

6478246 panic due to bad trap in ire_round_robin() 6479721 ire_arpresolve() can be invoked with incorrect ipif when vni is involved.
author sowmini
date Tue, 10 Oct 2006 08:42:03 -0700
parents 6f6187d05358
children d18c5b0839cf
files usr/src/uts/common/inet/ip/ip.c usr/src/uts/common/inet/ip/ip_ftable.c usr/src/uts/common/inet/ip/ip_ire.c usr/src/uts/common/inet/ip_ire.h
diffstat 4 files changed, 30 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip/ip.c	Tue Oct 10 06:05:36 2006 -0700
+++ b/usr/src/uts/common/inet/ip/ip.c	Tue Oct 10 08:42:03 2006 -0700
@@ -28446,7 +28446,7 @@
 		 * holds a ref on the ire until ARP is completed.
 		 */
 
-		ire_arpresolve(ire, ire->ire_ipif->ipif_ill);
+		ire_arpresolve(ire, ire_to_ill(ire));
 		return (LOOKUP_IN_PROGRESS);
 	default:
 		ASSERT(0);
--- a/usr/src/uts/common/inet/ip/ip_ftable.c	Tue Oct 10 06:05:36 2006 -0700
+++ b/usr/src/uts/common/inet/ip/ip_ftable.c	Tue Oct 10 08:42:03 2006 -0700
@@ -1609,8 +1609,10 @@
 
 	rw_enter(&irb_ptr->irb_lock, RW_WRITER);
 	ire_origin = irb_ptr->irb_rr_origin;
-	if (ire_origin != NULL)
+	if (ire_origin != NULL) {
 		ire_origin = ire_origin->ire_next;
+		IRE_FIND_NEXT_ORIGIN(ire_origin);
+	}
 
 	if (ire_origin == NULL) {
 		/*
@@ -1618,11 +1620,15 @@
 		 * of list.
 		 */
 		ire_origin = irb_ptr->irb_ire;
+		IRE_FIND_NEXT_ORIGIN(ire_origin);
 	}
 	irb_ptr->irb_rr_origin = ire_origin;
 	IRB_REFHOLD_LOCKED(irb_ptr);
 	rw_exit(&irb_ptr->irb_lock);
 
+	DTRACE_PROBE2(ire__rr__origin, (irb_t *), irb_ptr,
+	    (ire_t *), ire_origin);
+
 	/*
 	 * Round-robin the routers list looking for a route that
 	 * matches the passed in parameters.
--- a/usr/src/uts/common/inet/ip/ip_ire.c	Tue Oct 10 06:05:36 2006 -0700
+++ b/usr/src/uts/common/inet/ip/ip_ire.c	Tue Oct 10 08:42:03 2006 -0700
@@ -699,12 +699,19 @@
 					goto done;
 				}
 
+				DTRACE_PROBE1(ip__ire__del__origin,
+				    (ire_t *), gw_ire);
 
 				/* Skip past the potentially bad gateway */
 				if (ire->ire_gateway_addr ==
-				    gw_ire->ire_gateway_addr)
-					irb->irb_rr_origin = gw_ire->ire_next;
-
+				    gw_ire->ire_gateway_addr) {
+					ire_t *next = gw_ire->ire_next;
+
+					DTRACE_PROBE2(ip__ire__del,
+					    (ire_t *), gw_ire, (irb_t *), irb);
+					IRE_FIND_NEXT_ORIGIN(next);
+					irb->irb_rr_origin = next;
+				}
 				rw_exit(&irb->irb_lock);
 			}
 		}
--- a/usr/src/uts/common/inet/ip_ire.h	Tue Oct 10 06:05:36 2006 -0700
+++ b/usr/src/uts/common/inet/ip_ire.h	Tue Oct 10 08:42:03 2006 -0700
@@ -151,6 +151,18 @@
 	NCE_REFRELE(nce);			\
 }
 
+/*
+ * find the next ire_t entry in the ire_next chain starting at ire
+ * that is not CONDEMNED.  ire is set to NULL if we reach the end of the list.
+ * Caller must hold the ire_bucket lock.
+ */
+
+#define	IRE_FIND_NEXT_ORIGIN(ire) {					\
+	while ((ire) != NULL && ((ire)->ire_marks & IRE_MARK_CONDEMNED))\
+		(ire) = (ire)->ire_next;				\
+}
+
+
 /* Structure for ire_cache_count() */
 typedef struct {
 	int	icc_total;	/* Total number of IRE_CACHE */