Hello,

> 
> For now the code gets more as we have two ways to iterate over the
> tree.  When you remove the additional work queues I expect many -
> diffs.  So if this code dupliation is temporary, this aproach is
> fine for me.

yes code duplication is temporary, I'd like to kill work queues.

> >  #define pfrw_dyn   pfrw_1.pfrw1_dyn
> > +#define    pfrw_tzero      pfrw_1.pfrw1_clstat.tzero
> > +#define    pfrw_negchange  pfrw_1.pfrw1_clstat.negchange
> >  #define pfrw_cnt   pfrw_free
> 
> Use space instead of tab after the define.  Otherwise it is incosistent
> and the diff looks ugly.
thanks for catching that.

I will postpone commit for few more days. Just to give a chance other folks
to give OK / !OK

I also would like to finish prototype of pfr_set_addrs(), which still prevents
me from removing work queues in my OpenBSD branch.

thanks and
regards
sasha

--------8<---------------8<---------------8<------------------8<--------
Index: pf_table.c
===================================================================
RCS file: /cvs/src/sys/net/pf_table.c,v
retrieving revision 1.116
diff -u -p -r1.116 pf_table.c
--- pf_table.c  3 Nov 2015 22:10:33 -0000       1.116
+++ pf_table.c  9 Nov 2015 19:24:52 -0000
@@ -107,7 +107,9 @@ struct pfr_walktree {
                PFRW_GET_ADDRS,
                PFRW_GET_ASTATS,
                PFRW_POOL_GET,
-               PFRW_DYNADDR_UPDATE
+               PFRW_DYNADDR_UPDATE,
+               PFRW_WININFO_UPDATE,
+               PFRW_CLSTAT
        }        pfrw_op;
        union {
                struct pfr_addr         *pfrw1_addr;
@@ -115,15 +117,22 @@ struct pfr_walktree {
                struct pfr_kentryworkq  *pfrw1_workq;
                struct pfr_kentry       *pfrw1_kentry;
                struct pfi_dynaddr      *pfrw1_dyn;
+               struct {
+                       time_t  tzero;
+                       int     negchange;
+               }                        pfrw1_clstat;
        }        pfrw_1;
        int      pfrw_free;
        int      pfrw_flags;
+       struct pfr_ktable       *pfrw_kt;
 };
 #define pfrw_addr      pfrw_1.pfrw1_addr
 #define pfrw_astats    pfrw_1.pfrw1_astats
 #define pfrw_workq     pfrw_1.pfrw1_workq
 #define pfrw_kentry    pfrw_1.pfrw1_kentry
 #define pfrw_dyn       pfrw_1.pfrw1_dyn
+#define pfrw_tzero     pfrw_1.pfrw1_clstat.tzero
+#define pfrw_negchange pfrw_1.pfrw1_clstat.negchange
 #define pfrw_cnt       pfrw_free
 
 #define senderr(e)     do { rv = (e); goto _bad; } while (0)
@@ -156,6 +165,8 @@ void                         pfr_remove_kentries(struct 
pfr_k
                            struct pfr_kentryworkq *);
 void                    pfr_clstats_kentries(struct pfr_kentryworkq *, time_t,
                            int);
