Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SAI] Add support for dash configuration from sai interface #419

Merged
merged 1 commit into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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