Skip to content

Commit

Permalink
Fix comments
Browse files Browse the repository at this point in the history
Signed-off-by: Longxiang Lyu <lolv@microsoft.com>
  • Loading branch information
lolyu committed Dec 21, 2021
1 parent 4976f79 commit 7edbd5e
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 103 deletions.
22 changes: 0 additions & 22 deletions src/link_prober/IcmpPayload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,28 +38,6 @@ boost::uuids::uuid IcmpPayload::mGuid;
uint32_t IcmpPayload::mCookie = 0x47656d69;
uint32_t IcmpPayload::mVersion = 0;

//
// ---> TlvCommand();
//
// struct TlvCommand constructor
//
TlvCommand::TlvCommand() :
type(tlvtype), length(htons(1)), command(static_cast<uint8_t> (Command::COMMAND_SWITCH_ACTIVE))
{
}

//
// ---> TlvSentinel();
//
// struct TlvSentinel constructor
//
TlvSentinel::TlvSentinel() :
type(tlvtype), length(htons(1))
{
}



//
// ---> IcmpPayload();
//
Expand Down
19 changes: 0 additions & 19 deletions src/link_prober/IcmpPayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,6 @@ struct TlvCommand
TlvHead;
uint8_t command;
static const uint8_t tlvtype = TlvType::TLV_COMMAND;

/**
*@method TlvCommand
*
*@brief struct TlvCommand default constructor
*/
TlvCommand();
} __attribute__((packed));

/**
Expand All @@ -100,15 +93,7 @@ struct TlvCommand
struct TlvSentinel
{
TlvHead;
uint8_t padding = 0;
static const uint8_t tlvtype = TlvType::TLV_SENTINEL;

/**
*@method TlvSentinel
*
*@brief struct TlvSentinel default constructor
*/
TlvSentinel();
} __attribute__((packed));

