On Tue, Oct 13, 2015 at 20:36 +1000, David Gwynne wrote:
> 
> > On 12 Oct 2015, at 12:00 AM, Alexandr Nedvedicky 
> > <[email protected]> wrote:
> > 
> > Hello,
> > 
> > patch below introduces struct refcnt to pfi_kif structure. Patch also 
> > changes
> > pfi_kif_get() function to always return a reference to pfi_kif instance.
> > 
> > Furthermore existing functions pfi_kif_ref()/pfi_kif_unref() are thrown away
> > in favor of pfi_kif_take()/pfi_kif_rele(), which follow naming convention
> > set by refcnt_init(9).  Patch also removes kif reference types (enum
> > pfi_kif_refs).
> >
[snip]
> > 
> > thanks and
> > regards
> > sasha
> > 
> > ---------8<----------------8<----------------8<---------------8<--------
> > Index: if_pfsync.c
> > ===================================================================
> > RCS file: /cvs/src/sys/net/if_pfsync.c,v
> > retrieving revision 1.220
> > diff -u -p -r1.220 if_pfsync.c
> > --- if_pfsync.c     11 Sep 2015 08:17:06 -0000      1.220
> > +++ if_pfsync.c     11 Oct 2015 13:46:11 -0000
> > @@ -631,6 +631,8 @@ pfsync_state_import(struct pfsync_state 
> >     }
> >     CLR(st->state_flags, PFSTATE_ACK);
> > 
> > +   pfi_kif_rele(kif);
> > +
> >     return (0);
> > 
> >  cleanup:
> > @@ -650,6 +652,9 @@ pfsync_state_import(struct pfsync_state 
> >                     pool_put(&pf_state_scrub_pl, st->src.scrub);
> >             pool_put(&pf_state_pl, st);
> >     }
> > +
> > +   pfi_kif_rele(kif);
> > +
> >     return (error);
> > }
> > 
> > @@ -759,6 +764,7 @@ pfsync_in_clr(caddr_t buf, int len, int 
> >     struct pf_state *st, *nexts;
> >     struct pf_state_key *sk, *nextsk;
> >     struct pf_state_item *si;
> > +   struct pfi_kif *kif;
> >     u_int32_t creatorid;
> > 
> >     for (i = 0; i < count; i++) {
> > @@ -775,7 +781,11 @@ pfsync_in_clr(caddr_t buf, int len, int 
> >                             }
> >                     }
> >             } else {
> > -                   if (pfi_kif_get(clr->ifname) == NULL)
> > +                   /*
> > +                    * Do we realize here the pfi_kif_get() actually
> > +                    * creates kif for name if it does not exist? 
> > +                    */
> > +                   if ((kif = pfi_kif_get(clr->ifname)) == NULL)
> >                             continue;
> > 
> >                     /* XXX correct? */
> > @@ -791,6 +801,8 @@ pfsync_in_clr(caddr_t buf, int len, int 
> >                                     }
> >                             }
> >                     }
> > +
> > +                   pfi_kif_rele(kif);
> >             }
> >     }
> > 
> > Index: pf.c
> > ===================================================================
> > RCS file: /cvs/src/sys/net/pf.c,v
> > retrieving revision 1.946
> > diff -u -p -r1.946 pf.c
> > --- pf.c    8 Oct 2015 11:36:51 -0000       1.946
> > +++ pf.c    11 Oct 2015 13:46:14 -0000
> > @@ -944,7 +944,7 @@ pf_state_insert(struct pfi_kif *kif, str
> >     TAILQ_INSERT_TAIL(&state_list, s, entry_list);
> >     pf_status.fcounters[FCNT_STATE_INSERT]++;
> >     pf_status.states++;
> > -   pfi_kif_ref(kif, PFI_KIF_REF_STATE);
> > +   pfi_kif_take(kif);
> > #if NPFSYNC > 0
> >     pfsync_insert_state(s);
> > #endif      /* NPFSYNC > 0 */
> > @@ -1315,7 +1315,7 @@ pf_free_state(struct pf_state *cur)
> >             pool_put(&pf_rule_item_pl, ri);
> >     }
> >     pf_normalize_tcp_cleanup(cur);
> > -   pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
> > +   pfi_kif_rele(cur->kif);
> >     TAILQ_REMOVE(&state_list, cur, entry_list);
> >     if (cur->tag)
> >             pf_tag_unref(cur->tag);
> > Index: pf_if.c
> > ===================================================================
> > RCS file: /cvs/src/sys/net/pf_if.c,v
> > retrieving revision 1.80
> > diff -u -p -r1.80 pf_if.c
> > --- pf_if.c 4 Sep 2015 21:40:25 -0000       1.80
> > +++ pf_if.c 11 Oct 2015 13:46:14 -0000
> > @@ -107,7 +107,7 @@ pfi_kif_get(const char *kif_name)
> >     bzero(&s, sizeof(s));
> >     strlcpy(s.pfik_name, kif_name, sizeof(s.pfik_name));
> >     if ((kif = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s)) != NULL)
> > -           return (kif);
> > +           return (pfi_kif_take(kif));
> > 
> >     /* create new one */
> >     if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_NOWAIT|M_ZERO)) == NULL)
> > @@ -116,6 +116,7 @@ pfi_kif_get(const char *kif_name)
> >     strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
> >     kif->pfik_tzero = time_second;
> >     TAILQ_INIT(&kif->pfik_dynaddrs);
> > +   PF_REF_INIT(kif->pfik_refcnt);
> > 
> >     if (!strcmp(kif->pfik_name, "any")) {
> >             /* both so it works in the ioctl and the regular case */
> > @@ -124,72 +125,21 @@ pfi_kif_get(const char *kif_name)
> >     }
> > 
> >     RB_INSERT(pfi_ifhead, &pfi_ifs, kif);
> > +   /* 
> > +    * there is no pfi_kif_remove(), hence caller shares reference with
> > +    * pfi_ifs look up table.
> > +    */
> >     return (kif);
> > }
> > 
> > -void
> > -pfi_kif_ref(struct pfi_kif *kif, enum pfi_kif_refs what)
> > -{
> > -   switch (what) {
> > -   case PFI_KIF_REF_RULE:
> > -           kif->pfik_rules++;
> > -           break;
> > -   case PFI_KIF_REF_STATE:
> > -           kif->pfik_states++;
> > -           break;
> > -   case PFI_KIF_REF_ROUTE:
> > -           kif->pfik_routes++;
> > -           break;
> > -   default:
> > -           panic("pfi_kif_ref with unknown type");
> > -   }
> > -}
> > -
> > -void
> > -pfi_kif_unref(struct pfi_kif *kif, enum pfi_kif_refs what)
> > +int
> > +pfi_kif_check(const char *kif_name)
> > {
> > -   if (kif == NULL)
> > -           return;
> > -
> > -   switch (what) {
> > -   case PFI_KIF_REF_NONE:
> > -           break;
> > -   case PFI_KIF_REF_RULE:
> > -           if (kif->pfik_rules <= 0) {
> > -                   DPFPRINTF(LOG_ERR,
> > -                       "pfi_kif_unref: rules refcount <= 0");
> > -                   return;
> > -           }
> > -           kif->pfik_rules--;
> > -           break;
> > -   case PFI_KIF_REF_STATE:
> > -           if (kif->pfik_states <= 0) {
> > -                   DPFPRINTF(LOG_ERR,
> > -                       "pfi_kif_unref: state refcount <= 0");
> > -                   return;
> > -           }
> > -           kif->pfik_states--;
> > -           break;
> > -   case PFI_KIF_REF_ROUTE:
> > -           if (kif->pfik_routes <= 0) {
> > -                   DPFPRINTF(LOG_ERR,
> > -                       "pfi_kif_unref: state refcount <= 0");
> > -                   return;
> > -           }
> > -           kif->pfik_routes--;
> > -           break;
> > -   default:
> > -           panic("pfi_kif_unref with unknown type");
> > -   }
> > -
> > -   if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == pfi_all)
> > -           return;
> > -
> > -   if (kif->pfik_rules || kif->pfik_states || kif->pfik_routes)
> > -           return;
> > +   struct pfi_kif_cmp      s;
> > 
> > -   RB_REMOVE(pfi_ifhead, &pfi_ifs, kif);
> > -   free(kif, PFI_MTYPE, 0);
> > +   bzero(&s, sizeof(s));
> > +   strlcpy(s.pfik_name, kif_name, sizeof (s.pfik_name));
> > +   return (RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s));
> > }
> > 
> > int
> > @@ -258,7 +208,7 @@ pfi_detach_ifnet(struct ifnet *ifp)
> > 
> >     kif->pfik_ifp = NULL;
> >     ifp->if_pf_kif = NULL;
> > -   pfi_kif_unref(kif, PFI_KIF_REF_NONE);
> > +   pfi_kif_rele(kif);
> > 
> >     splx(s);
> > }
> > @@ -275,6 +225,7 @@ pfi_attach_ifgroup(struct ifg_group *ifg
> >     if ((kif = pfi_kif_get(ifg->ifg_group)) == NULL)
> >             panic("pfi_kif_get failed");
> > 
> > +   KASSERT(kif->pfik_group == NULL);
> >     kif->pfik_group = ifg;
> >     ifg->ifg_pf_kif = (caddr_t)kif;
> > 
> > @@ -295,7 +246,7 @@ pfi_detach_ifgroup(struct ifg_group *ifg
> > 
> >     kif->pfik_group = NULL;
> >     ifg->ifg_pf_kif = NULL;
> > -   pfi_kif_unref(kif, PFI_KIF_REF_NONE);
> > +   pfi_kif_rele(kif);
> >     splx(s);
> > }
> > 
> > @@ -312,6 +263,8 @@ pfi_group_change(const char *group)
> > 
> >     pfi_kif_update(kif);
> > 
> > +   pfi_kif_rele(kif);
> > +
> >     splx(s);
> > }
> > 
> > @@ -371,7 +324,6 @@ pfi_dynaddr_setup(struct pf_addr_wrap *a
> >             rv = 1;
> >             goto _bad;
> >     }
> > -   pfi_kif_ref(dyn->pfid_kif, PFI_KIF_REF_RULE);
> > 
> >     dyn->pfid_net = pfi_unmask(&aw->v.a.mask);
> >     if (af == AF_INET && dyn->pfid_net == 32)
> > @@ -414,7 +366,7 @@ _bad:
> >     if (ruleset != NULL)
> >             pf_remove_if_empty_ruleset(ruleset);
> >     if (dyn->pfid_kif != NULL)
> > -           pfi_kif_unref(dyn->pfid_kif, PFI_KIF_REF_RULE);
> > +           pfi_kif_rele(dyn->pfid_kif);
> >     pool_put(&pfi_addr_pl, dyn);
> >     splx(s);
> >     return (rv);
> > @@ -595,7 +547,7 @@ pfi_dynaddr_remove(struct pf_addr_wrap *
> > 
> >     s = splsoftnet();
> >     TAILQ_REMOVE(&aw->p.dyn->pfid_kif->pfik_dynaddrs, aw->p.dyn, entry);
> > -   pfi_kif_unref(aw->p.dyn->pfid_kif, PFI_KIF_REF_RULE);
> > +   pfi_kif_rele(aw->p.dyn->pfid_kif);
> >     aw->p.dyn->pfid_kif = NULL;
> >     pfr_detach_table(aw->p.dyn->pfid_kt);
> >     aw->p.dyn->pfid_kt = NULL;
> > @@ -709,14 +661,14 @@ pfi_get_ifaces(const char *name, struct 
> >             if (*size > n++) {
> >                     if (!p->pfik_tzero)
> >                             p->pfik_tzero = time_second;
> > -                   pfi_kif_ref(p, PFI_KIF_REF_RULE);
> > +                   pfi_kif_take(p);
> >                     if (copyout(p, buf++, sizeof(*buf))) {
> > -                           pfi_kif_unref(p, PFI_KIF_REF_RULE);
> > +                           pfi_kif_rele(p);
> >                             splx(s);
> >                             return (EFAULT);
> >                     }
> >                     nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
> > -                   pfi_kif_unref(p, PFI_KIF_REF_RULE);
> > +                   pfi_kif_rele(p);
> >             }
> >     }
> >     splx(s);
> > @@ -810,3 +762,28 @@ pfi_unmask(void *addr)
> >     return (b);
> > }
> > 
> > +struct pfi_kif *
> > +pfi_kif_take(struct pfi_kif *kif)
> > +{
> > +   if (kif != pfi_all) {
> > +           PF_REF_TAKE(kif->pfik_refcnt);
> > +   }

No need for curly braces here --^

> > +
> > +   return (kif);
> > +}
> > +
> > +void
> > +pfi_kif_rele(struct pfi_kif *kif)
> > +{
> > +   if (kif == pfi_all)
> > +           return;
> > +
> > +   if (PF_REF_RELE(kif->pfik_refcnt)) {
> > +           KASSERT(kif->pfik_ifp == NULL);
> > +           KASSERT(kif->pfik_group == NULL);
> > +           KASSERT(TAILQ_EMPTY(&kif->pfik_dynaddrs));
> > +
> > +           RB_REMOVE(pfi_ifhead, &pfi_ifs, kif);
> > +           free(kif, PFI_MTYPE, 0);
> > +   }
> > +}
> > Index: pf_ioctl.c
> > ===================================================================
> > RCS file: /cvs/src/sys/net/pf_ioctl.c,v
> > retrieving revision 1.290
> > diff -u -p -r1.290 pf_ioctl.c
> > --- pf_ioctl.c      4 Sep 2015 21:40:25 -0000       1.290
> > +++ pf_ioctl.c      11 Oct 2015 13:46:15 -0000
> > @@ -289,11 +289,11 @@ pf_rm_rule(struct pf_rulequeue *rulequeu
> >             if (rule->overload_tbl)
> >                     pfr_detach_table(rule->overload_tbl);
> >     }
> > -   pfi_kif_unref(rule->rcv_kif, PFI_KIF_REF_RULE);
> > -   pfi_kif_unref(rule->kif, PFI_KIF_REF_RULE);
> > -   pfi_kif_unref(rule->rdr.kif, PFI_KIF_REF_RULE);
> > -   pfi_kif_unref(rule->nat.kif, PFI_KIF_REF_RULE);
> > -   pfi_kif_unref(rule->route.kif, PFI_KIF_REF_RULE);
> > +   PFI_KIF_RELE(rule->rcv_kif);
> > +   PFI_KIF_RELE(rule->kif);
> > +   PFI_KIF_RELE(rule->rdr.kif);
> > +   PFI_KIF_RELE(rule->nat.kif);
> > +   PFI_KIF_RELE(rule->route.kif);
> >     pf_anchor_remove(rule);
> >     pool_put(&pf_rule_pl, rule);
> > }
> > @@ -529,7 +529,7 @@ pf_free_queues(struct pf_queuehead *wher
> >             if (ifp && q->kif->pfik_ifp != ifp)
> >                     continue;
> >             TAILQ_REMOVE(where, q, entries);
> > -           pfi_kif_unref(q->kif, PFI_KIF_REF_RULE);
> > +           PFI_KIF_RELE(q->kif);
> >             pool_put(&pf_queue_pl, q);
> >     }
> >     return (0);
> > @@ -788,8 +788,6 @@ pf_kif_setup(char *ifname, struct pfi_ki
> >             *kif = pfi_kif_get(ifname);
> >             if (*kif == NULL)
> >                     return (EINVAL);
> > -
> > -           pfi_kif_ref(*kif, PFI_KIF_REF_RULE);
> >     } else
> >             *kif = NULL;
> > 
> > @@ -1035,7 +1033,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
> >                     break;
> >             }
> >             /* XXX resolve bw percentage specs */
> > -           pfi_kif_ref(qs->kif, PFI_KIF_REF_RULE);
> >             if (qs->qlimit == 0)
> >                     qs->qlimit = HFSC_DEFAULT_QLIMIT;
> >             TAILQ_INSERT_TAIL(pf_queues_inactive, qs, entries);
> > Index: pf_table.c
> > ===================================================================
> > RCS file: /cvs/src/sys/net/pf_table.c,v
> > retrieving revision 1.115
> > diff -u -p -r1.115 pf_table.c
> > --- pf_table.c      7 Oct 2015 11:57:44 -0000       1.115
> > +++ pf_table.c      11 Oct 2015 13:46:17 -0000
> > @@ -847,8 +847,6 @@ pfr_create_kentry(struct pfr_addr *ad)
> >     case PFRKE_ROUTE:
> >             if (ad->pfra_ifname[0])
> >                     ke->pfrke_rkif = pfi_kif_get(ad->pfra_ifname);
> > -           if (ke->pfrke_rkif)
> > -                   pfi_kif_ref(ke->pfrke_rkif, PFI_KIF_REF_ROUTE);
> >             break;
> >     default:
> >             panic("unknown pfrke_type %d", ke->pfrke_type);
> > @@ -893,8 +891,7 @@ pfr_destroy_kentry(struct pfr_kentry *ke
> >     if (ke->pfrke_counters)
> >             pool_put(&pfr_kcounters_pl, ke->pfrke_counters);
> >     if (ke->pfrke_type == PFRKE_COST || ke->pfrke_type == PFRKE_ROUTE)
> > -           pfi_kif_unref(((struct pfr_kentry_all *)ke)->pfrke_rkif,
> > -               PFI_KIF_REF_ROUTE);
> > +           pfi_kif_rele(((struct pfr_kentry_all *)ke)->pfrke_rkif);
> >     pool_put(&pfr_kentry_pl[ke->pfrke_type], ke);
> > }
> > 
> > Index: pfvar.h
> > ===================================================================
> > RCS file: /cvs/src/sys/net/pfvar.h,v
> > retrieving revision 1.420
> > diff -u -p -r1.420 pfvar.h
> > --- pfvar.h 19 Aug 2015 21:22:41 -0000      1.420
> > +++ pfvar.h 11 Oct 2015 13:46:17 -0000
> > @@ -38,6 +38,7 @@
> > #include <sys/tree.h>
> > #include <sys/rwlock.h>
> > #include <sys/syslimits.h>
> > +#include <sys/refcnt.h>
> > 
> > #include <net/radix.h>
> > #include <net/route.h>
> > @@ -55,6 +56,8 @@ struct ip6_hdr;
> > #endif
> > #endif
> > 
> > +typedef struct refcnt      pf_refcnt_t;
> > +
> > enum        { PF_INOUT, PF_IN, PF_OUT, PF_FWD };
> > enum        { PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT,
> >       PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER,
> > @@ -1125,17 +1128,8 @@ struct pfi_kif {
> >     void                            *pfik_ah_cookie;
> >     struct ifnet                    *pfik_ifp;
> >     struct ifg_group                *pfik_group;
> > -   int                              pfik_states;
> > -   int                              pfik_rules;
> > -   int                              pfik_routes;
> >     TAILQ_HEAD(, pfi_dynaddr)        pfik_dynaddrs;
> > -};
> > -
> > -enum pfi_kif_refs {
> > -   PFI_KIF_REF_NONE,
> > -   PFI_KIF_REF_STATE,
> > -   PFI_KIF_REF_RULE,
> > -   PFI_KIF_REF_ROUTE
> > +   pf_refcnt_t                      pfik_refcnt;
> > };
> > 
> > #define PFI_IFLAG_SKIP              0x0100  /* skip filtering on interface 
> > */
> > @@ -1811,8 +1805,9 @@ extern struct pfi_kif         *pfi_all;
> > 
> > void                 pfi_initialize(void);
> > struct pfi_kif      *pfi_kif_get(const char *);
> > -void                pfi_kif_ref(struct pfi_kif *, enum pfi_kif_refs);
> > -void                pfi_kif_unref(struct pfi_kif *, enum pfi_kif_refs);
> > +struct pfi_kif     *pfi_kif_take(struct pfi_kif *);
> > +void                pfi_kif_rele(struct pfi_kif *);
> > +int                 pfi_kif_check(const char *);
> > int          pfi_kif_match(struct pfi_kif *, struct pfi_kif *);
> > void                 pfi_attach_ifnet(struct ifnet *);
> > void                 pfi_detach_ifnet(struct ifnet *);
> > @@ -1909,5 +1904,16 @@ void                  pf_cksum(struct pf_pdesc *, 
> > stru
> > 
> > #endif /* _KERNEL */
> > 
> > +#define    PF_REF_INIT(_x_)        refcnt_init(&(_x_))
> > +
> > +#define    PF_REF_TAKE(_x_)        refcnt_take(&(_x_))
> > +
> > +#define    PF_REF_RELE(_x_)        refcnt_rele(&(_x_)) 
> > +
> > +#define    PFI_KIF_TAKE(_kif_)     \
> > +   (((_kif_) != NULL) ? pfi_kif_take((_kif_)) : NULL)
> > +
> > +#define    PFI_KIF_RELE(_kif_)     \
> > +   (((_kif_) != NULL) ? pfi_kif_rele((_kif_)) : ((void)(0)))
> > 
> > #endif /* _NET_PFVAR_H_ */
> > 
> 
> it all looks good to me. ok.
>

Even the typedef? (-:

But seriously I hate the _x_ things that Sasha is introducing
as it's certainly not the style we're using and not the style
pfvar.h is using.  There's a bit of a mix of _x and just x,
but I'd prefer the former, e.g. _k instead of _kif_.  Double
parenthesis are also not needed, e.g. pfi_kif_take((_kif_))
should be pfi_kif_take(_k).

PFI_KIF_TAKE and PFI_KIF_RELE macros add another level of
complexity for almost zero gain.  PFI_KIF_TAKE is not even
used.  I'd say scrap them.

I would also say that the PF_REF_* should stay under _KERNEL
as they simply cannot be used in the userland and moved some-
where before "extern struct pf_status pf_status" (after the
prototypes chunk) or after the "extern struct pf_pool_limit"
right before the "#endif /* _KERNEL */".

Reply via email to