On 04/07/17 19:09, Reyk Floeter wrote: > First of all, please send a proper bug reports to bugs@, not misc. > "It used to work but now it doesn't" is not very helpful. > > Could you share your actual configuration or, even better, provide a > simplified way to reproduce your problem? rzalamena, me, and some > other people have tested different setups but you seem to have an > interestingly complex configuration. > > The new code has more validation, so it might be that it rightfully or > wrongfully rejects packets that have been accepted before. > > Could you try again with the attached diff? It doesn't change > behavior but it adds some chatty logging when a packet is rejected. > Maybe it helps to find the issue. > > Reyk
Hi and thanks for the answer. I would have send a better report if I could debug it. -d does not produce any messages. Also I'm not sure how to reproduce it. It just happened after the upgrade and it happens in a random way... Not all users and not on all vlans. I will try the patch and send a report to @bugs G > Index: usr.sbin/dhcrelay/bpf.c > =================================================================== > RCS file: /cvs/src/usr.sbin/dhcrelay/bpf.c,v > retrieving revision 1.19 > diff -u -p -u -p -r1.19 bpf.c > --- usr.sbin/dhcrelay/bpf.c 19 Apr 2017 05:36:12 -0000 1.19 > +++ usr.sbin/dhcrelay/bpf.c 4 Jul 2017 16:01:29 -0000 > @@ -349,11 +349,17 @@ send_packet(struct interface_info *inter > > /* Assemble the headers... */ > if ((bufp = assemble_hw_header(buf, sizeof(buf), 0, pc, > - interface->hw_address.htype)) == -1) > + interface->hw_address.htype)) == -1) { > + log_warnx("%s:%d: assemble_hw_header failed, len %zu", > + __func__, __LINE__, len); > goto done; > + } > if ((bufp = assemble_udp_ip_header(buf, sizeof(buf), bufp, pc, > - (unsigned char *)raw, len)) == -1) > + (unsigned char *)raw, len)) == -1) { > + log_warnx("%s:%d: assemble_udp_ip_header failed," > + " offset %zd len %zu", __func__, __LINE__, bufp, len); > goto done; > + } > > /* Fire it off */ > iov[0].iov_base = (char *)buf; > @@ -447,6 +453,9 @@ receive_packet(struct interface_info *in > * skip this packet. > */ > if (offset < 0) { > + log_warnx("%s:%d: decode_hw_header failed," > + " len %zu", __func__, __LINE__, > + interface->rbuf_len); > interface->rbuf_offset += hdr.bh_caplen; > continue; > } > @@ -457,6 +466,9 @@ receive_packet(struct interface_info *in > > /* If the IP or UDP checksum was bad, skip the packet... */ > if (offset < 0) { > + log_warnx("%s:%d: decode_udp_ip_header failed," > + " offset %zd len %zu", __func__, __LINE__, > + offset, interface->rbuf_len); > interface->rbuf_offset += hdr.bh_caplen; > continue; > } > @@ -470,6 +482,10 @@ receive_packet(struct interface_info *in > * life, though). > */ > if (hdr.bh_caplen > len) { > + log_warnx("%s:%d: XXX shouldn't happen in real life," > + " caplen %u > len %zu", __func__, __LINE__, > + hdr.bh_caplen, len); > + > interface->rbuf_offset += hdr.bh_caplen; > continue; > } > Index: usr.sbin/dhcrelay/packet.c > =================================================================== > RCS file: /cvs/src/usr.sbin/dhcrelay/packet.c,v > retrieving revision 1.14 > diff -u -p -u -p -r1.14 packet.c > --- usr.sbin/dhcrelay/packet.c 5 Apr 2017 14:40:56 -0000 1.14 > +++ usr.sbin/dhcrelay/packet.c 4 Jul 2017 16:01:29 -0000 > @@ -104,8 +104,12 @@ assemble_hw_header(unsigned char *buf, s > > switch (intfhtype) { > case HTYPE_ETHER: > - if (buflen < offset + ETHER_HDR_LEN) > + if (buflen < offset + ETHER_HDR_LEN) { > + log_warnx("%s:%d: short ether hdr buflen %zu < %zu", > + __func__, __LINE__, > + buflen, offset + ETHER_HDR_LEN); > return (-1); > + } > > /* Use the supplied address or let the kernel fill it. */ > memcpy(eh.ether_shost, pc->pc_smac, ETHER_ADDR_LEN); > @@ -117,6 +121,8 @@ assemble_hw_header(unsigned char *buf, s > offset += ETHER_HDR_LEN; > break; > default: > + log_warnx("%s:%d: invalid htype %u", __func__, __LINE__, > + intfhtype); > return (-1); > } > > @@ -130,8 +136,12 @@ assemble_udp_ip_header(unsigned char *bu > struct ip ip; > struct udphdr udp; > > - if (buflen < offset + sizeof(ip) + sizeof(udp)) > + if (buflen < offset + sizeof(ip) + sizeof(udp)) { > + log_warnx("%s:%d: short udp pkt buflen %zu < %zu", > + __func__, __LINE__, > + buflen, offset + sizeof(ip) + sizeof(udp)); > return (-1); > + } > > ip.ip_v = 4; > ip.ip_hl = 5; > @@ -174,18 +184,24 @@ decode_hw_header(unsigned char *buf, siz > > switch (intfhtype) { > case HTYPE_IPSEC_TUNNEL: > - if (buflen < offset + ENC_HDRLEN + sizeof(*ip)) > + if (buflen < offset + ENC_HDRLEN + sizeof(*ip)) { > + log_warnx("%s:%d", __func__, __LINE__); > return (-1); > + } > offset += ENC_HDRLEN; > ip_len = (buf[offset] & 0xf) << 2; > - if (buflen < offset + ip_len) > + if (buflen < offset + ip_len) { > + log_warnx("%s:%d", __func__, __LINE__); > return (-1); > + } > > ip = (struct ip *)(buf + offset); > > /* Encapsulated IP */ > - if (ip->ip_p != IPPROTO_IPIP) > + if (ip->ip_p != IPPROTO_IPIP) { > + log_warnx("%s:%d", __func__, __LINE__); > return (-1); > + } > > memset(pc->pc_dmac, 0xff, ETHER_ADDR_LEN); > offset += ip_len; > @@ -194,8 +210,12 @@ decode_hw_header(unsigned char *buf, siz > pc->pc_hlen = ETHER_ADDR_LEN; > break; > case HTYPE_ETHER: > - if (buflen < offset + ETHER_HDR_LEN) > + if (buflen < offset + ETHER_HDR_LEN) { > + log_warnx("%s:%d: short ether hdr buflen %zu < %zu", > + __func__, __LINE__, > + buflen, offset + ETHER_HDR_LEN); > return (-1); > + } > > memcpy(pc->pc_dmac, buf + offset, ETHER_ADDR_LEN); > memcpy(pc->pc_smac, buf + offset + ETHER_ADDR_LEN, > @@ -206,6 +226,8 @@ decode_hw_header(unsigned char *buf, siz > pc->pc_hlen = ETHER_ADDR_LEN; > break; > default: > + log_warnx("%s:%d: invalid htype %u", __func__, __LINE__, > + intfhtype); > return (-1); > } > > @@ -230,11 +252,19 @@ decode_udp_ip_header(unsigned char *buf, > int len; > > /* Assure that an entire IP header is within the buffer. */ > - if (buflen < offset + sizeof(*ip)) > + if (buflen < offset + sizeof(*ip)) { > + log_warnx("%s:%d: short ip hdr buflen %zu < %zu", > + __func__, __LINE__, > + buflen, offset + sizeof(*ip)); > return (-1); > + } > ip_len = (buf[offset] & 0xf) << 2; > - if (buflen < offset + ip_len) > + if (buflen < offset + ip_len) { > + log_warnx("%s:%d: short ip pkt buflen %zu < %zu", > + __func__, __LINE__, > + buflen, offset + offset + ip_len); > return (-1); > + } > > ip = (struct ip *)(buf + offset); > ip_packets_seen++; > @@ -242,6 +272,9 @@ decode_udp_ip_header(unsigned char *buf, > /* Check the IP header checksum - it should be zero. */ > if (wrapsum(checksum(buf + offset, ip_len, 0)) != 0) { > ip_packets_bad_checksum++; > + log_warnx("%s:%d: %u bad IP checksums seen in %u packets", > + __func__, __LINE__, > + ip_packets_bad_checksum, ip_packets_seen); > if (ip_packets_seen > 4 && ip_packets_bad_checksum != 0 && > (ip_packets_seen / ip_packets_bad_checksum) < 2) { > log_info("%u bad IP checksums seen in %u packets", > @@ -268,18 +301,24 @@ decode_udp_ip_header(unsigned char *buf, > #endif > > /* Assure that the entire IP packet is within the buffer. */ > - if (buflen < offset + ntohs(ip->ip_len)) > + if (buflen < offset + ntohs(ip->ip_len)) { > + log_warnx("%s:%d", __func__, __LINE__); > return (-1); > + } > > /* Assure that the UDP header is within the buffer. */ > - if (buflen < offset + ip_len + sizeof(*udp)) > + if (buflen < offset + ip_len + sizeof(*udp)) { > + log_warnx("%s:%d", __func__, __LINE__); > return (-1); > + } > udp = (struct udphdr *)(buf + offset + ip_len); > udp_packets_seen++; > > /* Assure that the entire UDP packet is within the buffer. */ > - if (buflen < offset + ip_len + ntohs(udp->uh_ulen)) > + if (buflen < offset + ip_len + ntohs(udp->uh_ulen)) { > + log_warnx("%s:%d", __func__, __LINE__); > return (-1); > + } > data = buf + offset + ip_len + sizeof(*udp); > > /* > @@ -291,6 +330,10 @@ decode_udp_ip_header(unsigned char *buf, > len = ntohs(udp->uh_ulen) - sizeof(*udp); > if ((len < 0) || (len + data > buf + buflen)) { > udp_packets_length_overflow++; > + log_warnx("%s:%d: %u udp packets in %u too long - dropped", > + __func__, __LINE__, > + udp_packets_length_overflow, > + udp_packets_length_checked); > if (udp_packets_length_checked > 4 && > udp_packets_length_overflow != 0 && > (udp_packets_length_checked / > @@ -317,6 +360,9 @@ decode_udp_ip_header(unsigned char *buf, > udp_packets_seen++; > if (usum && usum != sum) { > udp_packets_bad_checksum++; > + log_warnx("%s:%d: %u bad udp checksums in %u packets", > + __func__, __LINE__, > + udp_packets_bad_checksum, udp_packets_seen); > if (udp_packets_seen > 4 && udp_packets_bad_checksum != 0 && > (udp_packets_seen / udp_packets_bad_checksum) < 2) { > log_info("%u bad udp checksums in %u packets", >