/**
Expand Down Expand Up @@ -183,10 +168,6 @@ struct IcmpPayload {
static_assert(sizeof(IcmpPayload) % 2 == 0,
"ICMP Payload size should be even sized, please add zero padding");

static_assert(sizeof(TlvCommand) % 2 == 0, "TLV size should be even sized, please add zero padding");

static_assert(sizeof(TlvSentinel) % 2 == 0, "TLV size should be even sized, please add zero padding");

static_assert(sizeof(ether_header) + sizeof(iphdr) + sizeof(icmphdr) + sizeof(IcmpPayload) < MUX_MAX_ICMP_BUFFER_SIZE,
"Buffer Size doesn't fit Link Prober ICMP packet with its payload");

Expand Down
135 changes: 96 additions & 39 deletions src/link_prober/LinkProber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,22 +232,22 @@ void LinkProber::handleUpdateEthernetFrame()
//
void LinkProber::handleSendSwitchCommand()
{
new (mTxBuffer.data() + mPacketHeaderSize + sizeof(IcmpPayload)) TlvCommand();
new (mTxBuffer.data() + mPacketHeaderSize + sizeof(IcmpPayload) + sizeof(TlvCommand)) TlvSentinel();
resetTxBufferTlv();
appendTlvCommand(Command::COMMAND_SWITCH_ACTIVE);
appendTlvSentinel();

size_t totalPayloadSize = sizeof(IcmpPayload) + sizeof(TlvCommand) + sizeof(TlvSentinel);
size_t totalPayloadSize = mTxPacketSize - mPacketHeaderSize;
iphdr *ipHeader = reinterpret_cast<iphdr *> (mTxBuffer.data() + sizeof(ether_header));
icmphdr *icmpHeader = reinterpret_cast<icmphdr *> (mTxBuffer.data() + sizeof(ether_header) + sizeof(iphdr));
computeChecksum(icmpHeader, sizeof(icmphdr) + totalPayloadSize);
mTxPacketSize = mPacketHeaderSize + totalPayloadSize;
ipHeader->tot_len = htons(sizeof(iphdr) + sizeof(icmphdr) + totalPayloadSize);

sendHeartbeat();

new (mTxBuffer.data() + mPacketHeaderSize + sizeof(IcmpPayload)) TlvSentinel();
totalPayloadSize = sizeof(IcmpPayload) + sizeof(TlvSentinel);
resetTxBufferTlv();
appendTlvSentinel();
totalPayloadSize = mTxPacketSize - mPacketHeaderSize;
computeChecksum(icmpHeader, sizeof(icmphdr) + totalPayloadSize);
mTxPacketSize = mPacketHeaderSize + totalPayloadSize;
ipHeader->tot_len = htons(sizeof(iphdr) + sizeof(icmphdr) + totalPayloadSize);

// inform the composite state machine about commend send completion
Expand Down Expand Up @@ -285,16 +285,16 @@ void LinkProber::sendHeartbeat()
}

//
// ---> handleTlvCommandRecv(size_t offset, bool isPeer);
// ---> handleTlvCommandRecv(Tlv *tlvPtr,, bool isPeer);
//
// handle packet reception
//
void LinkProber::handleTlvCommandRecv(
size_t offset,
Tlv *tlvPtr,
bool isPeer
)
{
TlvCommand *tlvCommand = reinterpret_cast<TlvCommand *> (mTxBuffer.data() + offset);
TlvCommand *tlvCommand = reinterpret_cast<TlvCommand *> (tlvPtr);
if (isPeer) {
if (tlvCommand->command == static_cast<uint8_t> (Command::COMMAND_SWITCH_ACTIVE)) {
boost::asio::io_service::strand &strand = mLinkProberStateMachine.getStrand();
Expand Down Expand Up @@ -327,6 +327,12 @@ void LinkProber::handleRecv(
mRxBuffer.data() + sizeof(ether_header) + sizeof(iphdr)
);

MUXLOGTRACE(boost::format("%s: Got data from: %s, size: %d") %
mMuxPortConfig.getPortName() %
boost::asio::ip::address_v4(ntohl(ipHeader->saddr)).to_string() %
(bytesTransferred - sizeof(iphdr) - sizeof(ether_header))
);

IcmpPayload *icmpPayload = reinterpret_cast<IcmpPayload *> (
mRxBuffer.data() + mPacketHeaderSize
);
Expand All @@ -347,14 +353,14 @@ void LinkProber::handleRecv(
mLinkProberStateMachine.postLinkProberStateEvent(LinkProberStateMachine::getIcmpSelfEvent());
}

uint8_t tlvStartOffset = mPacketHeaderSize + sizeof(IcmpPayload);
size_t nextTlvOffset = mTlvStartOffset;
size_t nextTlvSize = 0;
bool stopProcessTlv = false;
while (tlvStartOffset + sizeof(Tlv) <= bytesTransferred) {
Tlv *currentTlv = reinterpret_cast<Tlv *> (mTxBuffer.data() + tlvStartOffset);
size_t currentTlvLength = ntohs(currentTlv->length);
switch (currentTlv->type) {
while ((nextTlvSize = findNextTlv(nextTlvOffset, bytesTransferred)) > 0 && !stopProcessTlv) {
Tlv *nextTlvPtr = reinterpret_cast<Tlv *> (mRxBuffer.data() + nextTlvOffset);
switch (nextTlvPtr->type) {
case TlvType::TLV_COMMAND: {
handleTlvCommandRecv(tlvStartOffset, !isMatch);
handleTlvCommandRecv(nextTlvPtr, !isMatch);
break;
}
case TlvType::TLV_SENTINEL: {
Expand All @@ -363,27 +369,26 @@ void LinkProber::handleRecv(
break;
}
default: {
// unknonw TLV, try to skip
if (currentTlvLength == 0) {
// try to skip unknown TLV with valid length(>0)
if (nextTlvSize == sizeof(Tlv)) {
stopProcessTlv = true;
break;
}
}
tlvStartOffset += sizeof(Tlv) + currentTlvLength;
}
if (stopProcessTlv) {
break;
}
nextTlvOffset += nextTlvSize;
}

if (nextTlvOffset < bytesTransferred) {
size_t BytesNotProcessed = bytesTransferred - nextTlvOffset;
MUXLOGTRACE(boost::format("%s: %d bytes in RxBuffer not processed") %
mMuxPortConfig.getPortName() %
BytesNotProcessed
);
}
} else {
// Unknown ICMP packet, ignore.
}

MUXLOGTRACE(boost::format("%s: Got data from: %s, size: %d") %
mMuxPortConfig.getPortName() %
boost::asio::ip::address_v4(ntohl(ipHeader->saddr)).to_string() %
(bytesTransferred - sizeof(iphdr) - sizeof(ether_header))
);
// start another receive to consume as much as possible of backlog packets if any
startRecv();
}
Expand Down Expand Up @@ -530,11 +535,15 @@ void LinkProber::startTimer()
uint32_t LinkProber::calculateChecksum(uint16_t *data, size_t size)
{
uint32_t sum = 0;
size_t offset = 0;

do {
sum += ntohs(data[offset++]);
} while (offset < size);
while (size > 1) {
sum += ntohs(*data++);
size -= sizeof(uint16_t);
}

if (size) {
sum += ntohs(static_cast<uint16_t> ((*reinterpret_cast<uint8_t *> (data))));
}

return sum;
}
Expand All @@ -560,7 +569,7 @@ void LinkProber::computeChecksum(icmphdr *icmpHeader, size_t size)
{
icmpHeader->checksum = 0;
mIcmpChecksum = calculateChecksum(
reinterpret_cast<uint16_t *> (icmpHeader), size / 2
reinterpret_cast<uint16_t *> (icmpHeader), size
);
addChecksumCarryover(&icmpHeader->checksum, mIcmpChecksum);
}
Expand All @@ -574,7 +583,7 @@ void LinkProber::computeChecksum(iphdr *ipHeader, size_t size)
{
ipHeader->check = 0;
mIpChecksum = calculateChecksum(
reinterpret_cast<uint16_t *> (ipHeader), size / 2
reinterpret_cast<uint16_t *> (ipHeader), size
);
addChecksumCarryover(&ipHeader->check, mIpChecksum);
}
Expand All @@ -593,14 +602,16 @@ void LinkProber::initializeSendBuffer()

iphdr *ipHeader = reinterpret_cast<iphdr *> (mTxBuffer.data() + sizeof(ether_header));
icmphdr *icmpHeader = reinterpret_cast<icmphdr *> (mTxBuffer.data() + sizeof(ether_header) + sizeof(iphdr));
IcmpPayload *icmpPayload = new (mTxBuffer.data() + mPacketHeaderSize) IcmpPayload();
TlvSentinel *tlvSentinel = new (mTxBuffer.data() + mPacketHeaderSize + sizeof(IcmpPayload)) TlvSentinel();
mTxPacketSize = mPacketHeaderSize + sizeof(IcmpPayload) + sizeof(TlvSentinel);

new (mTxBuffer.data() + mPacketHeaderSize) IcmpPayload();
resetTxBufferTlv();
appendTlvSentinel();
size_t totalPayloadSize = mTxPacketSize - mPacketHeaderSize;

ipHeader->ihl = sizeof(iphdr) >> 2;
ipHeader->version = IPVERSION;
ipHeader->tos = 0xb8;
ipHeader->tot_len = htons(sizeof(iphdr) + sizeof(icmphdr) + sizeof(IcmpPayload) + sizeof(TlvSentinel));
ipHeader->tot_len = htons(sizeof(iphdr) + sizeof(icmphdr) + totalPayloadSize);
ipHeader->id = static_cast<uint16_t> (rand());
ipHeader->frag_off = 0;
ipHeader->ttl = 64;
Expand All @@ -615,7 +626,7 @@ void LinkProber::initializeSendBuffer()
icmpHeader->un.echo.id = htons(mMuxPortConfig.getServerId());
icmpHeader->un.echo.sequence = htons(mTxSeqNo);

computeChecksum(icmpHeader, sizeof(icmphdr) + sizeof(*icmpPayload) + sizeof(*tlvSentinel));
computeChecksum(icmpHeader, sizeof(icmphdr) + totalPayloadSize);
}

//
Expand All @@ -635,4 +646,50 @@ void LinkProber::updateIcmpSequenceNo()
addChecksumCarryover(&icmpHeader->checksum, mIcmpChecksum);
}

//
// ---> findNextTlv
//
// Find next TLV to process in rxBuffer
//
size_t LinkProber::findNextTlv(size_t readOffset, size_t bytesTransferred)
{
size_t tlvSize = 0;
if (readOffset + sizeof(Tlv) <= bytesTransferred) {
Tlv *tlvPtr = reinterpret_cast<Tlv *> (mRxBuffer.data() + readOffset);
tlvSize = (sizeof(Tlv) + ntohs(tlvPtr->length));
}
return tlvSize;
}

//
// ---> appendTlvCommand
//
// Append TlvCommand to the end of txBuffer
//
size_t LinkProber::appendTlvCommand(Command commandType)
{
assert(mTxPacketSize + sizeof(TlvCommand) <= MUX_MAX_ICMP_BUFFER_SIZE);
TlvCommand *tlvCommand = reinterpret_cast<TlvCommand *> (mTxBuffer.data() + mTxPacketSize);
tlvCommand->type = TlvCommand::tlvtype;
tlvCommand->length = htons(1);
tlvCommand->command = static_cast<uint8_t> (Command::COMMAND_SWITCH_ACTIVE);
mTxPacketSize += sizeof(TlvCommand);
return sizeof(TlvCommand);
}

//
// ---> appendTlvSentinel
//
// Append TlvSentinel to the end of txBuffer
//
size_t LinkProber::appendTlvSentinel()
{
assert(mTxPacketSize + sizeof(TlvSentinel) <= MUX_MAX_ICMP_BUFFER_SIZE);
TlvSentinel *tlvSentinel = reinterpret_cast<TlvSentinel *> (mTxBuffer.data() + mTxPacketSize);
tlvSentinel->type = TlvSentinel::tlvtype;
tlvSentinel->length = 0;
mTxPacketSize += sizeof(TlvSentinel);
return sizeof(TlvSentinel);
}

} /* namespace link_prober */
41 changes: 38 additions & 3 deletions src/link_prober/LinkProber.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,13 @@ class LinkProber
*
*@brief handle TLV command
*
*@param offset (in) start offset for TlvCommand struct in mRxBuffer
*@param tlvPtr (in) Tlv ptr points to the start of TlvCommand in mRxBuffer
*@param isPeer (in) True if the reply received is from the peer ToR
*
*@return none
*/
void handleTlvCommandRecv(
size_t offset,
Tlv *tlvPtr,
bool isPeer
);

