IT WORKSSSS

This commit is contained in:
2026-09-18 15:40:45 +02:00
parent 7a210f7a2c
commit 47c1334e5e
+28 -16
View File
@@ -145,14 +145,15 @@ static __always_inline const __u8 *get_tcp_data(const __u16 EtherType,
return NULL; return NULL;
} }
static __u16 tcp_checksum_fold(__u32 sum) { static __always_inline __u16 tcp_checksum_fold(__u32 sum) {
sum = (sum & 0xFFFF) + (sum >> 16); sum = (sum & 0xFFFF) + (sum >> 16);
sum = (sum & 0xFFFF) + (sum >> 16); sum = (sum & 0xFFFF) + (sum >> 16);
sum = (sum & 0xFFFF) + (sum >> 16); sum = (sum & 0xFFFF) + (sum >> 16);
return (__u16)~sum; return (__u16)~sum;
} }
static __u32 tcp_checksum_add(const void *data, const void *data_end, static __always_inline __u32 tcp_checksum_add(const void *data,
const void *data_end,
__u32 sum) { __u32 sum) {
const __u8 *p = data; const __u8 *p = data;
for (int i = 0; i < 740; i++) { // MTU/2, upper bound for the verifier for (int i = 0; i < 740; i++) { // MTU/2, upper bound for the verifier
@@ -227,8 +228,10 @@ int xdp_drop_prog(struct xdp_md *ctx) {
*tcp_flags_ptr = tcp_flags | ACK_MASK; *tcp_flags_ptr = tcp_flags | ACK_MASK;
*(__u16 *)(tcp_packet_data + TCP_CHECKSUM_OFFSET) = 0; // must be zero for calculation
const __u8 tcp_data_offset = const __u8 tcp_data_offset =
bpf_ntohs(((*(__u8 *)(tcp_packet_data + TCP_DATA_OFFSET_OFFSET))) >> ((*(__u8 *)(tcp_packet_data + TCP_DATA_OFFSET_OFFSET)) >>
TCP_DATA_OFFSET_SHIFT) * TCP_DATA_OFFSET_SHIFT) *
sizeof(__u32); sizeof(__u32);
@@ -246,25 +249,31 @@ int xdp_drop_prog(struct xdp_md *ctx) {
{ // swap src and dst ip { // swap src and dst ip
__u32 src_ip_BE = *src_ip_ptr; __u32 src_ip_BE = *src_ip_ptr;
*src_ip_ptr = *dst_ip_ptr; *src_ip_ptr = *dst_ip_ptr;
*dst_ip_ptr = *src_ip_ptr; *dst_ip_ptr = src_ip_BE;
} }
*(__u8 *)(ip_packet_data + IPV4_TTL_OFFSET) = DEFAULT_TTL; *(__u8 *)(ip_packet_data + IPV4_TTL_OFFSET) = DEFAULT_TTL;
{ // calculate ipv4 header checksum { // calculate ipv4 header checksum
if ((*ip_packet_data & 0b00001111) != 5) {
return XDP_PASS;
}
if (ip_packet_data + 20 > data_end) {
return XDP_PASS;
}
__u16 *ipv4_checksum_ptr = __u16 *ipv4_checksum_ptr =
(__u16 *)(ip_packet_data + IPV4_CHECKSUM_OFFSET); (__u16 *)(ip_packet_data + IPV4_CHECKSUM_OFFSET);
*ipv4_checksum_ptr = 0; // must be zero for calculation *ipv4_checksum_ptr = 0; // must be zero for calculation
__u16 new_checksum = 0; __u32 new_checksum = 0;
const __u8 *p = ip_packet_data; for (int i = 0; i < 10; i++) {
for (int i = 0; i < 30; i++) { if (ip_packet_data + i * 2 + 2 > data_end) {
if (p + 2 > data_end || p + 2 > tcp_packet_data) {
break; break;
} }
new_checksum += bpf_ntohs(*(const __u16 *)p); new_checksum += bpf_ntohs(*(__u16 *)(ip_packet_data + i * 2));
p += 2;
} }
*ipv4_checksum_ptr = bpf_htons(new_checksum); new_checksum = (new_checksum & 0xFFFF) + (new_checksum >> 16);
new_checksum = (new_checksum & 0xFFFF) + (new_checksum >> 16);
*ipv4_checksum_ptr = bpf_htons((__u16)new_checksum);
} }
struct tcp_v4_pseudo_header pseudo_header = { struct tcp_v4_pseudo_header pseudo_header = {
@@ -275,6 +284,12 @@ int xdp_drop_prog(struct xdp_md *ctx) {
&pseudo_header, &pseudo_header,
(const __u8 *)&pseudo_header + sizeof(pseudo_header), tmp_sum); (const __u8 *)&pseudo_header + sizeof(pseudo_header), tmp_sum);
} else { } else {
if (EtherType != ETHER_TYPE_IPV6) {
return XDP_PASS;
}
if (ip_packet_data + IPV6_HEADER_SIZE > data_end) {
return XDP_PASS;
}
__u128 *src_ip_ptr = __u128 *src_ip_ptr =
(__u128 *)(ip_packet_data + IPV6_SRC_ADDR_OFFSET); (__u128 *)(ip_packet_data + IPV6_SRC_ADDR_OFFSET);
__u128 *dst_ip_ptr = __u128 *dst_ip_ptr =
@@ -283,7 +298,7 @@ int xdp_drop_prog(struct xdp_md *ctx) {
{ // swap src and dst ip { // swap src and dst ip
__u128 src_ip_BE = *src_ip_ptr; __u128 src_ip_BE = *src_ip_ptr;
*src_ip_ptr = *dst_ip_ptr; *src_ip_ptr = *dst_ip_ptr;
*dst_ip_ptr = *src_ip_ptr; *dst_ip_ptr = src_ip_BE;
} }
*(__u8 *)(ip_packet_data + IPV6_HOP_LIMIT_OFFSET) = DEFAULT_TTL; *(__u8 *)(ip_packet_data + IPV6_HOP_LIMIT_OFFSET) = DEFAULT_TTL;
@@ -300,10 +315,7 @@ int xdp_drop_prog(struct xdp_md *ctx) {
(const __u8 *)&pseudo_header + sizeof(pseudo_header), tmp_sum); (const __u8 *)&pseudo_header + sizeof(pseudo_header), tmp_sum);
} }
tmp_sum = tcp_checksum_add(tcp_packet_data, tmp_sum = tcp_checksum_add(tcp_packet_data, data_end, tmp_sum);
tcp_packet_data + tcp_data_offset, tmp_sum);
tmp_sum = tcp_checksum_add(tcp_packet_data + tcp_data_offset, data_end,
tmp_sum);
tcp_checksum = bpf_htons(tcp_checksum_fold(tmp_sum)); tcp_checksum = bpf_htons(tcp_checksum_fold(tmp_sum));
} }
*(__u16 *)(tcp_packet_data + TCP_CHECKSUM_OFFSET) = tcp_checksum; *(__u16 *)(tcp_packet_data + TCP_CHECKSUM_OFFSET) = tcp_checksum;