2

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 ?

Qeole
  • 8,284
  • 1
  • 24
  • 52
  • How are you computing the IP checksum? Why are you not using the dedicated helper to compute the TCP checksum? Did you check statistics of your NIC to see why it drops the packets (if that is indeed what it does)? – pchaigno Jun 02 '20 at 08:42
  • What does not work exactly? From your previous question I understand you can load and attach the program successfully, but redirection fails, right? Do the `printt()` print what you expect? What interface are you attaching the program to? – Qeole Jun 02 '20 at 09:01

1 Answers1

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