On Sat, Jan 20, 2018 at 03:46:36PM +0100, Axel Rau wrote:
> this is a IPsec client, which crashes on reboot of the IPsec master (same 
> hardware and software as client).
> The IPsec tunnel connects some IP6 and IP4 public nets to the internet plus 
> some private nets.

Looks like this bug, already fixed in -current.

https://marc.info/?l=openbsd-cvs&m=150841096918888&w=2

You have configured a routing loop on the loopback interface, this
results in a kernel stack overrun.  You can try the attached diff
and see if helps.

bluhm

Index: net/if_loop.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_loop.c,v
retrieving revision 1.81
diff -u -p -r1.81 if_loop.c
--- net/if_loop.c       19 Apr 2017 15:21:54 -0000      1.81
+++ net/if_loop.c       22 Jan 2018 13:40:13 -0000
@@ -143,6 +143,7 @@
 int    loioctl(struct ifnet *, u_long, caddr_t);
 void   loopattach(int);
 void   lortrequest(struct ifnet *, int, struct rtentry *);
+int    loinput(struct ifnet *, struct mbuf *, void *);
 int    looutput(struct ifnet *,
            struct mbuf *, struct sockaddr *, struct rtentry *);
 
@@ -191,6 +192,7 @@ loop_clone_create(struct if_clone *ifc, 
 #if NBPFILTER > 0
        bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t));
 #endif
+       if_ih_insert(ifp, loinput, NULL);
        return (0);
 }
 
@@ -200,6 +202,7 @@ loop_clone_destroy(struct ifnet *ifp)
        if (ifp->if_index == rtable_loindex(ifp->if_rdomain))
                return (EPERM);
 
+       if_ih_remove(ifp, loinput, NULL);
        if_detach(ifp);
 
        free(ifp, M_DEVBUF, sizeof(*ifp));
@@ -207,11 +210,26 @@ loop_clone_destroy(struct ifnet *ifp)
 }
 
 int
+loinput(struct ifnet *ifp, struct mbuf *m, void *cookie)
+{
+       int error;
+
+       if ((m->m_flags & M_PKTHDR) == 0)
+               panic("%s: no header mbuf", __func__);
+
+       error = if_input_local(ifp, m, m->m_pkthdr.ph_family);
+       if (error)
+               ifp->if_ierrors++;
+
+       return (1);
+}
+
+int
 looutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
     struct rtentry *rt)
 {
        if ((m->m_flags & M_PKTHDR) == 0)
-               panic("looutput: no header mbuf");
+               panic("%s: no header mbuf", __func__);
 
        if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
                m_freem(m);
@@ -219,7 +237,16 @@ looutput(struct ifnet *ifp, struct mbuf 
                        rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
        }
 
-       return (if_input_local(ifp, m, dst->sa_family));
+       /* Use the quick path only once to avoid stack overflow. */
+       if ((m->m_flags & M_LOOP) == 0)
+               return (if_input_local(ifp, m, dst->sa_family));
+
+       m->m_pkthdr.ph_family = dst->sa_family;
+       if (mq_enqueue(&ifp->if_inputqueue, m))
+               return ENOBUFS;
+       task_add(softnettq, ifp->if_inputtask);
+
+       return (0);
 }
 
 void
Index: sys/mbuf.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/sys/mbuf.h,v
retrieving revision 1.231
diff -u -p -r1.231 mbuf.h
--- sys/mbuf.h  23 Jun 2017 11:18:12 -0000      1.231
+++ sys/mbuf.h  22 Jan 2018 13:40:13 -0000
@@ -134,6 +134,7 @@ struct      pkthdr {
        u_int                    ph_rtableid;   /* routing table id */
        u_int                    ph_ifidx;      /* rcv interface index */
        u_int8_t                 ph_loopcnt;    /* mbuf is looping in kernel */
+       u_int8_t                 ph_family;     /* af, used when queueing */
        struct pkthdr_pf         pf;
 };
 

Reply via email to