K 10 svn:author V 7 glebius K 8 svn:date V 27 2012-04-17T14:26:55.787393Z K 7 svn:log V 1694 Fixes to pf_route(), pf_route6(). These functions are very special, they may call into send side of IP stack, for example they call ifp->if_output(), icmp_error(), icmp6_error(), ip6_output(), and they also can perform route lookup. Even more, they can call pf_test() or pf_test6() recursively! Hence, they need dropping any pf(4) locks before. Fortunately, pf_route() and pf_route6() are called only at the very end of packet processing, so we can drop the pf(4) locks with no need re-acquire them, thus: o Drop locks in pf_route(), pf_route6() in all error cases. o Drop locks in pf_route(), pf_route6() as soon as we get information from the state, or if there is no state, or if we don't need state. More cleanups and fixes to pf_route(): - We don't need to check for m_len, pf_test() already did this. - To do route lookup we don't need to allocate 'struct route' on stack, we can just have a sockaddr and rtentry pointer. - We need rtentry for a quite short time, so it is better to avoid its unlocking and refcounting. - In case if new interface (after routing rule applied) is a loopback one, then put M_SKIP_FIREWALL on mbuf, otherwise we may end up with infinite processing. [1] - Update the copy-paste from ip_output() bringing in TSO and SCTP support. - Reduce number of byte order swaps. More cleanups and fixes to pf_route6(): - We don't need to check for m_len, pf_test() already did this. - We don't need struct route_in6 on stack, a sockaddr_in6 would be enough. - In case if new interface (after routing rule applied) is a loopback one, then put M_SKIP_FIREWALL on mbuf, otherwise we may end up with infinite processing. [1] Discussed with: eri [1] END