How can I redirect traffic from one port to another in the same interface?

Viewed 199

I need the traffic that gets into the docker container to a specific port to be redirected to another container, the ip of which I know, to another port using xdp. For this, I change the checksum of the iphdr structure:

// 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));
...

and then the checksum of the tcphdr structure:

// 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;

but it doesn’t work, what am I doing wrong ?

1 Answers
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;
}
Related