--- old/usr/src/uts/common/inet/ip.h	Mon Feb 13 14:38:29 2017
+++ new/usr/src/uts/common/inet/ip.h	Mon Feb 13 14:38:29 2017
@@ -24,7 +24,7 @@
  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
- * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
+ * Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #ifndef	_INET_IP_H
@@ -551,7 +551,7 @@
 #define	DCEF_DEFAULT		0x0001	/* Default DCE - no pmtu or uinfo */
 #define	DCEF_PMTU		0x0002	/* Different than interface MTU */
 #define	DCEF_UINFO		0x0004	/* dce_uinfo set */
-#define	DCEF_TOO_SMALL_PMTU	0x0008	/* Smaller than IPv4/IPv6 MIN */
+#define	DCEF_TOO_SMALL_PMTU	0x0008	/* Smaller than IPv4 MIN */
 
 #ifdef _KERNEL
 /*
--- old/usr/src/uts/common/inet/ip/ip.c	Mon Feb 13 14:38:29 2017
+++ new/usr/src/uts/common/inet/ip/ip.c	Mon Feb 13 14:38:29 2017
@@ -23,7 +23,7 @@
  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 1990 Mentat Inc.
  * Copyright (c) 2012 Joyent, Inc. All rights reserved.
- * Copyright (c) 2014, OmniTI Computer Consulting, Inc. All rights reserved.
+ * Copyright (c) 2017 OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -3858,10 +3858,9 @@
 	}
 
 	/*
-	 * After receiving an ICMPv6 "packet too big" message with a
-	 * MTU < 1280, and for multirouted IPv6 packets, the IP layer
-	 * will insert a 8-byte fragment header in every packet. We compensate
-	 * for those cases by returning a smaller path MTU to the ULP.
+	 * For multirouted IPv6 packets, the IP layer will insert a 8-byte
+	 * fragment header in every packet. We compensate for those cases by
+	 * returning a smaller path MTU to the ULP.
 	 *
 	 * In the case of CGTP then ip_output will add a fragment header.
 	 * Make sure there is room for it by telling a smaller number
@@ -3872,8 +3871,7 @@
 	 * which is the size of the packets it can send.
 	 */
 	if (!(ixa->ixa_flags & IXAF_IS_IPV4)) {
-		if ((dce->dce_flags & DCEF_TOO_SMALL_PMTU) ||
-		    (ire->ire_flags & RTF_MULTIRT) ||
+		if ((ire->ire_flags & RTF_MULTIRT) ||
 		    (ixa->ixa_flags & IXAF_MULTIRT_MULTICAST)) {
 			pmtu -= sizeof (ip6_frag_t);
 			ixa->ixa_flags |= IXAF_IPV6_ADD_FRAGHDR;
--- old/usr/src/uts/common/inet/ip/ip6.c	Mon Feb 13 14:38:30 2017
+++ new/usr/src/uts/common/inet/ip/ip6.c	Mon Feb 13 14:38:30 2017
@@ -21,6 +21,7 @@
 /*
  * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 1990 Mentat Inc.
+ * Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -682,6 +683,18 @@
 	ip6h = (ip6_t *)&icmp6[1];
 	final_dst = ip_get_dst_v6(ip6h, NULL, NULL);
 
+	mtu = ntohl(icmp6->icmp6_mtu);
+	if (mtu < IPV6_MIN_MTU) {
+		/*
+		 * RFC 8021 suggests to ignore messages where mtu is
+		 * less than the IPv6 minimum.
+		 */
+		ip1dbg(("Received mtu less than IPv6 "
+		    "min mtu %d: %d\n", IPV6_MIN_MTU, mtu));
+		DTRACE_PROBE1(icmp6__too__small__mtu, uint32_t, mtu);
+		return;
+	}
+
 	/*
 	 * For link local destinations matching simply on address is not
 	 * sufficient. Same link local addresses for different ILL's is
@@ -704,8 +717,6 @@
 		return;
 	}
 
-	mtu = ntohl(icmp6->icmp6_mtu);
-
 	mutex_enter(&dce->dce_lock);
 	if (dce->dce_flags & DCEF_PMTU)
 		old_max_frag = dce->dce_pmtu;
@@ -714,37 +725,15 @@
 	else
 		old_max_frag = ill->ill_mtu;
 
-	if (mtu < IPV6_MIN_MTU) {
-		ip1dbg(("Received mtu less than IPv6 "
-		    "min mtu %d: %d\n", IPV6_MIN_MTU, mtu));
-		mtu = IPV6_MIN_MTU;
-		/*
-		 * If an mtu less than IPv6 min mtu is received,
-		 * we must include a fragment header in
-		 * subsequent packets.
-		 */
-		dce->dce_flags |= DCEF_TOO_SMALL_PMTU;
-	} else {
-		dce->dce_flags &= ~DCEF_TOO_SMALL_PMTU;
-	}
 	ip1dbg(("Received mtu from router: %d\n", mtu));
+	DTRACE_PROBE1(icmp6__received__mtu, uint32_t, mtu);
 	dce->dce_pmtu = MIN(old_max_frag, mtu);
+	icmp6->icmp6_mtu = htonl(dce->dce_pmtu);
 
-	/* Prepare to send the new max frag size for the ULP. */
-	if (dce->dce_flags & DCEF_TOO_SMALL_PMTU) {
-		/*
-		 * If we need a fragment header in every packet
-		 * (above case or multirouting), make sure the
-		 * ULP takes it into account when computing the
-		 * payload size.
-		 */
-		icmp6->icmp6_mtu = htonl(dce->dce_pmtu - sizeof (ip6_frag_t));
-	} else {
-		icmp6->icmp6_mtu = htonl(dce->dce_pmtu);
-	}
 	/* We now have a PMTU for sure */
 	dce->dce_flags |= DCEF_PMTU;
 	dce->dce_last_change_time = TICK_TO_SEC(ddi_get_lbolt64());
+
 	mutex_exit(&dce->dce_lock);
 	/*
 	 * After dropping the lock the new value is visible to everyone.
--- old/usr/src/uts/common/inet/ip/ip6_output.c	Mon Feb 13 14:38:30 2017
+++ new/usr/src/uts/common/inet/ip/ip6_output.c	Mon Feb 13 14:38:30 2017
@@ -22,6 +22,7 @@
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved.
  */
 /* Copyright (c) 1990 Mentat Inc. */
 
@@ -245,7 +246,7 @@
 			 * Older than 20 minutes. Drop the path MTU information.
 			 */
 			mutex_enter(&dce->dce_lock);
-			dce->dce_flags &= ~(DCEF_PMTU|DCEF_TOO_SMALL_PMTU);
+			dce->dce_flags &= ~DCEF_PMTU;
 			dce->dce_last_change_time = TICK_TO_SEC(now);
 			mutex_exit(&dce->dce_lock);
 			dce_increment_generation(dce);
