Hi Patrick,

I think your revised diff should be committed.  Any objections?

On Fri, Feb 26, 2016 at 15:12 +0100, Patrick Wildt wrote:
> Bump with updated diff, now that tree is unlocked again.
> 
> Patrick
> 
> diff --git sys/netinet/ipsec_output.c sys/netinet/ipsec_output.c
> index 91c319f..18a3f57 100644
> --- sys/netinet/ipsec_output.c
> +++ sys/netinet/ipsec_output.c
> @@ -375,13 +375,30 @@ ipsp_process_done(struct mbuf *m, struct tdb *tdb)
>       if ((tdb->tdb_flags & TDBF_UDPENCAP) != 0) {
>               struct mbuf *mi;
>               struct udphdr *uh;
> +             int iphlen;
>  
>               if (!udpencap_enable || !udpencap_port) {
>                       m_freem(m);
>                       return ENXIO;
>               }
> -             mi = m_inject(m, sizeof(struct ip), sizeof(struct udphdr),
> -                 M_DONTWAIT);
> +
> +             switch (tdb->tdb_dst.sa.sa_family) {
> +             case AF_INET:
> +                     iphlen = sizeof(struct ip);
> +                     break;
> +#ifdef INET6
> +             case AF_INET6:
> +                     iphlen = sizeof(struct ip6_hdr);
> +                     break;
> +#endif /* INET6 */
> +             default:
> +                     m_freem(m);
> +                     DPRINTF(("ipsp_process_done(): unknown protocol family "
> +                         "(%d)\n", tdb->tdb_dst.sa.sa_family));
> +                     return ENXIO;
> +             }
> +
> +             mi = m_inject(m, iphlen, sizeof(struct udphdr), M_DONTWAIT);
>               if (mi == NULL) {
>                       m_freem(m);
>                       return ENOMEM;
> @@ -391,8 +408,13 @@ ipsp_process_done(struct mbuf *m, struct tdb *tdb)
>               if (tdb->tdb_udpencap_port)
>                       uh->uh_dport = tdb->tdb_udpencap_port;
>  
> -             uh->uh_ulen = htons(m->m_pkthdr.len - sizeof(struct ip));
> +             uh->uh_ulen = htons(m->m_pkthdr.len - iphlen);
>               uh->uh_sum = 0;
> +#ifdef INET6
> +             if (tdb->tdb_dst.sa.sa_family == AF_INET6)
> +                     uh->uh_sum = in6_cksum(m, IPPROTO_UDP,
> +                         iphlen, m->m_pkthdr.len - iphlen);
> +#endif /* INET6 */
>               espstat.esps_udpencout++;
>       }
>  
> 
> 
> On Sun, Feb 21, 2016 at 09:14:13PM +0100, Patrick Wildt wrote:
> > Hi,
> > 
> > debugging my setup at home I realized that NAT-T on IPv6 is broken.
> > I know that NAT in IPv6 sucks, but apparently my dsl modem does not
> > reliably forward ESP packets, so I use NAT-T instead... *sigh*
> > 
> > Moving that setup from IPv4 to IPv6 I noticed that pf was blocking
> > outgoing packets and its src/dst addresses were broken.  Digging
> > in the code I saw that the UDP header injection is written only
> > for IPv4.
> > 
> > This diff was written for and tested on OpenBSD 5.8, then ported
> > to -current.  The only difference in the tested diff and this
> > diff is that m_makespace() was replaced by m_inject().
> > 
> > Patrick
> > 
> > diff --git sys/netinet/ipsec_output.c sys/netinet/ipsec_output.c
> > index 91c319f..372d8d4 100644
> > --- sys/netinet/ipsec_output.c
> > +++ sys/netinet/ipsec_output.c
> > @@ -375,13 +375,30 @@ ipsp_process_done(struct mbuf *m, struct tdb *tdb)
> >     if ((tdb->tdb_flags & TDBF_UDPENCAP) != 0) {
> >             struct mbuf *mi;
> >             struct udphdr *uh;
> > +           int iphlen;
> >  
> >             if (!udpencap_enable || !udpencap_port) {
> >                     m_freem(m);
> >                     return ENXIO;
> >             }
> > -           mi = m_inject(m, sizeof(struct ip), sizeof(struct udphdr),
> > -               M_DONTWAIT);
> > +
> > +           switch (tdb->tdb_dst.sa.sa_family) {
> > +           case AF_INET:
> > +                   iphlen = sizeof(struct ip);
> > +                   break;
> > +#ifdef INET6
> > +           case AF_INET6:
> > +                   iphlen = sizeof(struct ip6_hdr);
> > +                   break;
> > +#endif /* INET6 */
> > +           default:
> > +                   m_freem(m);
> > +                   DPRINTF(("ipsp_process_done(): unknown protocol family 
> > (%d)\n",
> > +                       tdb->tdb_dst.sa.sa_family));
> > +                   return ENXIO;
> > +           }
> > +
> > +           mi = m_inject(m, iphlen, sizeof(struct udphdr), M_DONTWAIT);
> >             if (mi == NULL) {
> >                     m_freem(m);
> >                     return ENOMEM;
> > @@ -391,8 +408,11 @@ ipsp_process_done(struct mbuf *m, struct tdb *tdb)
> >             if (tdb->tdb_udpencap_port)
> >                     uh->uh_dport = tdb->tdb_udpencap_port;
> >  
> > -           uh->uh_ulen = htons(m->m_pkthdr.len - sizeof(struct ip));
> > +           uh->uh_ulen = htons(m->m_pkthdr.len - iphlen);
> >             uh->uh_sum = 0;
> > +           if (tdb->tdb_dst.sa.sa_family == AF_INET6)
> > +                   uh->uh_sum = in6_cksum(m, IPPROTO_UDP,
> > +                       iphlen, m->m_pkthdr.len - iphlen);
> >             espstat.esps_udpencout++;
> >     }
> >  
> 

Reply via email to