Both walk the list of rulesets aka. anchors, first one yields a count,
second yields a specific's anchor name.

Same data access pattern, different copy out, basically.

pf_anchor_global are contained within pf_ioctl.c and pf_ruleset.c and
fully protected by the pf lock.

Same for pf_main_ruleset and its pf.c usage.

Running with extra asserts to double check works and handling 60k rules
an anchor works noticably faster:

        # jot -w 'pass proto tcp to port ' 60000 | pfctl -a test -o none -f -
        # time pfctl -a test -s r | wc -l
          60000
            0m02.10s real     0m00.40s user     0m01.70s system

Dropped from around 3.5s to around 2.0s for me.

Feedback? OK without asserts?

Either way, I'll wait for hackathon changes to go through snaps for a bit before
unlocking more of pf, just in case.


RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.1174
diff -u -p -r1.1174 pf.c
--- pf.c        28 Apr 2023 14:08:34 -0000      1.1174
+++ pf.c        29 Apr 2023 11:36:01 -0000
@@ -1370,6 +1370,8 @@ pf_state_import(const struct pfsync_stat
        int error = ENOMEM;
        int n = 0;
 
+       PF_ASSERT_LOCKED();
+
        if (sp->creatorid == 0) {
                DPFPRINTF(LOG_NOTICE, "%s: invalid creator id: %08x", __func__,
                    ntohl(sp->creatorid));
@@ -4269,6 +4271,8 @@ pf_test_rule(struct pf_pdesc *pd, struct
        int                      action = PF_DROP;
        struct pf_test_ctx       ctx;
        int                      rv;
+
+       PF_ASSERT_LOCKED();
 
        memset(&ctx, 0, sizeof(ctx));
        ctx.pd = pd;
Index: pf_ioctl.c
===================================================================
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.402
diff -u -p -r1.402 pf_ioctl.c
--- pf_ioctl.c  29 Apr 2023 10:25:32 -0000      1.402
+++ pf_ioctl.c  29 Apr 2023 11:36:01 -0000
@@ -858,6 +858,8 @@ pf_commit_rules(u_int32_t version, char 
        struct pf_rulequeue     *old_rules;
        u_int32_t                old_rcount;
 
+       PF_ASSERT_LOCKED();
+
        rs = pf_find_ruleset(anchor);
        if (rs == NULL || !rs->rules.inactive.open ||
            version != rs->rules.inactive.version)
@@ -2151,13 +2153,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                struct pf_ruleset       *ruleset;
                struct pf_anchor        *anchor;
 
-               NET_LOCK();
                PF_LOCK();
                pr->path[sizeof(pr->path) - 1] = '\0';
                if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
                        error = EINVAL;
                        PF_UNLOCK();
-                       NET_UNLOCK();
                        goto fail;
                }
                pr->nr = 0;
@@ -2172,7 +2172,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                                pr->nr++;
                }
                PF_UNLOCK();
-               NET_UNLOCK();
                break;
        }
 
@@ -2182,13 +2181,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                struct pf_anchor        *anchor;
                u_int32_t                nr = 0;
 
-               NET_LOCK();
                PF_LOCK();
                pr->path[sizeof(pr->path) - 1] = '\0';
                if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
                        error = EINVAL;
                        PF_UNLOCK();
-                       NET_UNLOCK();
                        goto fail;
                }
                pr->name[0] = '\0';
@@ -2210,7 +2207,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                                }
                }
                PF_UNLOCK();
-               NET_UNLOCK();
                if (!pr->name[0])
                        error = EBUSY;
                break;

Reply via email to