On Mon, Nov 07, 2022 at 04:09:44PM +0100, Alexandr Nedvedicky wrote:
> Hello,
> 
> resending the same diff, just updated to current.
> (pointed out by dlg@)

I like trading the rule garbage collector for a simple flag.

OK kn, but...

pfctl(8) already skips printing PFRULE_EXPIRED rules (unless -v),
so that is good, but previously this meant the rule would eventually
disappear.

No they remain and keep being printed in verbose mode without any
indication as to whether they're permanent or expired once rules.

So I think this should go in together with something in pfctl that
clearly shows expired rules as such.

> 
> thanks and
> regards
> sashan
> 
> --------8<---------------8<---------------8<------------------8<--------
> diff --git a/sys/net/pf.c b/sys/net/pf.c
> index 2c6124e74f2..6295b4eb9d7 100644
> --- a/sys/net/pf.c
> +++ b/sys/net/pf.c
> @@ -313,9 +313,6 @@ RB_GENERATE(pf_state_tree, pf_state_key, entry, 
> pf_state_compare_key);
>  RB_GENERATE(pf_state_tree_id, pf_state,
>      entry_id, pf_state_compare_id);
>  
> -SLIST_HEAD(pf_rule_gcl, pf_rule)     pf_rule_gcl =
> -     SLIST_HEAD_INITIALIZER(pf_rule_gcl);
> -
>  __inline int
>  pf_addr_compare(struct pf_addr *a, struct pf_addr *b, sa_family_t af)
>  {
> @@ -1478,23 +1475,6 @@ pf_state_import(const struct pfsync_state *sp, int 
> flags)
>  
>  /* END state table stuff */
>  
> -void
> -pf_purge_expired_rules(void)
> -{
> -     struct pf_rule  *r;
> -
> -     PF_ASSERT_LOCKED();
> -
> -     if (SLIST_EMPTY(&pf_rule_gcl))
> -             return;
> -
> -     while ((r = SLIST_FIRST(&pf_rule_gcl)) != NULL) {
> -             SLIST_REMOVE(&pf_rule_gcl, r, pf_rule, gcle);
> -             KASSERT(r->rule_flag & PFRULE_EXPIRED);
> -             pf_purge_rule(r);
> -     }
> -}
> -
>  void          pf_purge_states(void *);
>  struct task   pf_purge_states_task =
>                    TASK_INITIALIZER(pf_purge_states, NULL);
> @@ -1588,7 +1568,6 @@ pf_purge(void *null)
>       PF_LOCK();
>  
>       pf_purge_expired_src_nodes();
> -     pf_purge_expired_rules();
>  
>       PF_UNLOCK();
>  
> @@ -3916,8 +3895,11 @@ pf_match_rule(struct pf_test_ctx *ctx, struct 
> pf_ruleset *ruleset)
>       struct pf_rule  *save_a;
>       struct pf_ruleset       *save_aruleset;
>  
> +retry:
>       r = TAILQ_FIRST(ruleset->rules.active.ptr);
>       while (r != NULL) {
> +             PF_TEST_ATTRIB(r->rule_flag & PFRULE_EXPIRED,
> +                 TAILQ_NEXT(r, entries));
>               r->evaluations++;
>               PF_TEST_ATTRIB(
>                   (pfi_kif_match(r->kif, ctx->pd->kif) == r->ifnot),
> @@ -4042,6 +4024,19 @@ pf_match_rule(struct pf_test_ctx *ctx, struct 
> pf_ruleset *ruleset)
>               if (r->tag)
>                       ctx->tag = r->tag;
>               if (r->anchor == NULL) {
> +
> +                     if (r->rule_flag & PFRULE_ONCE) {
> +                             u_int32_t       rule_flag;
> +
> +                             rule_flag = r->rule_flag;
> +                             if (((rule_flag & PFRULE_EXPIRED) == 0) &&
> +                                 atomic_cas_uint(&r->rule_flag, rule_flag,
> +                                 rule_flag | PFRULE_EXPIRED) == rule_flag)
> +                                     r->exptime = gettime();
> +                             else
> +                                     goto retry;
> +                     }
> +
>                       if (r->action == PF_MATCH) {
>                               if ((ctx->ri = pool_get(&pf_rule_item_pl,
>                                   PR_NOWAIT)) == NULL) {
> @@ -4253,13 +4248,6 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, 
> struct pf_state **sm,
>       if (r->action == PF_DROP)
>               goto cleanup;
>  
> -     /*
> -      * If an expired "once" rule has not been purged, drop any new matching
> -      * packets.
> -      */
> -     if (r->rule_flag & PFRULE_EXPIRED)
> -             goto cleanup;
> -
>       pf_tag_packet(pd->m, ctx.tag, ctx.act.rtableid);
>       if (ctx.act.rtableid >= 0 &&
>           rtable_l2(ctx.act.rtableid) != pd->rdomain)
> @@ -4330,22 +4318,6 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, 
> struct pf_state **sm,
>               m_copyback(pd->m, pd->off, pd->hdrlen, &pd->hdr, M_NOWAIT);
>       }
>  
> -     if (r->rule_flag & PFRULE_ONCE) {
> -             u_int32_t       rule_flag;
> -
> -             /*
> -              * Use atomic_cas() to determine a clear winner, which will
> -              * insert an expired rule to gcl.
> -              */
> -             rule_flag = r->rule_flag;
> -             if (((rule_flag & PFRULE_EXPIRED) == 0) &&
> -                 atomic_cas_uint(&r->rule_flag, rule_flag,
> -                     rule_flag | PFRULE_EXPIRED) == rule_flag) {
> -                     r->exptime = gettime();
> -                     SLIST_INSERT_HEAD(&pf_rule_gcl, r, gcle);
> -             }
> -     }
> -
>  #if NPFSYNC > 0
>       if (*sm != NULL && !ISSET((*sm)->state_flags, PFSTATE_NOSYNC) &&
>           pd->dir == PF_OUT && pfsync_up()) {
> diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
> index b5d3261f8d1..6744fc022fb 100644
> --- a/sys/net/pf_ioctl.c
> +++ b/sys/net/pf_ioctl.c
> @@ -348,27 +348,6 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct 
> pf_rule *rule)
>       pool_put(&pf_rule_pl, rule);
>  }
>  
> -void
> -pf_purge_rule(struct pf_rule *rule)
> -{
> -     u_int32_t                nr = 0;
> -     struct pf_ruleset       *ruleset;
> -
> -     KASSERT((rule != NULL) && (rule->ruleset != NULL));
> -     ruleset = rule->ruleset;
> -
> -     pf_rm_rule(ruleset->rules.active.ptr, rule);
> -     ruleset->rules.active.rcount--;
> -     TAILQ_FOREACH(rule, ruleset->rules.active.ptr, entries)
> -             rule->nr = nr++;
> -     ruleset->rules.active.ticket++;
> -     pf_calc_skip_steps(ruleset->rules.active.ptr);
> -     pf_remove_if_empty_ruleset(ruleset);
> -
> -     if (ruleset == &pf_main_ruleset)
> -             pf_calc_chksum(ruleset);
> -}
> -
>  u_int16_t
>  tagname2tag(struct pf_tags *head, char *tagname, int create)
>  {
> @@ -837,9 +816,6 @@ pf_commit_rules(u_int32_t ticket, char *anchor)
>       struct pf_rulequeue     *old_rules;
>       u_int32_t                old_rcount;
>  
> -     /* Make sure any expired rules get removed from active rules first. */
> -     pf_purge_expired_rules();
> -
>       rs = pf_find_ruleset(anchor);
>       if (rs == NULL || !rs->rules.inactive.open ||
>           ticket != rs->rules.inactive.ticket)
> @@ -1447,7 +1423,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, 
> struct proc *p)
>               }
>               TAILQ_INSERT_TAIL(ruleset->rules.inactive.ptr,
>                   rule, entries);
> -             rule->ruleset = ruleset;
>               ruleset->rules.inactive.rcount++;
>               PF_UNLOCK();
>               NET_UNLOCK();
> @@ -1521,8 +1496,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, 
> struct proc *p)
>               pr->rule.anchor = NULL;
>               pr->rule.overload_tbl = NULL;
>               pr->rule.pktrate.limit /= PF_THRESHOLD_MULT;
> -             memset(&pr->rule.gcle, 0, sizeof(pr->rule.gcle));
> -             pr->rule.ruleset = NULL;
>               if (pf_anchor_copyout(ruleset, rule, pr)) {
>                       error = EBUSY;
>                       PF_UNLOCK();
> @@ -1713,7 +1686,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, 
> struct proc *p)
>                                   ruleset->rules.active.ptr,
>                                   oldrule, newrule, entries);
>                       ruleset->rules.active.rcount++;
> -                     newrule->ruleset = ruleset;
>               }
>  
>               nr = 0;
> diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
> index 91b309ab729..bf6a91131a8 100644
> --- a/sys/net/pfvar.h
> +++ b/sys/net/pfvar.h
> @@ -599,8 +599,6 @@ struct pf_rule {
>               u_int8_t                type;
>       }                       divert;
>  
> -     SLIST_ENTRY(pf_rule)     gcle;
> -     struct pf_ruleset       *ruleset;
>       time_t                   exptime;
>  };
>  
> 

Reply via email to