Skip to content

Commit

Permalink
[SAI] Add support for dash configuration from sai interface
Browse files Browse the repository at this point in the history
  • Loading branch information
kcudnik committed Aug 2, 2023
1 parent f475caa commit 9ccebe4
Show file tree
Hide file tree
Showing 6 changed files with 257 additions and 17 deletions.
2 changes: 1 addition & 1 deletion dash-pipeline/SAI/sai_api_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ def write_sai_makefile(sai_api_name_list, sai_api_full_name_list):
def write_sai_fixed_api_files(sai_api_full_name_list):
env = Environment(loader=FileSystemLoader('.'))

for filename in ['utils.cpp', 'utils.h', 'saifixedapis.cpp', 'saiimpl.h', 'logger.h', 'logger.cpp']:
for filename in ['utils.cpp', 'utils.h', 'saifixedapis.cpp', 'saiimpl.h', 'logger.h', 'logger.cpp', 'saidash.h', 'config.h', 'config.cpp']:
env = Environment(loader=FileSystemLoader('.'), trim_blocks=True, lstrip_blocks=True)
sai_impl_tm = env.get_template('/templates/%s.j2' % filename)
sai_impl_str = sai_impl_tm.render(tables = sai_api[TABLES_TAG], app_name = sai_api['app_name'], api_names = sai_api_full_name_list)
Expand Down
3 changes: 2 additions & 1 deletion dash-pipeline/SAI/templates/Makefile.j2
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ SAI_OBJS=$(SAI_SRCS:.c=.o)
# DASH libsai "fixed" sources (not generated from P4 code)
DASH_FIXED_SAI_SRCS=utils.cpp \
saifixedapis.cpp \
logger.cpp
logger.cpp \
config.cpp
DASH_FIXED_SAI_OBJ=$(DASH_FIXED_SAI_SRCS:.cpp=.o)

# DASH libsai "generated" sources (from P4 code)
Expand Down
127 changes: 127 additions & 0 deletions dash-pipeline/SAI/templates/config.cpp.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#include "config.h"
#include "logger.h"
#include "saidash.h"

#include <cstdlib>
#include <sstream>

using namespace dash;

Config::Config():
m_grpcTarget(DEFAULT_GRPC_TARGET),
m_pipelineJson(DEFAULT_PIPELINE_JSON),
m_pipelineProto(DEFAULT_PIPELINE_PROTO),
m_deviceId(DEFAULT_DEVICE_ID),
m_bmv2NumPorts(DEFAULT_BMV2_NUM_PORTS)
{
DASH_LOG_ENTER();

// empty intentionally
}

std::shared_ptr<Config> Config::getDefaultConfig()
{
DASH_LOG_ENTER();

return std::make_shared<Config>();
}

std::shared_ptr<Config> Config::getConfig(
const sai_service_method_table_t* serviceMethodTable)
{
DASH_LOG_ENTER();

auto cfg = getDefaultConfig();

if (serviceMethodTable == nullptr)
{
DASH_LOG_NOTICE("service method table is null, returning default config");

return cfg;
}

if (serviceMethodTable->profile_get_value == nullptr)
{
DASH_LOG_NOTICE("profile_get_value member is null, returning default config");

return cfg;
}

auto grpcTarget = serviceMethodTable->profile_get_value(0, SAI_KEY_DASH_GRPC_TARGET);

if (grpcTarget)
{
DASH_LOG_NOTICE("%s: %s", SAI_KEY_DASH_GRPC_TARGET, grpcTarget);

cfg->m_grpcTarget = grpcTarget;
}

auto pipelineJson = serviceMethodTable->profile_get_value(0, SAI_KEY_DASH_PIPELINE_JSON);

if (pipelineJson)
{
DASH_LOG_NOTICE("%s: %s", SAI_KEY_DASH_PIPELINE_JSON, pipelineJson);

cfg->m_pipelineJson = pipelineJson;
}

auto pipelineProto = serviceMethodTable->profile_get_value(0, SAI_KEY_DASH_PIPELINE_PROTO);

if (pipelineProto)
{
DASH_LOG_NOTICE("%s: %s", SAI_KEY_DASH_PIPELINE_JSON, pipelineProto);

cfg->m_pipelineProto = pipelineProto;
}

auto deviceId = serviceMethodTable->profile_get_value(0, SAI_KEY_DASH_DEVICE_ID);

if (deviceId)
{
int devId = atoi(deviceId);

cfg->m_deviceId = devId;

DASH_LOG_NOTICE("%s: %s (%d)", SAI_KEY_DASH_DEVICE_ID, deviceId, devId);
}

auto numPorts = serviceMethodTable->profile_get_value(0, SAI_KEY_DASH_BMV2_NUM_PORTS);

if (numPorts)
{
uint32_t num = (uint32_t)atoi(numPorts);

if (num > MAX_BMV2_NUM_PORTS)
{
DASH_LOG_ERROR("%s: %s (%u > %u), setting to default %u",
SAI_KEY_DASH_BMV2_NUM_PORTS,
numPorts,
num,
MAX_BMV2_NUM_PORTS,
DEFAULT_BMV2_NUM_PORTS);

num = DEFAULT_BMV2_NUM_PORTS;
}

cfg->m_bmv2NumPorts = num;

DASH_LOG_NOTICE("%s: %s (%u)", SAI_KEY_DASH_BMV2_NUM_PORTS, numPorts, num);
}

return cfg;
}

