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