PERFORCE change 1202823 for review
John-Mark Gurney
jmg at FreeBSD.org
Fri Nov 14 18:20:10 UTC 2014
http://p4web.freebsd.org/@@1202823?ac=10
Change 1202823 by jmg at jmg_carbon2 on 2014/11/14 18:19:46
fix from ae for fixing IPv6 transport ICMP...
Affected files ...
.. //depot/projects/opencrypto/sys/netipsec/ipsec_input.c#4 edit
Differences ...
==== //depot/projects/opencrypto/sys/netipsec/ipsec_input.c#4 (text+ko) ====
@@ -432,7 +432,7 @@
}
#ifdef INET6
/* IPv6-in-IP encapsulation. */
- if (prot == IPPROTO_IPV6 &&
+ else if (prot == IPPROTO_IPV6 &&
saidx->mode != IPSEC_MODE_TRANSPORT) {
if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) {
@@ -469,6 +469,15 @@
#endif /* notyet */
}
#endif /* INET6 */
+ else if (prot != IPPROTO_IPV6 && saidx->mode == IPSEC_MODE_ANY) {
+ /*
+ * When mode is wildcard, inner protocol is IPv6 and
+ * we have no INET6 support - drop this packet a bit later.
+ * In other cases we assume transport mode and outer
+ * header was already stripped in xform_xxx_cb.
+ */
+ prot = IPPROTO_IPIP;
+ }
/*
* Record what we've done to the packet (under what SA it was
@@ -664,11 +673,11 @@
}
ip6 = mtod(m, struct ip6_hdr *);
- ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr));
+ ip6->ip6_plen = htons(m->m_pkthdr.len);
/* Save protocol */
- prot = 0;
- m_copydata(m, protoff, 1, (unsigned char *) &prot);
+ m_copydata(m, protoff, 1, &nxt8);
+ prot = nxt8;
#ifdef DEV_ENC
if_inc_counter(encif, IFCOUNTER_IPACKETS, 1);
@@ -686,32 +695,33 @@
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)));
@@ -722,33 +732,33 @@
}
#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)));
@@ -759,6 +769,10 @@
}
#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
@@ -809,10 +823,6 @@
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
More information about the p4-projects
mailing list