On 06/12/16(Tue) 15:23, Alexander Bluhm wrote:
> On Mon, Nov 21, 2016 at 03:15:39PM +0100, Martin Pieuchot wrote:
> > naddy@ confirmed this diff fixes his tunnel mode setup, ok?
> 
> IPv6 neighbor discovery over IPsec does not work reliably.  It uses
> link-local, global and multicast addresses and depending on your
> flows and SA it either works or not.
> 
> The (sizeof(*hip6) < ln->ln_hold->m_len) check is wrong, so the
> code used saddr6 = NULL before.  With that and m_inject() it worked.
> We have a bug that was hiding a problem, but now the bug is not
> triggered anymore.
> 
> Then there is RFC 2461 written in this old IPv6 spirit.  If we have
> a bunch of address scopes, use the best matching address.  Then
> chances are high, that autoconfiguration and featuritis works.
> 
> SEND brings the issue to a new x509 certificate problem level.
> 
> I am not sure what to do.
> 
> mpi@ suggests to remove the IPv6 spirit and by accident it fixes
> naddy@'s problem.  I am a bit reluctant to remove it.  It is not a
> propper fix and may trigger problems elsewhere.
> 
> In my IPv6+IPsec setup I use a separate unencrypted network for
> IKE, ESP and corresponding ND packets.
> 
> For transparent mode I have no better solution than excluding ICMP6
> from the flow.
> 
> At least we should put something into the ipsec.conf(5) man page.

This is still an issue, multiple diffs are floating around, could we
commit a fix?

> > > Index: netinet6/nd6_nbr.c
> > > ===================================================================
> > > RCS file: /cvs/src/sys/netinet6/nd6_nbr.c,v
> > > retrieving revision 1.110
> > > diff -u -p -r1.110 nd6_nbr.c
> > > --- netinet6/nd6_nbr.c    23 Aug 2016 11:03:10 -0000      1.110
> > > +++ netinet6/nd6_nbr.c    4 Nov 2016 09:02:47 -0000
> > > @@ -433,54 +433,23 @@ nd6_ns_output(struct ifnet *ifp, struct 
> > >   }
> > >   ip6->ip6_dst = dst_sa.sin6_addr;
> > >   if (!dad) {
> > > -         /*
> > > -          * RFC2461 7.2.2:
> > > -          * "If the source address of the packet prompting the
> > > -          * solicitation is the same as one of the addresses assigned
> > > -          * to the outgoing interface, that address SHOULD be placed
> > > -          * in the IP Source Address of the outgoing solicitation.
> > > -          * Otherwise, any one of the addresses assigned to the
> > > -          * interface should be used."
> > > -          *
> > > -          * We use the source address for the prompting packet
> > > -          * (saddr6), if:
> > > -          * - saddr6 is given from the caller (by giving "ln"), and
> > > -          * - saddr6 belongs to the outgoing interface.
> > > -          * Otherwise, we perform the source address selection as usual.
> > > -          */
> > > -         struct ip6_hdr *hip6;           /* hold ip6 */
> > > -         struct in6_addr *saddr6;
> > > +          /* Perform source address selection. */
> > > +         struct rtentry *rt;
> > >  
> > > -         if (ln && ln->ln_hold) {
> > > -                 hip6 = mtod(ln->ln_hold, struct ip6_hdr *);
> > > -                 /* XXX pullup? */
> > > -                 if (sizeof(*hip6) < ln->ln_hold->m_len)
> > > -                         saddr6 = &hip6->ip6_src;
> > > -                 else
> > > -                         saddr6 = NULL;
> > > -         } else
> > > -                 saddr6 = NULL;
> > > -         if (saddr6 && in6ifa_ifpwithaddr(ifp, saddr6))
> > > -                 src_sa.sin6_addr = *saddr6;
> > > -         else {
> > > -                 struct rtentry *rt;
> > > +         rt = rtalloc(sin6tosa(&dst_sa), RT_RESOLVE,
> > > +             m->m_pkthdr.ph_rtableid);
> > > +         if (!rtisvalid(rt)) {
> > > +                 char addr[INET6_ADDRSTRLEN];
> > >  
> > > -                 rt = rtalloc(sin6tosa(&dst_sa), RT_RESOLVE,
> > > -                     m->m_pkthdr.ph_rtableid);
> > > -                 if (!rtisvalid(rt)) {
> > > -                         char addr[INET6_ADDRSTRLEN];
> > > -
> > > -                         nd6log((LOG_DEBUG,
> > > -                             "%s: source can't be determined: dst=%s\n",
> > > -                             __func__, inet_ntop(AF_INET6,
> > > -                             &dst_sa.sin6_addr, addr, sizeof(addr))));
> > > -                         rtfree(rt);
> > > -                         goto bad;
> > > -                 }
> > > -                 src_sa.sin6_addr =
> > > -                     ifatoia6(rt->rt_ifa)->ia_addr.sin6_addr;
> > > +                 nd6log((LOG_DEBUG,
> > > +                     "%s: source can't be determined: dst=%s\n",
> > > +                     __func__, inet_ntop(AF_INET6,
> > > +                     &dst_sa.sin6_addr, addr, sizeof(addr))));
> > >                   rtfree(rt);
> > > +                 goto bad;
> > >           }
> > > +         src_sa.sin6_addr = ifatoia6(rt->rt_ifa)->ia_addr.sin6_addr;
> > > +         rtfree(rt);
> > >   } else {
> > >           /*
> > >            * Source address for DAD packet must always be IPv6
> > > 
> 

Reply via email to