diff options
author | kp <kp@FreeBSD.org> | 2015-10-21 15:32:21 +0000 |
---|---|---|
committer | kp <kp@FreeBSD.org> | 2015-10-21 15:32:21 +0000 |
commit | d621159ed6a7d1c98cf81f17e313dffc64bf7c4f (patch) | |
tree | bf808b690f2a7aeabe78ae7b008b62f190733067 /sys/net | |
parent | a7e84cb353a2230668d83d375dc3fae7f6419bab (diff) | |
download | FreeBSD-src-d621159ed6a7d1c98cf81f17e313dffc64bf7c4f.zip FreeBSD-src-d621159ed6a7d1c98cf81f17e313dffc64bf7c4f.tar.gz |
MFC r289316:
pf: Fix TSO issues
In certain configurations (mostly but not exclusively as a VM on Xen) pf
produced packets with an invalid TCP checksum.
The problem was that pf could only handle packets with a full checksum. The
FreeBSD IP stack produces TCP packets with a pseudo-header checksum (only
addresses, length and protocol).
Certain network interfaces expect to see the pseudo-header checksum, so they
end up producing packets with invalid checksums.
To fix this stop calculating the full checksum and teach pf to only update TCP
checksums if TSO is disabled or the change affects the pseudo-header checksum.
PR: 154428, 193579, 198868
Relnotes: yes
Sponsored by: RootBSD
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/pfvar.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 4a5f2a0..ae5ecb9 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1554,6 +1554,8 @@ extern void pf_print_state(struct pf_state *); extern void pf_print_flags(u_int8_t); extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t, u_int8_t); +extern u_int16_t pf_proto_cksum_fixup(struct mbuf *, u_int16_t, + u_int16_t, u_int16_t, u_int8_t); VNET_DECLARE(struct ifnet *, sync_ifp); #define V_sync_ifp VNET(sync_ifp); @@ -1583,6 +1585,9 @@ u_int32_t pf_new_isn(struct pf_state *); void *pf_pull_hdr(struct mbuf *, int, void *, int, u_short *, u_short *, sa_family_t); void pf_change_a(void *, u_int16_t *, u_int32_t, u_int8_t); +void pf_change_proto_a(struct mbuf *, void *, u_int16_t *, u_int32_t, + u_int8_t); +void pf_change_tcp_a(struct mbuf *, void *, u_int16_t *, u_int32_t); void pf_send_deferred_syn(struct pf_state *); int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *, struct pf_addr *, sa_family_t); |