Bug 93530 - [pf] Incorrect checksums when using pf's route-to on sparc64
Summary: [pf] Incorrect checksums when using pf's route-to on sparc64
Status: Closed Overcome By Events
Alias: None
Product: Base System
Classification: Unclassified
Component: sparc64 (show other bugs)
Version: 6.1-PRERELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-sparc64 (Nobody)
Depends on:
Reported: 2006-02-18 16:00 UTC by Pieter de Boer
Modified: 2021-01-07 20:26 UTC (History)
1 user (show)

See Also:


Note You need to log in before you can comment on or make changes to this bug.
Description Pieter de Boer 2006-02-18 16:00:19 UTC
Using route-to statements in pf gives incorrect checksums on sparc64.
Take for instance the following statement:

 pass out quick route-to (hme0 from to any

If hme0 has configured and the system sends a packet to, it has an incorrect checksum (tcpdumped on the receiving system):

 16:27:45.879243 IP (tos 0x0, ttl  64, id 27, offset 0, flags [none],
 proto: ICMP (1), length: 84, bad cksum 9041 (->b4a4)!) > ICMP echo reply, id 35127, seq 8, length 64

Default install, tcxsum and rxcsum don't make a difference. Traffic
that's not routed using route-to has correct checksums.

See 'Description', in short: use pf route-to on sparc64 and see wrong
Comment 1 Mark Linimon freebsd_committer freebsd_triage 2006-02-18 20:31:45 UTC
Responsible Changed
From-To: gnats-admin->freebsd-pf

Over to maintainer(s).
Comment 2 Pieter de Boer 2006-02-26 14:48:18 UTC
I've investigated some more and found an interesting heisenbug.

From pf.c, pf_route():

                ip->ip_sum = 0;
                if (sw_csum & CSUM_DELAY_IP) {
                        /* From KAME */
                        if (ip->ip_v == IPVERSION &&
                            (ip->ip_hl << 2) == sizeof(*ip)) {
                                ip->ip_sum = in_cksum_hdr(ip);
                        } else {
                                ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);

In the tests I've run, the in_cksum_hdr()-function is called, not the
in_cksum() function. Ok,  I inserted some printf's to find the problem. My

new code looks like this:

                ip->ip_sum = 0;
                if (sw_csum & CSUM_DELAY_IP) {
//                      printf("pf_route(): B1\n");
                        /* From KAME */
                        if (ip->ip_v == IPVERSION &&
                            (ip->ip_hl << 2) == sizeof(*ip)) {      
//                              printf("pf_route: B2\n");     
                                ip->ip_sum = in_cksum_hdr(ip);    
                        } else {
                        //      printf("pf_route: B3\n");
                                ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
With the printf B1 and B2 commented out, the checksums are wrong. With either
printf B1 or B2 not commented out, then the checksums are correct. My theory
is that there's some caching issue between the ip->ip_sum = 0; at the top and
the assembly-code of in_cksum_hdr(). When a printf is inserted between the
ip->ip_sum = 0; and the in_cksum_hdr(), the cache is invalidated long before
in_cksum_hdr() is called.

Perhaps a Sparc64-hacker could take a look at the assembly output of
pf_route() and determine whether this could be the case? :)
Comment 3 Pieter de Boer 2006-02-26 17:32:08 UTC
After some hints from a nice Swedish guy, I found out that compiling
pf.ko with CFLAGS=-O instead of -O2 seems to fix this problem.
Comment 4 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 07:59:46 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped