Skip to content
Snippets Groups Projects
Commit 95c682c1 authored by NGUYEN Do Duc Anh's avatar NGUYEN Do Duc Anh
Browse files

fix buf wrong tcp checksum conputation

parent 46e54308
No related branches found
No related tags found
No related merge requests found
...@@ -29,30 +29,35 @@ static inline __u16 csum_fold_helper(__u32 csum) ...@@ -29,30 +29,35 @@ static inline __u16 csum_fold_helper(__u32 csum)
return ~csum; return ~csum;
} }
static __always_inline __u32 sum16(const void *data, __u32 size, const void *data_end) static __always_inline __u32 sum16(const void* data, __u32 size, const void* data_end) {
{
__u32 s = 0; __u32 s = 0;
__u16 *buf = (__u16 *)data;
for (__u32 i = 0; i < MAX_CSUM_WORDS; i++) for (__u32 i = 0; i < MAX_CSUM_WORDS; i++)
{ {
if (2 * i >= size) if (2 * i >= size)
{ {
// bpf_trace_printk("csum4: %lx", s);
return s; /* normal exit */ return s; /* normal exit */
} }
if (data + 2 * i + 1 + 1 > data_end) if ((void *)(buf + 1) > data_end)
{ {
return 0; /* should be unreachable */ // bpf_trace_printk("csum5: %lx", s);
return 0;
} }
s += ((const __u16 *)data)[i]; s += *buf++;
if (2 * i + 1 == size) if (2 * i + 3 == size)
{ {
__u8 byte; if (data + 2 * i + 3 > data_end)
if (bpf_probe_read_kernel(&byte, sizeof(byte), data + (i * 2 + 1))) {
return 0; return 0; /* should be unreachable */
}
__u8 byte = *((__u8 *)data + 2*i + 2);
s += byte; s += byte;
// bpf_trace_printk("csum3: %lx, bytes: %x, byte2: %x", s, byte);
return s;
} }
} }
return s; return s;
} }
...@@ -67,18 +72,18 @@ static inline __u16 tcp_checksum(struct iphdr *ip, struct tcphdr *tcp, void *dat ...@@ -67,18 +72,18 @@ static inline __u16 tcp_checksum(struct iphdr *ip, struct tcphdr *tcp, void *dat
return 0; return 0;
// 2. Pseudo-header // 2. Pseudo-header
csum += (ip->saddr >> 16) & 0xFFFF; csum += (ip->saddr >> 16) + (ip->saddr & 0xFFFF);
csum += ip->saddr & 0xFFFF; csum += (ip->daddr >> 16) + (ip->daddr & 0xFFFF);
csum += (ip->daddr >> 16) & 0xFFFF;
csum += ip->daddr & 0xFFFF;
csum += htons(6); csum += htons(6);
csum += htons(tcp_len); csum += htons(tcp_len);
bpf_trace_printk("csum1: %lx", csum);
// 3. Manual unrolling (safer than loops) // 3. Manual unrolling (safer than loops)
__u16 *ptr = (__u16 *)tcp; __u16 *ptr = (__u16 *)tcp;
__u16 words = tcp_len / 2; __u16 words = tcp_len / 2;
csum += sum16(tcp, tcp_len, data_end); csum += sum16(tcp, tcp_len, data_end);
bpf_trace_printk("csum2: %lx", csum);
return csum_fold_helper(csum); return csum_fold_helper(csum);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment