]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Clarify AF_XDP/XSK flags
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 17 Nov 2025 15:26:43 +0000 (16:26 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 17 Nov 2025 15:43:28 +0000 (16:43 +0100)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist-xsk.cc
pdns/dnsdistdist/xsk.cc
pdns/dnsdistdist/xsk.hh

index 42e74bd966426912ac63b1fb3ba873d5d4e78589..c5f4b106340956e6fc5a2239d08df24237e08e26 100644 (file)
@@ -168,7 +168,7 @@ void XskRouter(std::shared_ptr<XskSocket> 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;
             }
index 9a50cdb1600c97d9a1da0acb1d6bafac289e80d4..8aeb7913f591689ebbd06b61690ec92e7801d299 100644 (file)
@@ -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<int64_t>(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();
   }
 }
index ff36be5ecd96c9d7d2a0b0026728a1d94f75ea7a..82bd13dc5525d8107687fef57bdddd81aab38f60 100644 (file)
@@ -94,7 +94,7 @@ class XskSocket
   vector<pollfd> 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<uint64_t> 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);