On Mon, Sep 02, 2013 at 11:11:43AM +0200, Martin Pieuchot wrote:
> On 31/08/13(Sat) 04:28, Nathanael Rensen wrote:
> > If no flowsrc is specified on a pflow(4) interface then the src address
> > is determined by ip_output(). However prior to calling ip_output() pflow(4)
> > has already calculated the UPD pseudo-header checksum based on INADDR_ANY.
> > This results in a bad UPD checksum and the resulting pflow packet is
> > rejected by the receiver.
> > 
> > The diff below resolves this by calling in_selectsrc() if flowsrc is not
> > specified.
> 
> I'm not sure we want to add yet-another different chunk of code to
> determine a source address, especially when I'm working on reducing 
> their number ;)
> 
> I'm not familiar with pflow(4), but is there any advantage of not
> specifying a flowsrc target?  Because reducing the number of code
> path passing an INADDR_ANY source address would simplify a lot of
> our address lookups.

If there is no strong usecase for not specifying flowsrc I think it's
better to not take the interface up if there is no flowsrc like we are
doing with flowdst. That requires some dicking around in pflowioctl()
and needs to be documented. (And don't take it up if someone sets it
explicitly to INADDR_ANY.)

Also style(9) says:
     Don't put declarations inside
     blocks unless the routine is unusually complicated.

> 
> Otherwise did you considered deferring the checksum?
> 
> > Index: if_pflow.c
> > ===================================================================
> > RCS file: /cvs/src/sys/net/if_pflow.c,v
> > retrieving revision 1.34
> > diff -u -p -r1.34 if_pflow.c
> > --- if_pflow.c      13 Aug 2013 08:44:05 -0000      1.34
> > +++ if_pflow.c      30 Aug 2013 18:54:03 -0000
> > @@ -1512,8 +1512,37 @@ pflow_sendout_mbuf(struct pflow_softc *s
> >     struct ifnet    *ifp = &sc->sc_if;
> >  #endif
> >     struct ip       *ip;
> > +   struct in_addr   sender_ip;
> >     int              err;
> >  
> > +   /* Determine the sender address */
> > +   sender_ip = sc->sc_sender_ip;
> > +   if (sender_ip.s_addr == INADDR_ANY) {
> > +           struct sockaddr_in       sin;
> > +           struct sockaddr_in      *ifaddr;
> > +           struct route             ro;
> > +
> > +           bzero(&ro, sizeof(ro));
> > +           bzero(&sin, sizeof(sin));
> > +           sin.sin_len = sizeof(sin);
> > +           sin.sin_family = AF_INET;
> > +           sin.sin_port = sc->sc_receiver_port;
> > +           sin.sin_addr = sc->sc_receiver_ip;
> > +
> > +           err = 0;
> > +           ifaddr = in_selectsrc(&sin, &ro, 0, NULL, &err, 0);
> > +           if (ifaddr == NULL) {
> > +                   if (err == 0)
> > +                           err = EADDRNOTAVAIL;
> > +                   return err;
> > +           }
> > +
> > +           sender_ip = ifaddr->sin_addr;
> > +
> > +           if (ro.ro_rt)
> > +                   rtfree(ro.ro_rt);
> > +   }
> > +
> >     /* UDP Header*/
> >     M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
> >     if (m == NULL) {
> > @@ -1523,7 +1552,7 @@ pflow_sendout_mbuf(struct pflow_softc *s
> >  
> >     ui = mtod(m, struct udpiphdr *);
> >     ui->ui_pr = IPPROTO_UDP;
> > -   ui->ui_src = sc->sc_sender_ip;
> > +   ui->ui_src = sender_ip;
> >     ui->ui_sport = sc->sc_sender_port;
> >     ui->ui_dst = sc->sc_receiver_ip;
> >     ui->ui_dport = sc->sc_receiver_port;
> > 
> 

-- 
I'm not entirely sure you are real.

Reply via email to