Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146591028
D53216.id164676.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D53216.id164676.diff
View Options
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -5384,9 +5384,20 @@
yyerror("nat-to and rdr-to require keep state");
problems++;
}
- if (r->direction == PF_INOUT) {
- yyerror("nat-to and rdr-to require a direction");
- problems++;
+ }
+ if (!(r->rule_flag & PFRULE_AFTO)) {
+ /* XXX: Do af-to rule require direction? */
+ if (!TAILQ_EMPTY(&(r->nat.list))) {
+ if (r->direction != PF_OUT) {
+ yyerror("nat-to can only be used with direction out");
+ problems++;
+ }
+ }
+ if (!TAILQ_EMPTY(&(r->rdr.list))) {
+ if (r->direction != PF_IN) {
+ yyerror("rdr-to can only be used with direction in");
+ problems++;
+ }
}
}
if (r->route.opts & PF_POOL_STICKYADDR && !r->keep_state) {
diff --git a/sbin/pfctl/tests/files/pf1076.fail b/sbin/pfctl/tests/files/pf1076.fail
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1076.fail
@@ -0,0 +1 @@
+rdr-to can only be used with direction in
diff --git a/sbin/pfctl/tests/files/pf1076.in b/sbin/pfctl/tests/files/pf1076.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1076.in
@@ -0,0 +1 @@
+pass out on lo0 from any rdr-to 2001:db8::1
diff --git a/sbin/pfctl/tests/files/pf1077.fail b/sbin/pfctl/tests/files/pf1077.fail
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1077.fail
@@ -0,0 +1 @@
+nat-to can only be used with direction out
diff --git a/sbin/pfctl/tests/files/pf1077.in b/sbin/pfctl/tests/files/pf1077.in
new file mode 100644
--- /dev/null
+++ b/sbin/pfctl/tests/files/pf1077.in
@@ -0,0 +1 @@
+pass in on lo0 from any nat-to 2001:db8::1
diff --git a/sbin/pfctl/tests/pfctl_test_list.inc b/sbin/pfctl/tests/pfctl_test_list.inc
--- a/sbin/pfctl/tests/pfctl_test_list.inc
+++ b/sbin/pfctl/tests/pfctl_test_list.inc
@@ -184,3 +184,5 @@
PFCTL_TEST(1073, "Filter AF different than route-to AF, with prefer-ipv6-nexthop")
PFCTL_TEST_FAIL(1074, "Filter AF different than route-to AF, without prefer-ipv6-nexthop")
PFCTL_TEST(1075, "One shot rule")
+PFCTL_TEST_FAIL(1076, "rdr-to can only be used with direction in")
+PFCTL_TEST_FAIL(1077, "nat-to can only be used with direction out")
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -974,6 +974,7 @@
{
struct pf_pdesc *pd = ctx->pd;
struct pf_addr *naddr;
+ int idx;
uint16_t *nportp;
uint16_t low, high;
u_short reason;
@@ -988,8 +989,19 @@
return (PFRES_MEMORY);
}
- naddr = &ctx->nk->addr[1];
- nportp = &ctx->nk->port[1];
+ switch (nat_action) {
+ case PF_NAT:
+ idx = pd->sidx;
+ break;
+ case PF_BINAT:
+ idx = 1;
+ break;
+ case PF_RDR:
+ idx = pd->didx;
+ break;
+ }
+ naddr = &ctx->nk->addr[idx];
+ nportp = &ctx->nk->port[idx];
switch (nat_action) {
case PF_NAT:
diff --git a/tests/sys/netpfil/pf/nat.sh b/tests/sys/netpfil/pf/nat.sh
--- a/tests/sys/netpfil/pf/nat.sh
+++ b/tests/sys/netpfil/pf/nat.sh
@@ -477,15 +477,49 @@
pft_cleanup
}
-atf_test_case "nat_pass" "cleanup"
-nat_pass_head()
+atf_test_case "nat_pass_in" "cleanup"
+nat_pass_in_head()
{
- atf_set descr 'IPv4 NAT on pass rule'
+ atf_set descr 'IPv4 NAT on inbound pass rule'
atf_set require.user root
atf_set require.progs scapy
}
-nat_pass_body()
+nat_pass_in_body()
+{
+ setup_router_server_ipv4
+ # Delete the route back to make sure that the traffic has been NAT-ed
+ jexec server route del -net ${net_tester} ${net_server_host_router}
+ # Provide routing back to the NAT address
+ jexec server route add 203.0.113.0/24 ${net_server_host_router}
+ jexec router route add 203.0.113.0/24 -iface ${epair_tester}b
+
+ pft_set_rules router \
+ "block" \
+ "pass in on ${epair_tester}b inet proto tcp nat-to 203.0.113.0 keep state" \
+ "pass out on ${epair_server}a inet proto tcp keep state"
+
+ ping_server_check_reply exit:0 --ping-type=tcp3way --send-sport=4201
+
+ jexec router pfctl -qvvsr
+ jexec router pfctl -qvvss
+ jexec router ifconfig
+ jexec router netstat -rn
+}
+
+nat_pass_in_cleanup()
+{
+ pft_cleanup
+}
+
+nat_pass_out_head()
+{
+ atf_set descr 'IPv4 NAT on outbound pass rule'
+ atf_set require.user root
+ atf_set require.progs scapy
+}
+
+nat_pass_out_body()
{
setup_router_server_ipv4
# Delete the route back to make sure that the traffic has been NAT-ed
@@ -504,7 +538,7 @@
jexec router netstat -rn
}
-nat_pass_cleanup()
+nat_pass_out_cleanup()
{
pft_cleanup
}
@@ -874,10 +908,14 @@
atf_add_test_case "no_addrs_random"
atf_add_test_case "map_e_compat"
atf_add_test_case "map_e_pass"
- atf_add_test_case "nat_pass"
+ atf_add_test_case "nat_pass_out"
atf_add_test_case "nat_match"
atf_add_test_case "binat_compat"
atf_add_test_case "binat_match"
atf_add_test_case "empty_pool"
atf_add_test_case "dummynet_mask"
+
+ # Skip this case: pfctl only allows nat-to on outbound rules even though
+ # kernel code properly nats and rdrs in the opposite direction.
+ # atf_add_test_case "nat_pass_in"
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 4, 10:16 PM (2 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29258031
Default Alt Text
D53216.id164676.diff (4 KB)
Attached To
Mode
D53216: pf: Make nat-to and rdr-to work properly both on in and out rules
Attached
Detach File
Event Timeline
Log In to Comment