Skip to content
Open
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: 2 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
common --check_direct_dependencies=off
common --noincompatible_disallow_empty_glob
2 changes: 1 addition & 1 deletion .bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.0.0
8.0.1
35 changes: 30 additions & 5 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,44 @@ exports_files(["LICENSE"])

cc_library(
name = "common",
srcs = glob(["common/*.cpp"], exclude=["common/loglevel.cpp", "common/loglevel_util.cpp"]),
srcs = glob(
["common/*.cpp"],
["common/loglevel.cpp", "common/loglevel_util.cpp"]
),
hdrs = glob([
"common/*.h",
"common/*.hpp",
]),
], allow_empty = True),
copts = [
"-std=c++14",
"-I/usr/include/libnl3", # Expected location in the SONiC build container"
# TODO: this is not required with apt.installed debs.
# "-I/usr/include/libnl3", # Expected location in the SONiC build container"
],
# Not needed with apt.install
# linkopts = ["-lpthread -lhiredis -lnl-genl-3 -lnl-nf-3 -lnl-route-3 -lnl-3 -lzmq -luuid -lyang"],
includes = [
"common",
],
linkopts = ["-lpthread -lhiredis -lnl-genl-3 -lnl-nf-3 -lnl-route-3 -lnl-3 -lzmq -lboost_serialization -luuid -lyang"],
# Approach 1:
deps = [
"@bookworm//libhiredis-dev:libhiredis",
"@bookworm//nlohmann-json3-dev:nlohmann-json3",
"@bookworm//libnl-3-dev:libnl-3",
"@bookworm//libnl-route-3-dev:libnl-route-3",
"@bookworm//libnl-nf-3-dev:libnl-nf-3",
"@bookworm//libyang2-dev:libyang2",
"@bookworm//libzmq3-dev:libzmq3",
"@bookworm//uuid-dev:uuid",
"@bookworm//libboost-dev:libboost"
],
# Approach 2: BCR entries compiled from source
# deps = [
# "@boost.algorithm",
# "@boost.serialization",
# "@nlohmann_json//:json",
# "@libuuid//:libuuid",
# "@swig//:swig",
# ],
visibility = ["//visibility:public"],
)

Expand All @@ -25,7 +50,7 @@ cc_library(
hdrs = glob([
"common/*.h",
"common/*.hpp",
]),
], allow_empty = True),
include_prefix = "swss",
strip_include_prefix = "common",
deps = [":common"],
Expand Down
71 changes: 71 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
module(name = "sonic-swss-common")

bazel_dep(name = "rules_distroless", version = "0.0.0")
local_path_override(
module_name = "rules_distroless",
path = "../rules_distroless"
)


apt = use_extension("@rules_distroless//apt:extensions.bzl", "apt")

apt.sources_list(
architectures = ["amd64"],
components = ["main"],
suites = ["bookworm", "bookworm-updates"],
uris = ["https://snapshot.debian.org/archive/debian/20251001T023456Z"],
)

apt.sources_list(
architectures = ["amd64"],
components = ["main"],
suites = ["bookworm-security"],
uris = ["https://snapshot.debian.org/archive/debian-security/20251001T023456Z"],
)



# sudo apt-get install -y
# make libtool m4 autoconf dh-exec debhelper cmake pkg-config
# nlohmann-json3-dev libhiredis-dev libnl-3-dev libnl-genl-3-dev
# libnl-route-3-dev libnl-nf-3-dev swig3.0 libpython2.7-dev libboost-dev
# libboost-serialization-dev uuid-dev libzmq3-dev

apt.install(
dependency_set = "bookworm",
target_release = "bookworm",
packages = [
"nlohmann-json3-dev",
"libhiredis-dev",
"libnl-3-dev",
"libnl-genl-3-dev",
"libnl-route-3-dev",
"libnl-nf-3-dev",
"libboost-dev",
"libboost-serialization-dev",
"uuid-dev",
"libzmq3-dev",
"libyang2-dev",

# These seem to be unused
# "swig3.0",
# "libpython2.7-dev",
# "libgtest-dev",
# "libgmock-dev",
]
)

apt.lock(into = ":packages.lock")

use_repo(apt, "bookworm")

