Date: Thu, 20 Nov 2014 18:49:11 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r274755 - in stable/10/sys: netinet6 netipsec Message-ID: <201411201849.sAKInBKM027715@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Thu Nov 20 18:49:11 2014 New Revision: 274755 URL: https://svnweb.freebsd.org/changeset/base/274755 Log: MFC r274434: Fix ips_out_nosa errors accounting. MFC r274454: ipsec6_process_packet is called before ip6_output fixes ip6_plen. Update ip6_plen before bpf processing to be able see correct value. MFC r274455: We don't return sp pointer, thus NULL assignment isn't needed. And reference to sp will be freed at the end. MFC r274465: Remove redundant ip6_plen initialization. MFC r274466: Strip IP header only when we act in tunnel mode. MFC r274467: Count statistics for the specific address family. Sponsored by: Yandex LLC Modified: stable/10/sys/netinet6/ip6_ipsec.c stable/10/sys/netipsec/ipsec_input.c stable/10/sys/netipsec/ipsec_output.c stable/10/sys/netipsec/xform_ipip.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/netinet6/ip6_ipsec.c ============================================================================== --- stable/10/sys/netinet6/ip6_ipsec.c Thu Nov 20 17:36:25 2014 (r274754) +++ stable/10/sys/netinet6/ip6_ipsec.c Thu Nov 20 18:49:11 2014 (r274755) @@ -272,11 +272,7 @@ ip6_ipsec_output(struct mbuf **m, struct /* * No IPsec processing is needed, free * reference to SP. - * - * NB: null pointer to avoid free at - * done: below. */ - KEY_FREESP(&sp), sp = NULL; goto done; } } Modified: stable/10/sys/netipsec/ipsec_input.c ============================================================================== --- stable/10/sys/netipsec/ipsec_input.c Thu Nov 20 17:36:25 2014 (r274754) +++ stable/10/sys/netipsec/ipsec_input.c Thu Nov 20 18:49:11 2014 (r274755) @@ -650,8 +650,8 @@ ipsec6_common_input_cb(struct mbuf *m, s ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); /* Save protocol */ - prot = 0; - m_copydata(m, protoff, 1, (unsigned char *) &prot); + m_copydata(m, protoff, 1, &nxt8); + prot = nxt8; #ifdef DEV_ENC encif->if_ipackets++; @@ -669,32 +669,33 @@ ipsec6_common_input_cb(struct mbuf *m, s return (error); #endif /* DEV_ENC */ -#ifdef INET - /* IP-in-IP encapsulation */ - if (prot == IPPROTO_IPIP) { - if (m->m_pkthdr.len - skip < sizeof(struct ip)) { + /* IPv6-in-IP encapsulation */ + if (prot == IPPROTO_IPV6 && + saidx->mode != IPSEC_MODE_TRANSPORT) { + if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { IPSEC_ISTAT(sproto, hdrops); error = EINVAL; goto bad; } - /* ipn will now contain the inner IPv4 header */ - m_striphdr(m, 0, skip); + /* ip6n will now contain the inner IPv6 header. */ + m_striphdr(m, 0, skip); skip = 0; #ifdef notyet /* * Check that the inner source address is the same as * the proxy address, if available. */ - if ((saidx->proxy.sa.sa_family == AF_INET && - saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY && - ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) || - (saidx->proxy.sa.sa_family != AF_INET && + if ((saidx->proxy.sa.sa_family == AF_INET6 && + !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) && + !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, + &saidx->proxy.sin6.sin6_addr)) || + (saidx->proxy.sa.sa_family != AF_INET6 && saidx->proxy.sa.sa_family != 0)) { DPRINTF(("%s: inner source address %s doesn't " "correspond to expected proxy source %s, " "SA %s/%08lx\n", __func__, - inet_ntoa4(ipn.ip_src), + ip6_sprintf(ip6buf, &ip6n.ip6_src), ipsec_address(&saidx->proxy), ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi))); @@ -705,33 +706,33 @@ ipsec6_common_input_cb(struct mbuf *m, s } #endif /* notyet */ } -#endif /* INET */ - /* IPv6-in-IP encapsulation */ - if (prot == IPPROTO_IPV6) { - if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { +#ifdef INET + /* IP-in-IP encapsulation */ + else if (prot == IPPROTO_IPIP && + saidx->mode != IPSEC_MODE_TRANSPORT) { + if (m->m_pkthdr.len - skip < sizeof(struct ip)) { IPSEC_ISTAT(sproto, hdrops); error = EINVAL; goto bad; } - /* ip6n will now contain the inner IPv6 header. */ - m_striphdr(m, 0, skip); + /* ipn will now contain the inner IPv4 header */ + m_striphdr(m, 0, skip); skip = 0; #ifdef notyet /* * Check that the inner source address is the same as * the proxy address, if available. */ - if ((saidx->proxy.sa.sa_family == AF_INET6 && - !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) && - !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, - &saidx->proxy.sin6.sin6_addr)) || - (saidx->proxy.sa.sa_family != AF_INET6 && + if ((saidx->proxy.sa.sa_family == AF_INET && + saidx->proxy.sin.sin_addr.s_addr != INADDR_ANY && + ipn.ip_src.s_addr != saidx->proxy.sin.sin_addr.s_addr) || + (saidx->proxy.sa.sa_family != AF_INET && saidx->proxy.sa.sa_family != 0)) { DPRINTF(("%s: inner source address %s doesn't " "correspond to expected proxy source %s, " "SA %s/%08lx\n", __func__, - ip6_sprintf(ip6buf, &ip6n.ip6_src), + inet_ntoa4(ipn.ip_src), ipsec_address(&saidx->proxy), ipsec_address(&saidx->dst), (u_long) ntohl(sav->spi))); @@ -742,6 +743,10 @@ ipsec6_common_input_cb(struct mbuf *m, s } #endif /* notyet */ } +#endif /* INET */ + else { + prot = IPPROTO_IPV6; /* for correct BPF processing */ + } /* * Record what we've done to the packet (under what SA it was @@ -792,10 +797,6 @@ ipsec6_common_input_cb(struct mbuf *m, s if ((error = ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_AFTER)) != 0) return (error); #endif /* DEV_ENC */ - /* Retrieve new protocol */ - /* We have stripped the IP6 header from the mbuf, we have to use the backuped proto value instead */ - nxt8 = prot; - /* * See the end of ip6_input for this logic. * IPPROTO_IPV[46] case will be processed just like other ones Modified: stable/10/sys/netipsec/ipsec_output.c ============================================================================== --- stable/10/sys/netipsec/ipsec_output.c Thu Nov 20 17:36:25 2014 (r274754) +++ stable/10/sys/netipsec/ipsec_output.c Thu Nov 20 18:49:11 2014 (r274755) @@ -164,11 +164,11 @@ ipsec_process_done(struct mbuf *m, struc * doing further processing. */ if (isr->next) { - IPSECSTAT_INC(ips_out_bundlesa); /* XXX-BZ currently only support same AF bundles. */ switch (saidx->dst.sa.sa_family) { #ifdef INET case AF_INET: + IPSECSTAT_INC(ips_out_bundlesa); return ipsec4_process_packet(m, isr->next, 0, 0); /* NOTREACHED */ #endif @@ -176,6 +176,7 @@ ipsec_process_done(struct mbuf *m, struc #ifdef INET6 case AF_INET6: /* XXX */ + IPSEC6STAT_INC(ips_out_bundlesa); return ipsec6_process_packet(m, isr->next); /* NOTREACHED */ #endif /* INET6 */ @@ -357,7 +358,16 @@ again: * this packet because it is responsibility for * upper layer to retransmit the packet. */ - IPSECSTAT_INC(ips_out_nosa); + switch(af) { + case AF_INET: + IPSECSTAT_INC(ips_out_nosa); + break; +#ifdef INET6 + case AF_INET6: + IPSEC6STAT_INC(ips_out_nosa); + break; +#endif + } goto bad; } sav = isr->sav; @@ -639,6 +649,8 @@ ipsec6_process_packet( sav = isr->sav; dst = &sav->sah->saidx.dst; + ip6 = mtod(m, struct ip6_hdr *); + ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); #ifdef DEV_ENC encif->if_opackets++; encif->if_obytes += m->m_pkthdr.len; @@ -650,8 +662,6 @@ ipsec6_process_packet( goto bad; #endif /* DEV_ENC */ - ip6 = mtod(m, struct ip6_hdr *); /* XXX */ - /* Do the appropriate encapsulation, if necessary */ if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */ dst->sa.sa_family != AF_INET6 || /* PF mismatch */ @@ -674,9 +684,6 @@ ipsec6_process_packet( goto bad; } - ip6 = mtod(m, struct ip6_hdr *); - ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); - /* Encapsulate the packet */ error = ipip_output(m, isr, &mp, 0, 0); if (mp == NULL && !error) { Modified: stable/10/sys/netipsec/xform_ipip.c ============================================================================== --- stable/10/sys/netipsec/xform_ipip.c Thu Nov 20 17:36:25 2014 (r274754) +++ stable/10/sys/netipsec/xform_ipip.c Thu Nov 20 18:49:11 2014 (r274755) @@ -486,12 +486,9 @@ ipip_output( ip6o->ip6_flow = 0; ip6o->ip6_vfc &= ~IPV6_VERSION_MASK; ip6o->ip6_vfc |= IPV6_VERSION; - ip6o->ip6_plen = htons(m->m_pkthdr.len); ip6o->ip6_hlim = IPV6_DEFHLIM; ip6o->ip6_dst = saidx->dst.sin6.sin6_addr; ip6o->ip6_src = saidx->src.sin6.sin6_addr; - - /* Fix payload length */ ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); switch (tp) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411201849.sAKInBKM027715>