On Sat, Dec 10, 2016 at 12:32:56AM +0100, Patrick Wildt wrote: > 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.
OK bluhm@ > > 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; > }
