Date: Fri, 12 May 2006 17:19:32 -0400 From: Adam McDougall <mcdouga9@egr.msu.edu> To: Daniel Hartmeier <daniel@benzedrine.cx> Cc: Andrew Thompson <thompsa@freebsd.org>, freebsd-pf@freebsd.org Subject: Re: broken ip checksum after frag reassemble of nfs READDIR? Message-ID: <20060512211932.GA9173@egr.msu.edu> In-Reply-To: <20060508182723.GG9739@insomnia.benzedrine.cx> References: <20060402054532.GF17711@egr.msu.edu> <20060404145704.GW2684@insomnia.benzedrine.cx> <20060404153443.GX2684@insomnia.benzedrine.cx> <200604051441.16865.max@love2party.net> <20060405130645.GB5683@insomnia.benzedrine.cx> <20060416053023.GD56603@heff.fud.org.nz> <20060508154929.GS30200@egr.msu.edu> <20060508182723.GG9739@insomnia.benzedrine.cx>
next in thread | previous in thread | raw e-mail | index | archive | help
Thanks, that does seem to work. I can now use UDP NFS because the checksum is valid. I am also testing it alongside the bridge fragmentation patch and that works as well. I'm pretty sure these two patches remove the roadblocks from me putting it into production in bridging mode! On Mon, May 08, 2006 at 08:27:23PM +0200, Daniel Hartmeier wrote: On Mon, May 08, 2006 at 11:49:30AM -0400, Adam McDougall wrote: > Could someone possibly produce a patch to force if_bridge to > recalculate the checksum on every packet so I can test that as well? > To me, the extra load on the firewall is less important than breaking > packets I am trying to pass. Try the patch below, the first one is against -current and the second against 6.0-stable. It compiles, but is otherwise untested. I'm not sure if the potential m_pullup() is needed, but better safe than sorry. Maybe Andrew can comment. Daniel Index: if_bridge.c =================================================================== RCS file: /pub/tmp/cvs/freebsd/src/sys/net/if_bridge.c,v retrieving revision 1.59 diff -u -r1.59 if_bridge.c --- if_bridge.c 29 Apr 2006 05:37:25 -0000 1.59 +++ if_bridge.c 8 May 2006 18:17:40 -0000 @@ -2590,7 +2590,7 @@ static int bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) { - int snap, error, i; + int snap, error, i, hlen; struct ether_header *eh1, eh2; struct ip_fw_args args; struct ip *ip; @@ -2787,8 +2787,25 @@ /* Restore ip and the fields ntohs()'d. */ ip = mtod(*mp, struct ip *); + if (ip == NULL) + goto bad; + hlen = ip->ip_hl << 2; + if (hlen < sizeof(struct ip)) + goto bad; + if (hlen > (*mp)->m_len) { + if ((*mp = m_pullup(*mp, hlen)) == 0) + goto bad; + ip = mtod(*mp, struct ip *); + if (ip == NULL) + goto bad; + } ip->ip_len = htons(ip->ip_len); ip->ip_off = htons(ip->ip_off); + ip->ip_sum = 0; + if (hlen == sizeof(struct ip)) + ip->ip_sum = in_cksum_hdr(ip); + else + ip->ip_sum = in_cksum(*mp, hlen); break; # ifdef INET6 Index: if_bridge.c =================================================================== RCS file: /pub/tmp/cvs/freebsd/src/sys/net/if_bridge.c,v retrieving revision 1.11.2.12.2.4 diff -u -r1.11.2.12.2.4 if_bridge.c --- if_bridge.c 25 Jan 2006 10:01:26 -0000 1.11.2.12.2.4 +++ if_bridge.c 8 May 2006 18:21:03 -0000 @@ -2281,7 +2281,7 @@ static int bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir) { - int snap, error, i; + int snap, error, i, hlen; struct ether_header *eh1, eh2; struct ip_fw_args args; struct ip *ip; @@ -2459,8 +2459,25 @@ /* Restore ip and the fields ntohs()'d. */ if (*mp != NULL && error == 0) { ip = mtod(*mp, struct ip *); + if (ip == NULL) + goto bad; + hlen = ip->ip_hl << 2; + if (hlen < sizeof(struct ip)) + goto bad; + if (hlen > (*mp)->m_len) { + if ((*mp = m_pullup(*mp, hlen)) == 0) + goto bad; + ip = mtod(*mp, struct ip *); + if (ip == NULL) + goto bad; + } ip->ip_len = htons(ip->ip_len); ip->ip_off = htons(ip->ip_off); + ip->ip_sum = 0; + if (hlen == sizeof(struct ip)) + ip->ip_sum = in_cksum_hdr(ip); + else + ip->ip_sum = in_cksum(*mp, hlen); } break;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20060512211932.GA9173>