changeset 11077:4bd474a3ea0e

6901158 Sending 4 NS instead of 3 before giving up 6901462 snoop -I lo0 fails; Network is down 6901463 IPv6 interface with /128 netmask doesn't work 6901792 Minor comment fixes from code review 6901924 assertion failure: ire != NULL in ipif_delete_bcast_ires
author Erik Nordmark <Erik.Nordmark@Sun.COM>
date Tue, 17 Nov 2009 11:42:22 -0800
parents 445f05f9f7b4
children 97a14b54f53b
files usr/src/uts/common/inet/ip.h usr/src/uts/common/inet/ip/igmp.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/ip_multi.c usr/src/uts/common/inet/ip/ip_ndp.c usr/src/uts/common/inet/ip/tn_ipopt.c usr/src/uts/common/inet/ip/tnet.c usr/src/uts/common/inet/tcp/tcp.c
diffstat 9 files changed, 183 insertions(+), 209 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip.h	Tue Nov 17 09:17:48 2009 -0800
+++ b/usr/src/uts/common/inet/ip.h	Tue Nov 17 11:42:22 2009 -0800
@@ -939,6 +939,7 @@
 	boolean_t	ipif_bound;	/* B_TRUE if we successfully bound */
 
 	struct ire_s	*ipif_ire_local; /* Our IRE_LOCAL or LOOPBACK */
+	struct ire_s	*ipif_ire_if;	 /* Our IRE_INTERFACE */
 } ipif_t;
 
 /*
@@ -990,6 +991,7 @@
  * ipif_bound		ipsq			ipsq
  *
  * ipif_ire_local	ipsq + ips_ill_g_lock	ipsq OR ips_ill_g_lock
+ * ipif_ire_if		ipsq + ips_ill_g_lock	ipsq OR ips_ill_g_lock
  */
 
 /*
--- a/usr/src/uts/common/inet/ip/igmp.c	Tue Nov 17 09:17:48 2009 -0800
+++ b/usr/src/uts/common/inet/ip/igmp.c	Tue Nov 17 11:42:22 2009 -0800
@@ -814,7 +814,7 @@
 		/*
 		 * We are holding ill_mcast_lock here and the timeout
 		 * handler (igmp_timeout_handler_per_ill) acquires that
-		 * lock. Hence we can't call igmp_start_timer since it could
+		 * lock. Hence we can't call igmp_start_timers since it could
 		 * deadlock in untimeout().
 		 * Instead the thread which drops ill_mcast_lock will have
 		 * to call ill_mcast_timer_start().
@@ -896,7 +896,7 @@
 		/*
 		 * We are holding ill_mcast_lock here and the timeout
 		 * handler (mld_timeout_handler_per_ill) acquires that
-		 * lock. Hence we can't call mld_start_timer since it could
+		 * lock. Hence we can't call mld_start_timers since it could
 		 * deadlock in untimeout().
 		 * Instead the thread which drops ill_mcast_lock will have
 		 * to call ill_mcast_timer_start().
--- a/usr/src/uts/common/inet/ip/ip6_if.c	Tue Nov 17 09:17:48 2009 -0800
+++ b/usr/src/uts/common/inet/ip/ip6_if.c	Tue Nov 17 11:42:22 2009 -0800
@@ -2492,14 +2492,12 @@
 {
 	ill_t		*ill = ipif->ipif_ill;
 	ip_stack_t	*ipst = ill->ill_ipst;
-	ire_t		*ire_array[20];
-	ire_t		**irep = ire_array;
-	ire_t		**irep1;
 	in6_addr_t	v6addr;
 	in6_addr_t	route_mask;
 	int		err;
 	char		buf[INET6_ADDRSTRLEN];
 	ire_t		*ire_local = NULL;	/* LOCAL or LOOPBACK */
+	ire_t		*ire_if = NULL;
 
 	if (!IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6lcl_addr) &&
 	    !(ipif->ipif_flags & IPIF_NOLOCAL)) {
@@ -2570,7 +2568,7 @@
 		    ill->ill_net_type,
 		    inet_ntop(AF_INET6, &v6addr, buf, sizeof (buf))));
 