+void                    pfr_clstats_kentries_pfrw(struct pfr_ktable *, time_t,
+                           int);
 void                    pfr_reset_feedback(struct pfr_addr *, int, int);
 void                    pfr_prepare_network(union sockaddr_union *, int, int);
 int                     pfr_route_kentry(struct pfr_ktable *,
@@ -181,6 +192,7 @@ int                  pfr_ktable_compare(struct pfr_kta
                            struct pfr_ktable *);
 void                    pfr_ktable_winfo_update(struct pfr_ktable *,
                            struct pfr_kentry *);
+void                    pfr_ktable_winfo_update_sum(struct pfr_ktable *);
 struct pfr_ktable      *pfr_lookup_table(struct pfr_table *);
 void                    pfr_clean_node_mask(struct pfr_ktable *,
                            struct pfr_kentryworkq *);
@@ -189,6 +201,8 @@ int                  pfr_skip_table(struct pfr_table *
                            struct pfr_ktable *, int);
 struct pfr_kentry      *pfr_kentry_byidx(struct pfr_ktable *, int, int);
 int                     pfr_islinklocal(sa_family_t, struct pf_addr *);
+void                    pfr_walk(struct pfr_ktable *, struct pfr_walktree *,
+                           const char *);
 
 RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
 RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
@@ -631,7 +645,6 @@ pfr_get_astats(struct pfr_table *tbl, st
 {
        struct pfr_ktable       *kt;
        struct pfr_walktree      w;
-       struct pfr_kentryworkq   workq;
        int                      rv;
        time_t                   tzero = time_second;
 
@@ -653,10 +666,8 @@ pfr_get_astats(struct pfr_table *tbl, st
        rv = rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
        if (!rv)
                rv = rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-       if (!rv && (flags & PFR_FLAG_CLSTATS)) {
-               pfr_enqueue_addrs(kt, &workq, NULL, 0);
-               pfr_clstats_kentries(&workq, tzero, 0);
-       }
+       if (!rv && (flags & PFR_FLAG_CLSTATS))
+               pfr_clstats_kentries_pfrw(kt, tzero, 0);
        if (rv)
                return (rv);
 
@@ -954,7 +965,6 @@ pfr_remove_kentries(struct pfr_ktable *k
     struct pfr_kentryworkq *workq)
 {
        struct pfr_kentry       *p;
-       struct pfr_kentryworkq   addrq;
        int                      n = 0;
 
        SLIST_FOREACH(p, workq, pfrke_workq) {
@@ -971,9 +981,7 @@ pfr_remove_kentries(struct pfr_ktable *k
        if (kt->pfrkt_refcntcost > 0) {
                kt->pfrkt_gcdweight = 0;
                kt->pfrkt_maxweight = 1;
-               pfr_enqueue_addrs(kt, &addrq, NULL, 0);
-               SLIST_FOREACH(p, &addrq, pfrke_workq)
-                       pfr_ktable_winfo_update(kt, p);
+               pfr_ktable_winfo_update_sum(kt);
        }
 }
 
@@ -989,6 +997,18 @@ pfr_clean_node_mask(struct pfr_ktable *k
 }
 
 void
+pfr_clstats_kentries_pfrw(struct pfr_ktable *kt, time_t tzero, int negchange)
+{
+       struct pfr_walktree     w;
+
+       bzero(&w, sizeof(pfr_walktree));
+       w.pfrw_op = PFRW_CLSTAT;
+       w.pfrw_tzero = tzero;
+       w.pfrw_negchange = negchange;
+       pfr_walk(kt, &w, "pfr_clstats_kentries_pfrw");
+}
+
+void
 pfr_clstats_kentries(struct pfr_kentryworkq *workq, time_t tzero, int 
negchange)
 {
        struct pfr_kentry       *p;
@@ -1256,6 +1276,20 @@ pfr_walktree(struct radix_node *rn, void
                        unhandled_af(ke->pfrke_af);
                }
                break;
+       case PFRW_WININFO_UPDATE:
+               pfr_ktable_winfo_update(w->pfrw_kt, ke);
+               break;
+       case PFRW_CLSTAT:
+               s = splsoftnet();
+               if (w->pfrw_negchange)
+                       ke->pfrke_flags ^= PFRKE_FLAG_NOT;
+               if (ke->pfrke_counters) {
+                       pool_put(&pfr_kcounters_pl, ke->pfrke_counters);
+                       ke->pfrke_counters = NULL;
+               }
+               splx(s);
+               ke->pfrke_tzero = w->pfrw_tzero;
+               break;
        }
        return (0);
 }
@@ -1993,13 +2027,11 @@ pfr_clstats_ktables(struct pfr_ktablewor
 void
 pfr_clstats_ktable(struct pfr_ktable *kt, time_t tzero, int recurse)
 {
-       struct pfr_kentryworkq   addrq;
        int                      s;
 
-       if (recurse) {
-               pfr_enqueue_addrs(kt, &addrq, NULL, 0);
-               pfr_clstats_kentries(&addrq, tzero, 0);
-       }
+       if (recurse)
+               pfr_clstats_kentries_pfrw(kt, tzero, 0);
+
        s = splsoftnet();
        bzero(kt->pfrkt_packets, sizeof(kt->pfrkt_packets));
        bzero(kt->pfrkt_bytes, sizeof(kt->pfrkt_bytes));
@@ -2554,6 +2586,21 @@ pfr_dynaddr_update(struct pfr_ktable *kt
 }
 
 void
+pfr_walk(struct pfr_ktable *kt, struct pfr_walktree *pfrw, const char *caller)
+{
+       if (kt->pfrkt_ip4 != NULL)
+               if (rn_walktree(kt->pfrkt_ip4, pfr_walktree, pfrw))
+                       DPFPRINTF(LOG_ERR,
+                           "pfr_walk: on behalf of %s IPv4 walktree failed.",
+                           caller);
+       if (kt->pfrkt_ip6 != NULL)
+               if (rn_walktree(kt->pfrkt_ip6, pfr_walktree, pfrw))
+                       DPFPRINTF(LOG_ERR,
+                           "pfr_walk: on behalf of %s IPv6 walktree failed.",
+                           caller);
+}
+
+void
 pfr_ktable_winfo_update(struct pfr_ktable *kt, struct pfr_kentry *p) {
        /* 
         * If cost flag is set, 
@@ -2574,4 +2621,15 @@ pfr_ktable_winfo_update(struct pfr_ktabl
                if (kt->pfrkt_maxweight < weight)
                        kt->pfrkt_maxweight = weight;
        }
+}
+
+void
+pfr_ktable_winfo_update_sum(struct pfr_ktable *kt)
+{
+       struct pfr_walktree     w;
+
+       bzero(&w, sizeof(pfr_walktree));
+       w.pfrw_kt = kt;
+       w.pfrw_op = PFRW_WININFO_UPDATE;
+       pfr_walk(kt, &w, "pfr_ktable_winfo_update_sum");
 }

Reply via email to