Expand Down Expand Up @@ -353,10 +353,44 @@ class LinkProber
*
*@brief getter for TxBuffer used for testing
*
*@return CRC checksum
*@return tx buffer
*/
std::array<uint8_t, MUX_MAX_ICMP_BUFFER_SIZE> getTxBuffer() {return mTxBuffer;};

/**
*@method findNextTlv
*
*@brief Find next TLV in rxBuffer starting at readOffset
*
*@param readOffset (in) starting offset to read
*@param bytesTransferred (in) total bytes received in rxBuffer
*
*@return the next TLV size
*/
size_t findNextTlv(size_t readOffset, size_t bytesTransferred);

void resetTxBufferTlv() {mTxPacketSize = mTlvStartOffset;};

/**
*@method appendTlvCommand
*
*@brief append TlvCommand to txBuffer
*
*@param commandType (in) command type
*
*@return the appended TLV size
*/
size_t appendTlvCommand(Command commandType = Command::COMMAND_SWITCH_ACTIVE);

/**
*@method appendTlvSentinel
*
*@brief append TlvSentinel to txBuffer
*
*@return the appended TLV size
*/
size_t appendTlvSentinel();

friend class test::LinkProberTest;

private:
Expand All @@ -375,6 +409,7 @@ class LinkProber
uint32_t mIpChecksum = 0;

static const size_t mPacketHeaderSize = sizeof(ether_header) + sizeof(iphdr) + sizeof(icmphdr);
static const size_t mTlvStartOffset = sizeof(ether_header) + sizeof(iphdr) + sizeof(icmphdr) + sizeof(IcmpPayload);

boost::asio::io_service::strand mStrand;
boost::asio::deadline_timer mDeadlineTimer;
Expand Down
Loading

0 comments on commit 7edbd5e

Please sign in to comment.