std::string Config::getConfigString() const
{
DASH_LOG_ENTER();

std::stringstream ss;

ss << " GrpcTarget=" << m_grpcTarget;
ss << " PipelineJson=" << m_pipelineJson;
ss << " PipelineProto=" << m_pipelineProto;
ss << " DeviceId=" << m_deviceId;
ss << " Bmv2NumPorts=" << m_bmv2NumPorts;

return ss.str();
}
52 changes: 52 additions & 0 deletions dash-pipeline/SAI/templates/config.h.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

extern "C" {
#include <sai.h>
}

#include <string>
#include <memory>

namespace dash
{
constexpr char DEFAULT_GRPC_TARGET[] = "0.0.0.0:9559";

constexpr char DEFAULT_PIPELINE_JSON[] = "/etc/dash/dash_pipeline.json";

constexpr char DEFAULT_PIPELINE_PROTO[] = "/etc/dash/dash_pipeline_p4rt.txt";

constexpr int DEFAULT_DEVICE_ID = 0;

constexpr uint32_t DEFAULT_BMV2_NUM_PORTS = 2;

constexpr uint32_t MAX_BMV2_NUM_PORTS = 64;

class Config
{
public:

Config();
~Config() = default;

public:

static std::shared_ptr<Config> getDefaultConfig();

static std::shared_ptr<Config> getConfig(
const sai_service_method_table_t* serviceMethodTable);

std::string getConfigString() const;

public:

std::string m_grpcTarget;

std::string m_pipelineJson;

std::string m_pipelineProto;

int m_deviceId;

uint32_t m_bmv2NumPorts;
};
}
48 changes: 48 additions & 0 deletions dash-pipeline/SAI/templates/saidash.h.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#pragma once

/**
* @def SAI_KEY_DASH_GRPC_TARGET
*
* Specifies GRPC target in format IP:port.
*
* Example: 0.0.0.0:9559
*/
#define SAI_KEY_DASH_GRPC_TARGET "SAI_DASH_GRPC_TARGET"

/**
* @def SAI_KEY_DASH_PIPELINE_JSON
*
* Specifies pipeline json file path.
*
* Example: /etc/dash/dash_pipeline.json
*/
#define SAI_KEY_DASH_PIPELINE_JSON "SAI_DASH_PIPELINE_JSON"

/**
* @def SAI_KEY_DASH_PIPELINE_PROTO
*
* Specifies pipeline proto p4rt file path.
*
* Example: /etc/dash/dash_pipeline_p4rt.txt
*/
#define SAI_KEY_DASH_PIPELINE_PROTO "SAI_DASH_PIPELINE_PROTO"

/** Below defines could be depreacated if multiple asic will appear */

/**
* @def SAI_KEY_DASH_DEVICE_ID
*
* Specifies device ID as integer.
*
* Example: 0
*/
#define SAI_KEY_DASH_DEVICE_ID "SAI_DASH_DEVICE_ID"

/**
* @def SAI_KEY_DASH_BMV2_NUM_PORTS
*
* Specifies number of ports in bmv2 as unsigned integer.
*
* Example: 2
*/
#define SAI_KEY_DASH_BMV2_NUM_PORTS "SAI_DASH_BMV2_NUM_PORTS"
42 changes: 27 additions & 15 deletions dash-pipeline/SAI/templates/saifixedapis.cpp.j2
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
*/
#include "utils.h"
#include "saiimpl.h"
#include "config.h"

