Subject: kern/34746: pf(4) synproxy state feature doesn't work with tag/tagged keywords
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Nino Dehne <ndehne@gmail.com>
List: netbsd-bugs
Date: 10/07/2006 18:05:00
>Number: 34746
>Category: kern
>Synopsis: pf(4)'s synproxy state breaks when used with tags
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Oct 07 18:05:00 +0000 2006
>Originator: Nino Dehne
>Release: 4.99.3
>Organization:
>Environment:
System: NetBSD [...] 4.99.3 NetBSD 4.99.3 (KERNEL) #0: Thu Oct 5 00:54:03 CEST 2006 build@[...]:/tmp/wrap/HEAD/obj/x/s/n/HEAD/src/sys/arch/i386/compile/KERNEL i386
Architecture: i386
Machine: i386
>Description:
Using the synproxy state feature of pf together with the tag/tagged keywords
doesn't work.
This problem was reported for OpenBSD here:
http://archives.neohapsis.com/archives/openbsd/2005-04/0709.html
A patch was committed to the OpenBSD CVS repository later. I believe the
relevant diff is from 1.483 to 1.486 of OpenBSD's src/sys/dev/net/pf.c.
They fixed some other bug in 1.487 which I pulled in locally as well, beware
though.
>How-To-Repeat:
/etc/pf.conf:
pass in quick on $ext_if proto tcp from any to any port 22 flags S/SA \
tag EXT-INT synproxy state (if-bound)
pass out quick on $int_if tagged EXT-INT (if-bound)
The packet is not matched by the second rule.
>Fix:
Pull a diff for src/sys/net/pf.c from revision 1.483 to 1.486 from OpenBSD's
CVS repository. It applies with some offsets to our version and fixes the
problem for me.
A diff from 1.483 to 1.487 that applies cleanly is attached.
--EVF5PPMfhYS0aIcm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pf.c.diff"
2c2
< /* $OpenBSD: pf.c,v 1.483 2005/03/15 17:38:43 dhartmei Exp $ */
---
> /* $OpenBSD: pf.c,v 1.487 2005/04/22 09:53:18 dhartmei Exp $ */
164c164
< struct ether_header *, struct ifnet *);
---
> u_int16_t, struct ether_header *, struct ifnet *);
1008c1008
< TH_RST|TH_ACK, 0, 0, 0, 1, NULL, NULL);
---
> TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
1471c1471
< struct ether_header *eh, struct ifnet *ifp)
---
> u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp)
1517a1518,1522
> if (rtag)
> if (pf_tag_packet(m, NULL, rtag)) {
> m_freem(m);
> return;
> }
2939c2944
< r->return_ttl, 1, pd->eh, kif->pfik_ifp);
---
> r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
3139c3144
< TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, NULL, NULL);
---
> TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL);
4115c4120
< NULL, NULL);
---
> 0, NULL, NULL);
4153c4158
< (*state)->src.mss, 0, 0, NULL, NULL);
---
> (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL);
4168c4173
< NULL, NULL);
---
> (*state)->tag, NULL, NULL);
4173c4178
< NULL, NULL);
---
> 0, NULL, NULL);
4179,4180d4183
< (*state)->src.max_win;
< (*state)->dst.seqhi = (*state)->dst.seqlo +
4181a4185,4186
> (*state)->dst.seqhi = (*state)->dst.seqlo +
> (*state)->src.max_win;
4452c4457
< (*state)->rule.ptr->return_ttl, 1,
---
> (*state)->rule.ptr->return_ttl, 1, 0,
--EVF5PPMfhYS0aIcm--
>Unformatted:
--EVF5PPMfhYS0aIcm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline