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");
}