#include <vector>

// TODO to be moved to separate class/namespace

static std::shared_ptr<grpc::Channel> _grpcChannel;
extern std::unique_ptr<p4::v1::P4Runtime::Stub> stub;

#define DASH_BMV2_NUM_PORTS 2
#define DASH_BMV2_CPU_QOS_NUMBER_OF_QUEUES 0

#define DASH_OBJECT_SHFT 48
Expand All @@ -21,10 +23,9 @@ extern std::unique_ptr<p4::v1::P4Runtime::Stub> stub;
#define DASH_BMV2_DEFAULT_VRF_ID DASH_MAKE_OID(SAI_OBJECT_TYPE_VIRTUAL_ROUTER,1)
#define DASH_BMV2_DEFAULT_1Q_BRIDGE_ID DASH_MAKE_OID(SAI_OBJECT_TYPE_BRIDGE,1)

static sai_object_id_t port_list[DASH_BMV2_NUM_PORTS] = {
DASH_MAKE_OID(SAI_OBJECT_TYPE_PORT,1),
DASH_MAKE_OID(SAI_OBJECT_TYPE_PORT,2)
};
static std::shared_ptr<dash::Config> cfg;

static std::vector<sai_object_id_t> port_list;

static sai_status_t dash_sai_create_switch(
_Out_ sai_object_id_t *switch_id,
Expand Down Expand Up @@ -57,22 +58,22 @@ static sai_status_t dash_sai_get_switch_attribute(
{
case SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS:

attr->value.u32 = DASH_BMV2_NUM_PORTS;
attr->value.u32 = cfg->m_bmv2NumPorts;

DASH_LOG_NOTICE("[%d] attr %d SAI_SWITCH_ATTR_NUMBER_OF_ACTIVE_PORTS = %d", i, attr->id, attr->value.u32);

break;

case SAI_SWITCH_ATTR_PORT_LIST:

attr->value.objlist.count = DASH_BMV2_NUM_PORTS;
attr->value.objlist.count = cfg->m_bmv2NumPorts;

for (uint32_t j = 0; j < DASH_BMV2_NUM_PORTS; j++)
for (size_t j = 0; j < cfg->m_bmv2NumPorts; j++)
{
attr->value.objlist.list[j] = port_list[j];
attr->value.objlist.list[j] = port_list.at(j);
}

DASH_LOG_NOTICE("[%d] attr %d SAI_SWITCH_ATTR_PORT_LIST = [%d objids]", i, attr->id, DASH_BMV2_NUM_PORTS);
DASH_LOG_NOTICE("[%d] attr %d SAI_SWITCH_ATTR_PORT_LIST = [%d objids]", i, attr->id, cfg->m_bmv2NumPorts);

break;

Expand Down Expand Up @@ -303,10 +304,21 @@ sai_status_t sai_api_initialize(
{
DASH_LOG_ENTER();

const grpc::string _grpcTarget = "0.0.0.0:9559";
char test_json[] = "/etc/dash/dash_pipeline.json";
char test_proto_json[] = "/etc/dash/dash_pipeline_p4rt.txt";
int dev_id = 0;
cfg = dash::Config::getConfig(services);

DASH_LOG_NOTICE("config: %s", cfg->getConfigString().c_str());

for (uint32_t i = 1; i <= cfg->m_bmv2NumPorts; i++)
{
port_list.push_back(DASH_MAKE_OID(SAI_OBJECT_TYPE_PORT,i));
}

assert(cfg->m_bmv2NumPorts == (uint32_t)port_list.size());

const grpc::string _grpcTarget = cfg->m_grpcTarget;
const char* test_json = cfg->m_pipelineJson.c_str();
const char* test_proto_json = cfg->m_pipelineProto.c_str();
int dev_id = cfg->m_deviceId;

DASH_LOG_NOTICE("GRPC call SetForwardingPipelineConfig %s => %s, %s", _grpcTarget.c_str(), test_json, test_proto_json);

Expand Down Expand Up @@ -361,7 +373,7 @@ sai_status_t sai_api_uninitialize(void)
{
DASH_LOG_ENTER();

// TODO delete stub
stub = nullptr;

return SAI_STATUS_SUCCESS;
}
Expand Down

0 comments on commit 9ccebe4

Please sign in to comment.