Skip to content

Commit

Permalink
[vs] SAI support for VOQ switches - Core Port Index Map File parser (s…
Browse files Browse the repository at this point in the history
…onic-net#700)

Signed-off-by: vedganes <vedavinayagam.ganesan@nokia.com>

Core port index map file parser class. The Core port index map is used
for voq switch testing in vs target
  • Loading branch information
vganesan-nokia authored Nov 10, 2020
1 parent 7e67eb2 commit 036ffba
Show file tree
Hide file tree
Showing 2 changed files with 270 additions and 0 deletions.
45 changes: 45 additions & 0 deletions vslib/inc/CorePortIndexMapFileParser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include "CorePortIndexMapContainer.h"

#include <vector>
#include <memory>

namespace saivs
{
class CorePortIndexMapFileParser
{
private:

CorePortIndexMapFileParser() = delete;
~CorePortIndexMapFileParser() = delete;

public:

static std::shared_ptr<CorePortIndexMapContainer> parseCorePortIndexMapFile(
_In_ const char* file);

static std::shared_ptr<CorePortIndexMapContainer> parseCorePortIndexMapFile(
_In_ const std::string& file);

static bool isInterfaceNameValid(
_In_ const std::string& name);

private:

static void parseLineWithIndex(
_In_ std::shared_ptr<CorePortIndexMapContainer> container,
_In_ const std::vector<std::string>& tokens);

static void parseLineWithNoIndex(
_In_ std::shared_ptr<CorePortIndexMapContainer> container,
_In_ const std::vector<std::string>& tokens);

static void parse(
_In_ std::shared_ptr<CorePortIndexMapContainer> container,
_In_ uint32_t switchIndex,
_In_ const std::string& ifname,
_In_ const std::string& slanes);

};
}
225 changes: 225 additions & 0 deletions vslib/src/CorePortIndexMapFileParser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
#include "CorePortIndexMapFileParser.h"

#include "swss/logger.h"
#include "swss/tokenize.h"

#include <net/if.h>

#include <fstream>
#include <cctype>

using namespace saivs;

// must be the same or less as SAI_VS_SWITCH_INDEX_MAX
#define MAX_SWITCH_INDEX (255)

bool CorePortIndexMapFileParser::isInterfaceNameValid(
_In_ const std::string& name)
{
SWSS_LOG_ENTER();

size_t size = name.size();

if (size == 0 || size > IFNAMSIZ)
{
SWSS_LOG_ERROR("invalid interface name %s or length: %zu", name.c_str(), size);
return false;
}

for (size_t i = 0; i < size; i++)
{
char c = name[i];

if (std::isalnum(c))
continue;

SWSS_LOG_ERROR("invalid character '%c' in interface name %s", c, name.c_str());
return false;
}

// interface name is valid
return true;
}

void CorePortIndexMapFileParser::parse(
_In_ std::shared_ptr<CorePortIndexMapContainer> container,
_In_ uint32_t switchIndex,
_In_ const std::string& ifname,
_In_ const std::string& scpidx)
{
SWSS_LOG_ENTER();

if (!isInterfaceNameValid(ifname))
{
SWSS_LOG_ERROR("interface name '%s' is invalid", ifname.c_str());
return;
}

auto tokens = swss::tokenize(scpidx,',');

size_t n = tokens.size();

if (n != 2)
{
SWSS_LOG_ERROR("Invalid core port index map %s assigned to interface %s", scpidx.c_str(), ifname.c_str());
return;
}

std::vector<uint32_t> cpidx;

for (auto c: tokens)
{
uint32_t c_or_pidx;
if (sscanf(c.c_str(), "%u", &c_or_pidx) != 1)
{
SWSS_LOG_ERROR("failed to parse core or port index: %s", c.c_str());
continue;
}

cpidx.push_back(c_or_pidx);
}

auto corePortIndexMap = container->getCorePortIndexMap(switchIndex);

if (!corePortIndexMap)
{
corePortIndexMap = std::make_shared<CorePortIndexMap>(switchIndex);

container->insert(corePortIndexMap);
}

corePortIndexMap->add(ifname, cpidx);
}

void CorePortIndexMapFileParser::parseLineWithNoIndex(
_In_ std::shared_ptr<CorePortIndexMapContainer> container,
_In_ const std::vector<std::string>& tokens)
{
SWSS_LOG_ENTER();

auto ifname = tokens.at(0);
auto scpidx = tokens.at(1);

parse(container, CorePortIndexMap::DEFAULT_SWITCH_INDEX, ifname, scpidx);
}

void CorePortIndexMapFileParser::parseLineWithIndex(
_In_ std::shared_ptr<CorePortIndexMapContainer> container,
_In_ const std::vector<std::string>& tokens)
{
SWSS_LOG_ENTER();

auto swidx = tokens.at(0);
auto ifname = tokens.at(1);
auto scpidx = tokens.at(2);

uint32_t switchIndex;

if (sscanf(swidx.c_str(), "%u", & switchIndex) != 1)
{
SWSS_LOG_ERROR("failed to parse switchIndex: %s", swidx.c_str());
return;
}

parse(container, switchIndex, ifname, scpidx);
}

std::shared_ptr<CorePortIndexMapContainer> CorePortIndexMapFileParser::parseCorePortIndexMapFile(
_In_ const std::string& file)
{
SWSS_LOG_ENTER();

auto container = std::make_shared<CorePortIndexMapContainer>();

std::ifstream ifs(file);

if (!ifs.is_open())
{
SWSS_LOG_WARN("failed to open core port index map file: %s, using default", file.c_str());

auto def = CorePortIndexMap::getDefaultCorePortIndexMap();

container->insert(def);

return container;
}

SWSS_LOG_NOTICE("loading core port index map from: %s", file.c_str());

std::string line;

while(getline(ifs, line))
{
/*
* line can be in 2 forms:
* ethX:core, core port index
* N:ethX:core, core port index
*
* where N is switchIndex (0..255) - SAI_VS_SWITCH_INDEX_MAX
* if N is not specified then zero (0) is assumed
*/

if (line.size() > 0 && (line[0] == '#' || line[0] == ';'))
{
continue;
}

SWSS_LOG_INFO("core port index line: %s", line.c_str());

auto tokens = swss::tokenize(line, ':');

if (tokens.size() == 3)
{
parseLineWithIndex(container, tokens);
}
else if (tokens.size() == 2)
{
parseLineWithNoIndex(container, tokens);
}
else
{
SWSS_LOG_ERROR("expected 2 or 3 tokens in line %s, got %zu", line.c_str(), tokens.size());
}
}

container->removeEmptyCorePortIndexMaps();

if (container->size() == 0)
{
SWSS_LOG_WARN("no core port index map loaded, returning default core port index map");

auto def = CorePortIndexMap::getDefaultCorePortIndexMap();

container->insert(def);

return container;
}

SWSS_LOG_NOTICE("loaded %zu core port index maps to container", container->size());

return container;
}

std::shared_ptr<CorePortIndexMapContainer> CorePortIndexMapFileParser::parseCorePortIndexMapFile(
_In_ const char* file)
{
SWSS_LOG_ENTER();

if (file == nullptr)
{
auto container = std::make_shared<CorePortIndexMapContainer>();

SWSS_LOG_NOTICE("no file map file specified, loading default");

auto def = CorePortIndexMap::getDefaultCorePortIndexMap();

container->insert(def);

return container;
}

std::string name(file);

return parseCorePortIndexMapFile(name);
}

0 comments on commit 036ffba

Please sign in to comment.