As reported recently by Jason Tubnor [0], calling ip_output() in
if_start() triggers splassert() because the NET_LOCK() might not
always be held.

dlg@'s TX mitigation diff also assumed the NET_LOCK() wasn't required
for if_start().  I believe this is the way to move forward.  if_start()
is a driver routine and should not rely on the stack lock.

So here's a diff to fix etherip(4) the same way I fixed gif(4).  Yes
this might add more latency due to an extra queue.  But I'd like to fix
this first then see how we can adapt if_enqueue()/if_input() to get rid
of extra queuing/latency for pseudo-interfaces.

ok?

[0] https://marc.info/?l=openbsd-bugs&m=151182901004017&w=2

Index: net/if_etherip.c
===================================================================
RCS file: /cvs/src/sys/net/if_etherip.c,v
retrieving revision 1.29
diff -u -p -r1.29 if_etherip.c
--- net/if_etherip.c    9 Jan 2018 15:24:24 -0000       1.29
+++ net/if_etherip.c    9 Jan 2018 17:58:28 -0000
@@ -394,7 +394,8 @@ ip_etherip_output(struct ifnet *ifp, str
        etheripstat_pkt(etherips_opackets, etherips_obytes, m->m_pkthdr.len -
            (sizeof(struct ip) + sizeof(struct etherip_header)));
 
-       return ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL, 0);
+       ip_send(m);
+       return (0);
 }
 
 int
@@ -546,7 +547,8 @@ ip6_etherip_output(struct ifnet *ifp, st
        etheripstat_pkt(etherips_opackets, etherips_obytes, m->m_pkthdr.len -
            (sizeof(struct ip6_hdr) + sizeof(struct etherip_header)));
 
-       return ip6_output(m, 0, NULL, IPV6_MINMTU, 0, NULL);
+       ip6_send(m);
+       return (0);
 
 drop:
        m_freem(m);

Reply via email to