From f65aed7bb0827accc07abc83566e21a44f7d35ac Mon Sep 17 00:00:00 2001 From: Srivats P Date: Sat, 18 Mar 2023 15:01:11 +0530 Subject: [PATCH] Add infra to update L4 checksum for T-Tag packets Pending * Calculate L4 checksum offset instead of hardcoded value * Recalculate packet L4 checksum instead of using 0 value --- server/packetsequence.h | 7 ++++++- server/pcaptxthread.cpp | 34 ++++++++++++++++++++++++---------- server/pcaptxthread.h | 4 ++-- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/server/packetsequence.h b/server/packetsequence.h index a4c8a88..8962bc9 100644 --- a/server/packetsequence.h +++ b/server/packetsequence.h @@ -37,6 +37,8 @@ public: repeatCount_ = 1; repeatSize_ = 1; usecDelay_ = 0; + ttagL4CksumOffset_ = 0; + ttagPktInterval_ = 0; } ~PacketSequence() { pcap_sendqueue_destroy(sendQueue_); @@ -69,6 +71,8 @@ public: streamStatsMeta_[guid].tx_bytes += pktHeader->caplen; } } + if (trackGuidStats_ && (packets_ == 1)) // first packet of seq + ttagL4CksumOffset_ = 40; // FIXME return ret; } pcap_send_queue *sendQueue_; @@ -79,7 +83,8 @@ public: int repeatCount_; int repeatSize_; long usecDelay_; - qulonglong ttagPktInterval_{0}; // ttag pkt once every X packets + quint16 ttagL4CksumOffset_; // For ttag packets + qulonglong ttagPktInterval_; // ttag pkt once every X packets StreamStats streamStatsMeta_; private: diff --git a/server/pcaptxthread.cpp b/server/pcaptxthread.cpp index 3946352..f428189 100644 --- a/server/pcaptxthread.cpp +++ b/server/pcaptxthread.cpp @@ -275,9 +275,10 @@ void PcapTxThread::run() packetSequenceList_.at(i)->repeatCount_, packetSequenceList_.at(i)->repeatSize_, packetSequenceList_.at(i)->usecDelay_); - qDebug("sendQ[%d]: pkts = %ld, usecDuration = %ld, ttagPktIntvl = %llu", i, + qDebug("sendQ[%d]: pkts = %ld, usecDuration = %ld, ttagL4CksumOfs = %hu ttagPktIntvl = %llu", i, packetSequenceList_.at(i)->packets_, packetSequenceList_.at(i)->usecDuration_, + packetSequenceList_.at(i)->ttagL4CksumOffset_, packetSequenceList_.at(i)->ttagPktInterval_); } @@ -314,12 +315,12 @@ _restart: if (stop_) ret = -2; } else { - ret = sendQueueTransmit(handle_, seq->sendQueue_, - seq->ttagPktInterval_, overHead, kSyncTransmit); + ret = sendQueueTransmit(handle_, seq, + overHead, kSyncTransmit); } #else - ret = sendQueueTransmit(handle_, seq->sendQueue_, - seq->ttagPktInterval_, overHead, kSyncTransmit); + ret = sendQueueTransmit(handle_, seq, + overHead, kSyncTransmit); #endif if (ret >= 0) { @@ -408,11 +409,12 @@ double PcapTxThread::lastTxDuration() return lastTxDuration_; } -int PcapTxThread::sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, - quint64 ttagPktInterval, long &overHead, int sync) +int PcapTxThread::sendQueueTransmit(pcap_t *p, PacketSequence *seq, + long &overHead, int sync) { TimeStamp ovrStart, ovrEnd; struct timeval ts; + pcap_send_queue *queue = seq->sendQueue_; struct pcap_pkthdr *hdr = (struct pcap_pkthdr*) queue->buffer; char *end = queue->buffer + queue->len; @@ -422,12 +424,20 @@ int PcapTxThread::sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, uchar *pkt = (uchar*)hdr + sizeof(*hdr); int pktLen = hdr->caplen; bool ttagPkt = false; + quint16 origCksum = 0; // Time for a T-Tag packet? - if (ttagPktInterval && ((stats_->pkts % ttagPktInterval) == 0)) { + // FIXME: optimize per packet costly modulo operation + if (seq->ttagPktInterval_ + && ((stats_->pkts % seq->ttagPktInterval_) == 0)) { ttagPkt = true; - // FIXME: fixup cksum(s) *(pkt+pktLen-5) = SignProtocol::kTypeLenTtag; + if (seq->ttagL4CksumOffset_) { + quint16 *cksum = reinterpret_cast( + pkt + seq->ttagL4CksumOffset_); + origCksum = *cksum; + *cksum = 0x0000; // FIXME: recalc cksum + } } if (sync) { @@ -457,6 +467,11 @@ int PcapTxThread::sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, // Revert T-Tag packet changes if (ttagPkt) { *(pkt+pktLen-5) = SignProtocol::kTypeLenTtagPlaceholder; + if (seq->ttagL4CksumOffset_) { + quint16 *cksum = reinterpret_cast( + pkt + seq->ttagL4CksumOffset_); + *cksum = origCksum; + } } // Step to the next packet in the buffer @@ -617,4 +632,3 @@ void PcapTxThread::udelay(unsigned long usec) QThread::usleep(usec); #endif } - diff --git a/server/pcaptxthread.h b/server/pcaptxthread.h index c3a3f1b..4dec9bc 100644 --- a/server/pcaptxthread.h +++ b/server/pcaptxthread.h @@ -66,8 +66,8 @@ private: }; static void udelay(unsigned long usec); - int sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, - quint64 ttagPktInterval, long &overHead, int sync); + int sendQueueTransmit(pcap_t *p, PacketSequence *seq, + long &overHead, int sync); void updateTxStreamStats(); // Intermediate state variables used while building the packet list