-		*irep++ = ire_create_v6(
+		ire_if = ire_create_v6(
 		    &v6addr,			/* dest pref */
 		    &route_mask,		/* mask */
 		    &ipif->ipif_v6lcl_addr,	/* gateway */
@@ -2581,14 +2579,8 @@
 		    RTF_PRIVATE : 0) | RTF_KERNEL,
 		    NULL,
 		    ipst);
-	}
-
-	/* If an earlier ire_create failed, get out now */
-	for (irep1 = irep; irep1 > ire_array; ) {
-		irep1--;
-		if (*irep1 == NULL) {
-			ip1dbg(("ipif_add_ires_v6: NULL ire found in"
-			    " ire_array\n"));
+		if (ire_if == NULL) {
+			ip1dbg(("ipif_up_done: NULL ire_if\n"));
 			err = ENOMEM;
 			goto bad;
 		}
@@ -2627,46 +2619,68 @@
 
 	/*
 	 * Add in all newly created IREs.
+	 * We add the IRE_INTERFACE before the IRE_LOCAL to ensure
+	 * that lookups find the IRE_LOCAL even if the IRE_INTERFACE is
+	 * a /128 route.
 	 */
+	if (ire_if != NULL) {
+		ire_if = ire_add(ire_if);
+		if (ire_if == NULL) {
+			err = ENOMEM;
+			goto bad2;
+		}
+#ifdef DEBUG
+		ire_refhold_notr(ire_if);
+		ire_refrele(ire_if);
+#endif
+	}
 	if (ire_local != NULL) {
 		ire_local = ire_add(ire_local);
+		if (ire_local == NULL) {
+			err = ENOMEM;
+			goto bad2;
+		}
 #ifdef DEBUG
-		if (ire_local != NULL) {
-			ire_refhold_notr(ire_local);
-			ire_refrele(ire_local);
-		}
+		ire_refhold_notr(ire_local);
+		ire_refrele(ire_local);
 #endif
 	}
 	rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
 	if (ire_local != NULL)
 		ipif->ipif_ire_local = ire_local;
+	if (ire_if != NULL)
+		ipif->ipif_ire_if = ire_if;
 	rw_exit(&ipst->ips_ill_g_lock);
 	ire_local = NULL;
-
-	for (irep1 = irep; irep1 > ire_array; ) {
-		irep1--;
-		/* Shouldn't be adding any bcast ire's */
-		ASSERT((*irep1)->ire_type != IRE_BROADCAST);
-		ASSERT(!MUTEX_HELD(&ipif->ipif_ill->ill_lock));
-		/* refheld by ire_add */
-		*irep1 = ire_add(*irep1);
-		if (*irep1 != NULL) {
-			ire_refrele(*irep1);
-			*irep1 = NULL;
-		}
-	}
+	ire_if = NULL;
 
 	if (ipif->ipif_addr_ready)
 		ipif_up_notify(ipif);
 	return (0);
 
+bad2:
+	ill->ill_ipif_up_count--;
+	ipif->ipif_flags &= ~IPIF_UP;
+
 bad:
 	if (ire_local != NULL)
 		ire_delete(ire_local);
-	while (irep > ire_array) {
-		irep--;
-		if (*irep != NULL)
-			ire_delete(*irep);
+	if (ire_if != NULL)
+		ire_delete(ire_if);
+
+	rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
+	ire_local = ipif->ipif_ire_local;
+	ipif->ipif_ire_local = NULL;
+	ire_if = ipif->ipif_ire_if;
+	ipif->ipif_ire_if = NULL;
+	rw_exit(&ipst->ips_ill_g_lock);
+	if (ire_local != NULL) {
+		ire_delete(ire_local);
+		ire_refrele_notr(ire_local);
+	}
+	if (ire_if != NULL) {
+		ire_delete(ire_if);
+		ire_refrele_notr(ire_if);
 	}
 	(void) ip_srcid_remove(&ipif->ipif_v6lcl_addr, ipif->ipif_zoneid, ipst);
 
@@ -2679,22 +2693,13 @@
 {
 	ill_t		*ill = ipif->ipif_ill;
 	ip_stack_t	*ipst = ill->ill_ipst;
-	in6_addr_t	v6addr;
-	in6_addr_t	route_mask;
 	ire_t		*ire;
-	int		match_args;
-	boolean_t	loopback;
-
-	/* Check if this is a loopback interface */
-	loopback = (ipif->ipif_ill->ill_wq == NULL);
-
-	match_args = MATCH_IRE_TYPE | MATCH_IRE_ILL | MATCH_IRE_MASK |
-	    MATCH_IRE_ZONEONLY;
 
 	rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
-	if ((ire = ipif->ipif_ire_local) != NULL) {
-		ipif->ipif_ire_local = NULL;
-		rw_exit(&ipst->ips_ill_g_lock);
+	ire = ipif->ipif_ire_local;
+	ipif->ipif_ire_local = NULL;
+	rw_exit(&ipst->ips_ill_g_lock);
+	if (ire != NULL) {
 		/*
 		 * Move count to ipif so we don't loose the count due to
 		 * a down/up dance.
@@ -2703,47 +2708,14 @@
 
 		ire_delete(ire);
 		ire_refrele_notr(ire);
-	} else {
-		rw_exit(&ipst->ips_ill_g_lock);
 	}
-
-	match_args |= MATCH_IRE_GW;
-
-	/*
-	 * Delete the IRE_IF_RESOLVER or IRE_IF_NORESOLVER, as appropriate.
-	 * Note that atun interfaces have an all-zero ipif_v6subnet.
-	 * Thus we allow a zero subnet as long as the mask is non-zero.
-	 */
-	if (IS_UNDER_IPMP(ill))
-		match_args |= MATCH_IRE_TESTHIDDEN;
-
-	if (!loopback && !(ipif->ipif_flags & IPIF_NOXMIT) &&
-	    !(IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6subnet) &&
-	    IN6_IS_ADDR_UNSPECIFIED(&ipif->ipif_v6net_mask))) {
-		/* ipif_v6subnet is ipif_v6pp_dst_addr for pt-pt */
-		v6addr = ipif->ipif_v6subnet;
-
-		if (ipif->ipif_flags & IPIF_POINTOPOINT) {
-			route_mask = ipv6_all_ones;
-		} else {
-			route_mask = ipif->ipif_v6net_mask;
-		}
-
-		ire = ire_ftable_lookup_v6(
-		    &v6addr,			/* dest pref */
-		    &route_mask,		/* mask */
-		    &ipif->ipif_v6lcl_addr,	/* gateway */
-		    ill->ill_net_type,		/* IF_[NO]RESOLVER */
-		    ipif->ipif_ill,
-		    ipif->ipif_zoneid,
-		    NULL,
-		    match_args,
-		    0,
-		    ipst,
-		    NULL);
-		ASSERT(ire != NULL);
+	rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
+	ire = ipif->ipif_ire_if;
+	ipif->ipif_ire_if = NULL;
+	rw_exit(&ipst->ips_ill_g_lock);
+	if (ire != NULL) {
 		ire_delete(ire);
-		ire_refrele(ire);
+		ire_refrele_notr(ire);
 	}
 }
 
--- a/usr/src/uts/common/inet/ip/ip_if.c	Tue Nov 17 09:17:48 2009 -0800
+++ b/usr/src/uts/common/inet/ip/ip_if.c	Tue Nov 17 11:42:22 2009 -0800
@@ -13194,6 +13194,7 @@
 	ASSERT(!(ipif->ipif_flags & (IPIF_UP | IPIF_DUPLICATE)));
 	ASSERT(ipif->ipif_recovery_id == 0);
 	ASSERT(ipif->ipif_ire_local == NULL);
+	ASSERT(ipif->ipif_ire_if == NULL);
 
 	/* Free the memory. */
 	mi_free(ipif);
@@ -14332,6 +14333,7 @@
 	ipaddr_t	subnet_mask, route_mask;
 	int		err;
 	ire_t		*ire_local = NULL;	/* LOCAL or LOOPBACK */
+	ire_t		*ire_if = NULL;
 
 	if ((ipif->ipif_lcl_addr != INADDR_ANY) &&
 	    !(ipif->ipif_flags & IPIF_NOLOCAL)) {
@@ -14414,20 +14416,24 @@
 
 		ip1dbg(("ipif_add_ires: ipif 0x%p ill 0x%p "
 		    "creating if IRE ill_net_type 0x%x for 0x%x\n",
-		    (void *)ipif, (void *)ill,
-		    ill->ill_net_type,
+		    (void *)ipif, (void *)ill, ill->ill_net_type,
 		    ntohl(ipif->ipif_subnet)));
-		*irep++ = ire_create(
-		    (uchar_t *)&ipif->ipif_subnet,	/* dest address */
-		    (uchar_t *)&route_mask,		/* mask */
-		    (uchar_t *)&ipif->ipif_lcl_addr,	/* gateway */
-		    ill->ill_net_type,			/* IF_[NO]RESOLVER */
+		ire_if = ire_create(
+		    (uchar_t *)&ipif->ipif_subnet,
+		    (uchar_t *)&route_mask,
+		    (uchar_t *)&ipif->ipif_lcl_addr,
+		    ill->ill_net_type,
 		    ill,
 		    ipif->ipif_zoneid,
 		    ((ipif->ipif_flags & IPIF_PRIVATE) ?
 		    RTF_PRIVATE: 0) | RTF_KERNEL,
 		    NULL,
 		    ipst);
+		if (ire_if == NULL) {
+			ip1dbg(("ipif_up_done: NULL ire_if\n"));
+			err = ENOMEM;
+			goto bad;
+		}
 	}
 
 	/*
@@ -14479,28 +14485,59 @@
 	/*
 	 * Add in all newly created IREs.  ire_create_bcast() has
 	 * already checked for duplicates of the IRE_BROADCAST type.
-	 */
+	 * We add the IRE_INTERFACE before the IRE_LOCAL to ensure
+	 * that lookups find the IRE_LOCAL even if the IRE_INTERFACE is
+	 * a /32 route.
+	 */
+	if (ire_if != NULL) {
+		ire_if = ire_add(ire_if);
+		if (ire_if == NULL) {
+			err = ENOMEM;
+			goto bad2;
+		}
+#ifdef DEBUG
+		ire_refhold_notr(ire_if);
+		ire_refrele(ire_if);
+#endif
+	}
 	if (ire_local != NULL) {
 		ire_local = ire_add(ire_local);
+		if (ire_local == NULL) {
+			err = ENOMEM;
+			goto bad2;
+		}
 #ifdef DEBUG
-		if (ire_local != NULL) {
-			ire_refhold_notr(ire_local);
-			ire_refrele(ire_local);
-		}
+		ire_refhold_notr(ire_local);
+		ire_refrele(ire_local);
 #endif
 	}
-
 	rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
 	if (ire_local != NULL)
 		ipif->ipif_ire_local = ire_local;
+	if (ire_if != NULL)
+		ipif->ipif_ire_if = ire_if;
 	rw_exit(&ipst->ips_ill_g_lock);
 	ire_local = NULL;
+	ire_if = NULL;
+
+	/*
+	 * We first add all of them, and if that succeeds we refrele the
+	 * bunch. That enables us to delete all of them should any of the
+	 * ire_adds fail.
+	 */
+	for (irep1 = irep; irep1 > ire_array; ) {
+		irep1--;
+		ASSERT(!MUTEX_HELD(&((*irep1)->ire_ill->ill_lock)));
+		*irep1 = ire_add(*irep1);
+		if (*irep1 == NULL) {
+			err = ENOMEM;
+			goto bad2;
+		}
+	}
 
 	for (irep1 = irep; irep1 > ire_array; ) {
 		irep1--;
-		ASSERT(!MUTEX_HELD(&((*irep1)->ire_ill->ill_lock)));
 		/* refheld by ire_add. */
-		*irep1 = ire_add(*irep1);
 		if (*irep1 != NULL) {
 			ire_refrele(*irep1);
 			*irep1 = NULL;
@@ -14538,10 +14575,32 @@
 	}
 	return (0);
 
+bad2:
+	ill->ill_ipif_up_count--;
+	ipif->ipif_flags &= ~IPIF_UP;
+
 bad:
 	ip1dbg(("ipif_add_ires: FAILED \n"));
 	if (ire_local != NULL)
 		ire_delete(ire_local);
+	if (ire_if != NULL)
+		ire_delete(ire_if);
+
+	rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
+	ire_local = ipif->ipif_ire_local;
+	ipif->ipif_ire_local = NULL;
+	ire_if = ipif->ipif_ire_if;
+	ipif->ipif_ire_if = NULL;
+	rw_exit(&ipst->ips_ill_g_lock);
+	if (ire_local != NULL) {
+		ire_delete(ire_local);
+		ire_refrele_notr(ire_local);
+	}
+	if (ire_if != NULL) {
+		ire_delete(ire_if);
+		ire_refrele_notr(ire_if);
+	}
+
 	while (irep > ire_array) {
 		irep--;
 		if (*irep != NULL) {
@@ -14559,22 +14618,13 @@
 {
 	ill_t		*ill = ipif->ipif_ill;
 	ip_stack_t	*ipst = ill->ill_ipst;
-	ipaddr_t	net_mask = 0;
-	ipaddr_t	subnet_mask, route_mask;
-	int		match_args;
 	ire_t		*ire;
-	boolean_t	loopback;
-
-	/* Check if this is a loopback interface */
-	loopback = (ipif->ipif_ill->ill_wq == NULL);
-
-	match_args = MATCH_IRE_TYPE | MATCH_IRE_ILL | MATCH_IRE_MASK |
-	    MATCH_IRE_ZONEONLY;
 
 	rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
-	if ((ire = ipif->ipif_ire_local) != NULL) {
-		ipif->ipif_ire_local = NULL;
-		rw_exit(&ipst->ips_ill_g_lock);
+	ire = ipif->ipif_ire_local;
+	ipif->ipif_ire_local = NULL;
+	rw_exit(&ipst->ips_ill_g_lock);
+	if (ire != NULL) {
 		/*
 		 * Move count to ipif so we don't loose the count due to
 		 * a down/up dance.
@@ -14583,62 +14633,18 @@
 
 		ire_delete(ire);
 		ire_refrele_notr(ire);
-	} else {
-		rw_exit(&ipst->ips_ill_g_lock);
-	}
-
-	match_args |= MATCH_IRE_GW;
-
-	if ((ipif->ipif_lcl_addr != INADDR_ANY) &&
-	    !(ipif->ipif_flags & IPIF_NOLOCAL)) {
-		net_mask = ip_net_mask(ipif->ipif_lcl_addr);
-	} else {
-		net_mask = htonl(IN_CLASSA_NET);	/* fallback */
-	}
-
-	subnet_mask = ipif->ipif_net_mask;
-
-	/*
-	 * If mask was not specified, use natural netmask of
-	 * interface address. Also, store this mask back into the
-	 * ipif struct.
-	 */
-	if (subnet_mask == 0)
-		subnet_mask = net_mask;
-
-	/* Delete the IRE_IF_RESOLVER or IRE_IF_NORESOLVER, as appropriate. */
-	if (IS_UNDER_IPMP(ill))
-		match_args |= MATCH_IRE_TESTHIDDEN;
-
-	if (!loopback && !(ipif->ipif_flags & IPIF_NOXMIT) &&
-	    ipif->ipif_subnet != INADDR_ANY) {
-		/* ipif_subnet is ipif_pp_dst_addr for pt-pt */
-
-		if (ipif->ipif_flags & IPIF_POINTOPOINT) {
-			route_mask = IP_HOST_MASK;
-		} else {
-			route_mask = subnet_mask;
-		}
-
-		ire = ire_ftable_lookup_v4(
-		    ipif->ipif_subnet,			/* dest address */
-		    route_mask,				/* mask */
-		    ipif->ipif_lcl_addr,		/* gateway */
-		    ill->ill_net_type,			/* IF_[NO]RESOLVER */
-		    ill,
-		    ipif->ipif_zoneid,
-		    NULL,
-		    match_args,
-		    0,
-		    ipst,
-		    NULL);
-		ASSERT(ire != NULL);
+	}
+	rw_enter(&ipst->ips_ill_g_lock, RW_WRITER);
+	ire = ipif->ipif_ire_if;
+	ipif->ipif_ire_if = NULL;
+	rw_exit(&ipst->ips_ill_g_lock);
+	if (ire != NULL) {
 		ire_delete(ire);
-		ire_refrele(ire);
-	}
-
-	/*
-	 * Create any necessary broadcast IREs.
+		ire_refrele_notr(ire);
+	}
+
+	/*
+	 * Delete the broadcast IREs.
 	 */
 	if ((ipif->ipif_flags & IPIF_BROADCAST) &&
 	    !(ipif->ipif_flags & IPIF_NOXMIT))
--- a/usr/src/uts/common/inet/ip/ip_multi.c	Tue Nov 17 09:17:48 2009 -0800
+++ b/usr/src/uts/common/inet/ip/ip_multi.c	Tue Nov 17 11:42:22 2009 -0800
@@ -922,6 +922,9 @@
 
 	ASSERT(RW_WRITE_HELD(&ill->ill_mcast_lock));
 
+	if (IS_LOOPBACK(ill))
+		return (0);
+
 	if (!ill->ill_dl_up) {
 		/*
 		 * Nobody there. All multicast addresses will be re-joined
@@ -992,6 +995,9 @@
 
 	ASSERT(RW_WRITE_HELD(&ill->ill_mcast_lock));
 
+	if (IS_LOOPBACK(ill))
+		return;
+
 	if (!ill->ill_dl_up) {
 		/*
 		 * Nobody there. All multicast addresses will be re-joined
--- a/usr/src/uts/common/inet/ip/ip_ndp.c	Tue Nov 17 09:17:48 2009 -0800
+++ b/usr/src/uts/common/inet/ip/ip_ndp.c	Tue Nov 17 11:42:22 2009 -0800
@@ -98,9 +98,6 @@
 	NCE_F_AUTHORITY | NCE_F_PUBLISH | NCE_F_STATIC)
 
 /*
- * Function names with nce_ prefix are static while function
- * names with ndp_ prefix are used by rest of the IP.
- *
  * Lock ordering:
  *
  *	ndp_g_lock -> ill_lock -> ncec_lock
@@ -219,7 +216,6 @@
 
 /*
  * NDP Cache Entry creation routine.
- * Mapped entries will never do NUD .
  * This routine must always be called with ndp6->ndp_g_lock held.
  */
 int
@@ -1028,9 +1024,7 @@
 		}
 		ip_mcast_mapping(ill, (uchar_t *)dst, hw_addr);
 	} else {
-		/*
-		 * So no hw_addr is needed for IRE_IF_NORESOLVER.
-		 */
+		/* No hw_addr is needed for IRE_IF_NORESOLVER. */
 		hw_addr = NULL;
 	}
 	ASSERT((flags & NCE_F_MCAST) != 0);
@@ -1269,7 +1263,6 @@
 }
 
 /*
- *
  * Attempt to recover an IPv6 interface that's been shut down as a duplicate.
  * As long as someone else holds the address, the interface will stay down.
  * When that conflict goes away, the interface is brought back up.  This is
@@ -2350,13 +2343,18 @@
 		ncec->ncec_pcnt = ND_MAX_UNICAST_SOLICIT;
 		if (isv6) {
 			mutex_exit(&ncec->ncec_lock);
-			(void) ndp_xmit(src_ill, ND_NEIGHBOR_SOLICIT,
+			dropped = ndp_xmit(src_ill, ND_NEIGHBOR_SOLICIT,
 			    src_ill->ill_phys_addr,
 			    src_ill->ill_phys_addr_length,
 			    &sender6, &ncec->ncec_addr,
 			    NDP_UNICAST);
 		} else {
-			(void) arp_request(ncec, sender4, src_ill);
+			dropped = arp_request(ncec, sender4, src_ill);
+			mutex_exit(&ncec->ncec_lock);
+		}
+		if (!dropped) {
+			mutex_enter(&ncec->ncec_lock);
+			ncec->ncec_pcnt--;
 			mutex_exit(&ncec->ncec_lock);
 		}
 		if (ip_debug > 3) {
@@ -2391,10 +2389,9 @@
 				nce_dad(ncec, src_ill, B_TRUE);
 			} else {
 				ASSERT(src_ill != NULL);
-				ncec->ncec_pcnt--;
 				if (isv6) {
 					mutex_exit(&ncec->ncec_lock);
-					(void) ndp_xmit(src_ill,
+					dropped = ndp_xmit(src_ill,
 					    ND_NEIGHBOR_SOLICIT,
 					    src_ill->ill_phys_addr,
 					    src_ill->ill_phys_addr_length,
@@ -2406,10 +2403,15 @@
 					 * the ARP request will be sent out
 					 * as a link-layer unicast.
 					 */
-					(void) arp_request(ncec, sender4,
+					dropped = arp_request(ncec, sender4,
 					    src_ill);
 					mutex_exit(&ncec->ncec_lock);
 				}
+				if (!dropped) {
+					mutex_enter(&ncec->ncec_lock);
+					ncec->ncec_pcnt--;
+					mutex_exit(&ncec->ncec_lock);
+				}
 				nce_restart_timer(ncec,
 				    ill->ill_reachable_retrans_time);
 			}
@@ -3257,7 +3259,7 @@
 	 * fastpath ack is used to update the nce.
 	 */
 	if (ud_mp == NULL)
-		return (0); /* MH_WALK_CONTINUE */
+		return (0);
 	mp_rptr = mp->b_rptr;
 	cmplen = mp->b_wptr - mp_rptr;
 	ASSERT(cmplen >= 0);
@@ -3277,10 +3279,10 @@
 		nce_fp_marg->nce_fp_match_res = nce;
 		mutex_exit(&ncec->ncec_lock);
 		nce_refhold(nce);
-		return (1); /* MH_WALK_TERMINATE */
+		return (1);
 	}
 	mutex_exit(&ncec->ncec_lock);
-	return (0); /* MH_WALK_CONTINUE */
+	return (0);
 }
 
 /*
@@ -3635,7 +3637,6 @@
 
 /*
  * NDP Cache Entry creation routine for IPv4.
- * Mapped entries are handled in arp.
  * This routine must always be called with ndp4->ndp_g_lock held.
  * Prior to return, ncec_refcnt is incremented.
  *
--- a/usr/src/uts/common/inet/ip/tn_ipopt.c	Tue Nov 17 09:17:48 2009 -0800
+++ b/usr/src/uts/common/inet/ip/tn_ipopt.c	Tue Nov 17 11:42:22 2009 -0800
@@ -806,7 +806,7 @@
  * point to NULL.
  *
  * Returns:
- *      0		Label on (was|is now) correct
+ *      0		Label (was|is now) correct
  *      EACCES		The packet failed the remote host accreditation.
  *      ENOMEM		Memory allocation failure.
  *	EINVAL		Label cannot be computed
@@ -1356,7 +1356,7 @@
  * point to NULL.
  *
  * Returns:
- *      0		Label on (was|is now) correct
+ *      0		Label (was|is now) correct
  *      EACCES		The packet failed the remote host accreditation.
  *      ENOMEM		Memory allocation failure.
  *	EINVAL		Label cannot be computed
--- a/usr/src/uts/common/inet/ip/tnet.c	Tue Nov 17 09:17:48 2009 -0800
+++ b/usr/src/uts/common/inet/ip/tnet.c	Tue Nov 17 11:42:22 2009 -0800
@@ -829,18 +829,15 @@
 		if (credp == NULL)
 			return (B_FALSE);
 	} else {
-		cred_t	*newcr;
-
-		newcr = copycred_from_bslabel(ira->ira_cred, &sl, doi,
+		credp = copycred_from_bslabel(ira->ira_cred, &sl, doi,
 		    KM_NOSLEEP);
-		if (newcr == NULL)
+		if (credp == NULL)
 			return (B_FALSE);
 		if (ira->ira_free_flags & IRA_FREE_CRED) {
 			crfree(ira->ira_cred);
 			ira->ira_free_flags &= ~IRA_FREE_CRED;
 			ira->ira_cred = NULL;
 		}
-		credp = newcr;
 	}
 
 	/*
@@ -880,7 +877,7 @@
 	 *	- MLD packets. (Anything between ICMPv6 code 130 and 138.)
 	 *	- IGMP packets.
 	 *	- IPv4 router discovery.
-	 * In those cases ire_cred is NULL.
+	 * In those cases ira_cred is NULL.
 	 */
 	credp = ira->ira_cred;
 	if (credp == NULL)
--- a/usr/src/uts/common/inet/tcp/tcp.c	Tue Nov 17 09:17:48 2009 -0800
+++ b/usr/src/uts/common/inet/tcp/tcp.c	Tue Nov 17 11:42:22 2009 -0800
@@ -5290,8 +5290,6 @@
 
 	/*
 	 * Lookup the route to determine a source address and the uinfo.
-	 * If there was a source route we have tcp_ipha->ipha_dst as the first
-	 * hop.
 	 * Setup TCP parameters based on the metrics/DCE.
 	 */
 	error = tcp_set_destination(tcp);
@@ -5385,8 +5383,6 @@
 
 	/*
 	 * Lookup the route to determine a source address and the uinfo.
-	 * If there was a source route we have tcp_ip6h->ip6_dst as the first
-	 * hop.
 	 * Setup TCP parameters based on the metrics/DCE.
 	 */
 	error = tcp_set_destination(tcp);
@@ -5413,7 +5409,6 @@
 static int
 tcp_disconnect_common(tcp_t *tcp, t_scalar_t seqnum)
 {
-	tcp_t	*ltcp = NULL;
 	conn_t		*lconnp;
 	tcp_stack_t	*tcps = tcp->tcp_tcps;
 	conn_t		*connp = tcp->tcp_connp;
@@ -5424,7 +5419,7 @@
 	 * since the destination IP address is not valid, and it can
 	 * be the initialized value of all zeros (broadcast address).
 	 */
-	if (tcp->tcp_state <= TCPS_BOUND || tcp->tcp_hard_binding) {
+	if (tcp->tcp_state <= TCPS_BOUND) {
 		if (connp->conn_debug) {
 			(void) strlog(TCP_MOD_ID, 0, 1, SL_ERROR|SL_TRACE,
 			    "tcp_disconnect: bad state, %d", tcp->tcp_state);
@@ -5456,7 +5451,6 @@
 		ASSERT(tcp->tcp_time_wait_next == NULL);
 		ASSERT(tcp->tcp_time_wait_prev == NULL);
 		ASSERT(tcp->tcp_time_wait_expire == 0);
-		ltcp = NULL;
 		/*
 		 * If it used to be a listener, check to make sure no one else
 		 * has taken the port before switching back to LISTEN state.
@@ -5464,8 +5458,6 @@
 		if (connp->conn_ipversion == IPV4_VERSION) {
 			lconnp = ipcl_lookup_listener_v4(connp->conn_lport,
 			    connp->conn_laddr_v4, IPCL_ZONEID(connp), ipst);
-			if (lconnp != NULL)
-				ltcp = lconnp->conn_tcp;
 		} else {
 			uint_t ifindex = 0;
 
@@ -5476,16 +5468,14 @@
 			lconnp = ipcl_lookup_listener_v6(connp->conn_lport,
 			    &connp->conn_laddr_v6, ifindex, IPCL_ZONEID(connp),
 			    ipst);
-			if (lconnp != NULL)
-				ltcp = lconnp->conn_tcp;
-		}
-		if (tcp->tcp_conn_req_max && ltcp == NULL) {
+		}
+		if (tcp->tcp_conn_req_max && lconnp == NULL) {
 			tcp->tcp_state = TCPS_LISTEN;
 		} else if (old_state > TCPS_BOUND) {
 			tcp->tcp_conn_req_max = 0;
 			tcp->tcp_state = TCPS_BOUND;
 		}
-		if (ltcp != NULL)
+		if (lconnp != NULL)
 			CONN_DEC_REF(lconnp);
 		if (old_state == TCPS_SYN_SENT || old_state == TCPS_SYN_RCVD) {
 			BUMP_MIB(&tcps->tcps_mib, tcpAttemptFails);