Date: Mon, 18 Feb 2002 09:31:13 -0800 From: "Crist J. Clark" <crist.clark@attbi.com> To: "Michael R. Wayne" <wayne@staff.msen.com> Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: Odd ipfw behaviour Message-ID: <20020218093113.H48401@blossom.cjclark.org> In-Reply-To: <20020218120117.E96593@staff.msen.com>; from wayne@staff.msen.com on Mon, Feb 18, 2002 at 12:01:17PM -0500 References: <200202152309.SAA00831@manor.msen.com> <20020216004721.B36782@blossom.cjclark.org> <20020218034112.D96593@staff.msen.com> <20020218054946.W48401@blossom.cjclark.org> <20020218120117.E96593@staff.msen.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Feb 18, 2002 at 12:01:17PM -0500, Michael R. Wayne wrote: > On Mon, Feb 18, 2002 at 05:49:46AM -0800, Crist J. Clark wrote: > > What precise version of FreeBSD are you running, BTW? > > 4.5 RELEASE, as stated in original message. Do these patches help? Index: ip_input.c =================================================================== RCS file: /export/ncvs/src/sys/netinet/ip_input.c,v retrieving revision 1.130.2.33 diff -u -r1.130.2.33 ip_input.c --- ip_input.c 14 Feb 2002 11:19:57 -0000 1.130.2.33 +++ ip_input.c 18 Feb 2002 17:19:24 -0000 @@ -1618,21 +1618,29 @@ int error, type = 0, code = 0; struct mbuf *mcopy; n_long dest; + struct in_addr pkt_dst; struct ifnet *destifp; #ifdef IPSEC struct ifnet dummyifp; #endif dest = 0; + /* + * Cache the destination address of the packet; this may be + * changed by use of 'ipfw fwd'. + */ + pkt_dst = ip_fw_fwd_addr == NULL ? + ip->ip_dst : ip_fw_fwd_addr->sin_addr; + #ifdef DIAGNOSTIC if (ipprintfs) printf("forward: src %lx dst %lx ttl %x\n", - (u_long)ip->ip_src.s_addr, (u_long)ip->ip_dst.s_addr, + (u_long)ip->ip_src.s_addr, (u_long)pkt_dst.s_addr, ip->ip_ttl); #endif - if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) { + if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(pkt_dst) == 0) { ipstat.ips_cantforward++; m_freem(m); return; @@ -1651,14 +1659,14 @@ sin = (struct sockaddr_in *)&ipforward_rt.ro_dst; if ((rt = ipforward_rt.ro_rt) == 0 || - ip->ip_dst.s_addr != sin->sin_addr.s_addr) { + pkt_dst.s_addr != sin->sin_addr.s_addr) { if (ipforward_rt.ro_rt) { RTFREE(ipforward_rt.ro_rt); ipforward_rt.ro_rt = 0; } sin->sin_family = AF_INET; sin->sin_len = sizeof(*sin); - sin->sin_addr = ip->ip_dst; + sin->sin_addr = pkt_dst; rtalloc_ign(&ipforward_rt, RTF_PRCLONING); if (ipforward_rt.ro_rt == 0) { @@ -1704,7 +1712,7 @@ if (rt->rt_ifp == m->m_pkthdr.rcvif && (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0 && satosin(rt_key(rt))->sin_addr.s_addr != 0 && - ipsendredirects && !srcrt) { + ipsendredirects && !srcrt && !ip_fw_fwd_addr) { #define RTA(rt) ((struct in_ifaddr *)(rt->rt_ifa)) u_long src = ntohl(ip->ip_src.s_addr); @@ -1713,7 +1721,7 @@ if (rt->rt_flags & RTF_GATEWAY) dest = satosin(rt->rt_gateway)->sin_addr.s_addr; else - dest = ip->ip_dst.s_addr; + dest = pkt_dst.s_addr; /* Router requirements says to only send host redirects */ type = ICMP_REDIRECT; code = ICMP_REDIRECT_HOST; Index: ip_output.c =================================================================== RCS file: /export/ncvs/src/sys/netinet/ip_output.c,v retrieving revision 1.99.2.25 diff -u -r1.99.2.25 ip_output.c --- ip_output.c 1 Feb 2002 10:42:09 -0000 1.99.2.25 +++ ip_output.c 18 Feb 2002 17:12:33 -0000 @@ -128,6 +128,7 @@ struct sockaddr_in *dst; struct in_ifaddr *ia = NULL; int isbroadcast, sw_csum; + struct in_addr pkt_dst; #ifdef IPSEC struct socket *so = NULL; struct secpolicy *sp = NULL; @@ -191,6 +192,9 @@ hlen = len; } ip = mtod(m, struct ip *); + pkt_dst = ip_fw_fwd_addr == NULL + ? ip->ip_dst : ip_fw_fwd_addr->sin_addr; + /* * Fill in IP header. */ @@ -219,14 +223,14 @@ * and is still up. If not, free it and try again. */ if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || - dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { + dst->sin_addr.s_addr != pkt_dst.s_addr)) { RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)0; } if (ro->ro_rt == 0) { dst->sin_family = AF_INET; dst->sin_len = sizeof(*dst); - dst->sin_addr = ip->ip_dst; + dst->sin_addr = pkt_dst; } /* * If routing to interface only, @@ -278,7 +282,7 @@ else isbroadcast = in_broadcast(dst->sin_addr, ifp); } - if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { + if (IN_MULTICAST(ntohl(pkt_dst.s_addr))) { struct in_multi *inm; m->m_flags |= M_MCAST; @@ -318,7 +322,7 @@ ip->ip_src = IA_SIN(ia)->sin_addr; } - IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm); + IN_LOOKUP_MULTI(pkt_dst, ifp, inm); if (inm != NULL && (imo == NULL || imo->imo_multicast_loop)) { /* @@ -582,8 +586,9 @@ /* * Check with the firewall... + * but not if we are already being fwd'd from a firewall. */ - if (fw_enable && IPFW_LOADED) { + if (fw_enable && IPFW_LOADED && !ip_fw_fwd_addr) { struct sockaddr_in *old = dst; off = ip_fw_chk_ptr(&ip, @@ -774,6 +779,7 @@ goto done; } + ip_fw_fwd_addr = NULL; pass: m->m_pkthdr.csum_flags |= CSUM_IP; sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist; -- Crist J. Clark | cjclark@alum.mit.edu | cjclark@jhu.edu http://people.freebsd.org/~cjc/ | cjc@freebsd.org To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020218093113.H48401>