pf: move pf_change_icmp_af() call for TCP/UDP in ICMP
The checksum of a ICMP "need to frag" packet for TCP was wrong when created from a ICMP6 "too big" packet. The function pf_change_icmp_af() has code to adjust the pseudo-header checksum in the ICMP6 case, but pf_test_state_icmp() changed the proto before the case was entered. So call pf_change_icmp_af() before the pd->proto is converted in the TCP and UDP payload case like it was already done for ICMP and ICMP6 payload. Found by sys/net/pf_forward regress test; OK henning@ Note that we fully recalculate ICMP checksums in pf_translate_af(), so this does not result in any functional changes on FreeBSD. It is imported to reduce the diff with OpenBSD. Obtained from: OpenBSD, bluhm <bluhm@openbsd.org>, 50188ace62 Sponsored by: Rubicon Communications, LLC ("Netgate")
This commit is contained in:
+10
-10
@@ -7987,6 +7987,11 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
|
||||
m_copyback(pd->m, pd->off,
|
||||
sizeof(struct icmp6_hdr),
|
||||
(c_caddr_t)&pd->hdr.icmp6);
|
||||
if (pf_change_icmp_af(pd->m, ipoff2, pd,
|
||||
&pd2, &nk->addr[sidx],
|
||||
&nk->addr[didx], pd->af,
|
||||
nk->af))
|
||||
return (PF_DROP);
|
||||
PF_ACPY(&pd->nsaddr, &nk->addr[pd2.sidx],
|
||||
nk->af);
|
||||
PF_ACPY(&pd->ndaddr,
|
||||
@@ -8006,11 +8011,6 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
|
||||
pd->src->addr32[0];
|
||||
}
|
||||
pd->naf = pd2.naf = nk->af;
|
||||
if (pf_change_icmp_af(pd->m, ipoff2, pd,
|
||||
&pd2, &nk->addr[sidx],
|
||||
&nk->addr[didx], pd->af,
|
||||
nk->af))
|
||||
return (PF_DROP);
|
||||
pf_change_ap(&pd2, pd2.src, &th->th_sport,
|
||||
&nk->addr[pd2.sidx], nk->port[sidx]);
|
||||
pf_change_ap(&pd2, pd2.dst, &th->th_dport,
|
||||
@@ -8119,6 +8119,11 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
|
||||
m_copyback(pd->m, pd->off,
|
||||
sizeof(struct icmp6_hdr),
|
||||
(c_caddr_t)&pd->hdr.icmp6);
|
||||
if (pf_change_icmp_af(pd->m, ipoff2, pd,
|
||||
&pd2, &nk->addr[sidx],
|
||||
&nk->addr[didx], pd->af,
|
||||
nk->af))
|
||||
return (PF_DROP);
|
||||
PF_ACPY(&pd->nsaddr,
|
||||
&nk->addr[pd2.sidx], nk->af);
|
||||
PF_ACPY(&pd->ndaddr,
|
||||
@@ -8138,11 +8143,6 @@ pf_test_state_icmp(struct pf_kstate **state, struct pf_pdesc *pd,
|
||||
pd->src->addr32[0];
|
||||
}
|
||||
pd->naf = pd2.naf = nk->af;
|
||||
if (pf_change_icmp_af(pd->m, ipoff2, pd,
|
||||
&pd2, &nk->addr[sidx],
|
||||
&nk->addr[didx], pd->af,
|
||||
nk->af))
|
||||
return (PF_DROP);
|
||||
pf_change_ap(&pd2, pd2.src, &uh->uh_sport,
|
||||
&nk->addr[pd2.sidx], nk->port[sidx]);
|
||||
pf_change_ap(&pd2, pd2.dst, &uh->uh_dport,
|
||||
|
||||
Reference in New Issue
Block a user