Hi, I have an IPsec setup that uses IPv6 with IPsec udpencap. In udpencap the "next protocol" field is set to UDP. After decapsulation that field is set to "IPIP". Unfortunately the udp decapsulation always uses the IPv4 offset of "next protocol". This means the other layers will write "IPIP" onto the wrong offset.
This is visible in tcpdump where the "next protocol" field has the old value of 17 (UDP), while 04 (IPIP) overwrites a part of the IPv6 source address. Patrick diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index ac66f0b..e27161e 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -183,7 +183,7 @@ udp_input(struct mbuf *m, ...) struct m_tag *mtag; struct tdb_ident *tdbi; struct tdb *tdb; - int error; + int error, protoff; #endif /* IPSEC */ #if defined(IPSEC) || defined(PIPEX) u_int32_t ipsecflowinfo = 0; @@ -202,12 +202,18 @@ udp_input(struct mbuf *m, ...) ip6 = NULL; #endif /* INET6 */ srcsa.sa.sa_family = AF_INET; +#ifdef IPSEC + protoff = offsetof(struct ip, ip_p); +#endif /* IPSEC */ break; #ifdef INET6 case 6: ip = NULL; ip6 = mtod(m, struct ip6_hdr *); srcsa.sa.sa_family = AF_INET6; +#ifdef IPSEC + protoff = offsetof(struct ip6_hdr, ip6_nxt); +#endif /* IPSEC */ break; #endif /* INET6 */ default: @@ -343,7 +349,7 @@ udp_input(struct mbuf *m, ...) skip -= sizeof(struct udphdr); espstat.esps_udpencin++; - ipsec_common_input(m, skip, offsetof(struct ip, ip_p), + ipsec_common_input(m, skip, protoff, srcsa.sa.sa_family, IPPROTO_ESP, 1); return; }