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
This commit is contained in:
Srivats P 2023-03-18 15:01:11 +05:30
parent 5d4a19174e
commit 90a3731a90
3 changed files with 32 additions and 13 deletions

View File

@ -37,6 +37,8 @@ public:
repeatCount_ = 1; repeatCount_ = 1;
repeatSize_ = 1; repeatSize_ = 1;
usecDelay_ = 0; usecDelay_ = 0;
ttagL4CksumOffset_ = 0;
ttagPktInterval_ = 0;
} }
~PacketSequence() { ~PacketSequence() {
pcap_sendqueue_destroy(sendQueue_); pcap_sendqueue_destroy(sendQueue_);
@ -69,6 +71,8 @@ public:
streamStatsMeta_[guid].tx_bytes += pktHeader->caplen; streamStatsMeta_[guid].tx_bytes += pktHeader->caplen;
} }
} }
if (trackGuidStats_ && (packets_ == 1)) // first packet of seq
ttagL4CksumOffset_ = 40; // FIXME
return ret; return ret;
} }
pcap_send_queue *sendQueue_; pcap_send_queue *sendQueue_;
@ -79,7 +83,8 @@ public:
int repeatCount_; int repeatCount_;
int repeatSize_; int repeatSize_;
long usecDelay_; 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_; StreamStats streamStatsMeta_;
private: private:

View File

@ -275,9 +275,10 @@ void PcapTxThread::run()
packetSequenceList_.at(i)->repeatCount_, packetSequenceList_.at(i)->repeatCount_,
packetSequenceList_.at(i)->repeatSize_, packetSequenceList_.at(i)->repeatSize_,
packetSequenceList_.at(i)->usecDelay_); 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)->packets_,
packetSequenceList_.at(i)->usecDuration_, packetSequenceList_.at(i)->usecDuration_,
packetSequenceList_.at(i)->ttagL4CksumOffset_,
packetSequenceList_.at(i)->ttagPktInterval_); packetSequenceList_.at(i)->ttagPktInterval_);
} }
@ -314,12 +315,12 @@ _restart:
if (stop_) if (stop_)
ret = -2; ret = -2;
} else { } else {
ret = sendQueueTransmit(handle_, seq->sendQueue_, ret = sendQueueTransmit(handle_, seq,
seq->ttagPktInterval_, overHead, kSyncTransmit); overHead, kSyncTransmit);
} }
#else #else
ret = sendQueueTransmit(handle_, seq->sendQueue_, ret = sendQueueTransmit(handle_, seq,
seq->ttagPktInterval_, overHead, kSyncTransmit); overHead, kSyncTransmit);
#endif #endif
if (ret >= 0) { if (ret >= 0) {
@ -408,11 +409,12 @@ double PcapTxThread::lastTxDuration()
return lastTxDuration_; return lastTxDuration_;
} }
int PcapTxThread::sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, int PcapTxThread::sendQueueTransmit(pcap_t *p, PacketSequence *seq,
quint64 ttagPktInterval, long &overHead, int sync) long &overHead, int sync)
{ {
TimeStamp ovrStart, ovrEnd; TimeStamp ovrStart, ovrEnd;
struct timeval ts; struct timeval ts;
pcap_send_queue *queue = seq->sendQueue_;
struct pcap_pkthdr *hdr = (struct pcap_pkthdr*) queue->buffer; struct pcap_pkthdr *hdr = (struct pcap_pkthdr*) queue->buffer;
char *end = queue->buffer + queue->len; 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); uchar *pkt = (uchar*)hdr + sizeof(*hdr);
int pktLen = hdr->caplen; int pktLen = hdr->caplen;
bool ttagPkt = false; bool ttagPkt = false;
quint16 origCksum = 0;
// Time for a T-Tag packet? // 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; ttagPkt = true;
// FIXME: fixup cksum(s)
*(pkt+pktLen-5) = SignProtocol::kTypeLenTtag; *(pkt+pktLen-5) = SignProtocol::kTypeLenTtag;
if (seq->ttagL4CksumOffset_) {
quint16 *cksum = reinterpret_cast<quint16*>(
pkt + seq->ttagL4CksumOffset_);
origCksum = *cksum;
*cksum = 0x0000; // FIXME: recalc cksum
}
} }
if (sync) { if (sync) {
@ -457,6 +467,11 @@ int PcapTxThread::sendQueueTransmit(pcap_t *p, pcap_send_queue *queue,
// Revert T-Tag packet changes // Revert T-Tag packet changes
if (ttagPkt) { if (ttagPkt) {
*(pkt+pktLen-5) = SignProtocol::kTypeLenTtagPlaceholder; *(pkt+pktLen-5) = SignProtocol::kTypeLenTtagPlaceholder;
if (seq->ttagL4CksumOffset_) {
quint16 *cksum = reinterpret_cast<quint16*>(
pkt + seq->ttagL4CksumOffset_);
*cksum = origCksum;
}
} }
// Step to the next packet in the buffer // Step to the next packet in the buffer
@ -617,4 +632,3 @@ void PcapTxThread::udelay(unsigned long usec)
QThread::usleep(usec); QThread::usleep(usec);
#endif #endif
} }

View File

@ -66,8 +66,8 @@ private:
}; };
static void udelay(unsigned long usec); static void udelay(unsigned long usec);
int sendQueueTransmit(pcap_t *p, pcap_send_queue *queue, int sendQueueTransmit(pcap_t *p, PacketSequence *seq,
quint64 ttagPktInterval, long &overHead, int sync); long &overHead, int sync);
void updateTxStreamStats(); void updateTxStreamStats();
// Intermediate state variables used while building the packet list // Intermediate state variables used while building the packet list