Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151291622
D49122.id151570.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
21 KB
Referenced Files
None
Subscribers
None
D49122.id151570.diff
View Options
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1005,9 +1005,10 @@
TAILQ_HEAD(, pf_kstate) states[2];
};
-#define PF_REVERSED_KEY(key, family) \
- ((key[PF_SK_WIRE]->af != key[PF_SK_STACK]->af) && \
- (key[PF_SK_WIRE]->af != (family)))
+#define PF_REVERSED_KEY(state, family) \
+ (((state)->key[PF_SK_WIRE]->af != (state)->key[PF_SK_STACK]->af) && \
+ ((state)->key[PF_SK_WIRE]->af != (family)) && \
+ ((state)->direction == PF_IN))
/* Keep synced with struct pf_kstate. */
struct pf_state_cmp {
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
@@ -351,9 +351,13 @@
static int pf_state_key_addr_setup(struct pf_pdesc *,
struct pf_state_key_cmp *, int);
static int pf_tcp_track_full(struct pf_kstate **,
- struct pf_pdesc *, u_short *, int *);
+ struct pf_pdesc *, u_short *, int *,
+ struct pf_state_peer *, struct pf_state_peer *,
+ u_int8_t, u_int8_t);
static int pf_tcp_track_sloppy(struct pf_kstate **,
- struct pf_pdesc *, u_short *);
+ struct pf_pdesc *, u_short *,
+ struct pf_state_peer *, struct pf_state_peer *,
+ u_int8_t, u_int8_t);
static int pf_test_state(struct pf_kstate **, struct pf_pdesc *,
u_short *);
int pf_icmp_state_lookup(struct pf_state_key_cmp *,
@@ -458,7 +462,7 @@
* Initially set to all, because we don't know what interface we'll be
* sending this out when we create the state.
*/
- if (st->rule->rt == PF_REPLYTO || (pd->af != pd->naf))
+ if (st->rule->rt == PF_REPLYTO || (pd->af != pd->naf && st->direction == PF_IN))
return (V_pfi_all);
/*
@@ -1739,11 +1743,18 @@
*/
bzero(&(*nk)->addr[0], sizeof((*nk)->addr[0]));
bzero(&(*nk)->addr[1], sizeof((*nk)->addr[1]));
+ if (pd->dir == PF_IN) {
+ PF_ACPY(&(*nk)->addr[pd->didx], &pd->nsaddr, pd->naf);
+ PF_ACPY(&(*nk)->addr[pd->sidx], &pd->ndaddr, pd->naf);
+ (*nk)->port[pd->didx] = pd->nsport;
+ (*nk)->port[pd->sidx] = pd->ndport;
+ } else {
+ PF_ACPY(&(*nk)->addr[pd->sidx], &pd->nsaddr, pd->naf);
+ PF_ACPY(&(*nk)->addr[pd->didx], &pd->ndaddr, pd->naf);
+ (*nk)->port[pd->sidx] = pd->nsport;
+ (*nk)->port[pd->didx] = pd->ndport;
+ }
- PF_ACPY(&(*nk)->addr[pd->didx], &pd->nsaddr, pd->naf);
- PF_ACPY(&(*nk)->addr[pd->sidx], &pd->ndaddr, pd->naf);
- (*nk)->port[pd->didx] = pd->nsport;
- (*nk)->port[pd->sidx] = pd->ndport;
switch (pd->proto) {
case IPPROTO_ICMP:
(*nk)->proto = IPPROTO_ICMPV6;
@@ -5934,24 +5945,25 @@
nat64 = pd->af != pd->naf;
if (nat64) {
- struct pf_state_key *_sk;
int ret;
if (sk == NULL)
sk = (*sm)->key[pd->dir == PF_IN ? PF_SK_STACK : PF_SK_WIRE];
if (nk == NULL)
nk = (*sm)->key[pd->dir == PF_IN ? PF_SK_WIRE : PF_SK_STACK];
- if (pd->dir == PF_IN)
- _sk = sk;
- else
- _sk = nk;
- ret = pf_translate(pd,
- &_sk->addr[pd->didx],
- _sk->port[pd->didx],
- &_sk->addr[pd->sidx],
- _sk->port[pd->sidx],
- virtual_type, icmp_dir);
+ if (pd->dir == PF_IN) {
+ ret = pf_translate(pd, &sk->addr[pd->didx],
+ sk->port[pd->didx], &sk->addr[pd->sidx],
+ sk->port[pd->sidx], virtual_type,
+ icmp_dir);
+ } else {
+ ret = pf_translate(pd, &sk->addr[pd->sidx],
+ sk->port[pd->sidx], &sk->addr[pd->didx],
+ sk->port[pd->didx], virtual_type,
+ icmp_dir);
+ }
+
if (ret < 0)
goto cleanup;
@@ -6383,37 +6395,15 @@
static int
pf_tcp_track_full(struct pf_kstate **state, struct pf_pdesc *pd,
- u_short *reason, int *copyback)
+ u_short *reason, int *copyback, struct pf_state_peer *src,
+ struct pf_state_peer *dst, u_int8_t psrc, u_int8_t pdst)
{
struct tcphdr *th = &pd->hdr.tcp;
- struct pf_state_peer *src, *dst;
u_int16_t win = ntohs(th->th_win);
u_int32_t ack, end, data_end, seq, orig_seq;
- u_int8_t sws, dws, psrc, pdst;
+ u_int8_t sws, dws;
int ackskew;
- if (pd->dir == (*state)->direction) {
- if (PF_REVERSED_KEY((*state)->key, pd->af)) {
- src = &(*state)->dst;
- dst = &(*state)->src;
- } else {
- src = &(*state)->src;
- dst = &(*state)->dst;
- }
- psrc = PF_PEER_SRC;
- pdst = PF_PEER_DST;
- } else {
- if (PF_REVERSED_KEY((*state)->key, pd->af)) {
- src = &(*state)->src;
- dst = &(*state)->dst;
- } else {
- src = &(*state)->dst;
- dst = &(*state)->src;
- }
- psrc = PF_PEER_DST;
- pdst = PF_PEER_SRC;
- }
-
if (src->wscale && dst->wscale && !(tcp_get_flags(th) & TH_SYN)) {
sws = src->wscale & PF_WSCALE_MASK;
dws = dst->wscale & PF_WSCALE_MASK;
@@ -6733,23 +6723,11 @@
}
static int
-pf_tcp_track_sloppy(struct pf_kstate **state, struct pf_pdesc *pd, u_short *reason)
+pf_tcp_track_sloppy(struct pf_kstate **state, struct pf_pdesc *pd,
+ u_short *reason, struct pf_state_peer *src, struct pf_state_peer *dst,
+ u_int8_t psrc, u_int8_t pdst)
{
struct tcphdr *th = &pd->hdr.tcp;
- struct pf_state_peer *src, *dst;
- u_int8_t psrc, pdst;
-
- if (pd->dir == (*state)->direction) {
- src = &(*state)->src;
- dst = &(*state)->dst;
- psrc = PF_PEER_SRC;
- pdst = PF_PEER_DST;
- } else {
- src = &(*state)->dst;
- dst = &(*state)->src;
- psrc = PF_PEER_DST;
- pdst = PF_PEER_SRC;
- }
if (tcp_get_flags(th) & TH_SYN)
if (src->state < TCPS_SYN_SENT)
@@ -6932,15 +6910,29 @@
STATE_LOOKUP(&key, *state, pd);
if (pd->dir == (*state)->direction) {
- src = &(*state)->src;
- dst = &(*state)->dst;
- psrc = PF_PEER_SRC;
- pdst = PF_PEER_DST;
+ if (PF_REVERSED_KEY(*state, pd->af)) {
+ src = &(*state)->dst;
+ dst = &(*state)->src;
+ psrc = PF_PEER_DST;
+ pdst = PF_PEER_SRC;
+ } else {
+ src = &(*state)->src;
+ dst = &(*state)->dst;
+ psrc = PF_PEER_SRC;
+ pdst = PF_PEER_DST;
+ }
} else {
- src = &(*state)->dst;
- dst = &(*state)->src;
- psrc = PF_PEER_DST;
- pdst = PF_PEER_SRC;
+ if (PF_REVERSED_KEY(*state, pd->af)) {
+ src = &(*state)->src;
+ dst = &(*state)->dst;
+ psrc = PF_PEER_SRC;
+ pdst = PF_PEER_DST;
+ } else {
+ src = &(*state)->dst;
+ dst = &(*state)->src;
+ psrc = PF_PEER_DST;
+ pdst = PF_PEER_SRC;
+ }
}
switch (pd->virtual_proto) {
@@ -6967,13 +6959,14 @@
return (PF_DROP);
}
if ((*state)->state_flags & PFSTATE_SLOPPY) {
- if (pf_tcp_track_sloppy(state, pd, reason) == PF_DROP)
+ if (pf_tcp_track_sloppy(state, pd, reason, src, dst,
+ psrc, pdst) == PF_DROP)
return (PF_DROP);
} else {
int ret;
ret = pf_tcp_track_full(state, pd, reason,
- ©back);
+ ©back, src, dst, psrc, pdst);
if (ret == PF_DROP)
return (PF_DROP);
}
@@ -7069,26 +7062,32 @@
struct pf_state_key *nk;
int afto, sidx, didx;
- if (PF_REVERSED_KEY((*state)->key, pd->af))
+ if (PF_REVERSED_KEY(*state, pd->af))
nk = (*state)->key[pd->sidx];
else
nk = (*state)->key[pd->didx];
afto = pd->af != nk->af;
- sidx = afto ? pd->didx : pd->sidx;
- didx = afto ? pd->sidx : pd->didx;
+
+ if (afto && (*state)->direction == PF_IN) {
+ sidx = pd->didx;
+ didx = pd->sidx;
+ } else {
+ sidx = pd->sidx;
+ didx = pd->didx;
+ }
if (afto || PF_ANEQ(pd->src, &nk->addr[sidx], pd->af) ||
nk->port[sidx] != pd->osport)
pf_change_ap(pd->m, pd->src, pd->sport, pd->ip_sum,
- pd->pcksum, &nk->addr[pd->sidx],
+ pd->pcksum, &nk->addr[sidx],
nk->port[sidx], pd->virtual_proto == IPPROTO_UDP,
pd->af, nk->af);
if (afto || PF_ANEQ(pd->dst, &nk->addr[didx], pd->af) ||
nk->port[didx] != pd->odport)
pf_change_ap(pd->m, pd->dst, pd->dport, pd->ip_sum,
- pd->pcksum, &nk->addr[pd->didx],
+ pd->pcksum, &nk->addr[didx],
nk->port[didx], pd->virtual_proto == IPPROTO_UDP,
pd->af, nk->af);
@@ -7114,12 +7113,12 @@
{
struct pf_state_peer *src;
if (pd->dir == state->direction) {
- if (PF_REVERSED_KEY(state->key, pd->af))
+ if (PF_REVERSED_KEY(state, pd->af))
src = &state->dst;
else
src = &state->src;
} else {
- if (PF_REVERSED_KEY(state->key, pd->af))
+ if (PF_REVERSED_KEY(state, pd->af))
src = &state->src;
else
src = &state->dst;
@@ -7679,15 +7678,21 @@
struct pf_state_key *nk;
int afto, sidx, didx;
- if (PF_REVERSED_KEY((*state)->key, pd->af))
+ if (PF_REVERSED_KEY(*state, pd->af))
nk = (*state)->key[pd->sidx];
else
nk = (*state)->key[pd->didx];
afto = pd->af != nk->af;
- sidx = afto ? pd->didx : pd->sidx;
- didx = afto ? pd->sidx : pd->didx;
- iidx = afto ? !iidx : iidx;
+
+ if (afto && (*state)->direction == PF_IN) {
+ sidx = pd->didx;
+ didx = pd->sidx;
+ iidx = !iidx;
+ } else {
+ sidx = pd->sidx;
+ didx = pd->didx;
+ }
switch (pd->af) {
#ifdef INET
@@ -7894,7 +7899,7 @@
STATE_LOOKUP(&key, *state, pd);
if (pd->dir == (*state)->direction) {
- if (PF_REVERSED_KEY((*state)->key, pd->af)) {
+ if (PF_REVERSED_KEY(*state, pd->af)) {
src = &(*state)->src;
dst = &(*state)->dst;
} else {
@@ -7902,7 +7907,7 @@
dst = &(*state)->src;
}
} else {
- if (PF_REVERSED_KEY((*state)->key, pd->af)) {
+ if (PF_REVERSED_KEY(*state, pd->af)) {
src = &(*state)->dst;
dst = &(*state)->src;
} else {
@@ -7958,7 +7963,7 @@
struct pf_state_key *nk;
- if (PF_REVERSED_KEY((*state)->key, pd->af))
+ if (PF_REVERSED_KEY(*state, pd->af))
nk = (*state)->key[pd->sidx];
else
nk = (*state)->key[pd->didx];
@@ -7967,8 +7972,14 @@
int afto, sidx, didx;
afto = pd->af != nk->af;
- sidx = afto ? pd2.didx : pd2.sidx;
- didx = afto ? pd2.sidx : pd2.didx;
+
+ if (afto && (*state)->direction == PF_IN) {
+ sidx = pd2.didx;
+ didx = pd2.sidx;
+ } else {
+ sidx = pd2.sidx;
+ didx = pd2.didx;
+ }
if (afto) {
if (pf_translate_icmp_af(nk->af,
@@ -8073,7 +8084,7 @@
(*state)->key[PF_SK_STACK]) {
struct pf_state_key *nk;
- if (PF_REVERSED_KEY((*state)->key, pd->af))
+ if (PF_REVERSED_KEY(*state, pd->af))
nk = (*state)->key[pd->sidx];
else
nk = (*state)->key[pd->didx];
@@ -8082,8 +8093,14 @@
int afto, sidx, didx;
afto = pd->af != nk->af;
- sidx = afto ? pd2.didx : pd2.sidx;
- didx = afto ? pd2.sidx : pd2.didx;
+
+ if (afto && (*state)->direction == PF_IN) {
+ sidx = pd2.didx;
+ didx = pd2.sidx;
+ } else {
+ sidx = pd2.sidx;
+ didx = pd2.didx;
+ }
if (afto) {
if (pf_translate_icmp_af(nk->af,
@@ -8183,12 +8200,12 @@
STATE_LOOKUP(&key, *state, pd);
if (pd->dir == (*state)->direction) {
- if (PF_REVERSED_KEY((*state)->key, pd->af))
+ if (PF_REVERSED_KEY(*state, pd->af))
src = &(*state)->src;
else
src = &(*state)->dst;
} else {
- if (PF_REVERSED_KEY((*state)->key, pd->af))
+ if (PF_REVERSED_KEY(*state, pd->af))
src = &(*state)->dst;
else
src = &(*state)->src;
@@ -8207,7 +8224,7 @@
struct pf_state_key *nk;
- if (PF_REVERSED_KEY((*state)->key, pd->af))
+ if (PF_REVERSED_KEY(*state, pd->af))
nk = (*state)->key[pd->sidx];
else
nk = (*state)->key[pd->didx];
@@ -8216,8 +8233,14 @@
int afto, sidx, didx;
afto = pd->af != nk->af;
- sidx = afto ? pd2.didx : pd2.sidx;
- didx = afto ? pd2.sidx : pd2.didx;
+
+ if (afto && (*state)->direction == PF_IN) {
+ sidx = pd2.didx;
+ didx = pd2.sidx;
+ } else {
+ sidx = pd2.sidx;
+ didx = pd2.didx;
+ }
if (afto) {
if (pf_translate_icmp_af(nk->af,
@@ -8325,7 +8348,7 @@
(*state)->key[PF_SK_STACK]) {
struct pf_state_key *nk;
- if (PF_REVERSED_KEY((*state)->key, pd->af))
+ if (PF_REVERSED_KEY(*state, pd->af))
nk = (*state)->key[pd->sidx];
else
nk = (*state)->key[pd->didx];
@@ -8334,9 +8357,15 @@
int afto, sidx, didx;
afto = pd->af != nk->af;
- sidx = afto ? pd2.didx : pd2.sidx;
- didx = afto ? pd2.sidx : pd2.didx;
- iidx = afto ? !iidx : iidx;
+
+ if (afto && (*state)->direction == PF_IN) {
+ sidx = pd2.didx;
+ didx = pd2.sidx;
+ iidx = !iidx;
+ } else {
+ sidx = pd2.sidx;
+ didx = pd2.didx;
+ }
if (afto) {
if (nk->af != AF_INET6)
@@ -8437,7 +8466,7 @@
(*state)->key[PF_SK_STACK]) {
struct pf_state_key *nk;
- if (PF_REVERSED_KEY((*state)->key, pd->af))
+ if (PF_REVERSED_KEY(*state, pd->af))
nk = (*state)->key[pd->sidx];
else
nk = (*state)->key[pd->didx];
@@ -8446,9 +8475,15 @@
int afto, sidx, didx;
afto = pd->af != nk->af;
- sidx = afto ? pd2.didx : pd2.sidx;
- didx = afto ? pd2.sidx : pd2.didx;
- iidx = afto ? !iidx : iidx;
+
+ if (afto && (*state)->direction == PF_IN) {
+ sidx = pd2.didx;
+ didx = pd2.sidx;
+ iidx = !iidx;
+ } else {
+ sidx = pd2.sidx;
+ didx = pd2.didx;
+ }
if (afto) {
if (nk->af != AF_INET)
@@ -8732,7 +8767,9 @@
PF_STATE_UNLOCK(s);
return;
} else {
- skip_test = true;
+ if (r_dir == PF_IN) {
+ skip_test = true;
+ }
}
}
@@ -9014,7 +9051,9 @@
PF_STATE_UNLOCK(s);
return;
} else {
- skip_test = true;
+ if (r_dir == PF_IN) {
+ skip_test = true;
+ }
}
}
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
@@ -1053,37 +1053,19 @@
}
if (pd->proto == IPPROTO_ICMPV6 && pd->naf == AF_INET) {
- if (pd->dir == PF_IN) {
- NTOHS(pd->ndport);
- if (pd->ndport == ICMP6_ECHO_REQUEST)
- pd->ndport = ICMP_ECHO;
- else if (pd->ndport == ICMP6_ECHO_REPLY)
- pd->ndport = ICMP_ECHOREPLY;
- HTONS(pd->ndport);
- } else {
- NTOHS(pd->nsport);
- if (pd->nsport == ICMP6_ECHO_REQUEST)
- pd->nsport = ICMP_ECHO;
- else if (pd->nsport == ICMP6_ECHO_REPLY)
- pd->nsport = ICMP_ECHOREPLY;
- HTONS(pd->nsport);
- }
+ NTOHS(pd->ndport);
+ if (pd->ndport == ICMP6_ECHO_REQUEST)
+ pd->ndport = ICMP_ECHO;
+ else if (pd->ndport == ICMP6_ECHO_REPLY)
+ pd->ndport = ICMP_ECHOREPLY;
+ HTONS(pd->ndport);
} else if (pd->proto == IPPROTO_ICMP && pd->naf == AF_INET6) {
- if (pd->dir == PF_IN) {
- NTOHS(pd->ndport);
- if (pd->ndport == ICMP_ECHO)
- pd->ndport = ICMP6_ECHO_REQUEST;
- else if (pd->ndport == ICMP_ECHOREPLY)
- pd->ndport = ICMP6_ECHO_REPLY;
- HTONS(pd->ndport);
- } else {
- NTOHS(pd->nsport);
- if (pd->nsport == ICMP_ECHO)
- pd->nsport = ICMP6_ECHO_REQUEST;
- else if (pd->nsport == ICMP_ECHOREPLY)
- pd->nsport = ICMP6_ECHO_REPLY;
- HTONS(pd->nsport);
- }
+ NTOHS(pd->ndport);
+ if (pd->ndport == ICMP_ECHO)
+ pd->ndport = ICMP6_ECHO_REQUEST;
+ else if (pd->ndport == ICMP_ECHOREPLY)
+ pd->ndport = ICMP6_ECHO_REPLY;
+ HTONS(pd->ndport);
}
/* get the destination address and port */
diff --git a/tests/sys/netpfil/pf/nat64.sh b/tests/sys/netpfil/pf/nat64.sh
--- a/tests/sys/netpfil/pf/nat64.sh
+++ b/tests/sys/netpfil/pf/nat64.sh
@@ -26,7 +26,7 @@
. $(atf_get_srcdir)/utils.subr
-nat64_setup()
+nat64_setup_base()
{
pft_init
@@ -51,22 +51,44 @@
jexec dst ping -c 1 192.0.2.1
jexec rtr pfctl -e
+}
+
+nat64_setup_in()
+{
+ nat64_setup_base
pft_set_rules rtr \
"set reassemble yes" \
"set state-policy if-bound" \
"pass in on ${epair}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_link}a)"
}
-atf_test_case "icmp_echo" "cleanup"
-icmp_echo_head()
+nat64_setup_out()
{
- atf_set descr 'Basic NAT64 ICMP echo test'
+ nat64_setup_base
+ jexec rtr sysctl net.inet6.ip6.forwarding=1
+ # AF translation happens post-routing, traffic must be directed
+ # towards the outbound interface using routes for the original AF.
+ # jexec rtr ifconfig ${epair_link}a inet6 2001:db8:2::1/64 up no_dad
+ jexec rtr route add -inet6 64:ff9b::/96 -iface ${epair_link}a;
+ pft_set_rules rtr \
+ "set reassemble yes" \
+ "set state-policy if-bound" \
+ "pass quick inet6 proto icmp6 icmp6-type { neighbrsol, neighbradv }" \
+ "pass in quick on ${epair}b from any to 64:ff9b::/96" \
+ "pass out quick on ${epair_link}a from any to 64:ff9b::/96 af-to inet from (${epair_link}a)" \
+ "block"
+}
+
+atf_test_case "icmp_echo_in" "cleanup"
+icmp_echo_in_head()
+{
+ atf_set descr 'Basic NAT64 ICMP echo test on inbound interface'
atf_set require.user root
}
-icmp_echo_body()
+icmp_echo_in_body()
{
- nat64_setup
+ nat64_setup_in
# One ping
atf_check -s exit:0 -o ignore \
@@ -78,21 +100,47 @@
ping6 -c 5 64:ff9b::192.0.2.2
}
-icmp_echo_cleanup()
+icmp_echo_in_cleanup()
{
pft_cleanup
}
-atf_test_case "fragmentation" "cleanup"
-fragmentation_head()
+atf_test_case "icmp_echo_out" "cleanup"
+icmp_echo_out_head()
{
- atf_set descr 'Test fragmented packets'
+ atf_set descr 'Basic NAT64 ICMP echo test on outbound interface'
atf_set require.user root
}
-fragmentation_body()
+icmp_echo_out_body()
{
- nat64_setup
+ nat64_setup_out
+
+ # One ping
+ atf_check -s exit:0 -o ignore \
+ ping6 -c 1 64:ff9b::192.0.2.2
+
+ # Make sure packets make it even when state is established
+ atf_check -s exit:0 \
+ -o match:'5 packets transmitted, 5 packets received, 0.0% packet loss' \
+ ping6 -c 5 64:ff9b::192.0.2.2
+}
+
+icmp_echo_out_cleanup()
+{
+ pft_cleanup
+}
+
+atf_test_case "fragmentation_in" "cleanup"
+fragmentation_in_head()
+{
+ atf_set descr 'Test fragmented packets on inbound interface'
+ atf_set require.user root
+}
+
+fragmentation_in_body()
+{
+ nat64_setup_in
atf_check -s exit:0 -o ignore \
ping6 -c 1 -s 1280 64:ff9b::192.0.2.2
@@ -105,21 +153,48 @@
ping6 -c 3 -s 10000 -b 20000 64:ff9b::192.0.2.2
}
-fragmentation_cleanup()
+fragmentation_in_cleanup()
{
pft_cleanup
}
-atf_test_case "tcp" "cleanup"
-tcp_head()
+atf_test_case "fragmentation_out" "cleanup"
+fragmentation_out_head()
{
- atf_set descr 'TCP NAT64 test'
+ atf_set descr 'Test fragmented packets on outbound interface'
atf_set require.user root
}
-tcp_body()
+fragmentation_out_body()
{
- nat64_setup
+ nat64_setup_out
+
+ atf_check -s exit:0 -o ignore \
+ ping6 -c 1 -s 1280 64:ff9b::192.0.2.2
+
+ atf_check -s exit:0 \
+ -o match:'3 packets transmitted, 3 packets received, 0.0% packet loss' \
+ ping6 -c 3 -s 2000 64:ff9b::192.0.2.2
+ atf_check -s exit:0 \
+ -o match:'3 packets transmitted, 3 packets received, 0.0% packet loss' \
+ ping6 -c 3 -s 10000 -b 20000 64:ff9b::192.0.2.2
+}
+
+fragmentation_out_cleanup()
+{
+ pft_cleanup
+}
+
+atf_test_case "tcp_in" "cleanup"
+tcp_in_head()
+{
+ atf_set descr 'TCP NAT64 test on inbound interface'
+ atf_set require.user root
+}
+
+tcp_in_body()
+{
+ nat64_setup_in
echo "foo" | jexec dst nc -l 1234 &
@@ -135,21 +210,51 @@
fi
}
-tcp_cleanup()
+tcp_in_cleanup()
{
pft_cleanup
}
-atf_test_case "udp" "cleanup"
-udp_head()
+atf_test_case "tcp_out" "cleanup"
+tcp_out_head()
{
- atf_set descr 'UDP NAT64 test'
+ atf_set descr 'TCP NAT64 test on outbound interface'
atf_set require.user root
}
-udp_body()
+tcp_out_body()
{
- nat64_setup
+ nat64_setup_out
+
+ echo "foo" | jexec dst nc -l 1234 &
+
+ # Sanity check & delay for nc startup
+ atf_check -s exit:0 -o ignore \
+ ping6 -c 1 64:ff9b::192.0.2.2
+
+ rcv=$(nc -w 3 -6 64:ff9b::c000:202 1234)
+ if [ "${rcv}" != "foo" ];
+ then
+ echo "rcv=${rcv}"
+ atf_fail "Failed to connect to TCP server"
+ fi
+}
+
+tcp_out_cleanup()
+{
+ pft_cleanup
+}
+
+atf_test_case "udp_in" "cleanup"
+udp_in_head()
+{
+ atf_set descr 'UDP NAT64 test on inbound interface'
+ atf_set require.user root
+}
+
+udp_in_body()
+{
+ nat64_setup_in
echo "foo" | jexec dst nc -u -l 1234 &
@@ -165,21 +270,51 @@
fi
}
-udp_cleanup()
+udp_in_cleanup()
{
pft_cleanup
}
-atf_test_case "sctp" "cleanup"
-sctp_head()
+atf_test_case "udp_out" "cleanup"
+udp_out_head()
{
- atf_set descr 'SCTP NAT64 test'
+ atf_set descr 'UDP NAT64 test on outbound interface'
atf_set require.user root
}
-sctp_body()
+udp_out_body()
{
- nat64_setup
+ nat64_setup_out
+
+ echo "foo" | jexec dst nc -u -l 1234 &
+
+ # Sanity check & delay for nc startup
+ atf_check -s exit:0 -o ignore \
+ ping6 -c 1 64:ff9b::192.0.2.2
+
+ rcv=$(echo bar | nc -w 3 -6 -u 64:ff9b::c000:202 1234)
+ if [ "${rcv}" != "foo" ];
+ then
+ echo "rcv=${rcv}"
+ atf_fail "Failed to connect to UDP server"
+ fi
+}
+
+udp_out_cleanup()
+{
+ pft_cleanup
+}
+
+atf_test_case "sctp_in" "cleanup"
+sctp_in_head()
+{
+ atf_set descr 'SCTP NAT64 test on inbound interface'
+ atf_set require.user root
+}
+
+sctp_in_body()
+{
+ nat64_setup_in
if ! kldstat -q -m sctp; then
atf_skip "This test requires SCTP"
fi
@@ -198,7 +333,40 @@
fi
}
-sctp_cleanup()
+sctp_in_cleanup()
+{
+ pft_cleanup
+}
+
+atf_test_case "sctp_out" "cleanup"
+sctp_out_head()
+{
+ atf_set descr 'SCTP NAT64 test on outbound interface'
+ atf_set require.user root
+}
+
+sctp_out_body()
+{
+ nat64_setup_out
+ if ! kldstat -q -m sctp; then
+ atf_skip "This test requires SCTP"
+ fi
+
+ echo "foo" | jexec dst nc --sctp -N -l 1234 &
+
+ # Sanity check & delay for nc startup
+ atf_check -s exit:0 -o ignore \
+ ping6 -c 1 64:ff9b::192.0.2.2
+
+ rcv=$(echo bar | nc --sctp -w 3 -6 64:ff9b::c000:202 1234)
+ if [ "${rcv}" != "foo" ];
+ then
+ echo "rcv=${rcv}"
+ atf_fail "Failed to connect to SCTP server"
+ fi
+}
+
+sctp_out_cleanup()
{
pft_cleanup
}
@@ -212,7 +380,7 @@
tos_body()
{
- nat64_setup
+ nat64_setup_in
# Ensure we can distinguish ToS on the destination
jexec dst pfctl -e
@@ -862,11 +1030,16 @@
atf_init_test_cases()
{
- atf_add_test_case "icmp_echo"
- atf_add_test_case "fragmentation"
- atf_add_test_case "tcp"
- atf_add_test_case "udp"
- atf_add_test_case "sctp"
+ atf_add_test_case "icmp_echo_in"
+ atf_add_test_case "icmp_echo_out"
+ atf_add_test_case "fragmentation_in"
+ atf_add_test_case "fragmentation_out"
+ atf_add_test_case "tcp_in"
+ atf_add_test_case "tcp_out"
+ atf_add_test_case "udp_in"
+ atf_add_test_case "udp_out"
+ atf_add_test_case "sctp_in"
+ atf_add_test_case "sctp_out"
atf_add_test_case "tos"
atf_add_test_case "no_v4"
atf_add_test_case "range"
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 8, 9:10 AM (5 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31090718
Default Alt Text
D49122.id151570.diff (21 KB)
Attached To
Mode
D49122: pf: Make af-to work on outbound interface
Attached
Detach File
Event Timeline
Log In to Comment