From owner-svn-src-head@FreeBSD.ORG Thu Oct 2 00:25:58 2014 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 76009D8E; Thu, 2 Oct 2014 00:25:58 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 621225F0; Thu, 2 Oct 2014 00:25:58 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s920Pw5b008960; Thu, 2 Oct 2014 00:25:58 GMT (envelope-from hrs@FreeBSD.org) Received: (from hrs@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s920PvEW008958; Thu, 2 Oct 2014 00:25:57 GMT (envelope-from hrs@FreeBSD.org) Message-Id: <201410020025.s920PvEW008958@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: hrs set sender to hrs@FreeBSD.org using -f From: Hiroki Sato Date: Thu, 2 Oct 2014 00:25:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r272391 - in head/sys: netinet netinet6 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Oct 2014 00:25:58 -0000 Author: hrs Date: Thu Oct 2 00:25:57 2014 New Revision: 272391 URL: https://svnweb.freebsd.org/changeset/base/272391 Log: Add an additional routing table lookup when m->m_pkthdr.fibnum is changed at a PFIL hook in ip{,6}_output(). IPFW setfib rule did not perform a routing table lookup when the destination address was not changed. CR: D805 Modified: head/sys/netinet/ip_output.c head/sys/netinet6/ip6_output.c Modified: head/sys/netinet/ip_output.c ============================================================================== --- head/sys/netinet/ip_output.c Thu Oct 2 00:19:24 2014 (r272390) +++ head/sys/netinet/ip_output.c Thu Oct 2 00:25:57 2014 (r272391) @@ -136,7 +136,9 @@ ip_output(struct mbuf *m, struct mbuf *o struct rtentry *rte; /* cache for ro->ro_rt */ struct in_addr odst; struct m_tag *fwd_tag = NULL; + uint32_t fibnum; int have_ia_ref; + int needfiblookup; #ifdef IPSEC int no_route_but_check_spd = 0; #endif @@ -202,6 +204,7 @@ ip_output(struct mbuf *m, struct mbuf *o * therefore we need restore gw if we're redoing lookup. */ gw = dst = (struct sockaddr_in *)&ro->ro_dst; + fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : M_GETFIB(m); again: ia = NULL; have_ia_ref = 0; @@ -283,10 +286,9 @@ again: #ifdef RADIX_MPATH rtalloc_mpath_fib(ro, ntohl(ip->ip_src.s_addr ^ ip->ip_dst.s_addr), - inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m)); + fibnum); #else - in_rtalloc_ign(ro, 0, - inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m)); + in_rtalloc_ign(ro, 0, fibnum); #endif rte = ro->ro_rt; } @@ -504,6 +506,7 @@ sendit: goto done; ip = mtod(m, struct ip *); + needfiblookup = 0; /* See if destination IP address was changed by packet filter. */ if (odst.s_addr != ip->ip_dst.s_addr) { @@ -529,9 +532,18 @@ sendit: } else { if (have_ia_ref) ifa_free(&ia->ia_ifa); - goto again; /* Redo the routing table lookup. */ + needfiblookup = 1; /* Redo the routing table lookup. */ } } + /* See if fib was changed by packet filter. */ + if (fibnum != M_GETFIB(m)) { + m->m_flags |= M_SKIP_FIREWALL; + fibnum = M_GETFIB(m); + RO_RTFREE(ro); + needfiblookup = 1; + } + if (needfiblookup) + goto again; /* See if local, if yes, send it to netisr with IP_FASTFWD_OURS. */ if (m->m_flags & M_FASTFWD_OURS) { Modified: head/sys/netinet6/ip6_output.c ============================================================================== --- head/sys/netinet6/ip6_output.c Thu Oct 2 00:19:24 2014 (r272390) +++ head/sys/netinet6/ip6_output.c Thu Oct 2 00:25:57 2014 (r272391) @@ -255,6 +255,8 @@ ip6_output(struct mbuf *m0, struct ip6_p struct route_in6 *ro_pmtu = NULL; int hdrsplit = 0; int sw_csum, tso; + int needfiblookup; + uint32_t fibnum; struct m_tag *fwd_tag = NULL; ip6 = mtod(m, struct ip6_hdr *); @@ -448,6 +450,7 @@ ip6_output(struct mbuf *m0, struct ip6_p if (ro->ro_rt == NULL) (void )flowtable_lookup(AF_INET6, m, (struct route *)ro); #endif + fibnum = (inp != NULL) ? inp->inp_inc.inc_fibnum : M_GETFIB(m); again: /* * if specified, try to fill in the traffic class field. @@ -489,7 +492,7 @@ again: dst_sa.sin6_addr = ip6->ip6_dst; } error = in6_selectroute_fib(&dst_sa, opt, im6o, ro, &ifp, - &rt, inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m)); + &rt, fibnum); if (error != 0) { if (ifp != NULL) in6_ifstat_inc(ifp, ifs6_out_discard); @@ -649,7 +652,7 @@ again: /* Determine path MTU. */ if ((error = ip6_getpmtu(ro_pmtu, ro, ifp, &finaldst, &mtu, - &alwaysfrag, inp ? inp->inp_inc.inc_fibnum : M_GETFIB(m))) != 0) + &alwaysfrag, fibnum)) != 0) goto bad; /* @@ -727,6 +730,7 @@ again: goto done; ip6 = mtod(m, struct ip6_hdr *); + needfiblookup = 0; /* See if destination IP address was changed by packet filter. */ if (!IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst)) { m->m_flags |= M_SKIP_FIREWALL; @@ -747,8 +751,17 @@ again: error = netisr_queue(NETISR_IPV6, m); goto done; } else - goto again; /* Redo the routing table lookup. */ + needfiblookup = 1; /* Redo the routing table lookup. */ } + /* See if fib was changed by packet filter. */ + if (fibnum != M_GETFIB(m)) { + m->m_flags |= M_SKIP_FIREWALL; + fibnum = M_GETFIB(m); + RO_RTFREE(ro); + needfiblookup = 1; + } + if (needfiblookup) + goto again; /* See if local, if yes, send it to netisr. */ if (m->m_flags & M_FASTFWD_OURS) {