Hrvoje Popovski reported the following panic:

  panic: kernel diagnostic assertion "sc->sc_carpdev != NULL" failed
  panic() at panic+0x128
  __assert() at __assert+0x24
  carp_output() at carp_output+0xde
  ip_output() at ip_output+0x948
  ipsp_process_done() at ipsp_process_done+0x254
  esp_output_cb() at esp_output_cb+0xe6
  taskq_thread(0) at taskq_thread+0x67


The KASSERT() in carp_output() is triggered when he deletes a trunk(4)
interface sitting under a carp(4) while IPsec packets are being
process/sent over the carp(4) interface.  The problem here is that the
carp(4) interface still exists but has no parent.  So as soon as
carp_output() is called we should drop the packets.

He confirmed the diff below works for him.

ok?

Index: netinet/ip_carp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_carp.c,v
retrieving revision 1.316
diff -u -p -r1.316 ip_carp.c
--- netinet/ip_carp.c   9 Oct 2017 08:35:38 -0000       1.316
+++ netinet/ip_carp.c   12 Oct 2017 09:44:30 -0000
@@ -2359,7 +2359,14 @@ carp_output(struct ifnet *ifp, struct mb
        struct srp_ref sr;
        int ismaster;
 
-       KASSERT(sc->sc_carpdev != NULL);
+       /*
+        * If the parent this carp(4) got destroyed while a
+        * packet was being processed, silently drop it.
+        */
+       if (sc->sc_carpdev == NULL) {
+               m_freem(m);
+               return (0);
+       }
 
        if (sc->cur_vhe == NULL) {
                vhe = SRPL_FIRST(&sr, &sc->carp_vhosts);

Reply via email to