nsresource: add client-side wrapper for creating tap links
This commit is contained in:
+1
-1
@@ -5459,7 +5459,7 @@ static int run_container(
|
||||
} else {
|
||||
_cleanup_free_ char *host_ifname = NULL;
|
||||
|
||||
r = nsresource_add_netif(userns_fd, child_netns_fd, /* namespace_ifname= */ NULL, &host_ifname, /* ret_namespace_ifname= */ NULL);
|
||||
r = nsresource_add_netif_veth(userns_fd, child_netns_fd, /* namespace_ifname= */ NULL, &host_ifname, /* ret_namespace_ifname= */ NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add network interface to container: %m");
|
||||
|
||||
|
||||
+70
-3
@@ -257,6 +257,7 @@ int nsresource_add_cgroup(int userns_fd, int cgroup_fd) {
|
||||
typedef struct InterfaceParams {
|
||||
char *host_interface_name;
|
||||
char *namespace_interface_name;
|
||||
unsigned interface_fd_index;
|
||||
} InterfaceParams;
|
||||
|
||||
static void interface_params_done(InterfaceParams *p) {
|
||||
@@ -266,7 +267,7 @@ static void interface_params_done(InterfaceParams *p) {
|
||||
free(p->namespace_interface_name);
|
||||
}
|
||||
|
||||
int nsresource_add_netif(
|
||||
int nsresource_add_netif_veth(
|
||||
int userns_fd,
|
||||
int netns_fd,
|
||||
const char *namespace_ifname,
|
||||
@@ -330,8 +331,8 @@ int nsresource_add_netif(
|
||||
return log_debug_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to add network to user namespace: %s", error_id);
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "hostInterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(InterfaceParams, host_interface_name), 0 },
|
||||
{ "namespaceInterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(InterfaceParams, namespace_interface_name), 0 },
|
||||
{ "hostInterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(InterfaceParams, host_interface_name), SD_JSON_MANDATORY },
|
||||
{ "namespaceInterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(InterfaceParams, namespace_interface_name), SD_JSON_MANDATORY },
|
||||
};
|
||||
|
||||
_cleanup_(interface_params_done) InterfaceParams p = {};
|
||||
@@ -346,3 +347,69 @@ int nsresource_add_netif(
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int nsresource_add_netif_tap(
|
||||
int userns_fd,
|
||||
char **ret_host_ifname) {
|
||||
|
||||
_cleanup_close_ int _userns_fd = -EBADF;
|
||||
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
|
||||
int r, userns_fd_idx;
|
||||
const char *error_id;
|
||||
|
||||
if (userns_fd < 0) {
|
||||
_userns_fd = namespace_open_by_type(NAMESPACE_USER);
|
||||
if (_userns_fd < 0)
|
||||
return _userns_fd;
|
||||
|
||||
userns_fd = _userns_fd;
|
||||
}
|
||||
|
||||
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.NamespaceResource");
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to connect to namespace resource manager: %m");
|
||||
|
||||
r = sd_varlink_set_allow_fd_passing_output(vl, true);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to enable varlink fd passing for write: %m");
|
||||
|
||||
r = sd_varlink_set_allow_fd_passing_input(vl, true);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to enable varlink fd passing for read: %m");
|
||||
|
||||
userns_fd_idx = sd_varlink_push_dup_fd(vl, userns_fd);
|
||||
if (userns_fd_idx < 0)
|
||||
return log_debug_errno(userns_fd_idx, "Failed to push userns fd into varlink connection: %m");
|
||||
|
||||
sd_json_variant *reply = NULL;
|
||||
r = sd_varlink_callbo(
|
||||
vl,
|
||||
"io.systemd.NamespaceResource.AddNetworkToUserNamespace",
|
||||
&reply,
|
||||
&error_id,
|
||||
SD_JSON_BUILD_PAIR("userNamespaceFileDescriptor", SD_JSON_BUILD_UNSIGNED(userns_fd_idx)),
|
||||
SD_JSON_BUILD_PAIR("mode", JSON_BUILD_CONST_STRING("tap")));
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to call AddNetworkToUserNamespace() varlink call: %m");
|
||||
if (error_id)
|
||||
return log_debug_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to add network to user namespace: %s", error_id);
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "hostInterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_string, offsetof(InterfaceParams, host_interface_name), SD_JSON_MANDATORY },
|
||||
{ "interfaceFileDescriptor", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint, offsetof(InterfaceParams, namespace_interface_name), SD_JSON_MANDATORY },
|
||||
};
|
||||
|
||||
_cleanup_(interface_params_done) InterfaceParams p = {};
|
||||
r = sd_json_dispatch(reply, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_close_ int tap_fd = sd_varlink_take_fd(vl, p.interface_fd_index);
|
||||
if (tap_fd < 0)
|
||||
return tap_fd;
|
||||
|
||||
if (ret_host_ifname)
|
||||
*ret_host_ifname = TAKE_PTR(p.host_interface_name);
|
||||
|
||||
return TAKE_FD(tap_fd);
|
||||
}
|
||||
|
||||
@@ -7,4 +7,5 @@ int nsresource_allocate_userns(const char *name, uint64_t size);
|
||||
int nsresource_register_userns(const char *name, int userns_fd);
|
||||
int nsresource_add_mount(int userns_fd, int mount_fd);
|
||||
int nsresource_add_cgroup(int userns_fd, int cgroup_fd);
|
||||
int nsresource_add_netif(int userns_fd, int netns_fd, const char *namespace_ifname, char **ret_host_ifname, char **ret_namespace_ifname);
|
||||
int nsresource_add_netif_veth(int userns_fd, int netns_fd, const char *namespace_ifname, char **ret_host_ifname, char **ret_namespace_ifname);
|
||||
int nsresource_add_netif_tap(int userns_fd, char **ret_host_ifname);
|
||||
|
||||
Reference in New Issue
Block a user