Page MenuHomeFreeBSD

D42609.diff
No OneTemporary

D42609.diff

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

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)

Event Timeline