From: Remi Gacogne Date: Mon, 17 Nov 2025 15:26:43 +0000 (+0100) Subject: dnsdist: Clarify AF_XDP/XSK flags X-Git-Tag: rec-5.4.0-alpha1~22^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd76105a45d31fde9049100273603d2895bae1f5;p=thirdparty%2Fpdns.git dnsdist: Clarify AF_XDP/XSK flags Signed-off-by: Remi Gacogne --- diff --git a/pdns/dnsdistdist/dnsdist-xsk.cc b/pdns/dnsdistdist/dnsdist-xsk.cc index 42e74bd966..c5f4b10634 100644 --- a/pdns/dnsdistdist/dnsdist-xsk.cc +++ b/pdns/dnsdistdist/dnsdist-xsk.cc @@ -168,7 +168,7 @@ void XskRouter(std::shared_ptr xsk) ready--; const auto& info = xsk->getWorkerByDescriptor(fds.at(fdIndex).fd); info->processOutgoingFrames([&](XskPacket packet) { - if ((packet.getFlags() & XskPacket::UPDATE) == 0) { + if ((packet.getFlags() & XskPacket::UPDATED) == 0) { xsk->markAsFree(packet); return; } diff --git a/pdns/dnsdistdist/xsk.cc b/pdns/dnsdistdist/xsk.cc index 9a50cdb160..8aeb7913f5 100644 --- a/pdns/dnsdistdist/xsk.cc +++ b/pdns/dnsdistdist/xsk.cc @@ -791,6 +791,7 @@ void XskPacket::changeDirectAndUpdateChecksum() noexcept } setEthernetHeader(ethHeader); + flags |= REWRITTEN; } void XskPacket::rewriteIpv4Header(struct iphdr* ipv4header, size_t frameLen) noexcept @@ -843,7 +844,7 @@ bool XskPacket::setPayload(const PacketBuffer& buf) if (bufSize == 0 || bufSize > currentCapacity) { return false; } - flags |= UPDATE; + flags |= UPDATED; // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) memcpy(frame + getDataOffset(), buf.data(), bufSize); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) @@ -857,6 +858,7 @@ void XskPacket::addDelay(const int relativeMilliseconds) noexcept sendTime.tv_nsec += static_cast(relativeMilliseconds) * 1000000L; sendTime.tv_sec += sendTime.tv_nsec / 1000000000L; sendTime.tv_nsec %= 1000000000L; + flags |= DELAY; } bool operator<(const XskPacket& lhs, const XskPacket& rhs) noexcept @@ -924,12 +926,11 @@ void XskPacket::setAddr(const ComboAddress& from_, MACAddr fromMAC, const ComboA to = to_; from = from_; v6 = !to.isIPv4(); - flags = 0; + flags |= UPDATED; } void XskPacket::rewrite() noexcept { - flags |= REWRITE; auto ethHeader = getEthernetHeader(); if (!v6) { ethHeader.h_proto = htons(ETH_P_IP); @@ -979,6 +980,7 @@ void XskPacket::rewrite() noexcept } setEthernetHeader(ethHeader); + flags |= REWRITTEN; } [[nodiscard]] __be16 XskPacket::ipv4Checksum(const struct iphdr* ipHeader) noexcept @@ -1124,10 +1126,13 @@ void XskPacket::rewrite() noexcept void XskPacket::setHeader(PacketBuffer& buf) { + if (buf.size() > frameSize) { + throw std::runtime_error("Trying to set an XSK header larger than the frame"); + } memcpy(frame, buf.data(), buf.size()); frameLength = buf.size(); buf.clear(); - flags = 0; + flags |= UPDATED; if (!parse(true)) { throw std::runtime_error("Error setting the XSK frame header"); } @@ -1313,10 +1318,10 @@ uint32_t XskPacket::getFlags() const noexcept void XskPacket::updatePacket() noexcept { - if ((flags & UPDATE) == 0U) { + if ((flags & UPDATED) == 0U) { return; } - if ((flags & REWRITE) == 0U) { + if ((flags & REWRITTEN) == 0U) { changeDirectAndUpdateChecksum(); } } diff --git a/pdns/dnsdistdist/xsk.hh b/pdns/dnsdistdist/xsk.hh index ff36be5ecd..82bd13dc55 100644 --- a/pdns/dnsdistdist/xsk.hh +++ b/pdns/dnsdistdist/xsk.hh @@ -94,7 +94,7 @@ class XskSocket vector fds; // list of frames, aka (indexes of) umem entries that can be reused to fill fq, // collected from packets that we could not route (unknown destination), - // could not parse, were dropped during processing (!UPDATE), or + // could not parse, were dropped during processing (!UPDATED), or // simply recycled from cq after being processed by the kernel vector uniqueEmptyFrameOffset; // completion ring: queue where sent packets are stored by the kernel @@ -192,11 +192,15 @@ class XskPacket public: enum Flags : uint32_t { - /* whether the payload has been modified */ - UPDATE = 1 << 0, + /* Whether the payload or the headers have + been updated (a packet that has not been + updated after processing will be discarded) */ + UPDATED = 1 << 0, DELAY = 1 << 1, - /* whether the headers have already been updated */ - REWRITE = 1 << 2 + /* Whether the packet has been rewritten after + the headers and/or payload have been updated. + */ + REWRITTEN = 1 << 2, }; private: @@ -236,7 +240,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) */ + /* Exchange the source and destination addresses (ethernet and IP) */ void changeDirectAndUpdateChecksum() noexcept; constexpr static uint8_t DefaultTTL = 64; @@ -253,13 +257,15 @@ 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 */ + /* Rewrite the headers, usually called after setAddr() then setPayload() */ 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 */ + /* If the payload has been updated, and the headers have not been rewritten via rewrite() yet, + exchange the source and destination addresses (ethernet and IP) and rewrite the headers. + This is what you want except if the headers (including source or destination addresses) + have been manually updated. */ void updatePacket() noexcept; // parse IP and UDP payloads bool parse(bool fromSetHeader);