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

link,config: fix config change for links in different netns #125

Merged
merged 1 commit into from
Jun 13, 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
10 changes: 7 additions & 3 deletions src/iproute2_sysrepo.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,9 @@ static int do_cmd(int argc, char **argv)
argv0 = basename + 2;
arg_skip = 3;
}
// we need to rtnl_open() for every command in order to have netns_switch() to work.
if (rtnl_open(&rth, 0) < 0)
return EXIT_FAILURE;

for (c = cmds; c->cmd; ++c) {
if (matches(argv0, c->cmd) == 0)
Expand All @@ -444,6 +447,7 @@ static int do_cmd(int argc, char **argv)
"1- Run with no argumentss to start iproute2-sysrepo.\n"
"2- Run with individual iproute2 commands arguments.\n",
argv[1]);
rtnl_close(&rth);

return EXIT_FAILURE;
}
Expand Down Expand Up @@ -738,15 +742,15 @@ int main(int argc, char **argv)
{
int ret;

if (rtnl_open(&rth, 0) < 0)
return EXIT_FAILURE;
// if (rtnl_open(&rth, 0) < 0)
// return EXIT_FAILURE;

if (argc == 1) {
atexit(exit_cb);
return sysrepo_start();
} else
ret = do_cmd(argc - 1, argv + 1);

rtnl_close(&rth);
// rtnl_close(&rth);
return ret;
}
64 changes: 64 additions & 0 deletions src/lib/cmdgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

extern sr_session_ctx_t *sr_session;
static int processed = 1;
const char *network_namespace = NULL;
/**
* @brief data struct to store cmd operation.
*
Expand Down Expand Up @@ -140,6 +141,36 @@ void free_cmds_info(struct cmd_info **cmds_info)
free(cmds_info);
}

void insert_netns(char *cmd, const char *netns)
{
char to_insert[100]; // Buffer to hold the "-n name" string

// Create the insertion string
snprintf(to_insert, sizeof(to_insert), " -n %s", netns);

// Find the position of the first space
char *pos = strchr(cmd, ' ');

if (pos != NULL) {
// Calculate the index of the first space
int index = pos - cmd;

// Calculate the lengths of the strings
int len_cmd = strlen(cmd);
int len_insert = strlen(to_insert);

// Shift the part of the string after the first space to the right
memmove(cmd + index + len_insert, cmd + index,
len_cmd - index + 1); // +1 to include the null terminator

// Insert the new string at the right position
memcpy(cmd + index, to_insert, len_insert);
} else {
// If there is no space, just concatenate the insert string to the end
strcat(cmd, to_insert);
}
}

/**
* @brief this function will extract static_arg and xpath_arg from string input,
* example: if input = "dev (../../name)" -result-> static = dev, and xpath = ../../name
Expand Down Expand Up @@ -385,6 +416,33 @@ int add_command(struct cmd_info **cmds, int *cmd_idx, char *cmd_line, char *cmd_
*/
int create_cmd_arg_name(struct lyd_node *dnode, oper_t startcmd_op_val, char **arg_name)
{
// get the network namespace of the startcmd, and add the "ip netns exec <netns>" to the
// beginning of the cmd.

if (!strcmp(dnode->schema->name, "netns")) {
oper_t dnode_oper = get_operation(dnode);
if (dnode_oper == UPDATE_OPR) {
struct lyd_meta *dnode_meta = NULL;
dnode_meta = lyd_find_meta(dnode->meta, NULL, "yang:orig-value");
if (dnode_meta == NULL) {
fprintf(stderr, "%s: failed to get yang:orig-value meta for netns node\n",
__func__);
return EXIT_FAILURE;
}
network_namespace = lyd_get_meta_value(dnode_meta);
if (network_namespace == NULL) {
fprintf(stderr,
"%s: failed to get the value of yang:original-value for netns node\n",
__func__);
network_namespace = "1";
return EXIT_FAILURE;
}
} else {
network_namespace = lyd_get_value(dnode);
}
if (!strcmp(network_namespace, "1"))
network_namespace = NULL;
}
// if operation delete generate args only if:
// - node is key or startcmd has INCLUDE_ALL_ON_DELETE extention.
int is_include_all_on_delete = 0;
Expand Down Expand Up @@ -940,6 +998,12 @@ char *lyd2cmd_line(struct lyd_node *startcmd_node, char *oper2cmd_prefix[3])
}
strlcat(cmd_line, cmd_args, sizeof(cmd_line));
free(cmd_args);
// check if netns found, then inset it in cmd "ip -netns red ..."
if (network_namespace != NULL) {
insert_netns(cmd_line, network_namespace);
network_namespace = NULL;
}

return strdup(cmd_line);
}

Expand Down
33 changes: 8 additions & 25 deletions yang/iproute2-ip-link.yang
Original file line number Diff line number Diff line change
Expand Up @@ -307,33 +307,16 @@ module iproute2-ip-link {
description "specifies the desired index of the new virtual device.
The link creation fails, if the index is busy.";
}
choice netns {
description "create the device in the network namespace associated with process
PID or the name NETNSNAME or the file NETNSFILE.";
case process-id {
description "create the device in the network namespace associated with process";
leaf pid {
ipr2cgen:arg-name "netns";
type uint64;
description "process id";
}
}
case name {
description "create the device in the network namespace associated with name NETNSNAME";
leaf netnsname {
ipr2cgen:arg-name "netns";
type ipnetns:netns-ref;
description "network namespace name";
}
}
case file {
description "create the device in the network namespace associated with file NETNSFILE";
leaf netnsfile {
ipr2cgen:arg-name "netns";
type string;
description "network namespace file";
leaf netns {
ipr2cgen:arg-name "netns";
type union {
type ipnetns:netns-ref;
type enumeration {
enum "1";
}
}
default "1";
description "network namespace name";
}
leaf group {
description "specify group id that this link belong to,
Expand Down