Author: kp
Date: Fri Oct 18 03:36:26 2019
New Revision: 353715
URL: https://svnweb.freebsd.org/changeset/base/353715

Log:
  pf: Must be in NET_EPOCH to call icmp_error
  
  icmp_reflect(), called through icmp_error() requires us to be in NET_EPOCH.
  Failure to hold it leads to the following panic (with INVARIANTS):
  
    panic: Assertion in_epoch(net_epoch_preempt) failed at 
/usr/src/sys/netinet/ip_icmp.c:742
    cpuid = 2
    time = 1571233273
    KDB: stack backtrace:
    db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 
0xfffffe00e0977920
    vpanic() at vpanic+0x17e/frame 0xfffffe00e0977980
    panic() at panic+0x43/frame 0xfffffe00e09779e0
    icmp_reflect() at icmp_reflect+0x625/frame 0xfffffe00e0977aa0
    icmp_error() at icmp_error+0x720/frame 0xfffffe00e0977b10
    pf_intr() at pf_intr+0xd5/frame 0xfffffe00e0977b50
    ithread_loop() at ithread_loop+0x1c6/frame 0xfffffe00e0977bb0
    fork_exit() at fork_exit+0x80/frame 0xfffffe00e0977bf0
    fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe00e0977bf0
  
  Note that we now enter NET_EPOCH twice if we enter ip_output() from pf_intr(),
  but ip_output() will soon be converted to a function that requires epoch, so
  entering NET_EPOCH directly from pf_intr() makes more sense.
  
  Discussed with:       glebius@

Modified:
  head/sys/netpfil/pf/pf.c

Modified: head/sys/netpfil/pf/pf.c
==============================================================================
--- head/sys/netpfil/pf/pf.c    Fri Oct 18 03:01:21 2019        (r353714)
+++ head/sys/netpfil/pf/pf.c    Fri Oct 18 03:36:26 2019        (r353715)
@@ -1428,6 +1428,7 @@ pf_send(struct pf_send_entry *pfse)
 void
 pf_intr(void *v)
 {
+       struct epoch_tracker et;
        struct pf_send_head queue;
        struct pf_send_entry *pfse, *next;
 
@@ -1438,6 +1439,8 @@ pf_intr(void *v)
        STAILQ_INIT(&V_pf_sendqueue);
        PF_SENDQ_UNLOCK();
 
+       NET_EPOCH_ENTER(et);
+
        STAILQ_FOREACH_SAFE(pfse, &queue, pfse_next, next) {
                switch (pfse->pfse_type) {
 #ifdef INET
@@ -1464,6 +1467,7 @@ pf_intr(void *v)
                }
                free(pfse, M_PFTEMP);
        }
+       NET_EPOCH_EXIT(et);
        CURVNET_RESTORE();
 }
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to