Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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