Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102552995
D42609.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D42609.diff
View Options
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -303,6 +303,8 @@
static void pf_state_key_detach(struct pf_kstate *, int);
static int pf_state_key_ctor(void *, int, void *, int);
static u_int32_t pf_tcp_iss(struct pf_pdesc *);
+static __inline void pf_dummynet_flag_remove(struct mbuf *m,
+ struct pf_mtag *pf_mtag);
static int pf_dummynet(struct pf_pdesc *, struct pf_kstate *,
struct pf_krule *, struct mbuf **);
static int pf_dummynet_route(struct pf_pdesc *,
@@ -4140,7 +4142,7 @@
/* But only once. We may see the packet multiple times (e.g.
* PFIL_IN/PFIL_OUT). */
- mtag->flags &= ~PF_MTAG_FLAG_DUMMYNET;
+ pf_dummynet_flag_remove(m, mtag);
return (PF_PASS);
}
@@ -4361,7 +4363,7 @@
mtag->flags |= PF_MTAG_FLAG_DUMMYNET;
ip_dn_io_ptr(m0, &dnflow);
if (*m0 != NULL)
- mtag->flags &= ~PF_MTAG_FLAG_DUMMYNET;
+ pf_dummynet_flag_remove(m, mtag);
} else {
PF_RULES_RUNLOCK();
}
@@ -7794,6 +7796,21 @@
return (pf_test_eth_rule(dir, kif, m0));
}
+static __inline void
+pf_dummynet_flag_remove(struct mbuf *m, struct pf_mtag *pf_mtag)
+{
+ struct m_tag *mtag;
+
+ pf_mtag->flags &= ~PF_MTAG_FLAG_DUMMYNET;
+
+ /* dummynet adds this tag, but pf does not need it,
+ * and keeping it creates unexpected behavior,
+ * e.g. in case of divert(4) usage right after dummynet. */
+ mtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL);
+ if (mtag != NULL)
+ m_tag_delete(m, mtag);
+}
+
static int
pf_dummynet(struct pf_pdesc *pd, struct pf_kstate *s,
struct pf_krule *r, struct mbuf **m0)
@@ -7844,7 +7861,7 @@
ip_dn_io_ptr(m0, &dnflow);
if (*m0 != NULL) {
pd->pf_mtag->flags &= ~PF_MTAG_FLAG_ROUTE_TO;
- pd->pf_mtag->flags &= ~PF_MTAG_FLAG_DUMMYNET;
+ pf_dummynet_flag_remove(*m0, pd->pf_mtag);
}
}
}
@@ -7933,7 +7950,7 @@
/* But only once. We may see the packet multiple times (e.g.
* PFIL_IN/PFIL_OUT). */
- pd.pf_mtag->flags &= ~PF_MTAG_FLAG_DUMMYNET;
+ pf_dummynet_flag_remove(m, pd.pf_mtag);
PF_RULES_RUNLOCK();
return (PF_PASS);
@@ -8494,7 +8511,7 @@
if (ip_dn_io_ptr != NULL && pd.pf_mtag != NULL &&
pd.pf_mtag->flags & PF_MTAG_FLAG_DUMMYNET) {
- pd.pf_mtag->flags &= ~PF_MTAG_FLAG_DUMMYNET;
+ pf_dummynet_flag_remove(m, pd.pf_mtag);
/* Dummynet re-injects packets after they've
* completed their delay. We've already
* processed them, so pass unconditionally. */
diff --git a/tests/sys/netpfil/pf/divert-to.sh b/tests/sys/netpfil/pf/divert-to.sh
--- a/tests/sys/netpfil/pf/divert-to.sh
+++ b/tests/sys/netpfil/pf/divert-to.sh
@@ -51,11 +51,13 @@
# > outbound > diverted > outbound | network terminated
#
# Test case naming legend:
+# ipfwon - with ipfw enabled
+# ipfwoff - with ipfw disabled
# in - inbound
# div - diverted
# out - outbound
# fwd - forwarded
-# ipfwon - with ipfw enabled, which allows all
+# dn - delayed by dummynet
#
. $(atf_get_srcdir)/utils.subr
@@ -67,6 +69,13 @@
fi
}
+dummynet_init()
+{
+ if ! kldstat -q -m dummynet; then
+ atf_skip "This test requires dummynet"
+ fi
+}
+
ipfw_init()
{
if ! kldstat -q -m ipfw; then
@@ -396,6 +405,110 @@
pft_cleanup
}
+atf_test_case "ipfwoff_in_dn_in_div_in_out_dn_out_div_out" "cleanup"
+ipfwoff_in_dn_in_div_in_out_dn_out_div_out_head()
+{
+ atf_set descr 'Test inbound > delayed+diverted > outbound > delayed+diverted > outbound | network terminated'
+ atf_set require.user root
+}
+ipfwoff_in_dn_in_div_in_out_dn_out_div_out_body()
+{
+ local ipfwon
+
+ pft_init
+ divert_init
+ dummynet_init
+ test "$1" == "ipfwon" && ipfwon="yes"
+ test $ipfwon && ipfw_init || assert_ipfw_is_off
+
+ epair=$(vnet_mkepair)
+ vnet_mkjail alcatraz ${epair}b
+ ifconfig ${epair}a 192.0.2.1/24 up
+ ifconfig ${epair}a ether 02:00:00:00:00:01
+ jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
+ test $ipfwon && jexec alcatraz ipfw add 65534 allow all from any to any
+
+ # Sanity check
+ atf_check -s exit:0 -o ignore ping -c3 192.0.2.2
+
+ # a) ping should time out due to very narrow dummynet pipes {
+
+ jexec alcatraz dnctl pipe 1001 config bw 1Byte/s
+ jexec alcatraz dnctl pipe 1002 config bw 1Byte/s
+
+ jexec alcatraz pfctl -e
+ pft_set_rules alcatraz \
+ "ether pass in from 02:00:00:00:00:01 l3 all dnpipe 1001" \
+ "ether pass out to 02:00:00:00:00:01 l3 all dnpipe 1002 " \
+ "pass all" \
+ "pass in inet proto icmp icmp-type echoreq divert-to 127.0.0.1 port 1001 no state" \
+ "pass out inet proto icmp icmp-type echorep divert-to 127.0.0.1 port 1002 no state"
+
+ jexec alcatraz $(atf_get_srcdir)/divapp 1001 divert-back &
+ indivapp_pid=$!
+ jexec alcatraz $(atf_get_srcdir)/divapp 1002 divert-back &
+ outdivapp_pid=$!
+ # Wait for the divappS to be ready
+ sleep 1
+
+ atf_check -s not-exit:0 -o ignore ping -c1 -s56 -t1 192.0.2.2
+
+ wait $indivapp_pid
+ atf_check_not_equal 0 $?
+ wait $outdivapp_pid
+ atf_check_not_equal 0 $?
+
+ # }
+
+ # b) ping should NOT time out due to wide enough dummynet pipes {
+
+ jexec alcatraz dnctl pipe 2001 config bw 100KByte/s
+ jexec alcatraz dnctl pipe 2002 config bw 100KByte/s
+
+ jexec alcatraz pfctl -e
+ pft_set_rules alcatraz \
+ "ether pass in from 02:00:00:00:00:01 l3 all dnpipe 2001" \
+ "ether pass out to 02:00:00:00:00:01 l3 all dnpipe 2002 " \
+ "pass all" \
+ "pass in inet proto icmp icmp-type echoreq divert-to 127.0.0.1 port 2001 no state" \
+ "pass out inet proto icmp icmp-type echorep divert-to 127.0.0.1 port 2002 no state"
+
+ jexec alcatraz $(atf_get_srcdir)/divapp 2001 divert-back &
+ indivapp_pid=$!
+ jexec alcatraz $(atf_get_srcdir)/divapp 2002 divert-back &
+ outdivapp_pid=$!
+ # Wait for the divappS to be ready
+ sleep 1
+
+ atf_check -s exit:0 -o ignore ping -c1 -s56 -t1 192.0.2.2
+
+ wait $indivapp_pid
+ atf_check_equal 0 $?
+ wait $outdivapp_pid
+ atf_check_equal 0 $?
+
+ # }
+}
+ipfwoff_in_dn_in_div_in_out_dn_out_div_out_cleanup()
+{
+ pft_cleanup
+}
+
+atf_test_case "ipfwon_in_dn_in_div_in_out_dn_out_div_out" "cleanup"
+ipfwon_in_dn_in_div_in_out_dn_out_div_out_head()
+{
+ atf_set descr 'Test inbound > delayed+diverted > outbound > delayed+diverted > outbound | network terminated, with ipfw enabled'
+ atf_set require.user root
+}
+ipfwon_in_dn_in_div_in_out_dn_out_div_out_body()
+{
+ ipfwoff_in_dn_in_div_in_out_dn_out_div_out_body "ipfwon"
+}
+ipfwon_in_dn_in_div_in_out_dn_out_div_out_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "ipfwoff_in_div"
@@ -410,4 +523,7 @@
atf_add_test_case "ipfwoff_in_div_in_fwd_out_div_out"
atf_add_test_case "ipfwon_in_div_in_fwd_out_div_out"
+
+ atf_add_test_case "ipfwoff_in_dn_in_div_in_out_dn_out_div_out"
+ atf_add_test_case "ipfwon_in_dn_in_div_in_out_dn_out_div_out"
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 14, 11:24 PM (9 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14626172
Default Alt Text
D42609.diff (6 KB)
Attached To
Mode
D42609: pf: fix dummynet + ipdivert use case
Attached
Detach File
Event Timeline
Log In to Comment