# bazel_dep(name = "googletest", version = "1.11.0", repo_name = "com_google_googletest")
# bazel_dep(name = "glog", version = "0.5.0", repo_name = "com_github_google_glog")
# bazel_dep(name = "nlohmann_json", version = "3.12.0")
# bazel_dep(name = "boost.algorithm", version = "1.87.0")
# bazel_dep(name = "boost.serialization", version = "1.87.0")
# bazel_dep(name = "libuuid", version = "2.39.3.bcr.1")
# bazel_dep(name = "libzmq", version = "4.3.5.bcr.3")
# bazel_dep(name = "swig", version = "4.3.0")
# bazel_dep(name = "abseil-cpp", version = "20210324.2")
# bazel_dep(name = "gflags", version = "2.2.2")
748 changes: 748 additions & 0 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

94 changes: 56 additions & 38 deletions common/defaultvalueprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include <string>
#include <vector>

#include <dirent.h>
#include <stdio.h>
#include <dirent.h>
#include <stdio.h>

#include "defaultvalueprovider.h"
#include "logger.h"
Expand Down Expand Up @@ -119,15 +119,15 @@ bool TableInfoMultipleList::FoundFieldMappingByKey(const string &key, FieldDefau
SWSS_LOG_DEBUG("TableInfoMultipleList::FoundFieldMappingByKey %s\n", key.c_str());
int fieldCount = (int)count(key.begin(), key.end(), '|') + 1;
auto keySchema = m_defaultValueMapping.find(fieldCount);

// when not found, key_info still a valid iterator
*foundMappingPtr = keySchema->second.get();

// return false when not found
return keySchema != m_defaultValueMapping.end();
}

shared_ptr<KeySchema> DefaultValueHelper::GetKeySchema(struct lys_node* tableChildNode)
shared_ptr<KeySchema> DefaultValueHelper::GetKeySchema(const struct lysc_node* tableChildNode)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This patch is directly taken from: #973

