Index: sys/netinet6/ip6_output.c =================================================================== --- sys/netinet6/ip6_output.c +++ sys/netinet6/ip6_output.c @@ -2249,10 +2249,12 @@ struct socket *so, struct sockopt *sopt) { struct ip6_pktopts *opt = *pktopt; + struct ip6_pktopts *tmp_opt = *pktopt; int error = 0; struct thread *td = sopt->sopt_td; + struct inpcb *in6p = sotoinpcb(so); - INP_WLOCK_ASSERT(sotoinpcb(so)); + INP_WLOCK_ASSERT(in6p); /* turn off any old options. */ if (opt) { @@ -2263,8 +2265,15 @@ printf("ip6_pcbopts: all specified options are cleared.\n"); #endif ip6_clearpktopts(opt, -1); - } else - opt = malloc(sizeof(*opt), M_IP6OPT, M_WAITOK); + } else { + INP_WUNLOCK(in6p); + tmp_opt = malloc(sizeof(*opt), M_IP6OPT, M_WAITOK); + INP_WLOCK(in6p); + if (!opt) + opt = tmp_opt; + else + free(tmp_opt, M_IP6OPT); + } *pktopt = NULL; if (!m || m->m_len == 0) {