On 04/04/16(Mon) 22:56, David Gwynne wrote:
> On Mon, Apr 04, 2016 at 08:07:47PM +1000, David Gwynne wrote:
> > > On 4 Apr 2016, at 6:41 PM, Martin Pieuchot <[email protected]> wrote:
> > > On 04/04/16(Mon) 13:09, David Gwynne wrote:
> > >> #ifdef DDB
> > >> @@ -593,6 +594,12 @@ if_enqueue(struct ifnet *ifp, struct mbu
> > >> struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET);
> > >> struct task if_input_task = TASK_INITIALIZER(if_input_process, 
> > >> &if_input_queue);
> > >> 
> > >> +int
> > >> +if_input_filter(void *if_bpf, const struct mbuf *m)
> > >> +{
> > >> +        return bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_IN);
> > >> +}
> > >> +
> > > 
> > > I find this filtering function confusing.  What about introducing a
> > > bpf_mtap() variant dealing with an ``mbuf_list'' : bpf_mltap()?
> > 
> > i could, but passing the direction through is difficult. i could have 
> > different wrappers for different directions though.

struct mbuf_list bpf_mltap(cadd_t arg, struct mbuf_list *ml, u_int dir);

How is that difficult?

> > > What about returning a mbuf (or a mbuf_list) instead of a boolean and
> > > check for NULL?  This would fit in the input_handler model where a 
> > > packet is "consumed", here by bpf(4), and processing should stop.
> > > 
> > > You could then write:
> > > 
> > >   m = bpf_mtap(if->if_bpf, m, BPF_DIRECTION_IN);
> > >   if (m == NULL)
> > >           return;
> > 
> > i wouldnt be able to pass the mbuf as a const struct mbuf * and return it 
> > without casting it to drop the const qualifier. to me it feels more like 
> > its being tested than consumed.

It is tested because you define it as const, or is it the other way
around?

> also consider that if bpf_mtap freed the mbuf, every caller would
> have to be fixed to check for that. at the moment we only respect
> drops on incoming packets.

So put a KASSERT if the direction is outgoing so you don't have to fix
all the callers.

>  void
>  if_input(struct ifnet *ifp, struct mbuf_list *ml)
>  {
> @@ -614,8 +621,15 @@ if_input(struct ifnet *ifp, struct mbuf_
>  #if NBPFILTER > 0
>       if_bpf = ifp->if_bpf;
>       if (if_bpf) {
> -             MBUF_LIST_FOREACH(ml, m)
> -                     bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_IN);
> +             struct mbuf *m0;
> +
> +             m0 = ml_filter(ml, if_input_filter, if_bpf);
> +             while (m0 != NULL) {
> +                     m = m0;
> +                     m0 = m->m_nextpkt;
> +
> +                     m_freem(m);
> +             }

Do you really want to add this mbuf horror show here?  It looks like
you've spent too much time in kern/uipc_mbuf.c recently!

Reply via email to