diff options
author | ae <ae@FreeBSD.org> | 2014-11-20 18:49:11 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2014-11-20 18:49:11 +0000 |
commit | b634635a73c9af335c794449b95fa6c02663e42a (patch) | |
tree | 06147572ea2d690b79a67d3d15b531d01d0db0fa /sys/netipsec/ipsec_input.c | |
parent | 84d8d047ba855b0e24f1009141363b9d5e1dcf29 (diff) | |
download | FreeBSD-src-b634635a73c9af335c794449b95fa6c02663e42a.zip FreeBSD-src-b634635a73c9af335c794449b95fa6c02663e42a.tar.gz |
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
Diffstat (limited to 'sys/netipsec/ipsec_input.c')
-rw-r--r-- | sys/netipsec/ipsec_input.c | 59 |
1 files changed, 30 insertions, 29 deletions
diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c index c098a16..199a3bf 100644 --- a/sys/netipsec/ipsec_input.c +++ b/sys/netipsec/ipsec_input.c @@ -650,8 +650,8 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto 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, struct secasvar *sav, int skip, int proto 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, struct secasvar *sav, int skip, int proto } #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, struct secasvar *sav, int skip, int proto } #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, struct secasvar *sav, int skip, int proto 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 |