Skip to content

Commit

Permalink
dnsdist: Fix wrong assertions in AF_XDP/XSK code
Browse files Browse the repository at this point in the history
  • Loading branch information
rgacogne committed Jul 9, 2024
1 parent 9d0e129 commit e380e9d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
24 changes: 16 additions & 8 deletions pdns/xsk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ void XskPacket::changeDirectAndUpdateChecksum() noexcept
// IPV6
auto ipv6 = getIPv6Header();
std::swap(ipv6.daddr, ipv6.saddr);
assert(ipv6.nexthdr == IPPROTO_UDP);
ipv6.nexthdr = IPPROTO_UDP;

auto udp = getUDPHeader();
std::swap(udp.dest, udp.source);
Expand All @@ -738,16 +738,18 @@ void XskPacket::changeDirectAndUpdateChecksum() noexcept
/* needed to get the correct checksum */
setIPv6Header(ipv6);
setUDPHeader(udp);
udp.check = tcp_udp_v6_checksum(&ipv6);
// do not bother setting the UDP checksum: 0 is a valid value and most AF_XDP
// implementations do the same
// udp.check = tcp_udp_v6_checksum(&ipv6);
rewriteIpv6Header(&ipv6, getFrameLen());
setIPv6Header(ipv6);
setUDPHeader(udp);
}
else {
else if (ethHeader.h_proto == htons(ETH_P_IP)) {
// IPV4
auto ipv4 = getIPv4Header();
std::swap(ipv4.daddr, ipv4.saddr);
assert(ipv4.protocol == IPPROTO_UDP);
ipv4.protocol = IPPROTO_UDP;

auto udp = getUDPHeader();
std::swap(udp.dest, udp.source);
Expand All @@ -756,7 +758,9 @@ void XskPacket::changeDirectAndUpdateChecksum() noexcept
/* needed to get the correct checksum */
setIPv4Header(ipv4);
setUDPHeader(udp);
udp.check = tcp_udp_v4_checksum(&ipv4);
// do not bother setting the UDP checksum: 0 is a valid value and most AF_XDP
// implementations do the same
// udp.check = tcp_udp_v4_checksum(&ipv4);
rewriteIpv4Header(&ipv4, getFrameLen());
setIPv4Header(ipv4);
setUDPHeader(udp);
Expand Down Expand Up @@ -908,16 +912,18 @@ void XskPacket::rewrite() noexcept
auto ipHeader = getIPv4Header();
ipHeader.daddr = to.sin4.sin_addr.s_addr;
ipHeader.saddr = from.sin4.sin_addr.s_addr;
ipHeader.protocol = IPPROTO_UDP;

auto udpHeader = getUDPHeader();
ipHeader.protocol = IPPROTO_UDP;
udpHeader.source = from.sin4.sin_port;
udpHeader.dest = to.sin4.sin_port;
udpHeader.len = htons(getDataSize() + sizeof(udpHeader));
udpHeader.check = 0;
/* needed to get the correct checksum */
setIPv4Header(ipHeader);
setUDPHeader(udpHeader);
// do not bother setting the UDP checksum: 0 is a valid value and most AF_XDP
// implementations do the same
// udpHeader.check = tcp_udp_v4_checksum(&ipHeader);
rewriteIpv4Header(&ipHeader, getFrameLen());
setIPv4Header(ipHeader);
Expand All @@ -929,17 +935,19 @@ void XskPacket::rewrite() noexcept
auto ipHeader = getIPv6Header();
memcpy(&ipHeader.daddr, &to.sin6.sin6_addr, sizeof(ipHeader.daddr));
memcpy(&ipHeader.saddr, &from.sin6.sin6_addr, sizeof(ipHeader.saddr));
ipHeader.nexthdr = IPPROTO_UDP;

auto udpHeader = getUDPHeader();
ipHeader.nexthdr = IPPROTO_UDP;
udpHeader.source = from.sin6.sin6_port;
udpHeader.dest = to.sin6.sin6_port;
udpHeader.len = htons(getDataSize() + sizeof(udpHeader));
udpHeader.check = 0;
/* needed to get the correct checksum */
setIPv6Header(ipHeader);
setUDPHeader(udpHeader);
udpHeader.check = tcp_udp_v6_checksum(&ipHeader);
// do not bother setting the UDP checksum: 0 is a valid value and most AF_XDP
// implementations do the same
// udpHeader.check = tcp_udp_v6_checksum(&ipHeader);
setIPv6Header(ipHeader);
setUDPHeader(udpHeader);
}
Expand Down
6 changes: 6 additions & 0 deletions pdns/xsk.hh
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,10 @@ class XskPacket
public:
enum Flags : uint32_t
{
/* whether the payload has been modified */
UPDATE = 1 << 0,
DELAY = 1 << 1,
/* whether the headers have already been updated */
REWRITE = 1 << 2
};

Expand Down Expand Up @@ -234,6 +236,7 @@ private:
void setIPv6Header(const ipv6hdr& ipv6Header) noexcept;
[[nodiscard]] udphdr getUDPHeader() const noexcept;
void setUDPHeader(const udphdr& udpHeader) noexcept;
/* exchange the source and destination addresses (ethernet and IP) */
void changeDirectAndUpdateChecksum() noexcept;

constexpr static uint8_t DefaultTTL = 64;
Expand All @@ -250,10 +253,13 @@ public:
[[nodiscard]] PacketBuffer cloneHeaderToPacketBuffer() const;
void setAddr(const ComboAddress& from_, MACAddr fromMAC, const ComboAddress& to_, MACAddr toMAC) noexcept;
bool setPayload(const PacketBuffer& buf);
/* rewrite the headers, usually after setAddr() and setPayload() have been called */
void rewrite() noexcept;
void setHeader(PacketBuffer& buf);
XskPacket(uint8_t* frame, size_t dataSize, size_t frameSize);
void addDelay(int relativeMilliseconds) noexcept;
/* if the payload have been updated, and the headers have not been rewritten, exchange the source
and destination addresses (ethernet and IP) and rewrite the headers */
void updatePacket() noexcept;
// parse IP and UDP payloads
bool parse(bool fromSetHeader);
Expand Down

0 comments on commit e380e9d

Please sign in to comment.