only skip pf once for packets that are injected by a divert-packet socket.
authordlg <dlg@openbsd.org>
Fri, 23 Apr 2021 03:29:24 +0000 (03:29 +0000)
committerdlg <dlg@openbsd.org>
Fri, 23 Apr 2021 03:29:24 +0000 (03:29 +0000)
when a divert socket gets a packet from userland to send back through
the kernel, it marks it as diverted so pf knows not to divert it
back to userland again. this marking stuck to the packet though,
so if it went through pf again (eg, on the way out of the network
stack) pf would skip it again. this is undesirable if you want pf
to do things to the packet on this outgoing hope, such as nat.

this has pf clear the mark once it's been used, which allows the
next run of a packet through pf to have stuff work on it.

found by some people at parta networks.
ok sashan@ lteo@ bluhm@
bluhm@ also suggested keeping my diff in the same style as the rest of pf.c

sys/net/pf.c

index 28aa615..12d0597 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: pf.c,v 1.1114 2021/03/10 10:21:48 jsg Exp $ */
+/*     $OpenBSD: pf.c,v 1.1115 2021/04/23 03:29:24 dlg Exp $ */
 
 /*
  * Copyright (c) 2001 Daniel Hartmeier
@@ -6844,8 +6844,10 @@ pf_test(sa_family_t af, int fwdir, struct ifnet *ifp, struct mbuf **m0)
        if ((*m0)->m_pkthdr.pf.flags & PF_TAG_GENERATED)
                return (PF_PASS);
 
-       if ((*m0)->m_pkthdr.pf.flags & PF_TAG_DIVERTED_PACKET)
+       if ((*m0)->m_pkthdr.pf.flags & PF_TAG_DIVERTED_PACKET) {
+               (*m0)->m_pkthdr.pf.flags &= ~PF_TAG_DIVERTED_PACKET;
                return (PF_PASS);
+       }
 
        if ((*m0)->m_pkthdr.pf.flags & PF_TAG_REFRAGMENTED) {
                (*m0)->m_pkthdr.pf.flags &= ~PF_TAG_REFRAGMENTED;