{
SWSS_LOG_DEBUG("DefaultValueHelper::GetKeySchema %s\n",tableChildNode->name);

Expand All @@ -138,15 +138,20 @@ shared_ptr<KeySchema> DefaultValueHelper::GetKeySchema(struct lys_node* tableChi
SWSS_LOG_DEBUG("Child list: %s\n",tableChildNode->name);

// when a top level container contains list, the key defined by the 'keys' field.
struct lys_node_list *listNode = (struct lys_node_list*)tableChildNode;
if (listNode->keys_str == nullptr)
const struct lysc_node_list *listNode = (const struct lysc_node_list*)tableChildNode;

for (const struct lysc_node *node = listNode->child; node != NULL; node = node->next)
{
SWSS_LOG_ERROR("Ignore empty key string on list: %s\n",tableChildNode->name);
return nullptr;
if (!lysc_is_key(node)) {
continue;
}
if (keyValue.length())
{
keyValue += " ";
}
keyValue += node->name;
keyFieldCount++;
}

string key(listNode->keys_str);
keyFieldCount = (int)count(key.begin(), key.end(), ' ') + 1;
}
else if (tableChildNode->nodetype == LYS_CONTAINER)
{
Expand All @@ -160,20 +165,20 @@ shared_ptr<KeySchema> DefaultValueHelper::GetKeySchema(struct lys_node* tableChi
SWSS_LOG_DEBUG("Ignore child element: %s\n",tableChildNode->name);
return nullptr;
}

return make_shared<KeySchema>(keyValue, keyFieldCount);
}

void DefaultValueHelper::GetDefaultValueInfoForLeaf(struct lys_node_leaf* leafNode, shared_ptr<FieldDefaultValueMapping> fieldMapping)
void DefaultValueHelper::GetDefaultValueInfoForLeaf(const struct lysc_node_leaf* leafNode, shared_ptr<FieldDefaultValueMapping> fieldMapping)
{
if (leafNode->dflt)
{
SWSS_LOG_DEBUG("field: %s, default: %s\n",leafNode->name, leafNode->dflt);
fieldMapping->emplace(string(leafNode->name), string(leafNode->dflt));
SWSS_LOG_DEBUG("field: %s, default: %s\n",leafNode->name, lyd_value_get_canonical(leafNode->module->ctx, leafNode->dflt));
fieldMapping->emplace(string(leafNode->name), string(lyd_value_get_canonical(leafNode->module->ctx, leafNode->dflt)));
}
}

void DefaultValueHelper::GetDefaultValueInfoForChoice(struct lys_node_choice* choiceNode, shared_ptr<FieldDefaultValueMapping> fieldMapping)
void DefaultValueHelper::GetDefaultValueInfoForChoice(const struct lysc_node_choice* choiceNode, shared_ptr<FieldDefaultValueMapping> fieldMapping)
{
if (choiceNode->dflt == nullptr)
{
Expand All @@ -190,64 +195,72 @@ void DefaultValueHelper::GetDefaultValueInfoForChoice(struct lys_node_choice* ch
SWSS_LOG_ERROR("choice case %s is not a leaf node\n",fieldInChoice->name);
continue;
}

SWSS_LOG_DEBUG("default choice leaf field: %s\n",fieldInChoice->name);
WARNINGS_NO_CAST_ALIGN
struct lys_node_leaf *dfltLeafNode = reinterpret_cast<struct lys_node_leaf*>(fieldInChoice);
struct lysc_node_leaf *dfltLeafNode = reinterpret_cast<struct lysc_node_leaf*>(fieldInChoice);
WARNINGS_RESET
if (dfltLeafNode->dflt)
{
SWSS_LOG_DEBUG("default choice leaf field: %s, default: %s\n",dfltLeafNode->name, dfltLeafNode->dflt);
fieldMapping->emplace(string(fieldInChoice->name), string(dfltLeafNode->dflt));
SWSS_LOG_DEBUG("default choice leaf field: %s, default: %s\n",dfltLeafNode->name, lyd_value_get_canonical(dfltLeafNode->module->ctx, dfltLeafNode->dflt));
fieldMapping->emplace(string(fieldInChoice->name), string(lyd_value_get_canonical(dfltLeafNode->module->ctx, dfltLeafNode->dflt)));
}

fieldInChoice = fieldInChoice->next;
}
}

void DefaultValueHelper::GetDefaultValueInfoForLeaflist(struct lys_node_leaflist *listNode, shared_ptr<FieldDefaultValueMapping> fieldMapping)
void DefaultValueHelper::GetDefaultValueInfoForLeaflist(const struct lysc_node_leaflist *listNode, shared_ptr<FieldDefaultValueMapping> fieldMapping)
{
size_t i;
// Get leaf-list default value according to:https://www.rfc-editor.org/rfc/rfc7950.html#section-7.7
if (listNode->dflt == nullptr)
if (listNode->dflts == nullptr)
{
return;
}

const char** dfltValues = listNode->dflt;
/* Convert to null-terminated array of const char * */
const char **dfltValues = (const char **)malloc((LY_ARRAY_COUNT(listNode->dflts)+1) * sizeof(*dfltValues));
for (i=0; i<LY_ARRAY_COUNT(listNode->dflts); i++) {
dfltValues[i] = lyd_value_get_canonical(listNode->module->ctx, listNode->dflts[i]);
}
dfltValues[LY_ARRAY_COUNT(listNode->dflts)] = NULL;

//convert list default value to json string
string dfltValueJson = JSon::buildJson(dfltValues);
free(dfltValues);
SWSS_LOG_DEBUG("list field: %s, default: %s\n",listNode->name, dfltValueJson.c_str());
fieldMapping->emplace(string(listNode->name), dfltValueJson);
}

FieldDefaultValueMappingPtr DefaultValueHelper::GetDefaultValueInfo(struct lys_node* tableChildNode)
FieldDefaultValueMappingPtr DefaultValueHelper::GetDefaultValueInfo(const struct lysc_node* tableChildNode)
{
SWSS_LOG_DEBUG("DefaultValueHelper::GetDefaultValueInfo %s\n",tableChildNode->name);

auto field = tableChildNode->child;
auto field = lysc_node_child(tableChildNode);
auto fieldMapping = make_shared<FieldDefaultValueMapping>();
while (field)
{
if (field->nodetype == LYS_LEAF)
{
WARNINGS_NO_CAST_ALIGN
struct lys_node_leaf *leafNode = reinterpret_cast<struct lys_node_leaf*>(field);
const struct lysc_node_leaf *leafNode = reinterpret_cast<const struct lysc_node_leaf*>(field);
WARNINGS_RESET

SWSS_LOG_DEBUG("leaf field: %s\n",leafNode->name);
GetDefaultValueInfoForLeaf(leafNode, fieldMapping);
}
else if (field->nodetype == LYS_CHOICE)
{
struct lys_node_choice *choiceNode = reinterpret_cast<struct lys_node_choice*>(field);
const struct lysc_node_choice *choiceNode = reinterpret_cast<const struct lysc_node_choice*>(field);

SWSS_LOG_DEBUG("choice field: %s\n",choiceNode->name);
GetDefaultValueInfoForChoice(choiceNode, fieldMapping);
}
else if (field->nodetype == LYS_LEAFLIST)
{
WARNINGS_NO_CAST_ALIGN
struct lys_node_leaflist *listNode = reinterpret_cast<struct lys_node_leaflist*>(field);
const struct lysc_node_leaflist *listNode = reinterpret_cast<const struct lysc_node_leaflist*>(field);
WARNINGS_RESET

SWSS_LOG_DEBUG("list field: %s\n",listNode->name);
Expand All @@ -260,10 +273,10 @@ FieldDefaultValueMappingPtr DefaultValueHelper::GetDefaultValueInfo(struct lys_n
return fieldMapping;
}

int DefaultValueHelper::BuildTableDefaultValueMapping(struct lys_node* table, TableDefaultValueMapping &tableDefaultValueMapping)
int DefaultValueHelper::BuildTableDefaultValueMapping(const struct lysc_node* table, TableDefaultValueMapping &tableDefaultValueMapping)
{
int childListCount = 0;
auto nextChild = table->child;
auto nextChild = lysc_node_child(table);
while (nextChild)
{
// get key from schema
Expand All @@ -289,7 +302,7 @@ int DefaultValueHelper::BuildTableDefaultValueMapping(struct lys_node* table, Ta
}

// Load default value info from yang model and append to default value mapping
void DefaultValueProvider::AppendTableInfoToMapping(struct lys_node* table)
void DefaultValueProvider::AppendTableInfoToMapping(const struct lysc_node* table)
{
SWSS_LOG_DEBUG("DefaultValueProvider::AppendTableInfoToMapping table name: %s\n",table->name);
TableDefaultValueMapping tableDefaultValueMapping;
Expand Down Expand Up @@ -401,7 +414,7 @@ DefaultValueProvider::~DefaultValueProvider()
if (m_context)
{
// set private_destructor to NULL because no any private data
ly_ctx_destroy(m_context, NULL);
ly_ctx_destroy(m_context);
}
}

Expand All @@ -418,7 +431,11 @@ void DefaultValueProvider::Initialize(const char* modulePath)
ThrowRunTimeError("Open Yang model path " + string(modulePath) + " failed");
}

m_context = ly_ctx_new(modulePath, LY_CTX_ALLIMPLEMENTED);
if (ly_ctx_new(modulePath, LY_CTX_ALL_IMPLEMENTED, &m_context) != LY_SUCCESS)
{
ThrowRunTimeError("ly_ctx_new() failed");
}

struct dirent *subDir;
while ((subDir = readdir(moduleDir)) != nullptr)
{
Expand All @@ -442,22 +459,23 @@ void DefaultValueProvider::LoadModule(const string &name, const string &path, st
const struct lys_module *module = ly_ctx_load_module(
context,
name.c_str(),
EMPTY_STR); // Use EMPTY_STR to revision to load the latest revision
EMPTY_STR, // Use EMPTY_STR to revision to load the latest revision
NULL);
if (module == nullptr)
{
const char* err = ly_errmsg(context);
SWSS_LOG_ERROR("Load Yang file %s failed: %s.\n", path.c_str(), err);
return;
}

if (module->data == nullptr)
if (module->compiled == nullptr || module->compiled->data == nullptr)
{
// Not every yang file should contains yang model
SWSS_LOG_WARN("Yang file %s does not contains model %s.\n", path.c_str(), name.c_str());
return;
}

struct lys_node *topLevelNode = module->data;
struct lysc_node *topLevelNode = module->compiled->data;
while (topLevelNode)
{
if (topLevelNode->nodetype != LYS_CONTAINER)
Expand All @@ -469,7 +487,7 @@ void DefaultValueProvider::LoadModule(const string &name, const string &path, st
}

SWSS_LOG_DEBUG("top level container: %s\n",topLevelNode->name);
auto container = topLevelNode->child;
auto container = lysc_node_child(topLevelNode);
while (container)
{
SWSS_LOG_DEBUG("container name: %s\n",container->name);
Expand Down
Loading
Loading