Page MenuHomeFreeBSD

D40256.id122371.diff
No OneTemporary

D40256.id122371.diff

diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -136,6 +136,12 @@
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 = {
@@ -816,6 +822,20 @@
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
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -177,6 +177,12 @@
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",
@@ -884,6 +890,20 @@
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
*/
diff --git a/tests/sys/netpfil/pf/rdr.sh b/tests/sys/netpfil/pf/rdr.sh
--- a/tests/sys/netpfil/pf/rdr.sh
+++ b/tests/sys/netpfil/pf/rdr.sh
@@ -67,7 +67,59 @@
pft_cleanup
}
+atf_test_case "local_redirect" "cleanup"
+local_redirect_head()
+{
+ atf_set descr 'Redirect local traffic test'
+ atf_set require.user root
+}
+
+local_redirect_body()
+{
+ pft_init
+
+ bridge=$(vnet_mkbridge)
+ ifconfig ${bridge} 192.0.2.1/24 up
+
+ epair1=$(vnet_mkepair)
+ epair2=$(vnet_mkepair)
+
+ vnet_mkjail first ${epair1}b
+ ifconfig ${epair1}a up
+ ifconfig ${bridge} addm ${epair1}a
+ jexec first ifconfig ${epair1}b 192.0.2.2/24 up
+ jexec first ifconfig lo0 127.0.0.1/8 up
+
+ vnet_mkjail second ${epair2}b
+ ifconfig ${epair2}a up
+ ifconfig ${bridge} addm ${epair2}a
+ jexec second ifconfig ${epair2}b 192.0.2.3/24 up
+ jexec second ifconfig lo0 127.0.0.1/8 up
+ jexec second sysctl net.inet.ip.forwarding=1
+ jexec second sysctl net.inet.ip.filter_local_output=1
+
+ # Enable pf!
+ jexec second pfctl -e
+ pft_set_rules second \
+ "rdr pass proto tcp from any to 192.0.2.3/24 port 1234 -> 192.0.2.2 port 4321"
+
+ echo "foo" | jexec first nc -N -l 4321 &
+ sleep 1
+
+ # Verify that second can use its rule to redirect local connections to first
+ result=$(jexec second nc -N -w 3 192.0.2.3 1234)
+ if [ "$result" != "foo" ]; then
+ atf_fail "Redirect failed"
+ fi
+}
+
+local_redirect_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "basic"
+ atf_add_test_case "local_redirect"
}

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 8, 4:22 AM (4 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31075351
Default Alt Text
D40256.id122371.diff (4 KB)

Event Timeline