mirror of
https://github.com/systemd/systemd.git
synced 2026-08-09 17:38:42 +00:00
network: several follow-ups for new varlink methods (#40808)
This commit is contained in:
7
NEWS
7
NEWS
@@ -172,9 +172,10 @@ CHANGES WITH 260 in spe:
|
||||
RouteMetric=, and UseGateway= settings. This allows systemd-networkd
|
||||
to establish a cellular modem connection to a broadband network.
|
||||
|
||||
* systemd-networkd gained a pair of varlink methods LinkUp()/LinkDown().
|
||||
networkctl up/down now utilizes the new varlink interfaces in place
|
||||
of direct RTNL message for better interaction with networkd.
|
||||
* systemd-networkd gained a pair of varlink methods
|
||||
io.systemd.Network.Link.Up()/Down(). networkctl up/down now utilizes
|
||||
the new varlink interfaces in place of direct RTNL message for better
|
||||
interaction with networkd.
|
||||
|
||||
Changes in systemd-boot and the stub:
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ systemd_networkd_extract_sources = files(
|
||||
'networkd-ipv6ll.c',
|
||||
'networkd-json.c',
|
||||
'networkd-link-bus.c',
|
||||
'networkd-link-varlink.c',
|
||||
'networkd-link.c',
|
||||
'networkd-lldp-rx.c',
|
||||
'networkd-lldp-tx.c',
|
||||
|
||||
@@ -67,7 +67,7 @@ int link_up_down(int argc, char *argv[], void *userdata) {
|
||||
ORDERED_SET_FOREACH(p, indexes)
|
||||
RET_GATHER(ret, varlink_callbo_and_log(
|
||||
vl,
|
||||
up ? "io.systemd.Network.LinkUp" : "io.systemd.Network.LinkDown",
|
||||
up ? "io.systemd.Network.Link.Up" : "io.systemd.Network.Link.Down",
|
||||
/* reply= */ NULL,
|
||||
SD_JSON_BUILD_PAIR_INTEGER("InterfaceIndex", PTR_TO_INT(p)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", arg_ask_password)));
|
||||
|
||||
102
src/network/networkd-link-varlink.c
Normal file
102
src/network/networkd-link-varlink.c
Normal file
@@ -0,0 +1,102 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "json-util.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-link-varlink.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-setlink.h"
|
||||
|
||||
int dispatch_link(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, DispatchLinkFlag flags, Link **ret) {
|
||||
struct {
|
||||
int ifindex;
|
||||
const char *ifname;
|
||||
} info = {};
|
||||
Link *link = NULL;
|
||||
int r;
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "InterfaceIndex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex, voffsetof(info, ifindex), SD_JSON_RELAX },
|
||||
{ "InterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, voffsetof(info, ifname), 0 },
|
||||
{}
|
||||
}, dispatch_polkit_table[] = {
|
||||
{ "InterfaceIndex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex, voffsetof(info, ifindex), SD_JSON_RELAX },
|
||||
{ "InterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, voffsetof(info, ifname), 0 },
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
|
||||
assert(vlink);
|
||||
assert(manager);
|
||||
assert(ret);
|
||||
|
||||
r = sd_varlink_dispatch(
|
||||
vlink,
|
||||
parameters,
|
||||
FLAGS_SET(flags, DISPATCH_LINK_POLKIT) ? dispatch_polkit_table : dispatch_table,
|
||||
&info);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
if (info.ifindex < 0)
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
|
||||
if (info.ifindex > 0 && link_get_by_index(manager, info.ifindex, &link) < 0)
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
|
||||
if (info.ifname) {
|
||||
Link *link_by_name;
|
||||
|
||||
if (link_get_by_name(manager, info.ifname, &link_by_name) < 0)
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceName"));
|
||||
|
||||
if (link && link_by_name != link)
|
||||
/* If both arguments are specified, then these must be consistent. */
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceName"));
|
||||
|
||||
link = link_by_name;
|
||||
}
|
||||
|
||||
if (!link && FLAGS_SET(flags, DISPATCH_LINK_MANDATORY))
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
|
||||
|
||||
/* If the DISPATCH_LINK_MANDATORY flag is not set, this function may return NULL. */
|
||||
*ret = link;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vl_method_link_up_or_down(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, bool up) {
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(vlink);
|
||||
assert(manager);
|
||||
|
||||
r = dispatch_link(vlink, parameters, manager, DISPATCH_LINK_POLKIT | DISPATCH_LINK_MANDATORY, &link);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
vlink,
|
||||
manager->bus,
|
||||
"org.freedesktop.network1.manage-links",
|
||||
/* details= */ NULL,
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (!up)
|
||||
/* Stop all network engines while interface is still up to allow proper cleanup,
|
||||
* e.g. sending IPv6 shutdown RA messages before the interface is brought down. */
|
||||
(void) link_stop_engines(link, /* may_keep_dynamic = */ false);
|
||||
|
||||
return link_up_or_down_now_by_varlink(link, up, vlink);
|
||||
}
|
||||
|
||||
int vl_method_link_up(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
return vl_method_link_up_or_down(vlink, parameters, userdata, /* up= */ true);
|
||||
}
|
||||
|
||||
int vl_method_link_down(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
return vl_method_link_up_or_down(vlink, parameters, userdata, /* up= */ false);
|
||||
}
|
||||
14
src/network/networkd-link-varlink.h
Normal file
14
src/network/networkd-link-varlink.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "networkd-forward.h"
|
||||
|
||||
typedef enum DispatchLinkFlag {
|
||||
DISPATCH_LINK_POLKIT = 1 << 0,
|
||||
DISPATCH_LINK_MANDATORY = 1 << 1,
|
||||
} DispatchLinkFlag;
|
||||
|
||||
int dispatch_link(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, DispatchLinkFlag flags, Link **ret);
|
||||
|
||||
int vl_method_link_up(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||
int vl_method_link_down(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||
@@ -14,11 +14,12 @@
|
||||
#include "networkd-dhcp-server.h"
|
||||
#include "networkd-json.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-link-varlink.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-manager-varlink.h"
|
||||
#include "networkd-setlink.h"
|
||||
#include "stat-util.h"
|
||||
#include "varlink-io.systemd.Network.h"
|
||||
#include "varlink-io.systemd.Network.Link.h"
|
||||
#include "varlink-io.systemd.service.h"
|
||||
#include "varlink-util.h"
|
||||
|
||||
@@ -93,55 +94,6 @@ static int vl_method_get_namespace_id(sd_varlink *link, sd_json_variant *paramet
|
||||
SD_JSON_BUILD_PAIR_CONDITION(nsid != UINT32_MAX, "NamespaceNSID", SD_JSON_BUILD_UNSIGNED(nsid)));
|
||||
}
|
||||
|
||||
static int dispatch_interface(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, bool polkit, Link **ret) {
|
||||
struct {
|
||||
int ifindex;
|
||||
const char *ifname;
|
||||
} info = {};
|
||||
Link *link = NULL;
|
||||
int r;
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "InterfaceIndex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex, voffsetof(info, ifindex), SD_JSON_RELAX },
|
||||
{ "InterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, voffsetof(info, ifname), 0 },
|
||||
{}
|
||||
}, dispatch_polkit_table[] = {
|
||||
{ "InterfaceIndex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex, voffsetof(info, ifindex), SD_JSON_RELAX },
|
||||
{ "InterfaceName", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, voffsetof(info, ifname), 0 },
|
||||
VARLINK_DISPATCH_POLKIT_FIELD,
|
||||
{}
|
||||
};
|
||||
|
||||
assert(vlink);
|
||||
assert(manager);
|
||||
assert(ret);
|
||||
|
||||
r = sd_varlink_dispatch(vlink, parameters, polkit ? dispatch_polkit_table : dispatch_table, &info);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
if (info.ifindex < 0)
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
|
||||
if (info.ifindex > 0 && link_get_by_index(manager, info.ifindex, &link) < 0)
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
|
||||
if (info.ifname) {
|
||||
Link *link_by_name;
|
||||
|
||||
if (link_get_by_name(manager, info.ifname, &link_by_name) < 0)
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceName"));
|
||||
|
||||
if (link && link_by_name != link)
|
||||
/* If both arguments are specified, then these must be consistent. */
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceName"));
|
||||
|
||||
link = link_by_name;
|
||||
}
|
||||
|
||||
/* If neither InterfaceIndex nor InterfaceName specified, this function returns NULL. */
|
||||
*ret = link;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_append_lldp_neighbors(Link *link, sd_json_variant *v, sd_json_variant **array) {
|
||||
assert(link);
|
||||
assert(array);
|
||||
@@ -163,7 +115,7 @@ static int vl_method_get_lldp_neighbors(sd_varlink *vlink, sd_json_variant *para
|
||||
assert(vlink);
|
||||
assert(manager);
|
||||
|
||||
r = dispatch_interface(vlink, parameters, manager, /* polkit= */ false, &link);
|
||||
r = dispatch_link(vlink, parameters, manager, /* flags= */ 0, &link);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
@@ -284,46 +236,6 @@ static int vl_method_set_persistent_storage(sd_varlink *vlink, sd_json_variant *
|
||||
return sd_varlink_reply(vlink, NULL);
|
||||
}
|
||||
|
||||
static int vl_method_link_up_or_down(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, bool up) {
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(vlink);
|
||||
assert(manager);
|
||||
|
||||
r = dispatch_interface(vlink, parameters, manager, /* polkit= */ true, &link);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
/* Require a specific link to be specified. */
|
||||
if (!link)
|
||||
return sd_varlink_error_invalid_parameter(vlink, JSON_VARIANT_STRING_CONST("InterfaceIndex"));
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
vlink,
|
||||
manager->bus,
|
||||
"org.freedesktop.network1.manage-links",
|
||||
/* details= */ NULL,
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (!up)
|
||||
/* Stop all network engines while interface is still up to allow proper cleanup,
|
||||
* e.g. sending IPv6 shutdown RA messages before the interface is brought down. */
|
||||
(void) link_stop_engines(link, /* may_keep_dynamic = */ false);
|
||||
|
||||
return link_up_or_down_now_by_varlink(link, up, vlink);
|
||||
}
|
||||
|
||||
static int vl_method_link_up(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
return vl_method_link_up_or_down(vlink, parameters, userdata, /* up= */ true);
|
||||
}
|
||||
|
||||
static int vl_method_link_down(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
return vl_method_link_up_or_down(vlink, parameters, userdata, /* up= */ false);
|
||||
}
|
||||
|
||||
int manager_varlink_init(Manager *m, int fd) {
|
||||
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL;
|
||||
_unused_ _cleanup_close_ int fd_close = fd; /* take possession */
|
||||
@@ -347,6 +259,7 @@ int manager_varlink_init(Manager *m, int fd) {
|
||||
r = sd_varlink_server_add_interface_many(
|
||||
s,
|
||||
&vl_interface_io_systemd_Network,
|
||||
&vl_interface_io_systemd_Network_Link,
|
||||
&vl_interface_io_systemd_service);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to add Network interface to varlink server: %m");
|
||||
@@ -358,8 +271,8 @@ int manager_varlink_init(Manager *m, int fd) {
|
||||
"io.systemd.Network.GetNamespaceId", vl_method_get_namespace_id,
|
||||
"io.systemd.Network.GetLLDPNeighbors", vl_method_get_lldp_neighbors,
|
||||
"io.systemd.Network.SetPersistentStorage", vl_method_set_persistent_storage,
|
||||
"io.systemd.Network.LinkUp", vl_method_link_up,
|
||||
"io.systemd.Network.LinkDown", vl_method_link_down,
|
||||
"io.systemd.Network.Link.Up", vl_method_link_up,
|
||||
"io.systemd.Network.Link.Down", vl_method_link_down,
|
||||
"io.systemd.service.Ping", varlink_method_ping,
|
||||
"io.systemd.service.SetLogLevel", varlink_method_set_log_level,
|
||||
"io.systemd.service.GetEnvironment", varlink_method_get_environment);
|
||||
|
||||
@@ -216,6 +216,7 @@ shared_sources = files(
|
||||
'varlink-io.systemd.MuteConsole.c',
|
||||
'varlink-io.systemd.NamespaceResource.c',
|
||||
'varlink-io.systemd.Network.c',
|
||||
'varlink-io.systemd.Network.Link.c',
|
||||
'varlink-io.systemd.PCRExtend.c',
|
||||
'varlink-io.systemd.PCRLock.c',
|
||||
'varlink-io.systemd.Repart.c',
|
||||
|
||||
28
src/shared/varlink-io.systemd.Network.Link.c
Normal file
28
src/shared/varlink-io.systemd.Network.Link.c
Normal file
@@ -0,0 +1,28 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "varlink-io.systemd.Network.Link.h"
|
||||
|
||||
#define VARLINK_NETWORK_INTERFACE_INPUTS \
|
||||
SD_VARLINK_FIELD_COMMENT("Index of the interface. If specified together with InterfaceName, both must reference the same link."), \
|
||||
SD_VARLINK_DEFINE_INPUT(InterfaceIndex, SD_VARLINK_INT, SD_VARLINK_NULLABLE), \
|
||||
SD_VARLINK_FIELD_COMMENT("Name of the interface. If specified together with InterfaceIndex, both must reference the same link."), \
|
||||
SD_VARLINK_DEFINE_INPUT(InterfaceName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE)
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Up,
|
||||
VARLINK_NETWORK_INTERFACE_INPUTS,
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Down,
|
||||
VARLINK_NETWORK_INTERFACE_INPUTS,
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
|
||||
SD_VARLINK_DEFINE_INTERFACE(
|
||||
io_systemd_Network_Link,
|
||||
"io.systemd.Network.Link",
|
||||
SD_VARLINK_SYMBOL_COMMENT("Bring the specified link up."),
|
||||
&vl_method_Up,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Bring the specified link down."),
|
||||
&vl_method_Down);
|
||||
6
src/shared/varlink-io.systemd.Network.Link.h
Normal file
6
src/shared/varlink-io.systemd.Network.Link.h
Normal file
@@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-varlink-idl.h"
|
||||
|
||||
extern const sd_varlink_interface vl_interface_io_systemd_Network_Link;
|
||||
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "varlink-io.systemd.Network.h"
|
||||
|
||||
/* Helper macro to define address fields with both binary and string representation */
|
||||
@@ -594,22 +593,6 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
SD_VARLINK_FIELD_COMMENT("Whether persistent storage is ready and writable"),
|
||||
SD_VARLINK_DEFINE_INPUT(Ready, SD_VARLINK_BOOL, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
LinkUp,
|
||||
SD_VARLINK_FIELD_COMMENT("Index of the interface. If specified together with InterfaceName, both must reference the same link."),
|
||||
SD_VARLINK_DEFINE_INPUT(InterfaceIndex, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Name of the interface. If specified together with InterfaceIndex, both must reference the same link."),
|
||||
SD_VARLINK_DEFINE_INPUT(InterfaceName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
LinkDown,
|
||||
SD_VARLINK_FIELD_COMMENT("Index of the interface. If specified together with InterfaceName, both must reference the same link."),
|
||||
SD_VARLINK_DEFINE_INPUT(InterfaceIndex, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Name of the interface. If specified together with InterfaceIndex, both must reference the same link."),
|
||||
SD_VARLINK_DEFINE_INPUT(InterfaceName, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
|
||||
static SD_VARLINK_DEFINE_ERROR(StorageReadOnly);
|
||||
|
||||
SD_VARLINK_DEFINE_INTERFACE(
|
||||
@@ -620,10 +603,6 @@ SD_VARLINK_DEFINE_INTERFACE(
|
||||
&vl_method_GetNamespaceId,
|
||||
&vl_method_GetLLDPNeighbors,
|
||||
&vl_method_SetPersistentStorage,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Bring the specified link up."),
|
||||
&vl_method_LinkUp,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Bring the specified link down."),
|
||||
&vl_method_LinkDown,
|
||||
&vl_type_Address,
|
||||
&vl_type_DHCPLease,
|
||||
&vl_type_DHCPServer,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "env-util.h"
|
||||
#include "json-util.h"
|
||||
#include "log.h"
|
||||
@@ -11,7 +12,9 @@
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(Ping);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(Reload);
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Reload,
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
SetLogLevel,
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "varlink-io.systemd.MuteConsole.h"
|
||||
#include "varlink-io.systemd.NamespaceResource.h"
|
||||
#include "varlink-io.systemd.Network.h"
|
||||
#include "varlink-io.systemd.Network.Link.h"
|
||||
#include "varlink-io.systemd.PCRExtend.h"
|
||||
#include "varlink-io.systemd.PCRLock.h"
|
||||
#include "varlink-io.systemd.Repart.h"
|
||||
@@ -199,6 +200,7 @@ TEST(parse_format) {
|
||||
&vl_interface_io_systemd_MuteConsole,
|
||||
&vl_interface_io_systemd_NamespaceResource,
|
||||
&vl_interface_io_systemd_Network,
|
||||
&vl_interface_io_systemd_Network_Link,
|
||||
&vl_interface_io_systemd_PCRExtend,
|
||||
&vl_interface_io_systemd_PCRLock,
|
||||
&vl_interface_io_systemd_Repart,
|
||||
|
||||
Reference in New Issue
Block a user