1

我需要将进入 docker 容器到特定端口的流量重定向到另一个容器(我知道它的 ip)到另一个使用 xdp 的端口。为此,我更改了 iphdr 结构的校验和:

// Backup old dest address
     unsigned short old_daddr = ntohs(*(unsigned short *)&iph->daddr);
// Override ip header
     iph->tos = 7 << 2;      // DSCP: 7
     iph->daddr = bpf_htonl(2887516418);  // Dest: 172.28.1.2
     iph->check = 0;
     iph->check = checksum((unsigned short *)iph, sizeof(struct iphdr));
...

然后是 tcphdr 结构的校验和:

// Update tcp checksum
    unsigned long sum = old_daddr + (~ntohs(*(unsigned short *)&iph->daddr) & 0xffff);
    sum += ntohs(tcp->check);
    sum = (sum & 0xffff) + (sum>>16);
    tcp->check = htons(sum + (sum>>16) - 1);

__u16 new_port = 5555;
    if ((__u16)bpf_ntohs(tcp->dest) == new_port) {
        printt("new check: %d, dest port: %d, source port: %d\n", tcp->check, (__u16)bpf_ntohs(tcp->dest), (__u16)bpf_ntohs(tcp->source));
    } else if ((__u16)bpf_ntohs(tcp->dest) == (__u16)4224) {
        update_tcp_header_port(tcp, &new_port);
        printt("change check: %d, dest port: %d, source port: %d\n", tcp->check, (__u16)bpf_ntohs(tcp->dest), (__u16)bpf_ntohs(tcp->source));
    }
...
return XDP_TX;

但它不起作用,我做错了什么?

4

1 回答 1

-1
INTERNAL unsigned short checksum(unsigned short *buf, int bufsz) {
    unsigned long sum = 0;

    while (bufsz > 1) {
        sum += *buf;
        buf++;
        bufsz -= 2;
    }

    if (bufsz == 1) {
        sum += *(unsigned char *)buf;
    }

    sum = (sum & 0xffff) + (sum >> 16);
    sum = (sum & 0xffff) + (sum >> 16);

    return ~sum;
}
于 2020-06-02T09:52:42.140 回答