-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvproxy_checksum.h
74 lines (64 loc) · 1.98 KB
/
vproxy_checksum.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#ifndef VPROXY_CHECKSUM_H
#define VPROXY_CHECKSUM_H
#define VP_CSUM_NO (0)
#define VP_CSUM_IP (1 << 0)
#define VP_CSUM_UP (1 << 1)
#define VP_CSUM_UP_PSEUDO (1 << 2)
#define VP_CSUM_ALL (VP_CSUM_UP | VP_CSUM_IP)
#define VP_CSUM_XDP_OFFLOAD (1 << 16)
struct vp_csum_out {
char* up_pos;
char* up_csum_pos;
};
inline int vp_csum_calc0(int sum, char* data, int len) {
for (int i = 0; i < len / 2; ++i) {
sum += ((data[2 * i] & 0xff) << 8) | (data[2 * i + 1] & 0xff);
while (sum > 0xffff) {
sum = (sum & 0xffff) + 1;
}
}
if (len % 2 != 0) {
sum += ((data[len - 1] & 0xff) << 8);
while (sum > 0xffff) {
sum = (sum & 0xffff) + 1;
}
}
return sum;
}
inline int vp_csum_plain_calc(char* data, int len) {
int n = vp_csum_calc0(0, data, len);
return 0xffff - n;
}
inline int vp_csum_ipv4_pseudo_calc(char* src, char* dst, char proto, char* data, int datalen) {
int sum = vp_csum_calc0(0, src, 4);
sum = vp_csum_calc0(sum, dst, 4);
char foo[2];
foo[0] = 0;
foo[1] = proto;
sum = vp_csum_calc0(sum, foo, 2);
foo[0] = (datalen >> 8) & 0xff;
foo[1] = datalen & 0xff;
sum = vp_csum_calc0(sum, foo, 2);
sum = vp_csum_calc0(sum, data, datalen);
return 0xffff - sum;
}
inline int vp_csum_ipv6_pseudo_calc(char* src, char* dst, char proto, char* data, int datalen) {
int sum = vp_csum_calc0(0, src, 16);
sum = vp_csum_calc0(sum, dst, 16);
char foo[4];
foo[0] = (datalen >> 24) & 0xff;
foo[1] = (datalen >> 16) & 0xff;
foo[2] = (datalen >> 8) & 0xff;
foo[3] = datalen & 0xff;
sum = vp_csum_calc0(sum, foo, 4);
foo[0] = 0;
foo[1] = 0;
foo[2] = 0;
foo[3] = proto;
sum = vp_csum_calc0(sum, foo, 4);
sum = vp_csum_calc0(sum, data, datalen);
return 0xffff - sum;
}
int vp_pkt_ether_csum (char* raw, int len, int flags);
int vp_pkt_ether_csum_ex(char* raw, int len, int flags, struct vp_csum_out* out);
#endif