diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -415,17 +415,13 @@ } NET_EPOCH_EXIT(et); - if (error != 0) - m_freem(m); - return (error); } /* * Sends mbuf @m to the wire via ip[6]_output(). * - * Returns 0 on success, @m is consumed. - * On failure, returns error code. It is caller responsibility to free @m. + * Returns 0 on success or an errno value on failure. @m is always consumed. */ static int div_output_outbound(int family, struct socket *so, struct mbuf *m) @@ -448,6 +444,7 @@ inp->inp_options != NULL) || ((u_short)ntohs(ip->ip_len) > m->m_pkthdr.len)) { INP_RUNLOCK(inp); + m_freem(m); return (EINVAL); } break; @@ -459,6 +456,7 @@ /* Don't allow packet length sizes that will crash */ if (((u_short)ntohs(ip6->ip6_plen) > m->m_pkthdr.len)) { INP_RUNLOCK(inp); + m_freem(m); return (EINVAL); } break; @@ -498,6 +496,7 @@ options = m_dup(inp->inp_options, M_NOWAIT); if (options == NULL) { INP_RUNLOCK(inp); + m_freem(m); return (ENOBUFS); } } @@ -525,8 +524,7 @@ /* * Schedules mbuf @m for local processing via IPv4/IPv6 netisr queue. * - * Returns 0 on success, @m is consumed. - * Returns error code on failure. It is caller responsibility to free @m. + * Returns 0 on success or an errno value on failure. @m is always consumed. */ static int div_output_inbound(int family, struct socket *so, struct mbuf *m, @@ -546,8 +544,10 @@ bzero(sin->sin_zero, sizeof(sin->sin_zero)); sin->sin_port = 0; ifa = ifa_ifwithaddr((struct sockaddr *) sin); - if (ifa == NULL) + if (ifa == NULL) { + m_freem(m); return (EADDRNOTAVAIL); + } m->m_pkthdr.rcvif = ifa->ifa_ifp; } #ifdef MAC @@ -573,6 +573,7 @@ break; #endif default: + m_freem(m); return (EINVAL); }