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

netns, cfg_load: loading config for each netns #133

Merged
merged 1 commit into from
Jun 28, 2024
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
23 changes: 20 additions & 3 deletions src/iproute2_sysrepo.c
Original file line number Diff line number Diff line change
Expand Up @@ -662,17 +662,34 @@ int ipr2_oper_get_items_cb(sr_session_ctx_t *session, uint32_t sub_id, const cha
const char *xpath, const char *request_xpath, uint32_t request_id,
struct lyd_node **parent, void *private_data)
{
return load_module_data(session, module_name, LYS_CONFIG_R | LYS_CONFIG_W, parent);
return load_module_data(session, module_name, LYS_CONFIG_R | LYS_CONFIG_W, parent, "1");
}

struct load_linux_runcfg_arg {
const char *module_name;
struct lyd_node **root_node;
};

int load_linux_runcfg_ns_cb(char *nsname, void *arg)
{
struct load_linux_runcfg_arg *runcfg_arg = (struct load_linux_runcfg_arg *)arg;
load_module_data(sr_session, runcfg_arg->module_name, LYS_CONFIG_W, runcfg_arg->root_node,
nsname);
return 0;
}

int load_linux_running_config()
{
int ret = 0;
int ret;
struct lyd_node *root_node = NULL;
fprintf(stdout, "%s: Started loading iproute2 running configuration.\n", __func__);
for (size_t i = 0; i < sizeof(ipr2_ip_modules) / sizeof(ipr2_ip_modules[0]); i++) {
fprintf(stdout, "%s: Loading module: %s data.\n", __func__, ipr2_ip_modules[i].module);
load_module_data(sr_session, ipr2_ip_modules[i].module, LYS_CONFIG_W, &root_node);
// load data from default netns
load_module_data(sr_session, ipr2_ip_modules[i].module, LYS_CONFIG_W, &root_node, "1");
// load data from all netns
struct load_linux_runcfg_arg runcfg_arg = { ipr2_ip_modules[i].module, &root_node };
netns_foreach(load_linux_runcfg_ns_cb, &runcfg_arg);
}

fprintf(stdout, "%s: Storing loaded data to sysrepo running datastore.\n", __func__);
Expand Down
24 changes: 16 additions & 8 deletions src/lib/cmdgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ struct cmd_info {
*/
void free_cmds_info(struct cmd_info **cmds_info);

/**
* parse the command line and convert it to argc, argv
* @param [in] command command line string "ip link add ..."
* @param [out] argc parsed argv count
* @param [out] argv parsed argv
*/
void parse_command(const char *command, int *argc, char ***argv);

/**
* this func insert the netns name in the cmd, for example if cmd = ip link, and netns = "red"
* the cmd will become "ip -n red link",
* @param cmd
* @param netns
*/
void insert_netns(char *cmd, const char *netns);

/**
* @brief generate list of commands info from the lyd_node (diff).
*
Expand All @@ -34,12 +50,4 @@ void free_cmds_info(struct cmd_info **cmds_info);
*/
struct cmd_info **lyd2cmds(const struct lyd_node *all_change_nodes);

/**
* parse the command line and convert it to argc, argv
* @param [in] command command line string "ip link add ..."
* @param [out] argc parsed argv count
* @param [out] argv parsed argv
*/
void parse_command(const char *command, int *argc, char ***argv);

#endif // IPROUTE2_SYSREPO_CMDGEN_H
36 changes: 31 additions & 5 deletions src/lib/oper_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "oper_data.h"
#include "cmdgen.h"

char *net_namespace;

/* to be merged with cmdgen */
typedef enum {
// leaf extensions
Expand Down Expand Up @@ -394,7 +396,12 @@ int get_list_keys2(const struct lysc_node_list *list, json_object *json_array_ob
free(value);
} else {
// key value not found in json data.
if (default_val != NULL) {
if (!strcmp(child->name, "netns")) {
json_object_object_add(keys_jobj, child->name,
json_object_new_string(net_namespace));
if (default_val)
free(default_val);
} else if (default_val != NULL) {
json_object_object_add(keys_jobj, child->name,
json_object_new_string(default_val));
free(default_val);
Expand Down Expand Up @@ -601,6 +608,13 @@ void jdata_to_leaf(struct json_object *json_obj, const char *arg_name,
struct lyd_node **parent_data_node, const struct lysc_node *s_node)
{
char *vmap_str = NULL, *fmap_str = NULL, *combine_ext_str = NULL, *static_value = NULL;
if (!strcmp(s_node->name, "netns")) {
if (LY_SUCCESS !=
lyd_new_term(*parent_data_node, NULL, s_node->name, net_namespace, 0, NULL)) {
fprintf(stderr, "%s: node %s creation failed\n", __func__, s_node->name);
return;
}
}
if (get_lys_extension(OPER_FLAG_MAP_EXT, s_node, &fmap_str) == EXIT_SUCCESS) {
if (fmap_str == NULL) {
fprintf(stderr,
Expand Down Expand Up @@ -831,7 +845,6 @@ void single_jobj_to_list2(struct json_object *json_obj, struct lyd_node **parent
{
const struct lysc_node_list *list = (const struct lysc_node_list *)s_node;
char *keys = NULL;
int keys_count;
if (get_list_keys2(list, json_obj, &keys) == EXIT_SUCCESS) {
add_missing_parents(s_node, parent_data_node);
struct lyd_node *new_data_node = NULL;
Expand Down Expand Up @@ -1022,8 +1035,7 @@ int process_node(const struct lysc_node *s_node, json_object *json_obj, uint16_t
int process_schema(const struct lysc_node *s_node, uint16_t lys_flags,
struct lyd_node **parent_data_node)
{
char *show_cmd = NULL;
const struct lysc_node *new_cmd_child;
char *show_cmd = "NULL";
struct json_object *cmd_output = NULL;
/* Create top-level lyd_node */
if (*parent_data_node == NULL) { // Top-level node
Expand All @@ -1038,6 +1050,19 @@ int process_schema(const struct lysc_node *s_node, uint16_t lys_flags,
__func__, s_node->name);
return EXIT_FAILURE;
}
if (strcmp(net_namespace, "1") != 0) {
// Calculate the new size needed for show_cmd
size_t new_size = strlen(show_cmd) + strlen(" -n ") + strlen(net_namespace) +
1; // +1 for the null terminator

// Reallocate memory for show_cmd
show_cmd = realloc(show_cmd, new_size);
if (show_cmd == NULL) {
perror("realloc");
exit(EXIT_FAILURE);
}
insert_netns(show_cmd, net_namespace);
}
if (apply_ipr2_cmd(show_cmd) != EXIT_SUCCESS) {
fprintf(stderr, "%s: command execution failed\n", __func__);

Expand Down Expand Up @@ -1083,12 +1108,13 @@ int process_schema(const struct lysc_node *s_node, uint16_t lys_flags,
* @return Returns an integer status code (SR_ERR_OK on success or an error code on failure).
*/
int load_module_data(sr_session_ctx_t *session, const char *module_name, uint16_t lys_flags,
struct lyd_node **parent)
struct lyd_node **parent, char *nsname)
{
int ret = SR_ERR_OK;
const struct ly_ctx *ly_ctx;
const struct lys_module *module = NULL;
struct lyd_node *data_tree = NULL;
net_namespace = nsname;

ly_ctx = sr_acquire_context(sr_session_get_connection(session));
module = ly_ctx_get_module_implemented(ly_ctx, module_name);
Expand Down
2 changes: 1 addition & 1 deletion src/lib/oper_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ extern char json_buffer[1024 * 1024]; /* holds iproute2 show commands json outpu
* @return Returns an integer status code (SR_ERR_OK on success or an error code on failure).
*/
int load_module_data(sr_session_ctx_t *session, const char *module_name, uint16_t lys_flags,
struct lyd_node **parent);
struct lyd_node **parent, char *nsname);

#endif // IPROUTE2_SYSREPO_OPER_DATA_H
6 changes: 3 additions & 3 deletions tests/cases/test_ip_netns.sh
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,19 @@ fi
sysrepocfg -S '/iproute2-ip-link:links/link[name="netns_if"]/mtu' --value 1400

# Step 2: Check if the MTU for IP netns_if is updated by iproute2-sysrepo
current_mtu=$(ip link show dev netns_if 2>/dev/null | grep -oP '(?<=mtu )\d+' | head -n 1)
current_mtu=$(ip -n vpn10 link show dev netns_if 2>/dev/null | grep -oP '(?<=mtu )\d+' | head -n 1)

if [ -z "$current_mtu" ]; then
echo "TEST-ERROR:netns: Failed to retrieve MTU for IP link netns_if "
if_clean_up
clean_up
exit 1
fi

if [ "$current_mtu" -eq 1400 ]; then
echo "TEST-INFO:netns: MTU for IP link netns_if updated successfully (OK)"
else
echo "TEST-ERROR:netns: Failed to update MTU for IP link netns_if, current_mtu = $current_mtu (FAIL)"
if_clean_up
clean_up
exit 1
fi

Expand Down