Page MenuHomeFreeBSD

D49095.id151301.diff
No OneTemporary

D49095.id151301.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
@@ -337,7 +337,7 @@
struct pf_krule *, struct mbuf **);
static int pf_dummynet_route(struct pf_pdesc *,
struct pf_kstate *, struct pf_krule *,
- struct ifnet *, struct sockaddr *, struct mbuf **);
+ struct ifnet *, const struct sockaddr *, struct mbuf **);
static int pf_test_eth_rule(int, struct pfi_kkif *,
struct mbuf **);
static int pf_test_rule(struct pf_krule **, struct pf_kstate **,
@@ -8665,7 +8665,9 @@
struct pf_kstate *s, struct pf_pdesc *pd, struct inpcb *inp)
{
struct mbuf *m0, *m1, *md;
- struct sockaddr_in dst;
+ struct route ro;
+ const struct sockaddr *gw = &ro.ro_dst;
+ struct sockaddr_in *dst;
struct ip *ip;
struct ifnet *ifp = NULL;
int error = 0;
@@ -8754,11 +8756,12 @@
ip = mtod(m0, struct ip *);
- bzero(&dst, sizeof(dst));
- dst.sin_family = AF_INET;
- dst.sin_len = sizeof(dst);
- dst.sin_addr = ip->ip_dst;
- dst.sin_addr.s_addr = pd->act.rt_addr.v4.s_addr;
+ bzero(&ro, sizeof(ro));
+ dst = (struct sockaddr_in *)&ro.ro_dst;
+ dst->sin_family = AF_INET;
+ dst->sin_len = sizeof(struct sockaddr_in);
+ dst->sin_addr = ip->ip_dst;
+ dst->sin_addr.s_addr = pd->act.rt_addr.v4.s_addr;
if (s != NULL){
if (ifp == NULL && (pd->af != pd->naf)) {
@@ -8769,10 +8772,10 @@
ifp = nh->nh_ifp;
/* Use the gateway if needed. */
- if (nh->nh_flags & NHF_GATEWAY)
- dst.sin_addr = nh->gw4_sa.sin_addr;
- else
- dst.sin_addr = ip->ip_dst;
+ if (nh->nh_flags & NHF_GATEWAY) {
+ gw = &nh->gw_sa;
+ ro.ro_flags |= RT_HAS_GW;
+ }
/*
* Bind to the correct interface if we're
@@ -8873,9 +8876,9 @@
m_clrprotoflags(m0); /* Avoid confusing lower layers. */
md = m0;
- error = pf_dummynet_route(pd, s, r, ifp, sintosa(&dst), &md);
+ error = pf_dummynet_route(pd, s, r, ifp, gw, &md);
if (md != NULL) {
- error = (*ifp->if_output)(ifp, md, sintosa(&dst), NULL);
+ error = (*ifp->if_output)(ifp, md, gw, &ro);
SDT_PROBE2(pf, ip, route_to, output, ifp, error);
}
goto done;
@@ -8915,10 +8918,9 @@
md = m0;
pd->pf_mtag = pf_find_mtag(md);
error = pf_dummynet_route(pd, s, r, ifp,
- sintosa(&dst), &md);
+ gw, &md);
if (md != NULL) {
- error = (*ifp->if_output)(ifp, md,
- sintosa(&dst), NULL);
+ error = (*ifp->if_output)(ifp, md, gw, &ro);
SDT_PROBE2(pf, ip, route_to, output, ifp, error);
}
} else
@@ -9442,7 +9444,7 @@
static int
pf_dummynet_route(struct pf_pdesc *pd, struct pf_kstate *s,
- struct pf_krule *r, struct ifnet *ifp, struct sockaddr *sa,
+ struct pf_krule *r, struct ifnet *ifp, const struct sockaddr *sa,
struct mbuf **m0)
{
struct ip_fw_args dnflow;
@@ -9473,7 +9475,7 @@
MPASS(sa != NULL);
- switch (pd->naf) {
+ switch (sa->sa_family) {
case AF_INET:
memcpy(&pd->pf_mtag->dst, sa,
sizeof(struct sockaddr_in));
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
@@ -799,6 +799,67 @@
pft_cleanup
}
+atf_test_case "v6_gateway" "cleanup"
+v6_gateway_head()
+{
+ atf_set descr 'nat64 when the IPv4 gateway is given by an IPv6 address'
+ atf_set require.user root
+}
+
+v6_gateway_body()
+{
+ pft_init
+
+ epair_wan_two=$(vnet_mkepair)
+ epair_wan_one=$(vnet_mkepair)
+ epair_lan=$(vnet_mkepair)
+
+ ifconfig ${epair_lan}a inet6 2001:db8::2/64 up no_dad
+ route -6 add default 2001:db8::1
+
+ vnet_mkjail rtr ${epair_lan}b ${epair_wan_one}a
+ jexec rtr ifconfig ${epair_lan}b inet6 2001:db8::1/64 up no_dad
+ jexec rtr ifconfig ${epair_wan_one}a 192.0.2.1/24 up
+ jexec rtr ifconfig ${epair_wan_one}a inet6 -ifdisabled
+ jexec rtr route add default -inet6 fe80::1%${epair_wan_one}a
+ #jexec rtr route add default 192.0.2.2
+
+ vnet_mkjail wan_one ${epair_wan_one}b ${epair_wan_two}a
+ jexec wan_one ifconfig ${epair_wan_one}b 192.0.2.2/24 up
+ jexec wan_one ifconfig ${epair_wan_one}b inet6 fe80::1/64
+ jexec wan_one ifconfig ${epair_wan_two}a 198.51.100.2/24 up
+ jexec wan_one route add default 192.0.2.1
+ jexec wan_one sysctl net.inet.ip.forwarding=1
+
+ vnet_mkjail wan_two ${epair_wan_two}b
+ jexec wan_two ifconfig ${epair_wan_two}b 198.51.100.1/24 up
+ jexec wan_two route add default 198.51.100.2
+
+ # Sanity checks
+ atf_check -s exit:0 -o ignore \
+ ping6 -c 1 2001:db8::1
+ atf_check -s exit:0 -o ignore \
+ jexec rtr ping -c 1 192.0.2.2
+ atf_check -s exit:0 -o ignore \
+ jexec rtr ping -c 1 198.51.100.1
+
+ jexec rtr pfctl -e
+ pft_set_rules rtr \
+ "set reassemble yes" \
+ "set state-policy if-bound" \
+ "pass in on ${epair_lan}b inet6 from any to 64:ff9b::/96 af-to inet from (${epair_wan_one}a)"
+
+ atf_check -s exit:0 -o ignore \
+ ping6 -c 3 64:ff9b::192.0.2.2
+ atf_check -s exit:0 -o ignore \
+ ping6 -c 3 64:ff9b::198.51.100.1
+}
+
+v6_gateway_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "icmp_echo"
@@ -818,4 +879,5 @@
atf_add_test_case "gateway6"
atf_add_test_case "route_to"
atf_add_test_case "reply_to"
+ atf_add_test_case "v6_gateway"
}

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 23, 5:01 AM (9 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16775171
Default Alt Text
D49095.id151301.diff (5 KB)

Event Timeline