Skip to content

Commit

Permalink
Add sentinel TLV
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 16, 2021
1 parent 189ff90 commit f2fd3b4
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 72 deletions.
50 changes: 21 additions & 29 deletions src/link_prober/IcmpPayload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,33 @@
namespace link_prober
{
//
// ---> TlvPayload();
// static members
//
boost::uuids::uuid IcmpPayload::mGuid;
uint32_t IcmpPayload::mCookie = 0x47656d69;
uint32_t IcmpPayload::mVersion = 0;

//
// struct constructor
// ---> TlvCommand();
//
TlvPayload::TlvPayload(uint8_t tlv_type) :
type(tlv_type)
// struct TlvCommand constructor
//
TlvCommand::TlvCommand() :
type(tlvtype), length(htons(1)), command(static_cast<uint8_t> (Command::COMMAND_SWITCH_ACTIVE))
{
if (tlv_type == 0)
{
new (&cmdtlv) TlvCommand();
}
}

//
// static members
// ---> TlvSentinel();
//
boost::uuids::uuid IcmpPayload::mGuid;
uint32_t IcmpPayload::mCookie = 0x47656d69;
uint32_t IcmpPayload::mVersion = 0;
// struct TlvSentinel constructor
//
TlvSentinel::TlvSentinel() :
type(tlvtype), length(htons(1))
{
}



//
// ---> IcmpPayload();
Expand All @@ -60,27 +68,11 @@ uint32_t IcmpPayload::mVersion = 0;
IcmpPayload::IcmpPayload() :
cookie(htonl(mCookie)),
version(htonl(mVersion)),
seq(0),
tlv(0)
seq(0)
{
memcpy(uuid, mGuid.data, sizeof(uuid));
}

//
// ---> getPayloadSize()
//
// return the actual payload size
//
unsigned int IcmpPayload::getPayloadSize()
{
unsigned int size = sizeof(IcmpPayload);
if (tlv.type == static_cast<uint8_t> (TlvType::TLV_COMMAND))
{
size += sizeof(TlvCommand) - sizeof(TlvPayload);
}
return size;
}

//
// ---> generateGuid()
//
Expand Down
71 changes: 43 additions & 28 deletions src/link_prober/IcmpPayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ __BEGIN_DECLS

namespace link_prober
{
/**
*@enum TlvType
*
*@brief Supported TLV types
*/
enum TlvType: uint8_t {
TLV_COMMAND = 1,
TLV_SENTINEL = 0x0f,
TLV_COUNT
};

#define TlvHead \
uint8_t type; \
uint16_t length

struct Tlv
{
TlvHead;
};

/**
*@enum Command
Expand All @@ -55,38 +74,40 @@ enum class Command: uint8_t {
Count
};

/**
*@enum TlvType
*
*@brief Supported TLV types
*/
enum class TlvType: uint8_t {
TLV_COMMAND
};

/**
*@struct TlvCommand
*
*@brief Build command TLV
*/
struct TlvCommand
{
uint8_t type = 0;
uint16_t length = htons(1);
uint8_t command = static_cast<uint8_t> (Command::COMMAND_NONE);
TlvHead;
uint8_t command;

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

/**
*@union TlvPayload
*@struct TlvCommand
*
*@brief Union to support multiple TLV structs
*@brief Build command TLV
*/
union TlvPayload
struct TlvSentinel
{
uint8_t type;
TlvCommand cmdtlv;
TlvHead;
uint8_t padding = 0;

TlvPayload(uint8_t tlv_type = 0);
/**
*@method TlvSentinel
*
*@brief struct TlvSentinel default constructor
*/
TlvSentinel();
} __attribute__((packed));

/**
Expand All @@ -99,7 +120,6 @@ struct IcmpPayload {
uint32_t version;
uint8_t uuid[8];
uint64_t seq;
TlvPayload tlv;

/**
*@method IcmpPayload
Expand All @@ -108,15 +128,6 @@ struct IcmpPayload {
*/
IcmpPayload();

/**
*@method getPayloadSize
*
*@brief get the ICMP payload size based on the tlv contained
*
*@return the ICMP payload actual size
*/
unsigned int getPayloadSize();

/**
*@method generateGuid
*
Expand Down Expand Up @@ -171,6 +182,10 @@ 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
1 change: 1 addition & 0 deletions src/link_prober/LinkProber.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ class LinkProber

int mSocket = 0;

std::size_t mTxPacketSize;
std::array<uint8_t, MUX_MAX_ICMP_BUFFER_SIZE> mTxBuffer;
std::array<uint8_t, MUX_MAX_ICMP_BUFFER_SIZE> mRxBuffer;

Expand Down
29 changes: 14 additions & 15 deletions test/LinkProberTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid_io.hpp>

#include "common/MuxException.h"
#include "link_prober/IcmpPayload.h"
#include "LinkProberTest.h"
Expand Down Expand Up @@ -64,14 +63,13 @@ TEST_F(LinkProberTest, InitializeSendBuffer)

iphdr *ipHeader = reinterpret_cast<iphdr *> (txBuffer.data() + sizeof(ether_header));
icmphdr *icmpHeader = reinterpret_cast<icmphdr *> (txBuffer.data() + sizeof(ether_header) + sizeof(iphdr));
link_prober::IcmpPayload *icmpPayload = new (
txBuffer.data() + sizeof(ether_header) + sizeof(iphdr) + sizeof(icmphdr)
) link_prober::IcmpPayload();
link_prober::IcmpPayload *icmpPayload = reinterpret_cast<link_prober::IcmpPayload *> (txBuffer.data() + sizeof(ether_header) + sizeof(iphdr) + sizeof(icmphdr));
link_prober::TlvSentinel *tlvSentinel = reinterpret_cast<link_prober::TlvSentinel *> (txBuffer.data() + sizeof(ether_header) + sizeof(iphdr) + sizeof(icmphdr) + sizeof(*icmpPayload));

EXPECT_TRUE(ipHeader->ihl == sizeof(iphdr) >> 2);
EXPECT_TRUE(ipHeader->version == IPVERSION);
EXPECT_TRUE(ipHeader->tos == 0xb8);
EXPECT_TRUE(ipHeader->tot_len == htons(sizeof(iphdr) + sizeof(icmphdr) + icmpPayload->getPayloadSize()));
EXPECT_TRUE(ipHeader->tot_len == htons(sizeof(iphdr) + sizeof(icmphdr) + sizeof(link_prober::IcmpPayload) + sizeof(link_prober::TlvSentinel)));
EXPECT_TRUE(ipHeader->frag_off == 0);
EXPECT_TRUE(ipHeader->ttl == 64);
EXPECT_TRUE(ipHeader->protocol == IPPROTO_ICMP);
Expand All @@ -86,40 +84,41 @@ TEST_F(LinkProberTest, InitializeSendBuffer)

EXPECT_TRUE(icmpPayload->cookie == htonl(link_prober::IcmpPayload::getCookie()));
EXPECT_TRUE(icmpPayload->version == htonl(link_prober::IcmpPayload::getVersion()));
EXPECT_TRUE(icmpPayload->tlv.type == 0);
EXPECT_TRUE(icmpPayload->tlv.cmdtlv.length == htons(1));
EXPECT_TRUE(icmpPayload->tlv.cmdtlv.command == static_cast<uint8_t> (link_prober::Command::COMMAND_NONE));
EXPECT_TRUE(memcmp(
icmpPayload->uuid,
link_prober::IcmpPayload::getGuidData(),
sizeof(icmpPayload->uuid)
) == 0);

EXPECT_TRUE(tlvSentinel->type == link_prober::TlvType::TLV_SENTINEL);
EXPECT_TRUE(tlvSentinel->length == htons(1));
EXPECT_TRUE(tlvSentinel->padding == 0);
}

TEST_F(LinkProberTest, CalculateChecksum)
{
link_prober::IcmpPayload *icmpPayload = new (
link_prober::IcmpPayload *icmpPayload = reinterpret_cast<link_prober::IcmpPayload *> (
getTxBuffer().data() + sizeof(ether_header) + sizeof(iphdr) + sizeof(icmphdr)
) link_prober::IcmpPayload();
);
boost::uuids::uuid guid = boost::lexical_cast<boost::uuids::uuid> ("44f49d86-c312-414b-b6a1-be82901ac459");
memcpy(icmpPayload->uuid, guid.data, sizeof(icmpPayload->uuid));
initializeSendBuffer();

icmphdr *icmpHeader = reinterpret_cast<icmphdr *> (getTxBuffer().data() + sizeof(ether_header) + sizeof(iphdr));
EXPECT_TRUE(icmpHeader->checksum == 12354);
EXPECT_TRUE(icmpHeader->checksum == 12339);
}

TEST_F(LinkProberTest, UpdateEthernetFrame)
{
link_prober::IcmpPayload *icmpPayload = new (
link_prober::IcmpPayload *icmpPayload = reinterpret_cast<link_prober::IcmpPayload *> (
getTxBuffer().data() + sizeof(ether_header) + sizeof(iphdr) + sizeof(icmphdr)
) link_prober::IcmpPayload();
);
boost::uuids::uuid guid = boost::lexical_cast<boost::uuids::uuid> ("44f49d86-c312-414b-b6a1-be82901ac459");
memcpy(icmpPayload->uuid, guid.data, sizeof(icmpPayload->uuid));
handleUpdateEthernetFrame();

icmphdr *icmpHeader = reinterpret_cast<icmphdr *> (getTxBuffer().data() + sizeof(ether_header) + sizeof(iphdr));
EXPECT_TRUE(icmpHeader->checksum == 12354);
EXPECT_TRUE(icmpHeader->checksum == 12339);
}

TEST_F(LinkProberTest, UpdateSequenceNo)
Expand All @@ -137,7 +136,7 @@ TEST_F(LinkProberTest, UpdateSequenceNo)
handleUpdateSequenceNumber();

icmphdr *icmpHeader = reinterpret_cast<icmphdr *> (getTxBuffer().data() + sizeof(ether_header) + sizeof(iphdr));
EXPECT_TRUE(icmpHeader->checksum == 12098);
EXPECT_TRUE(icmpHeader->checksum == 12083);

EXPECT_TRUE(getRxSelfSeqNo() + 1 == ntohs(icmpHeader->un.echo.sequence));
EXPECT_TRUE(getRxPeerSeqNo() + 1 == ntohs(icmpHeader->un.echo.sequence));
Expand Down

0 comments on commit f2fd3b4

Please sign in to comment.