FreeBSD Bugzilla – Attachment 239803 Details for
Bug 268717
[pf] [ipnat] rdr rules don't work for traffic originating at localhost
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Better fix for the problem, covering both pf and ipfilter
rdr2.diff (text/plain), 4.52 KB, created by
dfr
on 2023-01-30 11:57:21 UTC
(
hide
)
Description:
Better fix for the problem, covering both pf and ipfilter
Filename:
MIME Type:
Creator:
dfr
Created:
2023-01-30 11:57:21 UTC
Size:
4.52 KB
patch
obsolete
>commit 631eb96531891fa2598c96f1d833e81c2113d87c >Author: Doug Rabson <dfr@FreeBSD.org> >Date: Wed Jan 4 16:15:57 2023 +0000 > > netinet*: Fix redirects for connections from localhost > > Redirect rules use PFIL_IN and PFIL_OUT events to allow packet filter > rules to change the destination address and port for a connection. > Typically, the rule triggers on an input event when a packet is received > by a router and the destination address and/or port is changed to > implement the redirect. When a reply packet on this connection is output > to the network, the rule triggers again, reversing the modification. > > When the connection is initiated on the same host as the packet filter, > it is initially output via lo0 which queues it for input processing. > This causes an input event on the lo0 interface, allowing redirect > processing to rewrite the destination and create state for the > connection. However, when the reply is received, no corresponding output > event is generated; instead, the packet is delivered to the higher level > protocol (e.g. tcp or udp) without reversing the redirect, the reply is > not matched to the connection and the packet is dropped (for tcp, a > connection reset is also sent). > > This commit fixes the problem by adding a second packet filter call in > the input path. The second call happens right before the handoff to > higher level processing and provides the missing output event to allow > the redirect's reply processing to perform its rewrite. This extra > processing is disabled by default and can be enabled using sysctl: > > sysctl net.inet.ip.filter_local_output=1 > sysctl net.inet6.ip6.filter_local_output=1 > > PR: 268717 > >diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c >index b33d1e1b6697..4247462f0a8e 100644 >--- a/sys/netinet/ip_input.c >+++ b/sys/netinet/ip_input.c >@@ -135,6 +135,12 @@ SYSCTL_BOOL(_net_inet_ip, OID_AUTO, source_address_validation, > CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip_sav), true, > "Drop incoming packets with source address that is a local address"); > >+VNET_DEFINE_STATIC(bool, ip_filter_local_output) = false; >+#define V_ip_filter_local_output VNET(ip_filter_local_output) >+SYSCTL_BOOL(_net_inet_ip, OID_AUTO, filter_local_output, >+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip_filter_local_output), false, >+ "Generate filter output events for packets delivered for local processing"); >+ > VNET_DEFINE(pfil_head_t, inet_pfil_head); /* Packet filter hooks */ > > static struct netisr_handler ip_nh = { >@@ -810,6 +816,20 @@ ip_input(struct mbuf *m) > return; > #endif /* IPSTEALTH */ > >+ /* >+ * We are going to ship the packet to the local protocol stack. Call the >+ * filter again for this 'output' action, allowing redirect-like rules >+ * to adjust the source address. >+ */ >+ if (PFIL_HOOKED_OUT(V_inet_pfil_head) && V_ip_filter_local_output) { >+ if (pfil_mbuf_out(V_inet_pfil_head, &m, V_loif, NULL) != >+ PFIL_PASS) >+ return; >+ if (m == NULL) /* consumed by filter */ >+ return; >+ ip = mtod(m, struct ip *); >+ } >+ > /* > * Attempt reassembly; if it succeeds, proceed. > * ip_reass() will return a different mbuf. >diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c >index ff1402faac69..9a8f146eece6 100644 >--- a/sys/netinet6/ip6_input.c >+++ b/sys/netinet6/ip6_input.c >@@ -176,6 +176,12 @@ SYSCTL_BOOL(_net_inet6_ip6, OID_AUTO, source_address_validation, > CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_sav), true, > "Drop incoming packets with source address that is a local address"); > >+VNET_DEFINE_STATIC(bool, ip6_filter_local_output) = false; >+#define V_ip6_filter_local_output VNET(ip6_filter_local_output) >+SYSCTL_BOOL(_net_inet6_ip6, OID_AUTO, filter_local_output, >+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_filter_local_output), false, >+ "Generate filter output events for packets delivered for local processing"); >+ > #ifdef RSS > static struct netisr_handler ip6_direct_nh = { > .nh_name = "ip6_direct", >@@ -883,6 +889,20 @@ ip6_input(struct mbuf *m) > return; > } > >+ /* >+ * We are going to ship the packet to the local protocol stack. Call the >+ * filter again for this 'output' action, allowing redirect-like rules >+ * to adjust the source address. >+ */ >+ if (PFIL_HOOKED_OUT(V_inet_pfil_head) && V_ip6_filter_local_output) { >+ if (pfil_mbuf_out(V_inet6_pfil_head, &m, V_loif, NULL) != >+ PFIL_PASS) >+ return; >+ if (m == NULL) /* consumed by filter */ >+ return; >+ ip6 = mtod(m, struct ip6_hdr *); >+ } >+ > /* > * Tell launch routine the next header > */
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 268717
:
239212
|
239234
|
239274
| 239803