Skip to content

Commit d6518dd

Browse files
zjswhhhyxieca
authored andcommitted
Fix IP header checksum in handleSendSwitchCommand (#88)
Approach What is the motivation for this PR? Fix the IP header checksum error in the packet sent by handleSendSwitchCommand Signed-off-by: Longxiang Lyu [email protected] Jing Zhang [email protected] How did you do it? Update IP header checksum after appending TlvCommand. How did you verify/test it?
1 parent 2da783b commit d6518dd

File tree

4 files changed

+95
-16
lines changed

4 files changed

+95
-16
lines changed

src/link_prober/LinkProber.cpp

+45-15
Original file line numberDiff line numberDiff line change
@@ -261,25 +261,13 @@ void LinkProber::handleUpdateEthernetFrame()
261261
//
262262
void LinkProber::handleSendSwitchCommand()
263263
{
264-
resetTxBufferTlv();
265-
appendTlvCommand(Command::COMMAND_SWITCH_ACTIVE);
266-
appendTlvSentinel();
267-
268-
size_t totalPayloadSize = mTxPacketSize - mPacketHeaderSize;
269-
iphdr *ipHeader = reinterpret_cast<iphdr *> (mTxBuffer.data() + sizeof(ether_header));
270-
icmphdr *icmpHeader = reinterpret_cast<icmphdr *> (mTxBuffer.data() + sizeof(ether_header) + sizeof(iphdr));
271-
computeChecksum(icmpHeader, sizeof(icmphdr) + totalPayloadSize);
272-
ipHeader->tot_len = htons(sizeof(iphdr) + sizeof(icmphdr) + totalPayloadSize);
264+
initTxBufferTlvSendSwitch();
273265

274266
sendHeartbeat();
275267

276-
resetTxBufferTlv();
277-
appendTlvSentinel();
278-
totalPayloadSize = mTxPacketSize - mPacketHeaderSize;
279-
computeChecksum(icmpHeader, sizeof(icmphdr) + totalPayloadSize);
280-
ipHeader->tot_len = htons(sizeof(iphdr) + sizeof(icmphdr) + totalPayloadSize);
268+
initTxBufferTlvSentinel();
281269

282-
// inform the composite state machine about commend send completion
270+
// inform the composite state machine about command send completion
283271
boost::asio::io_service::strand &strand = mLinkProberStateMachinePtr->getStrand();
284272
boost::asio::io_service &ioService = strand.context();
285273
ioService.post(strand.wrap(boost::bind(
@@ -754,6 +742,48 @@ size_t LinkProber::appendTlvDummy(size_t paddingSize, int seqNo)
754742
return tlvSize;
755743
}
756744

745+
//
746+
// ---> initTxBufferTlvSendSwitch
747+
//
748+
// Initialize TX buffer TLVs to send switch command to peer
749+
//
750+
void LinkProber::initTxBufferTlvSendSwitch()
751+
{
752+
resetTxBufferTlv();
753+
appendTlvCommand(Command::COMMAND_SWITCH_ACTIVE);
754+
appendTlvSentinel();
755+
756+
calculateTxPacketChecksum();
757+
}
758+
759+
//
760+
// ---> initTxBufferTlvSentinel
761+
//
762+
// Initialize TX buffer to have only TLV sentinel
763+
//
764+
void LinkProber::initTxBufferTlvSentinel()
765+
{
766+
resetTxBufferTlv();
767+
appendTlvSentinel();
768+
769+
calculateTxPacketChecksum();
770+
}
771+
772+
//
773+
// ---> calculateChecksum
774+
//
775+
// Calculate TX packet checksums in both IP header and ICMP header
776+
//
777+
void LinkProber::calculateTxPacketChecksum()
778+
{
779+
size_t totalPayloadSize = mTxPacketSize - mPacketHeaderSize;
780+
iphdr *ipHeader = reinterpret_cast<iphdr *> (mTxBuffer.data() + sizeof(ether_header));
781+
icmphdr *icmpHeader = reinterpret_cast<icmphdr *> (mTxBuffer.data() + sizeof(ether_header) + sizeof(iphdr));
782+
computeChecksum(icmpHeader, sizeof(icmphdr) + totalPayloadSize);
783+
ipHeader->tot_len = htons(sizeof(iphdr) + sizeof(icmphdr) + totalPayloadSize);
784+
computeChecksum(ipHeader, ipHeader->ihl << 2);
785+
}
786+
757787
//
758788
// ---> resetIcmpPacketCounts
759789
//

src/link_prober/LinkProber.h

+28-1
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,34 @@ class LinkProber
450450
*@return the appended TLV size
451451
*/
452452
size_t appendTlvDummy(size_t paddingSize, int seqNo);
453-
453+
454+
/**
455+
* @method initTlvSendSwitch
456+
*
457+
* @brief initialize TX buffer TLVs to send switch command to peer
458+
*
459+
* @return none
460+
*/
461+
void initTxBufferTlvSendSwitch();
462+
463+
/**
464+
* @method initTxBufferTlvSentinel
465+
*
466+
* @brief initialize TX buffer to have only TLV sentinel
467+
*
468+
* @return none
469+
*/
470+
void initTxBufferTlvSentinel();
471+
472+
/**
473+
* @method calculateChecksum
474+
*
475+
* @brief calculate TX packet checksums in both IP header and ICMP header
476+
*
477+
* @return none
478+
*/
479+
inline void calculateTxPacketChecksum();
480+
454481
/**
455482
* @method getProbingInterval
456483
*

test/LinkProberTest.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,26 @@ TEST_F(LinkProberTest, CalculateChecksum)
128128
EXPECT_TRUE(icmpHeader->checksum == 12100);
129129
}
130130

131+
TEST_F(LinkProberTest, handleSendSwitchCommand)
132+
{
133+
initializeSendBuffer();
134+
135+
iphdr *ipHeader = reinterpret_cast<iphdr *>(getTxBufferData() + sizeof(ether_header));
136+
icmphdr *icmpHeader = reinterpret_cast<icmphdr *>(getTxBufferData() + sizeof(ether_header) + sizeof(iphdr));
137+
ipHeader->id = static_cast<uint16_t> (17767);
138+
initTxBufferSentinel();
139+
EXPECT_TRUE(ipHeader->check == 62919);
140+
EXPECT_TRUE(icmpHeader->checksum == 12100);
141+
142+
initTxBufferTlvSendSwitch();
143+
EXPECT_TRUE(ipHeader->check == 61895);
144+
EXPECT_TRUE(icmpHeader->checksum == 11838);
145+
146+
initTxBufferSentinel();
147+
EXPECT_TRUE(ipHeader->check == 62919);
148+
EXPECT_TRUE(icmpHeader->checksum == 12100);
149+
}
150+
131151
TEST_F(LinkProberTest, UpdateEthernetFrame)
132152
{
133153
link_prober::IcmpPayload *icmpPayload = new (

test/LinkProberTest.h

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ class LinkProberTest: public ::testing::Test
5757
uint16_t getRxSelfSeqNo() {return mLinkProber.mRxSelfSeqNo;};
5858
uint16_t getRxPeerSeqNo() {return mLinkProber.mRxPeerSeqNo;};
5959
bool getSuspendTx() {return mLinkProber.mSuspendTx;};
60+
void initTxBufferTlvSendSwitch() {mLinkProber.initTxBufferTlvSendSwitch();}
61+
void initTxBufferSentinel() {mLinkProber.initTxBufferTlvSentinel();}
6062

6163
boost::asio::io_service mIoService;
6264
common::MuxConfig mMuxConfig;

0 commit comments

Comments
 (0)