Page MenuHomeFreeBSD

D43589.diff
No OneTemporary

D43589.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
@@ -412,8 +412,27 @@
return (PF_PASS); \
} while (0)
-#define BOUND_IFACE(r, k) \
- ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : V_pfi_all
+static struct pfi_kkif *
+BOUND_IFACE(struct pf_krule *r, struct pfi_kkif *k, struct pf_pdesc *pd)
+{
+ /* Floating unless otherwise specified. */
+ if (! (r->rule_flag & PFRULE_IFBOUND))
+ return (V_pfi_all);
+
+ /* Don't overrule the interface for states created on incoming packets. */
+ if (pd->dir == PF_IN)
+ return (k);
+
+ /* No route-to, so don't overrrule. */
+ if (r->rt != PF_ROUTETO)
+ return (k);
+
+ if (r->rpool.cur == NULL)
+ return (k);
+
+ /* Bind to the route-to interface. */
+ return (r->rpool.cur->kif);
+}
#define STATE_INC_COUNTERS(s) \
do { \
@@ -1600,7 +1619,7 @@
/* List is sorted, if-bound states before floating ones. */
TAILQ_FOREACH(s, &sk->states[idx], key_list[idx])
- if (s->kif == V_pfi_all || s->kif == kif) {
+ if (s->kif == V_pfi_all || s->kif == kif || s->orig_kif == kif) {
PF_STATE_LOCK(s);
PF_HASHROW_UNLOCK(kh);
if (__predict_false(s->timeout >= PFTM_MAX)) {
@@ -4999,7 +5018,7 @@
__func__, nr, sk, nk));
/* Swap sk/nk for PF_OUT. */
- if (pf_state_insert(BOUND_IFACE(r, kif), kif,
+ if (pf_state_insert(BOUND_IFACE(r, kif, pd), kif,
(pd->dir == PF_IN) ? sk : nk,
(pd->dir == PF_IN) ? nk : sk, s)) {
REASON_SET(&reason, PFRES_STATEINS);
diff --git a/tests/sys/netpfil/pf/route_to.sh b/tests/sys/netpfil/pf/route_to.sh
--- a/tests/sys/netpfil/pf/route_to.sh
+++ b/tests/sys/netpfil/pf/route_to.sh
@@ -365,6 +365,48 @@
pft_cleanup
}
+atf_test_case "ifbound" "cleanup"
+ifbound_head()
+{
+ atf_set descr 'Test that route-to states bind the expected interface'
+ atf_set require.user root
+}
+
+ifbound_body()
+{
+ pft_init
+
+ j="route_to:ifbound"
+
+ epair_one=$(vnet_mkepair)
+ epair_two=$(vnet_mkepair)
+ ifconfig ${epair_one}b up
+
+ vnet_mkjail ${j}2 ${epair_two}b
+ jexec ${j}2 ifconfig ${epair_two}b inet 198.51.100.2/24 up
+ jexec ${j}2 ifconfig ${epair_two}b inet alias 203.0.113.1/24
+ jexec ${j}2 route add default 198.51.100.1
+
+ vnet_mkjail $j ${epair_one}a ${epair_two}a
+ jexec $j ifconfig ${epair_one}a 192.0.2.1/24 up
+ jexec $j ifconfig ${epair_two}a 198.51.100.1/24 up
+ jexec $j route add default 192.0.2.2
+
+ jexec $j pfctl -e
+ pft_set_rules $j \
+ "set state-policy if-bound" \
+ "block" \
+ "pass out route-to (${epair_two}a 198.51.100.2)"
+
+ atf_check -s exit:0 -o ignore \
+ jexec $j ping -c 3 203.0.113.1
+}
+
+ifbound_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "v4"
@@ -373,4 +415,5 @@
atf_add_test_case "multiwanlocal"
atf_add_test_case "icmp_nat"
atf_add_test_case "dummynet"
+ atf_add_test_case "ifbound"
}

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 13, 12:14 AM (18 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16619344
Default Alt Text
D43589.diff (2 KB)

Event Timeline