Hi, sysctl net.inet.ip.forwarding is checked before ip_input() passes the packet to ip_forward(). But with an af-to rule, pf(4) calls ip_forward() directly. I think we should check the sysctl also in pf to get consistent behaviour.
ok? bluhm Index: net/pf.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v retrieving revision 1.1098 diff -u -p -r1.1098 pf.c --- net/pf.c 14 Jan 2021 09:44:33 -0000 1.1098 +++ net/pf.c 15 Jan 2021 11:08:31 -0000 @@ -7259,20 +7259,32 @@ done: pd.m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; switch (pd.naf) { case AF_INET: - if (pd.dir == PF_IN) + if (pd.dir == PF_IN) { + if (ipforwarding == 0) { + ipstat_inc(ips_cantforward); + action = PF_DROP; + break; + } ip_forward(pd.m, ifp, NULL, 1); - else + } else ip_output(pd.m, NULL, NULL, 0, NULL, NULL, 0); break; case AF_INET6: - if (pd.dir == PF_IN) + if (pd.dir == PF_IN) { + if (ip6_forwarding == 0) { + ip6stat_inc(ip6s_cantforward); + action = PF_DROP; + break; + } ip6_forward(pd.m, NULL, 1); - else + } else ip6_output(pd.m, NULL, NULL, 0, NULL, NULL); break; } - pd.m = NULL; - action = PF_PASS; + if (action != PF_DROP) { + pd.m = NULL; + action = PF_PASS; + } break; #endif /* INET6 */ case PF_DROP: