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);