#include "env-util.h"
#include "def.h"
#include "rtnl-util.h"
+#include "udev-util.h"
typedef enum LinkJournal {
LINK_NO,
};
int c, r;
+ uint64_t plus = 0, minus = 0;
assert(argc >= 0);
assert(argv);
if (streq(t, "all")) {
if (c == ARG_CAPABILITY)
- arg_retain = (uint64_t) -1;
+ plus = (uint64_t) -1;
else
- arg_retain = 0;
+ minus = (uint64_t) -1;
} else {
if (cap_from_name(t, &cap) < 0) {
log_error("Failed to parse capability %s.", t);
}
if (c == ARG_CAPABILITY)
- arg_retain |= 1ULL << (uint64_t) cap;
+ plus |= 1ULL << (uint64_t) cap;
else
- arg_retain &= ~(1ULL << (uint64_t) cap);
+ minus |= 1ULL << (uint64_t) cap;
}
}
return -EINVAL;
}
+ arg_retain = (arg_retain | plus | (arg_private_network ? 1ULL << CAP_NET_ADMIN : 0)) & ~minus;
+
return 1;
}
}
static int move_network_interfaces(pid_t pid) {
- _cleanup_sd_rtnl_unref_ sd_rtnl *rtnl = NULL;
+ _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+ _cleanup_udev_unref_ struct udev *udev = NULL;
char **i;
int r;
if (strv_isempty(arg_network_interfaces))
return 0;
- r = sd_rtnl_open(NETLINK_ROUTE, &rtnl);
+ r = sd_rtnl_open(0, &rtnl);
if (r < 0) {
log_error("Failed to connect to netlink: %s", strerror(-r));
return r;
}
+ udev = udev_new();
+ if (!udev) {
+ log_error("Failed to connect to udev.");
+ return -ENOMEM;
+ }
+
STRV_FOREACH(i, arg_network_interfaces) {
- _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *m = NULL;
- unsigned ifi;
+ _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
+ _cleanup_udev_device_unref_ struct udev_device *d = NULL;
+ char ifi_str[2 + DECIMAL_STR_MAX(int)];
+ int ifi;
- ifi = if_nametoindex(*i);
- if (ifi == 0) {
+ ifi = (int) if_nametoindex(*i);
+ if (ifi <= 0) {
log_error("Failed to resolve interface %s: %m", *i);
return -errno;
}
- r = sd_rtnl_message_link_new(RTM_NEWLINK, ifi, &m);
+ sprintf(ifi_str, "n%i", ifi);
+ d = udev_device_new_from_device_id(udev, ifi_str);
+ if (!d) {
+ log_error("Failed to get udev device for interface %s: %m", *i);
+ return -errno;
+ }
+
+ if (udev_device_get_is_initialized(d) <= 0) {
+ log_error("Network interface %s is not initialized yet.", *i);
+ return -EBUSY;
+ }
+
+ r = sd_rtnl_message_new_link(RTM_NEWLINK, ifi, &m);
if (r < 0) {
log_error("Failed to allocate netlink message: %s", strerror(-r));
return r;
r = sd_rtnl_call(rtnl, m, 0, NULL);
if (r < 0) {
- log_error("Failed to move interface to namespace: %s", strerror(-r));
+ log_error("Failed to move interface %s to namespace: %s", *i, strerror(-r));
return r;
}
}