On 28 October 2015 at 18:41, Alexandr Nedvedicky
<alexandr.nedvedi...@oracle.com> wrote:
> Hello Mike,
>
> just a quick question:
>
>         are you going to commit your pfi_kif_find() et. al.?
>         or more work is needed there?
>

I need OKs

> thanks a lot
> regards
> sasha
>
>>
>> Turns out this is a rather simple issue that got slightly
>> complicated by the code diverging quite a bit since the
>> inception.  Essentially the clr->ifname comes from the
>> interface specification in the "pfctl -i foo0 -Fs" for
>> if-bound states (floating states use fake interface "any").
>>
>> Previously states have been hanging off of kif nodes but it's
>> long gone and we can simply iterate over the state table tree
>> (or even a state list like it's done in the DIOCGETSTATES in
>> pf_ioctl).
>>
>> Calling pf_kif_get here wouldn't be prudent because spawning
>> new objects while disposing of the other ones seems somewhat
>> counterproductive.
>>
> diff --git sys/net/if_pfsync.c sys/net/if_pfsync.c
> index 7d633db..fcaf5f5 100644
> --- sys/net/if_pfsync.c
> +++ sys/net/if_pfsync.c
> @@ -752,46 +752,28 @@ done:
>
>  int
>  pfsync_in_clr(caddr_t buf, int len, int count, int flags)
>  {
>         struct pfsync_clr *clr;
> -       int i;
> -
>         struct pf_state *st, *nexts;
> -       struct pf_state_key *sk, *nextsk;
> -       struct pf_state_item *si;
> +       struct pfi_kif *kif = NULL;
>         u_int32_t creatorid;
> +       int i;
>
>         for (i = 0; i < count; i++) {
>                 clr = (struct pfsync_clr *)buf + len * i;
>                 creatorid = clr->creatorid;
> +               if (strlen(clr->ifname) &&
> +                   (kif = pfi_kif_find(clr->ifname)) == NULL)
> +                       continue;
>
> -               if (clr->ifname[0] == '\0') {
> -                       for (st = RB_MIN(pf_state_tree_id, &tree_id);
> -                           st; st = nexts) {
> -                               nexts = RB_NEXT(pf_state_tree_id, &tree_id, 
> st);
> -                               if (st->creatorid == creatorid) {
> -                                       SET(st->state_flags, PFSTATE_NOSYNC);
> -                                       pf_unlink_state(st);
> -                               }
> -                       }
> -               } else {
> -                       if (pfi_kif_get(clr->ifname) == NULL)
> -                               continue;
> -
> -                       /* XXX correct? */
> -                       for (sk = RB_MIN(pf_state_tree, &pf_statetbl);
> -                           sk; sk = nextsk) {
> -                               nextsk = RB_NEXT(pf_state_tree,
> -                                   &pf_statetbl, sk);
> -                               TAILQ_FOREACH(si, &sk->states, entry) {
> -                                       if (si->s->creatorid == creatorid) {
> -                                               SET(si->s->state_flags,
> -                                                   PFSTATE_NOSYNC);
> -                                               pf_unlink_state(si->s);
> -                                       }
> -                               }
> +               for (st = RB_MIN(pf_state_tree_id, &tree_id); st; st = nexts) 
> {
> +                       nexts = RB_NEXT(pf_state_tree_id, &tree_id, st);
> +                       if (st->creatorid == creatorid &&
> +                           ((kif && st->kif == kif) || !kif)) {
> +                               SET(st->state_flags, PFSTATE_NOSYNC);
> +                               pf_unlink_state(st);
>                         }
>                 }
>         }
>
>         return (0);
> diff --git sys/net/pf_if.c sys/net/pf_if.c
> index caaf9f9..bf77184 100644
> --- sys/net/pf_if.c
> +++ sys/net/pf_if.c
> @@ -97,18 +97,25 @@ pfi_initialize(void)
>         if ((pfi_all = pfi_kif_get(IFG_ALL)) == NULL)
>                 panic("pfi_kif_get for pfi_all failed");
>  }
>
>  struct pfi_kif *
> -pfi_kif_get(const char *kif_name)
> +pfi_kif_find(const char *kif_name)
>  {
> -       struct pfi_kif          *kif;
>         struct pfi_kif_cmp       s;
>
>         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 (RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s));
> +}
> +
> +struct pfi_kif *
> +pfi_kif_get(const char *kif_name)
> +{
> +       struct pfi_kif          *kif;
> +
> +       if ((kif = pfi_kif_find(kif_name)))
>                 return (kif);
>
>         /* create new one */
>         if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_NOWAIT|M_ZERO)) == NULL)
>                 return (NULL);
> diff --git sys/net/pfvar.h sys/net/pfvar.h
> index cdb2f7f..76a98a9 100644
> --- sys/net/pfvar.h
> +++ sys/net/pfvar.h
> @@ -1808,10 +1808,11 @@ int     pfr_ina_define(struct pfr_table *, struct 
> pfr_addr *, int, int *,
>             int *, u_int32_t, int);
>
>  extern struct pfi_kif          *pfi_all;
>
>  void            pfi_initialize(void);
> +struct pfi_kif *pfi_kif_find(const char *);
>  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);
>  int             pfi_kif_match(struct pfi_kif *, struct pfi_kif *);
>  void            pfi_attach_ifnet(struct ifnet *);

Reply via email to