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 @@ -7614,6 +7614,24 @@ return (-1); } +static void +pf_translate_af_src(const struct pf_kstate *state, const struct pf_state_key *nk, + struct pf_pdesc *pd, const struct pf_pdesc *pd2) +{ + if (pd->af == AF_INET) { + struct pf_addr nsaddr; + int prefixlen = in6_mask2len( + (struct in6_addr *)&state->rule->dst.addr.v.a.mask, NULL); + + if (prefixlen < 32) + prefixlen = 96; + PF_ACPY(&nsaddr, pd->src, pd->af); + inet_nat64(AF_INET6, pd->src, &nsaddr, &nk->addr[pd2->sidx], + prefixlen); + PF_ACPY(&pd->nsaddr, &nsaddr, AF_INET6); + } +} + static int pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd, u_short *reason) @@ -7993,9 +8011,8 @@ pd->ip_sum, &th.th_sum, &nk->addr[pd2.didx], nk->port[didx], 1, pd->af, nk->af); m_copyback(pd2.m, pd2.off, 8, (c_caddr_t)&th); - PF_ACPY(pd->src, - &nk->addr[pd2.sidx], nk->af); - PF_ACPY(pd->dst, + pf_translate_af_src(*state, nk, pd, &pd2); + PF_ACPY(&pd->ndaddr, &nk->addr[pd2.didx], nk->af); pd->naf = nk->af; return (PF_AFRT); @@ -8109,8 +8126,7 @@ nk->port[didx], 1, pd->af, nk->af); m_copyback(pd2.m, pd2.off, sizeof(uh), (c_caddr_t)&uh); - PF_ACPY(&pd->nsaddr, - &nk->addr[pd2.sidx], nk->af); + pf_translate_af_src(*state, nk, pd, &pd2); PF_ACPY(&pd->ndaddr, &nk->addr[pd2.didx], nk->af); pd->naf = nk->af; @@ -8238,9 +8254,8 @@ sh.src_port = nk->port[sidx]; sh.dest_port = nk->port[didx]; m_copyback(pd2.m, pd2.off, sizeof(sh), (c_caddr_t)&sh); - PF_ACPY(pd->src, - &nk->addr[pd2.sidx], nk->af); - PF_ACPY(pd->dst, + pf_translate_af_src(*state, nk, pd, &pd2); + PF_ACPY(&pd->ndaddr, &nk->addr[pd2.didx], nk->af); pd->naf = nk->af; return (PF_AFRT); @@ -8360,8 +8375,7 @@ iih->icmp_id = nk->port[iidx]; m_copyback(pd2.m, pd2.off, ICMP_MINLEN, (c_caddr_t)&iih); - PF_ACPY(&pd->nsaddr, - &nk->addr[pd2.sidx], nk->af); + pf_translate_af_src(*state, nk, pd, &pd2); PF_ACPY(&pd->ndaddr, &nk->addr[pd2.didx], nk->af); pd->naf = nk->af; @@ -8473,8 +8487,7 @@ iih->icmp6_id = nk->port[iidx]; m_copyback(pd2.m, pd2.off, sizeof(struct icmp6_hdr), (c_caddr_t)&iih); - PF_ACPY(&pd->nsaddr, - &nk->addr[pd2.sidx], nk->af); + pf_translate_af_src(*state, nk, pd, &pd2); PF_ACPY(&pd->ndaddr, &nk->addr[pd2.didx], nk->af); pd->naf = nk->af;