From nobody@FreeBSD.org  Fri Apr 12 13:42:56 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115])
	by hub.freebsd.org (Postfix) with ESMTP id 32E2221C
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 12 Apr 2013 13:42:56 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 0A9D18AF
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 12 Apr 2013 13:42:56 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.5/8.14.5) with ESMTP id r3CDgtTo080882
	for <freebsd-gnats-submit@FreeBSD.org>; Fri, 12 Apr 2013 13:42:55 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.5/8.14.5/Submit) id r3CDgtXE080881;
	Fri, 12 Apr 2013 13:42:55 GMT
	(envelope-from nobody)
Message-Id: <201304121342.r3CDgtXE080881@red.freebsd.org>
Date: Fri, 12 Apr 2013 13:42:55 GMT
From: Kajetan Staszkiewicz <vegeta@tuxpowered.net>
To: freebsd-gnats-submit@FreeBSD.org
Subject: route-to rule forwarding traffic inspite of state limit
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         177808
>Category:       kern
>Synopsis:       [pf] [patch] route-to rule forwarding traffic inspite of state limit
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-pf
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 12 13:50:00 UTC 2013
>Closed-Date:    
>Last-Modified:  Mon Nov 18 16:20:00 UTC 2013
>Originator:     Kajetan Staszkiewicz
>Release:        FreeBSD 9.1-RELEASE
>Organization:
InnoGames GmbH
>Environment:
FreeBSD xxxxxxx 9.1-RELEASE FreeBSD 9.1-RELEASE #10 r247265M: Mon Feb 25 14:58:39 CET 2013     root@xxxxxxx:/usr/obj/usr/src/sys/IGLB3  amd64
>Description:
When a route-to rule is configured with a limit of states is hit, according to manual "further packets that would create state will not match this rule until existing states time out." This is only partially true. State is not created, src-node is not created, rule's action is PF_DROP. But if no next rule changes the routing behavior (e.g. if current rule is "quick"), the packet still gets forwarded according to route definition in this rule (so it was "matched").
>How-To-Repeat:
Feed a quick route-to rule with state limit with some traffic, it still is forwarded by pf.
>Fix:
--- pf.c.10 2013-04-04 16:56:04.000000000 +0200
+++ pf.c.11 2013-04-12 15:41:53.000000000 +0200
@@ -7148,7 +7148,7 @@
                break;
        default:
                /* pf_route can free the mbuf causing *m0 to become NULL */
-               if (r->rt)
+               if (action == PF_PASS && r->rt)
                        pf_route(m0, r, dir, kif->pfik_ifp, s, &pd);
                break;
        }
@@ -7655,7 +7655,7 @@
                break;
        default:
                /* pf_route6 can free the mbuf causing *m0 to become NULL */
-               if (r->rt)
+               if (action == PF_PASS && r->rt)
                        pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd);
                break;
        }


That's a quick and dirty hack, I have it tested only with a "quick" rule.

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-pf 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Fri Apr 12 23:56:00 UTC 2013 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=177808 

From: Kajetan Staszkiewicz <vegeta@tuxpowered.net>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/177808: [pf] [patch] route-to rule forwarding traffic inspite of state limit
Date: Mon, 18 Nov 2013 17:13:24 +0100

 --Boundary-00=_kyjiSwrOkn+usgI
 Content-Type: Text/Plain;
   charset="us-ascii"
 Content-Transfer-Encoding: 7bit
 
 The attached patch for FreeBSD 10 does basically the same thing, although in a 
 way that is easier to understand in code as it performs all actions inside 
 pf_test, instead of waiting for pf_check_in to free *m.
 
 -- 
 | pozdrawiam / greetings | powered by Debian, FreeBSD and CentOS |
 |  Kajetan Staszkiewicz  | jabber,email: vegeta()tuxpowered net  |
 |        Vegeta          | www: http://vegeta.tuxpowered.net     |
 `------------------------^---------------------------------------'
 
 --Boundary-00=_kyjiSwrOkn+usgI
 Content-Type: text/x-patch;
   charset="UTF-8";
   name="drop-traffic-on-state-creation-fail.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
 	filename="drop-traffic-on-state-creation-fail.patch"
 
 # It might happen that a passing rule fails to create a state for example due
 # to hitting its state limit. A PF_DROP action is set in such case but the rule
 # already has rt filled in which causes pf_route to be called and the packet
 # to be forwarded.
 #
 # Do not call pf_route at all if action is PF_DROP.
 # 
 # kajetan.staszkiewicz@innogames.de
 # Work sponsored by InnoGames GmbH
 #
 diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
 index 12d1e9a..59a349d 100644
 --- a/sys/netpfil/pf/pf.c
 +++ b/sys/netpfil/pf/pf.c
 @@ -6009,6 +6009,10 @@ done:
  		*m0 = NULL;
  		action = PF_PASS;
  		break;
 +	case PF_DROP:
 +		m_freem(*m0);
 +		*m0 = NULL;
 +		break;
  	default:
  		/* pf_route() returns unlocked. */
  		if (r->rt) {
 @@ -6382,6 +6386,10 @@ done:
  		*m0 = NULL;
  		action = PF_PASS;
  		break;
 +	case PF_DROP:
 +		m_freem(*m0);
 +		*m0 = NULL;
 +		break;
  	default:
  		/* pf_route6() returns unlocked. */
  		if (r->rt) {
 
 --Boundary-00=_kyjiSwrOkn+usgI--
>Unformatted:
