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.

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;
> 

Reply via email to