Index: sys/netinet6/ip6_output.c
===================================================================
--- sys/netinet6/ip6_output.c
+++ sys/netinet6/ip6_output.c
@@ -2301,25 +2301,39 @@
 	return (ip6_setpktopt(optname, buf, len, opt, cred, 1, 0, uproto));
 }
 
+#define GET_PKTOPT_RLOCK_INP_RECHECK(in6p) do {					\
+	INP_RLOCK(in6p);							\
+	if (in6p->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {			\
+		INP_RUNLOCK(in6p);						\
+		free(optdata, M_TEMP);						\
+		return (ECONNRESET);						\
+	}									\
+	pktopt = in6p->in6p_outputopts;						\
+	prev_optdatalen = optdatalen;						\
+} while(0)
+
+#define GET_PKTOPT_LEN(field, lenexpr) do {					\
+	if (pktopt && pktopt->field)						\
+		optdatalen = ulmin(lenexpr, sopt->sopt_valsize);		\
+	else									\
+		optdatalen = 0;							\
+} while(0)
+
 #define GET_PKTOPT_VAR(field, lenexpr) do {					\
-	if (pktopt && pktopt->field) {						\
+	GET_PKTOPT_LEN(field, lenexpr);						\
+	while (optdatalen) {							\
 		INP_RUNLOCK(in6p);						\
-		optdata = malloc(sopt->sopt_valsize, M_TEMP, M_WAITOK);		\
+		optdata = malloc(optdatalen, M_TEMP, M_WAITOK);			\
 		malloc_optdata = true;						\
-		INP_RLOCK(in6p);						\
-		if (in6p->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {		\
-			INP_RUNLOCK(in6p);					\
-			free(optdata, M_TEMP);					\
-			return (ECONNRESET);					\
-		}								\
-		pktopt = in6p->in6p_outputopts;					\
-		if (pktopt && pktopt->field) {					\
-			optdatalen = min(lenexpr, sopt->sopt_valsize);		\
-			bcopy(&pktopt->field, optdata, optdatalen);		\
-		} else {							\
+		GET_PKTOPT_RLOCK_INP_RECHECK(in6p);				\
+		GET_PKTOPT_LEN(field, lenexpr);					\
+		if (optdatalen != prev_optdatalen) {				\
 			free(optdata, M_TEMP);					\
 			optdata = NULL;						\
 			malloc_optdata = false;					\
+		} else {							\
+			bcopy(&pktopt->field, optdata, optdatalen);		\
+			break;							\
 		}								\
 	}									\
 } while(0)
@@ -2336,6 +2350,7 @@
 	void *optdata = NULL;
 	bool malloc_optdata = false;
 	int optdatalen = 0;
+	int prev_optdatalen = 0;
 	int error = 0;
 	struct in6_pktinfo null_pktinfo;
 	int deftclass = 0, on;