Date: Thu, 23 Feb 2006 15:04:42 GMT From: Joerg Pernfuss <elessar@bsdforen.de> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/93754: [patch] dummynet changes ip_id, breaking fragment reassembly Message-ID: <200602231504.k1NF4gu7000413@www.freebsd.org> Resent-Message-ID: <200602231510.k1NFA3p7017018@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 93754 >Category: kern >Synopsis: [patch] dummynet changes ip_id, breaking fragment reassembly >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Feb 23 15:10:02 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Joerg Pernfuss >Release: FreeBSD 5.4-STABLE i386 >Organization: >Environment: >Description: "When forwarding fragmented packets through a dummynet pipe (ip_input -> ip_forward -> ip_output -> pipe -> ip_output) the last ip_output() in the chain that does the actual IP delivery sets ip_id of all fragments to different values, making it impossible to reassemble the packet at receive side." (Taken from ru@'s description of the releng_6 patch) A patch for RELENG_6 was already committed. The patch below is based on that commit, stripped of the ipv6 case (releng_5 has no dummynet ipv6) and the netgraph stuff (netgraph/ng_ipfw.[ch] was introduced with releng_6). The problem was raised on de-bsd-questions@, i run 6.0-STABLE, so no uname(1) provided. >How-To-Repeat: Send fragmented ip packets through a dummynet pipe. >Fix: Either: a) update your system to releng_6 after 2006-02-17 (problem was fixed there) b) apply the following patch: cd /sys/inet; patch < /location/of/patch; rebuild your kernel, reboot --- ip_dummynet.c Tue Feb 21 01:01:23 2006 +++ ip_dummynet.c Tue Feb 21 01:13:00 2006 @@ -453,7 +453,7 @@ DUMMYNET_UNLOCK(); switch (pkt->dn_dir) { case DN_TO_IP_OUT: - (void)ip_output(m, NULL, NULL, pkt->flags, NULL, NULL); + (void)ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL); break ; case DN_TO_IP_IN : @@ -1128,7 +1128,6 @@ * NULL in ip_input, destination interface in ip_output, * real_dst in bdg_forward * rule matching rule, in case of multiple passes - * flags flags from the caller, only used in ip_output * */ static int @@ -1212,8 +1211,6 @@ pkt->dn_dir = dir ; pkt->ifp = fwa->oif; - if (dir == DN_TO_IP_OUT) - pkt->flags = fwa->flags; if (q->head == NULL) q->head = m; else --- ip_dummynet.h Tue Feb 21 01:24:10 2006 +++ ip_dummynet.h Tue Feb 21 01:28:26 2006 @@ -129,7 +129,6 @@ dn_key output_time; /* when the pkt is due for delivery */ struct ifnet *ifp; /* interface, for ip_output */ - int flags ; /* flags, for ip_output (IPv6 ?) */ }; #endif /* _KERNEL */ --- ip_fw.h Tue Feb 21 01:25:14 2006 +++ ip_fw.h Tue Feb 21 01:26:16 2006 @@ -435,8 +435,6 @@ struct ip_fw *rule; /* matching rule */ struct ether_header *eh; /* for bridged packets */ - int flags; /* for dummynet */ - struct ipfw_flow_id f_id; /* grabbed from IP header */ u_int32_t retval; struct inpcb *inp; >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200602231504.k1NF4gu7000413>