Kernel Panic
Kristof Provost
kristof at sigsegv.be
Tue Feb 27 04:40:30 UTC 2018
On 26 Feb 2018, at 17:06, Joe Jones wrote:
> Hi Kristof,
>
> we are not updating rules during the test although in production we
> will reload the rule set from time to time. We are constantly adding
> and removing from tables though, using the DIOCRADDADDRS and
> DIOCRDELADDRS ioctl, also DIOCKILLSTATES is being called a lot. These
> are all in response to RADIUS events. We tried using pfctl shell
> command rather than calling ioctl directly, to check that it wasn't a
> problem with how we are calling the ioctl.
>
That’s interesting.
The panic leads me to suspect something’s wrong with the
kt->pfrkt_ipv4->rt, which would explain why we get the unexpected NULL
result.
My first guess at the cause would be a race condition, where it’s
being modified (through one of the ioctls you do) while the
pfr_pool_get() is walking it.
I don’t immediately see where that’d happen though, because both
DIOCRADDADDRS and DIOCRDELADDRS take the rules lock (and pfr_pool_get()
takes it too).
It might be interesting to run this with these extra asserts (and be
sure to enable INVARIANTS).
diff --git a/sys/netpfil/pf/pf_table.c b/sys/netpfil/pf/pf_table.c
index 18342a94073..cad9b4ea89f 100644
--- a/sys/netpfil/pf/pf_table.c
+++ b/sys/netpfil/pf/pf_table.c
@@ -962,6 +962,8 @@ pfr_unroute_kentry(struct pfr_ktable *kt, struct
pfr_kentry *ke)
struct radix_node *rn;
struct radix_head *head = NULL;
+ PF_RULES_WASSERT();
+
if (ke->pfrke_af == AF_INET)
head = &kt->pfrkt_ip4->rh;
else if (ke->pfrke_af == AF_INET6)
@@ -1855,6 +1859,8 @@ pfr_destroy_ktable(struct pfr_ktable *kt, int
flushaddr)
{
struct pfr_kentryworkq addrq;
+ PF_RULES_WASSERT();
+
if (flushaddr) {
pfr_enqueue_addrs(kt, &addrq, NULL, 0);
pfr_clean_node_mask(kt, &addrq);
Regards,
Kristof
More information about the freebsd-pf
mailing list