#include "ns.h"
#include "command.h"
#include "memory.h"
+#include "lib_errors.h"
#include "zserv.h"
#include "zebra_memory.h"
#include "zebra_netns_notify.h"
#include "zebra_netns_id.h"
+#include "zebra_errors.h"
#ifdef HAVE_NETLINK
if (netnspath == NULL)
return;
- if (zserv_privs.change(ZPRIVS_RAISE))
- zlog_err("Can't raise privileges");
- ns_id = zebra_ns_id_get(netnspath);
- if (zserv_privs.change(ZPRIVS_LOWER))
- zlog_err("Can't lower privileges");
+ frr_elevate_privs(&zserv_privs) {
+ ns_id = zebra_ns_id_get(netnspath);
+ }
+ if (ns_id == NS_UNKNOWN)
+ return;
ns_id_external = ns_map_nsid_with_external(ns_id, true);
/* if VRF with NS ID already present */
vrf = vrf_lookup_by_id((vrf_id_t)ns_id_external);
if (vrf) {
- zlog_warn(
+ zlog_debug(
"NS notify : same NSID used by VRF %s. Ignore NS %s creation",
vrf->name, netnspath);
return;
}
if (vrf_handler_create(NULL, name, &vrf) != CMD_SUCCESS) {
- zlog_warn("NS notify : failed to create VRF %s", name);
+ flog_warn(EC_ZEBRA_NS_VRF_CREATION_FAILED,
+ "NS notify : failed to create VRF %s", name);
ns_map_nsid_with_external(ns_id, false);
return;
}
- if (zserv_privs.change(ZPRIVS_RAISE))
- zlog_err("Can't raise privileges");
- ret = vrf_netns_handler_create(NULL, vrf, netnspath,
- ns_id_external, ns_id);
- if (zserv_privs.change(ZPRIVS_LOWER))
- zlog_err("Can't lower privileges");
+ frr_elevate_privs(&zserv_privs) {
+ ret = vrf_netns_handler_create(NULL, vrf, netnspath,
+ ns_id_external, ns_id);
+ }
if (ret != CMD_SUCCESS) {
- zlog_warn("NS notify : failed to create NS %s", netnspath);
+ flog_warn(EC_ZEBRA_NS_VRF_CREATION_FAILED,
+ "NS notify : failed to create NS %s", netnspath);
ns_map_nsid_with_external(ns_id, false);
+ vrf_delete(vrf);
return;
}
zlog_info("NS notify : created VRF %s NS %s", name, netnspath);
struct ns *ns;
if (!vrf) {
- zlog_warn(
- "NS notify : no VRF found using NS %s",
- name);
+ flog_warn(EC_ZEBRA_NS_DELETION_FAILED_NO_VRF,
+ "NS notify : no VRF found using NS %s", name);
return 0;
}
/* Clear configured flag and invoke delete. */
return 0;
}
+static int zebra_ns_notify_self_identify(struct stat *netst)
+{
+ char net_path[64];
+ int netns;
+
+ sprintf(net_path, "/proc/self/ns/net");
+ netns = open(net_path, O_RDONLY);
+ if (netns < 0)
+ return -1;
+ if (fstat(netns, netst) < 0) {
+ close(netns);
+ return -1;
+ }
+ close(netns);
+ return 0;
+}
+
+static bool zebra_ns_notify_is_default_netns(const char *name)
+{
+ struct stat default_netns_stat;
+ struct stat st;
+ char netnspath[64];
+
+ if (zebra_ns_notify_self_identify(&default_netns_stat))
+ return false;
+
+ memset(&st, 0, sizeof(struct stat));
+ snprintf(netnspath, 64, "%s/%s", NS_RUN_DIR, name);
+ /* compare with local stat */
+ if (stat(netnspath, &st) == 0 &&
+ (st.st_dev == default_netns_stat.st_dev) &&
+ (st.st_ino == default_netns_stat.st_ino))
+ return true;
+ return false;
+}
static int zebra_ns_ready_read(struct thread *t)
{
netnspath = zns_info->netnspath;
if (--zns_info->retries == 0)
stop_retry = 1;
- if (zserv_privs.change(ZPRIVS_RAISE))
- zlog_err("Can't raise privileges");
- err = ns_switch_to_netns(netnspath);
- if (zserv_privs.change(ZPRIVS_LOWER))
- zlog_err("Can't lower privileges");
+ frr_elevate_privs(&zserv_privs) {
+ err = ns_switch_to_netns(netnspath);
+ }
if (err < 0)
return zebra_ns_continue_read(zns_info, stop_retry);
/* go back to default ns */
- if (zserv_privs.change(ZPRIVS_RAISE))
- zlog_err("Can't raise privileges");
- err = ns_switchback_to_initial();
- if (zserv_privs.change(ZPRIVS_LOWER))
- zlog_err("Can't lower privileges");
+ frr_elevate_privs(&zserv_privs) {
+ err = ns_switchback_to_initial();
+ }
if (err < 0)
return zebra_ns_continue_read(zns_info, stop_retry);
+ if (zebra_ns_notify_is_default_netns(basename(netnspath))) {
+ zlog_warn(
+ "NS notify : NS %s is default VRF."
+ " Updating VRF Name", basename(netnspath));
+ vrf_set_default_name(basename(netnspath));
+ return zebra_ns_continue_read(zns_info, 1);
+ }
+
/* success : close fd and create zns context */
zebra_ns_notify_create_context_from_entry_name(basename(netnspath));
return zebra_ns_continue_read(zns_info, 1);
zebrad.master, zebra_ns_notify_read, NULL, fd_monitor, NULL);
len = read(fd_monitor, buf, sizeof(buf));
if (len < 0) {
- zlog_warn("NS notify read: failed to read (%s)",
- safe_strerror(errno));
+ flog_err_sys(EC_ZEBRA_NS_NOTIFY_READ,
+ "NS notify read: failed to read (%s)",
+ safe_strerror(errno));
return 0;
}
for (event = (struct inotify_event *)buf; (char *)event < &buf[len];
if (offsetof(struct inotify_event, name) + event->len
>= sizeof(buf)) {
- zlog_err("NS notify read: buffer underflow");
+ flog_err(EC_ZEBRA_NS_NOTIFY_READ,
+ "NS notify read: buffer underflow");
break;
}
if (strnlen(event->name, event->len) == event->len) {
- zlog_err("NS notify error: bad event name");
+ flog_err(EC_ZEBRA_NS_NOTIFY_READ,
+ "NS notify error: bad event name");
break;
}
DIR *srcdir = opendir(NS_RUN_DIR);
if (srcdir == NULL) {
- zlog_warn("NS parsing init: failed to parse %s", NS_RUN_DIR);
+ flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ "NS parsing init: failed to parse %s", NS_RUN_DIR);
return;
}
while ((dent = readdir(srcdir)) != NULL) {
|| strcmp(dent->d_name, "..") == 0)
continue;
if (fstatat(dirfd(srcdir), dent->d_name, &st, 0) < 0) {
- zlog_warn("NS parsing init: failed to parse entry %s",
- dent->d_name);
+ flog_err_sys(
+ LIB_ERR_SYSTEM_CALL,
+ "NS parsing init: failed to parse entry %s",
+ dent->d_name);
continue;
}
if (S_ISDIR(st.st_mode)) {
- zlog_warn("NS parsing init: %s is not a NS",
- dent->d_name);
+ zlog_debug("NS parsing init: %s is not a NS",
+ dent->d_name);
+ continue;
+ }
+ if (zebra_ns_notify_is_default_netns(dent->d_name)) {
+ zlog_warn(
+ "NS notify : NS %s is default VRF."
+ " Updating VRF Name", dent->d_name);
+ vrf_set_default_name(dent->d_name);
continue;
}
zebra_ns_notify_create_context_from_entry_name(dent->d_name);
zebra_netns_notify_current = NULL;
fd_monitor = inotify_init();
if (fd_monitor < 0) {
- zlog_warn("NS notify init: failed to initialize inotify (%s)",
- safe_strerror(errno));
+ flog_err_sys(
+ LIB_ERR_SYSTEM_CALL,
+ "NS notify init: failed to initialize inotify (%s)",
+ safe_strerror(errno));
}
if (inotify_add_watch(fd_monitor, NS_RUN_DIR,
IN_CREATE | IN_DELETE) < 0) {
- zlog_warn("NS notify watch: failed to add watch (%s)",
- safe_strerror(errno));
+ flog_err_sys(LIB_ERR_SYSTEM_CALL,
+ "NS notify watch: failed to add watch (%s)",
+ safe_strerror(errno));
}
zebra_netns_notify_current = thread_add_read(
zebrad.master, zebra_ns_notify_read, NULL, fd_monitor, NULL);