[redirected to freebsd-ipfw]
Certainly, there is a bug.
Please test with attached patch.
On Thu, Oct 26, 2000 at 04:01:07PM +0200, Harti Brandt wrote:
>
> Hi,
>
> I stumbled over an interesting problem: the current kernel's NFS client
> code blocks when reading files of size 2828 byte over NFSv3 (see
> kern/22309). Today I tracked the problem down. It appears, that an IP
> packet cannot be reassembled, when the last fragment of it is from 1 to 7
> bytes long.
>
> For some reason I have IP_FIREWALL and IP_FIREWALL_DEFAULT_TO_ACCEPT in my
> kernel config (well, the reason is, that I wanted to play with
> 'sting'). Although there is a comment in ip_fw.c that it is not a problem,
> when an incoming packet is a fragment with off!=0, it appears to be a
> problem, if the packet is too short to contain a UDP header. ip_fw insists
> on having an UDP header (around line 1002) and drops the packet as a bogus
> fragment, if it is too short for a header. I think, this is wrong.
>
> Because I'm not too firm with the firewall code, I have no fix.
>
--
Ruslan Ermilov Oracle Developer/DBA,
[EMAIL PROTECTED] Sunbay Software AG,
[EMAIL PROTECTED] FreeBSD committer,
+380.652.512.251 Simferopol, Ukraine
http://www.FreeBSD.org The Power To Serve
http://www.oracle.com Enabling The Information Age
Index: ip_fw.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/ip_fw.c,v
retrieving revision 1.146
diff -u -p -w -r1.146 ip_fw.c
--- ip_fw.c 2000/10/26 00:16:12 1.146
+++ ip_fw.c 2000/10/26 15:57:53
@@ -970,21 +970,20 @@ ip_fw_chk(struct ip **pip, int hlen,
goto bogusfrag; \
ip = mtod(*m, struct ip *); \
*pip = ip; \
- offset = (ip->ip_off & IP_OFFMASK); \
} \
} while (0)
/*
* Collect parameters into local variables for faster matching.
*/
+ proto = ip->ip_p;
+ src_ip = ip->ip_src;
+ dst_ip = ip->ip_dst;
offset = (ip->ip_off & IP_OFFMASK);
- {
+ if (offset == 0) {
struct tcphdr *tcp;
struct udphdr *udp;
- dst_ip = ip->ip_dst ;
- src_ip = ip->ip_src ;
- proto = ip->ip_p ;
/*
* warning - if offset != 0, port values are bogus.
* Not a problem for ipfw, but could be for dummynet.
@@ -1014,6 +1013,7 @@ ip_fw_chk(struct ip **pip, int hlen,
default :
break;
}
+ }
#undef PULLUP_TO
last_pkt.src_ip = ntohl(src_ip.s_addr) ;
last_pkt.dst_ip = ntohl(dst_ip.s_addr) ;
@@ -1021,7 +1021,6 @@ ip_fw_chk(struct ip **pip, int hlen,
last_pkt.src_port = ntohs(src_port) ;
last_pkt.dst_port = ntohs(dst_port) ;
last_pkt.flags = flags ;
- }
if (*flow_id) {
/* Accept if passed first test */