networkd: replace D-Bus with Varlink in networkctl (#40780)
networkctl previously called networkd over D-Bus for several operations.
This replaces all of those calls with Varlink, making it the sole IPC
mechanism between networkctl and networkd.
New Varlink methods added to networkd:
- io.systemd.Network.Link (new sub-interface for link-specific
operations):
- Link.Describe — replaces Link.BitRates + DHCPServer.Leases D-Bus
properties
- Link.Up — replaces Link.SetUp D-Bus method (moved from
**io.systemd.Network.LinkUp**)
- Link.Down — replaces Link.SetDown D-Bus method (moved from
**io.systemd.Network.LinkDown**)
- Link.Renew — replaces Link.Renew D-Bus method
- Link.ForceRenew — replaces Link.ForceRenew D-Bus method
- Link.Reconfigure — replaces Link.Reconfigure D-Bus method
- io.systemd.service
- Reload — replaces Manager.Reload D-Bus method
Supporting changes:
- link_get_bit_rates() extracted from networkd-link.c into
networkd-speed-meter.c
- BitRates added to link_build_json() so Link.Describe returns them
inline
alongside the existing interface description, replacing a separate D-Bus
read
- link_reconfigure_full() and manager_reload() extended to accept
sd_varlink*
for deferred async replies (consistent with existing sd_bus_message*
path)
- DHCP lease display (networkctl status) uses Link.Describe instead of
DHCPServer.Leases; falls back to ClientId when hostname is not present
This commit is contained in:
@@ -2,17 +2,12 @@
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-daemon.h"
|
||||
#include "sd-device.h"
|
||||
#include "sd-netlink.h"
|
||||
#include "sd-network.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
#include "bus-util.h"
|
||||
#include "bus-wait-for-jobs.h"
|
||||
#include "conf-files.h"
|
||||
#include "edit-util.h"
|
||||
#include "errno-util.h"
|
||||
@@ -395,48 +390,8 @@ static int add_config_to_edit(
|
||||
return edit_files_add(context, dropin_path, old_dropin, comment_paths);
|
||||
}
|
||||
|
||||
static int udevd_reload(sd_bus *bus) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
|
||||
const char *job_path;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
|
||||
r = bus_wait_for_jobs_new(bus, &w);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not watch jobs: %m");
|
||||
|
||||
r = bus_call_method(bus,
|
||||
bus_systemd_mgr,
|
||||
"ReloadUnit",
|
||||
&error,
|
||||
&reply,
|
||||
"ss",
|
||||
"systemd-udevd.service",
|
||||
"replace");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to reload systemd-udevd: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "o", &job_path);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = bus_wait_for_jobs_one(w, job_path, /* flags= */ 0, NULL);
|
||||
if (r == -ENOEXEC) {
|
||||
log_debug("systemd-udevd is not running, skipping reload.");
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to reload systemd-udevd: %m");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int reload_daemons(ReloadFlags flags) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
int r, ret = 1;
|
||||
int ret = 1;
|
||||
|
||||
if (arg_no_reload)
|
||||
return 0;
|
||||
@@ -449,22 +404,14 @@ static int reload_daemons(ReloadFlags flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_bus_open_system(&bus);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to system bus: %m");
|
||||
|
||||
if (FLAGS_SET(flags, RELOAD_UDEVD))
|
||||
RET_GATHER(ret, udevd_reload(bus));
|
||||
RET_GATHER(ret, reload_udevd());
|
||||
|
||||
if (FLAGS_SET(flags, RELOAD_NETWORKD)) {
|
||||
if (networkd_is_running()) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
|
||||
r = bus_call_method(bus, bus_network_mgr, "Reload", &error, NULL, NULL);
|
||||
if (r < 0)
|
||||
RET_GATHER(ret, log_error_errno(r, "Failed to reload systemd-networkd: %s", bus_error_message(&error, r)));
|
||||
} else
|
||||
if (!networkd_is_running())
|
||||
log_debug("systemd-networkd is not running, skipping reload.");
|
||||
else
|
||||
RET_GATHER(ret, reload_networkd());
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
|
||||
#include <linux/if_tunnel.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-json.h"
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "bus-common-errors.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-util.h"
|
||||
#include "device-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "glob-util.h"
|
||||
@@ -28,6 +25,7 @@
|
||||
LinkInfo* link_info_array_free(LinkInfo *array) {
|
||||
for (unsigned i = 0; array && array[i].needs_freeing; i++) {
|
||||
sd_device_unref(array[i].sd_device);
|
||||
sd_json_variant_unref(array[i].description);
|
||||
free(array[i].netdev_kind);
|
||||
free(array[i].ssid);
|
||||
free(array[i].qdisc);
|
||||
@@ -280,33 +278,31 @@ static int decode_link(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int acquire_link_bitrates(sd_bus *bus, LinkInfo *link) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
static int acquire_link_bitrates(LinkInfo *link) {
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(link);
|
||||
|
||||
r = link_get_property(bus, link->ifindex, &error, &reply, "org.freedesktop.network1.Link", "BitRates", "(tt)");
|
||||
if (r < 0) {
|
||||
bool quiet = sd_bus_error_has_names(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY,
|
||||
BUS_ERROR_SPEED_METER_INACTIVE);
|
||||
|
||||
return log_full_errno(quiet ? LOG_DEBUG : LOG_WARNING,
|
||||
r, "Failed to query link bit rates: %s", bus_error_message(&error, r));
|
||||
}
|
||||
|
||||
r = sd_bus_message_read(reply, "(tt)", &link->tx_bitrate, &link->rx_bitrate);
|
||||
sd_json_variant *v;
|
||||
r = json_variant_find_object(link->description, STRV_MAKE("Interface", "BitRates"), &v);
|
||||
if (r == -ENODATA)
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "TxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, tx_bitrate), SD_JSON_MANDATORY },
|
||||
{ "RxBitRate", _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LinkInfo, rx_bitrate), SD_JSON_MANDATORY },
|
||||
{}
|
||||
};
|
||||
|
||||
r = sd_json_dispatch(v, dispatch_table,
|
||||
SD_JSON_LOG | SD_JSON_WARNING | SD_JSON_ALLOW_EXTENSIONS,
|
||||
link);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
link->has_bitrates = link->tx_bitrate != UINT64_MAX && link->rx_bitrate != UINT64_MAX;
|
||||
return r;
|
||||
|
||||
link->has_bitrates = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -356,7 +352,7 @@ static void acquire_wlan_link_info(LinkInfo *link) {
|
||||
link->has_wlan_link_info = r > 0 || k > 0;
|
||||
}
|
||||
|
||||
int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char * const *patterns, LinkInfo **ret) {
|
||||
int acquire_link_info(sd_varlink *vl, sd_netlink *rtnl, char * const *patterns, LinkInfo **ret) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
|
||||
_cleanup_(link_info_array_freep) LinkInfo *links = NULL;
|
||||
_cleanup_free_ bool *matched_patterns = NULL;
|
||||
@@ -402,6 +398,10 @@ int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char * const *patterns, Lin
|
||||
acquire_ether_link_info(&fd, &links[c]);
|
||||
acquire_wlan_link_info(&links[c]);
|
||||
|
||||
if (vl)
|
||||
(void) acquire_link_description(vl, links[c].ifindex, &links[c].description);
|
||||
(void) acquire_link_bitrates(&links[c]);
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
@@ -421,10 +421,6 @@ int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char * const *patterns, Lin
|
||||
|
||||
typesafe_qsort(links, c, link_info_compare);
|
||||
|
||||
if (bus)
|
||||
FOREACH_ARRAY(link, links, c)
|
||||
(void) acquire_link_bitrates(bus, link);
|
||||
|
||||
*ret = TAKE_PTR(links);
|
||||
|
||||
if (patterns && c == 0)
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef struct LinkInfo {
|
||||
char name[IFNAMSIZ+1];
|
||||
char *netdev_kind;
|
||||
sd_device *sd_device;
|
||||
sd_json_variant *description;
|
||||
int ifindex;
|
||||
unsigned short iftype;
|
||||
struct hw_addr_data hw_address;
|
||||
@@ -133,4 +134,4 @@ typedef struct LinkInfo {
|
||||
LinkInfo* link_info_array_free(LinkInfo *array);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(LinkInfo*, link_info_array_free);
|
||||
|
||||
int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char * const *patterns, LinkInfo **ret);
|
||||
int acquire_link_info(sd_varlink *vl, sd_netlink *rtnl, char * const *patterns, LinkInfo **ret);
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
#include "bus-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
@@ -46,35 +43,6 @@ static int parse_interfaces(sd_netlink **rtnl, char *argv[], OrderedSet **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int verb_link_up_down(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
int r, ret = 0;
|
||||
|
||||
bool up = streq_ptr(argv[0], "up");
|
||||
|
||||
_cleanup_ordered_set_free_ OrderedSet *indexes = NULL;
|
||||
r = parse_interfaces(/* rtnl= */ NULL, argv, &indexes);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *vl = NULL;
|
||||
r = varlink_connect_networkd(&vl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password);
|
||||
|
||||
void *p;
|
||||
ORDERED_SET_FOREACH(p, indexes)
|
||||
RET_GATHER(ret, varlink_callbo_and_log(
|
||||
vl,
|
||||
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)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int verb_link_delete(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
int r, ret = 0;
|
||||
|
||||
@@ -104,25 +72,26 @@ int verb_link_delete(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int verb_link_bus_simple_method(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
int verb_link_varlink_simple_method(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
int r, ret = 0;
|
||||
|
||||
typedef struct LinkBusAction {
|
||||
typedef struct LinkVarlinkAction {
|
||||
const char *verb;
|
||||
const char *bus_method;
|
||||
const char *error_message;
|
||||
} LinkBusAction;
|
||||
const char *method;
|
||||
} LinkVarlinkAction;
|
||||
|
||||
static const LinkBusAction link_bus_action_table[] = {
|
||||
{ "renew", "RenewLink", "Failed to renew dynamic configuration of interface" },
|
||||
{ "forcerenew", "ForceRenewLink", "Failed to forcibly renew dynamic configuration of interface" },
|
||||
{ "reconfigure", "ReconfigureLink", "Failed to reconfigure network interface" },
|
||||
static const LinkVarlinkAction link_varlink_action_table[] = {
|
||||
{ "up", "io.systemd.Network.Link.Up", },
|
||||
{ "down", "io.systemd.Network.Link.Down", },
|
||||
{ "renew", "io.systemd.Network.Link.Renew", },
|
||||
{ "forcerenew", "io.systemd.Network.Link.ForceRenew", },
|
||||
{ "reconfigure", "io.systemd.Network.Link.Reconfigure", },
|
||||
};
|
||||
|
||||
/* Common implementation for 'simple' method calls that just take an ifindex, and nothing else. */
|
||||
|
||||
const LinkBusAction *a = NULL;
|
||||
FOREACH_ELEMENT(i, link_bus_action_table)
|
||||
const LinkVarlinkAction *a = NULL;
|
||||
FOREACH_ELEMENT(i, link_varlink_action_table)
|
||||
if (streq(argv[0], i->verb)) {
|
||||
a = i;
|
||||
break;
|
||||
@@ -134,47 +103,27 @@ int verb_link_bus_simple_method(int argc, char *argv[], uintptr_t _data, void *u
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
r = acquire_bus(&bus);
|
||||
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *vl = NULL;
|
||||
r = varlink_connect_networkd(&vl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password);
|
||||
|
||||
void *p;
|
||||
ORDERED_SET_FOREACH(p, indexes) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int index = PTR_TO_INT(p);
|
||||
|
||||
r = bus_call_method(bus, bus_network_mgr, a->bus_method, &error, /* ret_reply= */ NULL, "i", index);
|
||||
if (r < 0) {
|
||||
RET_GATHER(ret, r);
|
||||
log_error_errno(r, "%s %s: %s",
|
||||
a->error_message,
|
||||
FORMAT_IFNAME_FULL(index, FORMAT_IFNAME_IFINDEX),
|
||||
bus_error_message(&error, r));
|
||||
}
|
||||
}
|
||||
ORDERED_SET_FOREACH(p, indexes)
|
||||
RET_GATHER(ret, varlink_callbo_and_log(
|
||||
vl,
|
||||
a->method,
|
||||
/* reply= */ NULL,
|
||||
SD_JSON_BUILD_PAIR_INTEGER("InterfaceIndex", PTR_TO_INT(p)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", arg_ask_password)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int verb_reload(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
|
||||
r = acquire_bus(&bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password);
|
||||
|
||||
r = bus_call_method(bus, bus_network_mgr, "Reload", &error, NULL, NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to reload network settings: %s", bus_error_message(&error, r));
|
||||
|
||||
return 0;
|
||||
return reload_networkd();
|
||||
}
|
||||
|
||||
int verb_persistent_storage(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
#include "shared-forward.h"
|
||||
|
||||
int verb_link_up_down(int argc, char *argv[], uintptr_t _data, void *userdata);
|
||||
int verb_link_delete(int argc, char *argv[], uintptr_t _data, void *userdata);
|
||||
int verb_link_bus_simple_method(int argc, char *argv[], uintptr_t _data, void *userdata);
|
||||
int verb_link_varlink_simple_method(int argc, char *argv[], uintptr_t _data, void *userdata);
|
||||
int verb_reload(int argc, char *argv[], uintptr_t _data, void *userdata);
|
||||
int verb_persistent_storage(int argc, char *argv[], uintptr_t _data, void *userdata);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "sd-device.h"
|
||||
#include "sd-dhcp-client-id.h"
|
||||
#include "sd-dhcp-lease.h"
|
||||
@@ -12,8 +11,6 @@
|
||||
#include "alloc-util.h"
|
||||
#include "bond-util.h"
|
||||
#include "bridge-util.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "escape.h"
|
||||
#include "extract-word.h"
|
||||
@@ -21,7 +18,9 @@
|
||||
#include "format-util.h"
|
||||
#include "geneve-util.h"
|
||||
#include "glyph-util.h"
|
||||
#include "iovec-util.h"
|
||||
#include "ipvlan-util.h"
|
||||
#include "json-util.h"
|
||||
#include "macvlan-util.h"
|
||||
#include "netif-util.h"
|
||||
#include "network-internal.h"
|
||||
@@ -40,87 +39,58 @@
|
||||
#include "time-util.h"
|
||||
#include "udev-util.h"
|
||||
|
||||
static int dump_dhcp_leases(Table *table, const char *prefix, sd_bus *bus, const LinkInfo *link) {
|
||||
typedef struct LeaseInfo {
|
||||
const char *address;
|
||||
struct iovec client_id;
|
||||
} LeaseInfo;
|
||||
|
||||
static void lease_info_done(LeaseInfo *p) {
|
||||
assert(p);
|
||||
|
||||
iovec_done(&p->client_id);
|
||||
}
|
||||
|
||||
static int dump_dhcp_leases(Table *table, const char *prefix, const LinkInfo *link) {
|
||||
_cleanup_strv_free_ char **buf = NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
int r;
|
||||
|
||||
assert(table);
|
||||
assert(prefix);
|
||||
assert(bus);
|
||||
assert(link);
|
||||
|
||||
r = link_get_property(bus, link->ifindex, &error, &reply, "org.freedesktop.network1.DHCPServer", "Leases", "a(uayayayayt)");
|
||||
if (r < 0) {
|
||||
bool quiet = sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_PROPERTY);
|
||||
|
||||
log_full_errno(quiet ? LOG_DEBUG : LOG_WARNING,
|
||||
r, "Failed to query link DHCP leases: %s", bus_error_message(&error, r));
|
||||
sd_json_variant *leases;
|
||||
r = json_variant_find_object(link->description, STRV_MAKE("Interface", "DHCPServer", "Leases"), &leases);
|
||||
if (r == -ENODATA)
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_bus_message_enter_container(reply, 'a', "(uayayayayt)");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
return r;
|
||||
|
||||
while ((r = sd_bus_message_enter_container(reply, 'r', "uayayayayt")) > 0) {
|
||||
_cleanup_free_ char *id = NULL, *ip = NULL;
|
||||
const void *client_id, *addr, *gtw, *hwaddr;
|
||||
size_t client_id_sz, sz;
|
||||
uint64_t expiration;
|
||||
uint32_t family;
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "AddressString", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, offsetof(LeaseInfo, address), SD_JSON_MANDATORY },
|
||||
{ "ClientId", SD_JSON_VARIANT_ARRAY, json_dispatch_byte_array_iovec, offsetof(LeaseInfo, client_id), 0 },
|
||||
{}
|
||||
};
|
||||
|
||||
r = sd_bus_message_read(reply, "u", &family);
|
||||
sd_json_variant *lease;
|
||||
JSON_VARIANT_ARRAY_FOREACH(lease, leases) {
|
||||
_cleanup_(lease_info_done) LeaseInfo info = {};
|
||||
_cleanup_free_ char *client_id = NULL;
|
||||
|
||||
r = sd_json_dispatch(lease, dispatch_table, SD_JSON_LOG | SD_JSON_WARNING | SD_JSON_ALLOW_EXTENSIONS, &info);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
continue;
|
||||
|
||||
r = sd_bus_message_read_array(reply, 'y', &client_id, &client_id_sz);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
if (info.client_id.iov_len > 0)
|
||||
(void) sd_dhcp_client_id_to_string_from_raw(info.client_id.iov_base, info.client_id.iov_len, &client_id);
|
||||
|
||||
r = sd_bus_message_read_array(reply, 'y', &addr, &sz);
|
||||
if (r < 0 || sz != 4)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_read_array(reply, 'y', >w, &sz);
|
||||
if (r < 0 || sz != 4)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_read_array(reply, 'y', &hwaddr, &sz);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_read_basic(reply, 't', &expiration);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_dhcp_client_id_to_string_from_raw(client_id, client_id_sz, &id);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = in_addr_to_string(family, addr, &ip);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = strv_extendf(&buf, "%s (to %s)", ip, id);
|
||||
r = strv_extendf(&buf, "%s%s%s%s",
|
||||
info.address,
|
||||
client_id ? " (to " : "",
|
||||
strempty(client_id),
|
||||
client_id ? ")" : "");
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
}
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_bus_message_exit_container(reply);
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
if (strv_isempty(buf)) {
|
||||
r = strv_extendf(&buf, "none");
|
||||
@@ -259,7 +229,6 @@ static int format_config_files(char ***files, const char *main_config) {
|
||||
}
|
||||
|
||||
static int link_status_one(
|
||||
sd_bus *bus,
|
||||
sd_netlink *rtnl,
|
||||
sd_hwdb *hwdb,
|
||||
sd_varlink *vl,
|
||||
@@ -276,7 +245,6 @@ static int link_status_one(
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(rtnl);
|
||||
assert(vl);
|
||||
assert(info);
|
||||
@@ -919,7 +887,7 @@ static int link_status_one(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dump_dhcp_leases(table, "Offered DHCP leases", bus, info);
|
||||
r = dump_dhcp_leases(table, "Offered DHCP leases", info);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -940,7 +908,6 @@ static int link_status_one(
|
||||
}
|
||||
|
||||
int verb_link_status(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
|
||||
_cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
|
||||
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *vl = NULL;
|
||||
@@ -951,10 +918,6 @@ int verb_link_status(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = acquire_bus(&bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
pager_open(arg_pager_flags);
|
||||
|
||||
r = sd_netlink_open(&rtnl);
|
||||
@@ -970,11 +933,11 @@ int verb_link_status(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
return r;
|
||||
|
||||
if (arg_all)
|
||||
c = acquire_link_info(bus, rtnl, NULL, &links);
|
||||
c = acquire_link_info(vl, rtnl, NULL, &links);
|
||||
else if (argc <= 1)
|
||||
return system_status(rtnl, hwdb);
|
||||
else
|
||||
c = acquire_link_info(bus, rtnl, argv + 1, &links);
|
||||
c = acquire_link_info(vl, rtnl, argv + 1, &links);
|
||||
if (c < 0)
|
||||
return c;
|
||||
|
||||
@@ -985,7 +948,7 @@ int verb_link_status(int argc, char *argv[], uintptr_t _data, void *userdata) {
|
||||
if (!first)
|
||||
putchar('\n');
|
||||
|
||||
RET_GATHER(r, link_status_one(bus, rtnl, hwdb, vl, i));
|
||||
RET_GATHER(r, link_status_one(rtnl, hwdb, vl, i));
|
||||
|
||||
first = false;
|
||||
}
|
||||
|
||||
@@ -3,14 +3,12 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "bus-util.h"
|
||||
#include "log.h"
|
||||
#include "networkctl.h"
|
||||
#include "networkctl-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "polkit-agent.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "varlink-util.h"
|
||||
@@ -62,6 +60,40 @@ int varlink_connect_networkd(sd_varlink **ret_varlink) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int reload_networkd(void) {
|
||||
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *vl = NULL;
|
||||
int r;
|
||||
|
||||
r = varlink_connect_networkd(&vl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password);
|
||||
|
||||
return varlink_callbo_and_log(
|
||||
vl,
|
||||
"io.systemd.service.Reload",
|
||||
/* reply= */ NULL,
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", arg_ask_password));
|
||||
}
|
||||
|
||||
int reload_udevd(void) {
|
||||
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *vl = NULL;
|
||||
int r;
|
||||
|
||||
r = sd_varlink_connect_address(&vl, "/run/udev/io.systemd.Udev");
|
||||
if (r == -ENOENT) {
|
||||
log_debug("systemd-udevd is not running, skipping reload.");
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to udev: %m");
|
||||
|
||||
(void) sd_varlink_set_description(vl, "udev");
|
||||
|
||||
return varlink_call_and_log(vl, "io.systemd.service.Reload", /* parameters= */ NULL, /* reply= */ NULL);
|
||||
}
|
||||
|
||||
bool networkd_is_running(void) {
|
||||
static int cached = -1;
|
||||
int r;
|
||||
@@ -81,59 +113,6 @@ bool networkd_is_running(void) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
int acquire_bus(sd_bus **ret) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
r = sd_bus_open_system(&bus);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to system bus: %m");
|
||||
|
||||
(void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
|
||||
|
||||
if (networkd_is_running()) {
|
||||
r = varlink_connect_networkd(/* ret_varlink= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else
|
||||
log_warning("systemd-networkd is not running, output might be incomplete.");
|
||||
|
||||
*ret = TAKE_PTR(bus);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_get_property(
|
||||
sd_bus *bus,
|
||||
int ifindex,
|
||||
sd_bus_error *error,
|
||||
sd_bus_message **reply,
|
||||
const char *iface,
|
||||
const char *propname,
|
||||
const char *type) {
|
||||
|
||||
_cleanup_free_ char *path = NULL;
|
||||
char ifindex_str[DECIMAL_STR_MAX(int)];
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(ifindex >= 0);
|
||||
assert(error);
|
||||
assert(reply);
|
||||
assert(iface);
|
||||
assert(propname);
|
||||
assert(type);
|
||||
|
||||
xsprintf(ifindex_str, "%i", ifindex);
|
||||
|
||||
r = sd_bus_path_encode("/org/freedesktop/network1/link", ifindex_str, &path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_bus_get_property(bus, "org.freedesktop.network1", path, iface, propname, error, reply, type);
|
||||
}
|
||||
|
||||
void operational_state_to_color(const char *name, const char *state, const char **on, const char **off) {
|
||||
if (STRPTR_IN_SET(state, "routable", "enslaved") ||
|
||||
(streq_ptr(name, "lo") && streq_ptr(state, "carrier"))) {
|
||||
@@ -196,3 +175,40 @@ void online_state_to_color(const char *state, const char **on, const char **off)
|
||||
*off = "";
|
||||
}
|
||||
}
|
||||
|
||||
int acquire_link_description(sd_varlink *vl, int ifindex, sd_json_variant **ret) {
|
||||
int r;
|
||||
|
||||
assert(vl);
|
||||
assert(ifindex > 0);
|
||||
assert(ret);
|
||||
|
||||
sd_json_variant *v; /* borrowed from vl, do not unref */
|
||||
r = varlink_callbo_and_log(
|
||||
vl,
|
||||
"io.systemd.Network.Link.Describe",
|
||||
&v,
|
||||
SD_JSON_BUILD_PAIR_INTEGER("InterfaceIndex", ifindex));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = sd_json_variant_ref(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int json_variant_find_object(sd_json_variant *v, char * const *object_names, sd_json_variant **ret) {
|
||||
assert(object_names);
|
||||
assert(ret);
|
||||
|
||||
if (!v || sd_json_variant_is_null(v))
|
||||
return -ENODATA;
|
||||
|
||||
STRV_FOREACH(name, object_names) {
|
||||
v = sd_json_variant_by_key(v, *name);
|
||||
if (!v || sd_json_variant_is_null(v))
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
*ret = v;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4,17 +4,13 @@
|
||||
#include "shared-forward.h"
|
||||
|
||||
int varlink_connect_networkd(sd_varlink **ret_varlink);
|
||||
int reload_networkd(void);
|
||||
int reload_udevd(void);
|
||||
bool networkd_is_running(void);
|
||||
int acquire_bus(sd_bus **ret);
|
||||
int link_get_property(
|
||||
sd_bus *bus,
|
||||
int ifindex,
|
||||
sd_bus_error *error,
|
||||
sd_bus_message **reply,
|
||||
const char *iface,
|
||||
const char *propname,
|
||||
const char *type);
|
||||
|
||||
void operational_state_to_color(const char *name, const char *state, const char **on, const char **off);
|
||||
void setup_state_to_color(const char *state, const char **on, const char **off);
|
||||
void online_state_to_color(const char *state, const char **on, const char **off);
|
||||
|
||||
int acquire_link_description(sd_varlink *vl, int ifindex, sd_json_variant **ret);
|
||||
int json_variant_find_object(sd_json_variant *v, char * const *object_names, sd_json_variant **ret);
|
||||
|
||||
+16
-16
@@ -223,22 +223,22 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
static int networkctl_main(int argc, char *argv[]) {
|
||||
static const Verb verbs[] = {
|
||||
{ "list", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, verb_list_links },
|
||||
{ "status", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_link_status },
|
||||
{ "lldp", VERB_ANY, VERB_ANY, 0, verb_link_lldp_status },
|
||||
{ "label", 1, 1, 0, verb_list_address_labels },
|
||||
{ "delete", 2, VERB_ANY, 0, verb_link_delete },
|
||||
{ "up", 2, VERB_ANY, 0, verb_link_up_down },
|
||||
{ "down", 2, VERB_ANY, 0, verb_link_up_down },
|
||||
{ "renew", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_link_bus_simple_method },
|
||||
{ "forcerenew", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_link_bus_simple_method },
|
||||
{ "reconfigure", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_link_bus_simple_method },
|
||||
{ "reload", 1, 1, VERB_ONLINE_ONLY, verb_reload },
|
||||
{ "edit", 2, VERB_ANY, 0, verb_edit },
|
||||
{ "cat", 1, VERB_ANY, 0, verb_cat },
|
||||
{ "mask", 2, VERB_ANY, 0, verb_mask },
|
||||
{ "unmask", 2, VERB_ANY, 0, verb_unmask },
|
||||
{ "persistent-storage", 2, 2, 0, verb_persistent_storage },
|
||||
{ "list", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, verb_list_links },
|
||||
{ "status", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_link_status },
|
||||
{ "lldp", VERB_ANY, VERB_ANY, 0, verb_link_lldp_status },
|
||||
{ "label", 1, 1, 0, verb_list_address_labels },
|
||||
{ "delete", 2, VERB_ANY, 0, verb_link_delete },
|
||||
{ "up", 2, VERB_ANY, 0, verb_link_varlink_simple_method },
|
||||
{ "down", 2, VERB_ANY, 0, verb_link_varlink_simple_method },
|
||||
{ "renew", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_link_varlink_simple_method },
|
||||
{ "forcerenew", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_link_varlink_simple_method },
|
||||
{ "reconfigure", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_link_varlink_simple_method },
|
||||
{ "reload", 1, 1, VERB_ONLINE_ONLY, verb_reload },
|
||||
{ "edit", 2, VERB_ANY, 0, verb_edit },
|
||||
{ "cat", 1, VERB_ANY, 0, verb_cat },
|
||||
{ "mask", 2, VERB_ANY, 0, verb_mask },
|
||||
{ "unmask", 2, VERB_ANY, 0, verb_unmask },
|
||||
{ "persistent-storage", 2, 2, 0, verb_persistent_storage },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "networkd-route.h"
|
||||
#include "networkd-route-util.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-speed-meter.h"
|
||||
#include "networkd-wwan.h"
|
||||
#include "ordered-set.h"
|
||||
#include "set.h"
|
||||
@@ -1639,6 +1640,20 @@ int link_build_json(Link *link, sd_json_variant **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Append BitRates if speed meter is active */
|
||||
uint64_t tx, rx;
|
||||
link_get_bit_rates(link, &tx, &rx);
|
||||
if (tx != UINT64_MAX && rx != UINT64_MAX) {
|
||||
r = sd_json_variant_merge_objectbo(
|
||||
&v,
|
||||
SD_JSON_BUILD_PAIR("BitRates",
|
||||
SD_JSON_BUILD_OBJECT(
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("TxBitRate", tx),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("RxBitRate", rx))));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-link-bus.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-speed-meter.h"
|
||||
#include "networkd-state-file.h"
|
||||
#include "ordered-set.h"
|
||||
#include "parse-util.h"
|
||||
@@ -42,32 +43,12 @@ static int property_get_bit_rates(
|
||||
sd_bus_error *error) {
|
||||
|
||||
Link *link = ASSERT_PTR(userdata);
|
||||
Manager *manager;
|
||||
double interval_sec;
|
||||
uint64_t tx, rx;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
manager = link->manager;
|
||||
|
||||
if (!manager->use_speed_meter ||
|
||||
manager->speed_meter_usec_old == 0 ||
|
||||
!link->stats_updated)
|
||||
return sd_bus_message_append(reply, "(tt)", UINT64_MAX, UINT64_MAX);
|
||||
|
||||
assert(manager->speed_meter_usec_new > manager->speed_meter_usec_old);
|
||||
interval_sec = (double) (manager->speed_meter_usec_new - manager->speed_meter_usec_old) / USEC_PER_SEC;
|
||||
|
||||
if (link->stats_new.tx_bytes > link->stats_old.tx_bytes)
|
||||
tx = (uint64_t) ((link->stats_new.tx_bytes - link->stats_old.tx_bytes) / interval_sec);
|
||||
else
|
||||
tx = (uint64_t) ((UINT64_MAX - (link->stats_old.tx_bytes - link->stats_new.tx_bytes)) / interval_sec);
|
||||
|
||||
if (link->stats_new.rx_bytes > link->stats_old.rx_bytes)
|
||||
rx = (uint64_t) ((link->stats_new.rx_bytes - link->stats_old.rx_bytes) / interval_sec);
|
||||
else
|
||||
rx = (uint64_t) ((UINT64_MAX - (link->stats_old.rx_bytes - link->stats_new.rx_bytes)) / interval_sec);
|
||||
link_get_bit_rates(link, &tx, &rx);
|
||||
|
||||
return sd_bus_message_append(reply, "(tt)", tx, rx);
|
||||
}
|
||||
@@ -672,7 +653,7 @@ int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_
|
||||
if (r == 0)
|
||||
return 1; /* Polkit will call us back */
|
||||
|
||||
r = link_reconfigure_full(l, LINK_RECONFIGURE_UNCONDITIONALLY | LINK_RECONFIGURE_CLEANLY, message, /* counter= */ NULL);
|
||||
r = link_reconfigure_full(l, LINK_RECONFIGURE_UNCONDITIONALLY | LINK_RECONFIGURE_CLEANLY, message, /* varlink= */ NULL, /* counter= */ NULL);
|
||||
if (r != 0)
|
||||
return r; /* Will reply later when r > 0. */
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-dhcp-server.h"
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "json-util.h"
|
||||
#include "networkd-dhcp4.h"
|
||||
#include "networkd-json.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-link-varlink.h"
|
||||
#include "networkd-manager.h"
|
||||
@@ -65,6 +68,27 @@ int dispatch_link(sd_varlink *vlink, sd_json_variant *parameters, Manager *manag
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vl_method_link_describe(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(vlink);
|
||||
|
||||
r = dispatch_link(vlink, parameters, manager, DISPATCH_LINK_MANDATORY, &link);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = link_build_json(link, &v);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to format JSON data: %m");
|
||||
|
||||
return sd_varlink_replybo(
|
||||
vlink,
|
||||
SD_JSON_BUILD_PAIR_VARIANT("Interface", v));
|
||||
}
|
||||
|
||||
static int vl_method_link_up_or_down(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, bool up) {
|
||||
Link *link;
|
||||
int r;
|
||||
@@ -100,3 +124,98 @@ int vl_method_link_up(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink
|
||||
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 vl_method_link_renew(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(vlink);
|
||||
|
||||
r = dispatch_link(vlink, parameters, manager, DISPATCH_LINK_POLKIT | DISPATCH_LINK_MANDATORY, &link);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
if (!link->network)
|
||||
return sd_varlink_error(vlink, "io.systemd.Network.Link.InterfaceUnmanaged", NULL);
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
vlink,
|
||||
manager->bus,
|
||||
"org.freedesktop.network1.renew",
|
||||
/* details= */ NULL,
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = dhcp4_renew(link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to renew DHCPv4 lease: %m");
|
||||
|
||||
return sd_varlink_reply(vlink, NULL);
|
||||
}
|
||||
|
||||
int vl_method_link_force_renew(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(vlink);
|
||||
|
||||
r = dispatch_link(vlink, parameters, manager, DISPATCH_LINK_POLKIT | DISPATCH_LINK_MANDATORY, &link);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
if (!link->network)
|
||||
return sd_varlink_error(vlink, "io.systemd.Network.Link.InterfaceUnmanaged", NULL);
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
vlink,
|
||||
manager->bus,
|
||||
"org.freedesktop.network1.forcerenew",
|
||||
/* details= */ NULL,
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (sd_dhcp_server_is_running(link->dhcp_server)) {
|
||||
r = sd_dhcp_server_forcerenew(link->dhcp_server);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to force-renew DHCP server leases: %m");
|
||||
}
|
||||
|
||||
return sd_varlink_reply(vlink, NULL);
|
||||
}
|
||||
|
||||
int vl_method_link_reconfigure(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
Manager *manager = ASSERT_PTR(userdata);
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(vlink);
|
||||
|
||||
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.reconfigure",
|
||||
/* details= */ NULL,
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = link_reconfigure_full(link,
|
||||
LINK_RECONFIGURE_UNCONDITIONALLY | LINK_RECONFIGURE_CLEANLY,
|
||||
/* message= */ NULL,
|
||||
/* varlink= */ vlink,
|
||||
/* counter= */ NULL);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to reconfigure link: %m");
|
||||
if (r > 0)
|
||||
return 0; /* Reply will be sent asynchronously via vlink */
|
||||
|
||||
return sd_varlink_reply(vlink, NULL);
|
||||
}
|
||||
|
||||
@@ -10,5 +10,9 @@ typedef enum DispatchLinkFlag {
|
||||
|
||||
int dispatch_link(sd_varlink *vlink, sd_json_variant *parameters, Manager *manager, DispatchLinkFlag flags, Link **ret);
|
||||
|
||||
int vl_method_link_describe(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||
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);
|
||||
int vl_method_link_renew(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||
int vl_method_link_force_renew(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||
int vl_method_link_reconfigure(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
|
||||
|
||||
+23
-12
@@ -18,6 +18,7 @@
|
||||
#include "sd-ndisc.h"
|
||||
#include "sd-netlink.h"
|
||||
#include "sd-radv.h"
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "arphrd-util.h"
|
||||
@@ -1509,6 +1510,7 @@ typedef struct LinkReconfigurationData {
|
||||
Link *link;
|
||||
LinkReconfigurationFlag flags;
|
||||
sd_bus_message *message;
|
||||
sd_varlink *varlink;
|
||||
unsigned *counter;
|
||||
} LinkReconfigurationData;
|
||||
|
||||
@@ -1518,6 +1520,7 @@ static LinkReconfigurationData* link_reconfiguration_data_free(LinkReconfigurati
|
||||
|
||||
link_unref(data->link);
|
||||
sd_bus_message_unref(data->message);
|
||||
sd_varlink_unref(data->varlink);
|
||||
|
||||
return mfree(data);
|
||||
}
|
||||
@@ -1528,24 +1531,30 @@ static void link_reconfiguration_data_destroy_callback(LinkReconfigurationData *
|
||||
int r;
|
||||
|
||||
assert(data);
|
||||
assert(!data->message || !data->varlink); /* D-Bus and Varlink callers are mutually exclusive */
|
||||
|
||||
if (data->message) {
|
||||
if (data->counter) {
|
||||
assert(*data->counter > 0);
|
||||
(*data->counter)--;
|
||||
}
|
||||
if (data->counter) {
|
||||
assert(*data->counter > 0);
|
||||
(*data->counter)--;
|
||||
}
|
||||
|
||||
if (!data->counter || *data->counter <= 0) {
|
||||
/* Update the state files before replying the bus method. Otherwise,
|
||||
* systemd-networkd-wait-online following networkctl reload/reconfigure may read an
|
||||
* outdated state file and wrongly handle an interface is already in the configured
|
||||
* state. */
|
||||
(void) manager_clean_all(data->manager);
|
||||
if (!data->counter || *data->counter == 0) {
|
||||
/* Update the state files before replying. Otherwise, systemd-networkd-wait-online following
|
||||
* networkctl reload/reconfigure may read an outdated state file and wrongly consider an
|
||||
* interface already in the configured state. */
|
||||
(void) manager_clean_all(data->manager);
|
||||
|
||||
if (data->message) {
|
||||
r = sd_bus_reply_method_return(data->message, NULL);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to reply for DBus method, ignoring: %m");
|
||||
}
|
||||
|
||||
if (data->varlink) {
|
||||
r = sd_varlink_reply(data->varlink, NULL);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to reply to Varlink request, ignoring: %m");
|
||||
}
|
||||
}
|
||||
|
||||
link_reconfiguration_data_free(data);
|
||||
@@ -1568,7 +1577,7 @@ static int link_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin
|
||||
return r;
|
||||
}
|
||||
|
||||
int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_message *message, unsigned *counter) {
|
||||
int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_message *message, sd_varlink *varlink, unsigned *counter) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
_cleanup_(link_reconfiguration_data_freep) LinkReconfigurationData *data = NULL;
|
||||
int r;
|
||||
@@ -1576,6 +1585,7 @@ int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_mess
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
assert(!message || !varlink); /* D-Bus and Varlink callers are mutually exclusive */
|
||||
|
||||
/* When the link is in the pending or initialized state, link_reconfigure_impl() will be called later
|
||||
* by link_initialized() or link_initialized_and_synced(). To prevent the function from being called
|
||||
@@ -1594,6 +1604,7 @@ int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_mess
|
||||
.link = link_ref(link),
|
||||
.flags = flags,
|
||||
.message = sd_bus_message_ref(message), /* message may be NULL, but _ref() works fine. */
|
||||
.varlink = sd_varlink_ref(varlink), /* varlink may be NULL, but _ref() works fine. */
|
||||
.counter = counter,
|
||||
};
|
||||
|
||||
|
||||
@@ -243,9 +243,9 @@ DECLARE_STRING_TABLE_LOOKUP(link_state, LinkState);
|
||||
int link_request_stacked_netdevs(Link *link, NetDevLocalAddressType type);
|
||||
|
||||
int link_reconfigure_impl(Link *link, LinkReconfigurationFlag flags);
|
||||
int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_message *message, unsigned *counter);
|
||||
int link_reconfigure_full(Link *link, LinkReconfigurationFlag flags, sd_bus_message *message, sd_varlink *varlink, unsigned *counter);
|
||||
static inline int link_reconfigure(Link *link, LinkReconfigurationFlag flags) {
|
||||
return link_reconfigure_full(link, flags, NULL, NULL);
|
||||
return link_reconfigure_full(link, flags, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int link_check_initialized(Link *link);
|
||||
|
||||
@@ -215,7 +215,7 @@ static int bus_method_reload(sd_bus_message *message, void *userdata, sd_bus_err
|
||||
if (r == 0)
|
||||
return 1; /* Polkit will call us back */
|
||||
|
||||
r = manager_reload(manager, message);
|
||||
r = manager_reload(manager, message, /* varlink= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -236,6 +236,38 @@ static int vl_method_set_persistent_storage(sd_varlink *vlink, sd_json_variant *
|
||||
return sd_varlink_reply(vlink, NULL);
|
||||
}
|
||||
|
||||
static int vl_method_reload(sd_varlink *vlink, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(vlink);
|
||||
|
||||
if (m->reloading > 0)
|
||||
return sd_varlink_error(vlink, "io.systemd.Network.AlreadyReloading", NULL);
|
||||
|
||||
r = sd_varlink_dispatch(vlink, parameters, dispatch_table_polkit_only, /* userdata= */ NULL);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = varlink_verify_polkit_async(
|
||||
vlink,
|
||||
m->bus,
|
||||
"org.freedesktop.network1.reload",
|
||||
/* details= */ NULL,
|
||||
&m->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = manager_reload(m, /* message= */ NULL, vlink);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to reload: %m");
|
||||
|
||||
if (m->reloading > 0)
|
||||
return 0; /* Reply will be sent asynchronously. */
|
||||
|
||||
return sd_varlink_reply(vlink, NULL);
|
||||
}
|
||||
|
||||
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 */
|
||||
@@ -271,9 +303,14 @@ 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.Link.Describe", vl_method_link_describe,
|
||||
"io.systemd.Network.Link.Up", vl_method_link_up,
|
||||
"io.systemd.Network.Link.Down", vl_method_link_down,
|
||||
"io.systemd.Network.Link.Renew", vl_method_link_renew,
|
||||
"io.systemd.Network.Link.ForceRenew", vl_method_link_force_renew,
|
||||
"io.systemd.Network.Link.Reconfigure", vl_method_link_reconfigure,
|
||||
"io.systemd.service.Ping", varlink_method_ping,
|
||||
"io.systemd.service.Reload", vl_method_reload,
|
||||
"io.systemd.service.SetLogLevel", varlink_method_set_log_level,
|
||||
"io.systemd.service.GetEnvironment", varlink_method_get_environment);
|
||||
if (r < 0)
|
||||
|
||||
@@ -533,7 +533,7 @@ static int signal_restart_callback(sd_event_source *s, const struct signalfd_sig
|
||||
static int signal_reload_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
|
||||
(void) manager_reload(m, /* message= */ NULL);
|
||||
(void) manager_reload(m, /* message= */ NULL, /* varlink= */ NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1257,11 +1257,12 @@ int manager_set_timezone(Manager *m, const char *tz) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int manager_reload(Manager *m, sd_bus_message *message) {
|
||||
int manager_reload(Manager *m, sd_bus_message *message, sd_varlink *varlink) {
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(!message || !varlink); /* D-Bus and Varlink callers are mutually exclusive */
|
||||
|
||||
log_debug("Reloading...");
|
||||
(void) notify_reloading();
|
||||
@@ -1279,8 +1280,12 @@ int manager_reload(Manager *m, sd_bus_message *message) {
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(link, m->links_by_index)
|
||||
(void) link_reconfigure_full(link, /* flags= */ 0, message,
|
||||
/* counter= */ message ? &m->reloading : NULL);
|
||||
(void) link_reconfigure_full(
|
||||
link,
|
||||
/* flags= */ 0,
|
||||
message,
|
||||
varlink,
|
||||
/* counter= */ (message || varlink) ? &m->reloading : NULL);
|
||||
|
||||
log_debug("Reloaded.");
|
||||
r = 0;
|
||||
|
||||
@@ -151,7 +151,7 @@ int manager_enumerate(Manager *m);
|
||||
int manager_set_hostname(Manager *m, const char *hostname);
|
||||
int manager_set_timezone(Manager *m, const char *tz);
|
||||
|
||||
int manager_reload(Manager *m, sd_bus_message *message);
|
||||
int manager_reload(Manager *m, sd_bus_message *message, sd_varlink *varlink);
|
||||
|
||||
static inline Hashmap** manager_get_sysctl_shadow(Manager *manager) {
|
||||
#if ENABLE_SYSCTL_BPF
|
||||
|
||||
@@ -86,6 +86,38 @@ static int speed_meter_handler(sd_event_source *s, uint64_t usec, void *userdata
|
||||
return 0;
|
||||
}
|
||||
|
||||
void link_get_bit_rates(Link *link, uint64_t *ret_tx, uint64_t *ret_rx) {
|
||||
Manager *manager;
|
||||
double interval_sec;
|
||||
|
||||
assert(link);
|
||||
assert(ret_tx);
|
||||
assert(ret_rx);
|
||||
|
||||
manager = link->manager;
|
||||
|
||||
if (!manager->use_speed_meter ||
|
||||
manager->speed_meter_usec_old == 0 ||
|
||||
!link->stats_updated) {
|
||||
*ret_tx = UINT64_MAX;
|
||||
*ret_rx = UINT64_MAX;
|
||||
return;
|
||||
}
|
||||
|
||||
assert(manager->speed_meter_usec_new > manager->speed_meter_usec_old);
|
||||
interval_sec = (double) (manager->speed_meter_usec_new - manager->speed_meter_usec_old) / USEC_PER_SEC;
|
||||
|
||||
if (link->stats_new.tx_bytes > link->stats_old.tx_bytes)
|
||||
*ret_tx = (uint64_t) ((link->stats_new.tx_bytes - link->stats_old.tx_bytes) / interval_sec);
|
||||
else
|
||||
*ret_tx = (uint64_t) ((UINT64_MAX - (link->stats_old.tx_bytes - link->stats_new.tx_bytes)) / interval_sec);
|
||||
|
||||
if (link->stats_new.rx_bytes > link->stats_old.rx_bytes)
|
||||
*ret_rx = (uint64_t) ((link->stats_new.rx_bytes - link->stats_old.rx_bytes) / interval_sec);
|
||||
else
|
||||
*ret_rx = (uint64_t) ((UINT64_MAX - (link->stats_old.rx_bytes - link->stats_new.rx_bytes)) / interval_sec);
|
||||
}
|
||||
|
||||
int manager_start_speed_meter(Manager *manager) {
|
||||
_cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL;
|
||||
int r;
|
||||
|
||||
@@ -9,4 +9,5 @@
|
||||
#define SPEED_METER_DEFAULT_TIME_INTERVAL (10 * USEC_PER_SEC)
|
||||
#define SPEED_METER_MINIMUM_TIME_INTERVAL (100 * USEC_PER_MSEC)
|
||||
|
||||
void link_get_bit_rates(Link *link, uint64_t *ret_tx, uint64_t *ret_rx);
|
||||
int manager_start_speed_meter(Manager *m);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "varlink-io.systemd.Network.h"
|
||||
#include "varlink-io.systemd.Network.Link.h"
|
||||
|
||||
#define VARLINK_NETWORK_INTERFACE_INPUTS \
|
||||
@@ -9,6 +10,12 @@
|
||||
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(
|
||||
Describe,
|
||||
VARLINK_NETWORK_INTERFACE_INPUTS,
|
||||
SD_VARLINK_FIELD_COMMENT("Interface description"),
|
||||
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(Interface, Interface, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Up,
|
||||
VARLINK_NETWORK_INTERFACE_INPUTS,
|
||||
@@ -19,10 +26,64 @@ static SD_VARLINK_DEFINE_METHOD(
|
||||
VARLINK_NETWORK_INTERFACE_INPUTS,
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Renew,
|
||||
VARLINK_NETWORK_INTERFACE_INPUTS,
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
ForceRenew,
|
||||
VARLINK_NETWORK_INTERFACE_INPUTS,
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Reconfigure,
|
||||
VARLINK_NETWORK_INTERFACE_INPUTS,
|
||||
VARLINK_DEFINE_POLKIT_INPUT);
|
||||
|
||||
static SD_VARLINK_DEFINE_ERROR(InterfaceUnmanaged);
|
||||
|
||||
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);
|
||||
&vl_method_Down,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Renew DHCP leases on the specified link."),
|
||||
&vl_method_Renew,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Force-renew DHCP server leases on the specified link."),
|
||||
&vl_method_ForceRenew,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Unconditionally reconfigure the specified link."),
|
||||
&vl_method_Reconfigure,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Describe the specified link by index or name."),
|
||||
&vl_method_Describe,
|
||||
SD_VARLINK_SYMBOL_COMMENT("The specified interface is not managed by systemd-networkd."),
|
||||
&vl_error_InterfaceUnmanaged,
|
||||
&vl_type_Address,
|
||||
&vl_type_BitRates,
|
||||
&vl_type_DHCPLease,
|
||||
&vl_type_DHCPServer,
|
||||
&vl_type_DHCPServerLease,
|
||||
&vl_type_DHCPv6Client,
|
||||
&vl_type_DHCPv6ClientPD,
|
||||
&vl_type_DHCPv6ClientVendorOption,
|
||||
&vl_type_DNS,
|
||||
&vl_type_DNSSECNegativeTrustAnchor,
|
||||
&vl_type_DNSSetting,
|
||||
&vl_type_Domain,
|
||||
&vl_type_Interface,
|
||||
&vl_type_LinkState,
|
||||
&vl_type_LinkAddressState,
|
||||
&vl_type_LinkOnlineState,
|
||||
&vl_type_LinkRequiredAddressFamily,
|
||||
&vl_type_LLDPNeighbor,
|
||||
&vl_type_NDisc,
|
||||
&vl_type_Neighbor,
|
||||
&vl_type_NextHop,
|
||||
&vl_type_NextHopGroup,
|
||||
&vl_type_NTP,
|
||||
&vl_type_Pref64,
|
||||
&vl_type_PrivateOption,
|
||||
&vl_type_Route,
|
||||
&vl_type_SIP);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
SD_VARLINK_FIELD_COMMENT(comment " (human-readable format)"), \
|
||||
SD_VARLINK_DEFINE_FIELD(field_name##String, SD_VARLINK_STRING, (flags))
|
||||
|
||||
static SD_VARLINK_DEFINE_ENUM_TYPE(
|
||||
SD_VARLINK_DEFINE_ENUM_TYPE(
|
||||
LinkState,
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(pending),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(initialized),
|
||||
@@ -93,7 +93,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Configuration state of this rule"),
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigState, SD_VARLINK_STRING, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
Route,
|
||||
SD_VARLINK_FIELD_COMMENT("Address family (AF_INET or AF_INET6)"),
|
||||
SD_VARLINK_DEFINE_FIELD(Family, SD_VARLINK_INT, 0),
|
||||
@@ -149,14 +149,14 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("TCP congestion control algorithm for this route"),
|
||||
SD_VARLINK_DEFINE_FIELD(TCPCongestionControlAlgorithm, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
NextHopGroup,
|
||||
SD_VARLINK_FIELD_COMMENT("Next hop identifier in the multipath group"),
|
||||
SD_VARLINK_DEFINE_FIELD(ID, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Weight for load balancing (higher means more traffic)"),
|
||||
SD_VARLINK_DEFINE_FIELD(Weight, SD_VARLINK_INT, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
NextHop,
|
||||
SD_VARLINK_FIELD_COMMENT("Next hop identifier"),
|
||||
SD_VARLINK_DEFINE_FIELD(ID, SD_VARLINK_INT, 0),
|
||||
@@ -181,7 +181,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Configuration state of this next hop"),
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigState, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
LLDPNeighbor,
|
||||
SD_VARLINK_FIELD_COMMENT("Chassis identifier in human-readable format"),
|
||||
SD_VARLINK_DEFINE_FIELD(ChassisID, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
@@ -204,7 +204,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("VLAN identifier"),
|
||||
SD_VARLINK_DEFINE_FIELD(VlanID, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
DNS,
|
||||
SD_VARLINK_FIELD_COMMENT("Address family (AF_INET or AF_INET6)"),
|
||||
SD_VARLINK_DEFINE_FIELD(Family, SD_VARLINK_INT, 0),
|
||||
@@ -219,7 +219,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigSource, SD_VARLINK_STRING, 0),
|
||||
VARLINK_DEFINE_IN_ADDR_WITH_STRING_FIELD(ConfigProvider, "Address of the configuration provider", SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
NTP,
|
||||
SD_VARLINK_FIELD_COMMENT("Address family (AF_INET or AF_INET6) for address-based servers"),
|
||||
SD_VARLINK_DEFINE_FIELD(Family, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
@@ -230,7 +230,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigSource, SD_VARLINK_STRING, 0),
|
||||
VARLINK_DEFINE_IN_ADDR_WITH_STRING_FIELD(ConfigProvider, "Address of the configuration provider", SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SIP,
|
||||
SD_VARLINK_FIELD_COMMENT("Address family (AF_INET or AF_INET6) for address-based servers"),
|
||||
SD_VARLINK_DEFINE_FIELD(Family, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
@@ -241,7 +241,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigSource, SD_VARLINK_STRING, 0),
|
||||
VARLINK_DEFINE_IN_ADDR_WITH_STRING_FIELD(ConfigProvider, "Address of the configuration provider", SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
Domain,
|
||||
SD_VARLINK_FIELD_COMMENT("DNS search or route domain name"),
|
||||
SD_VARLINK_DEFINE_FIELD(Domain, SD_VARLINK_STRING, 0),
|
||||
@@ -249,14 +249,14 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigSource, SD_VARLINK_STRING, 0),
|
||||
VARLINK_DEFINE_IN_ADDR_WITH_STRING_FIELD(ConfigProvider, "Address of the configuration provider", SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
DNSSECNegativeTrustAnchor,
|
||||
SD_VARLINK_FIELD_COMMENT("Domain name for which DNSSEC validation is disabled"),
|
||||
SD_VARLINK_DEFINE_FIELD(DNSSECNegativeTrustAnchor, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Configuration source for this negative trust anchor"),
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigSource, SD_VARLINK_STRING, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
DNSSetting,
|
||||
SD_VARLINK_FIELD_COMMENT("Link-Local Multicast Name Resolution setting"),
|
||||
SD_VARLINK_DEFINE_FIELD(LLMNR, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
@@ -269,7 +269,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Configuration source for this DNS setting"),
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigSource, SD_VARLINK_STRING, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
Pref64,
|
||||
SD_VARLINK_FIELD_COMMENT("IPv6 prefix for NAT64/DNS64"),
|
||||
SD_VARLINK_DEFINE_FIELD(Prefix, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
@@ -281,12 +281,12 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(LifetimeUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
VARLINK_DEFINE_IN_ADDR_WITH_STRING_FIELD(ConfigProvider, "Address of router that provided this prefix", SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
NDisc,
|
||||
SD_VARLINK_FIELD_COMMENT("PREF64 (RFC8781) prefixes advertised via IPv6 Router Advertisements"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(PREF64, Pref64, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
Address,
|
||||
SD_VARLINK_FIELD_COMMENT("Address family (AF_INET or AF_INET6)"),
|
||||
SD_VARLINK_DEFINE_FIELD(Family, SD_VARLINK_INT, 0),
|
||||
@@ -319,7 +319,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Configuration state of this address"),
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigState, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
Neighbor,
|
||||
SD_VARLINK_FIELD_COMMENT("Address family (AF_INET or AF_INET6)"),
|
||||
SD_VARLINK_DEFINE_FIELD(Family, SD_VARLINK_INT, 0),
|
||||
@@ -331,7 +331,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Configuration state of this neighbor entry"),
|
||||
SD_VARLINK_DEFINE_FIELD(ConfigState, SD_VARLINK_STRING, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
DHCPLease,
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the lease was acquired in microseconds"),
|
||||
SD_VARLINK_DEFINE_FIELD(LeaseTimestampUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
@@ -342,14 +342,14 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Hostname received from DHCP server"),
|
||||
SD_VARLINK_DEFINE_FIELD(Hostname, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
PrivateOption,
|
||||
SD_VARLINK_FIELD_COMMENT("DHCP option number"),
|
||||
SD_VARLINK_DEFINE_FIELD(Option, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Raw data of the private DHCP option"),
|
||||
SD_VARLINK_DEFINE_FIELD(PrivateOptionData, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
DHCPv6ClientPD,
|
||||
SD_VARLINK_FIELD_COMMENT("Delegated IPv6 prefix"),
|
||||
SD_VARLINK_DEFINE_FIELD(Prefix, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
@@ -362,7 +362,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Valid lifetime of the prefix in microseconds"),
|
||||
SD_VARLINK_DEFINE_FIELD(ValidLifetimeUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
DHCPv6ClientVendorOption,
|
||||
SD_VARLINK_FIELD_COMMENT("IANA enterprise number identifying the vendor"),
|
||||
SD_VARLINK_DEFINE_FIELD(EnterpriseId, SD_VARLINK_INT, 0),
|
||||
@@ -371,7 +371,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Raw data of the vendor-specific sub-option"),
|
||||
SD_VARLINK_DEFINE_FIELD(SubOptionData, SD_VARLINK_STRING, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
DHCPv6Client,
|
||||
SD_VARLINK_FIELD_COMMENT("DHCPv6 lease information including timestamps and timeouts"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(Lease, DHCPLease, SD_VARLINK_NULLABLE),
|
||||
@@ -382,7 +382,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("DHCP Unique Identifier (DUID) of the client"),
|
||||
SD_VARLINK_DEFINE_FIELD(DUID, SD_VARLINK_INT, SD_VARLINK_ARRAY));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
DHCPServerLease,
|
||||
SD_VARLINK_FIELD_COMMENT("DHCP client identifier"),
|
||||
SD_VARLINK_DEFINE_FIELD(ClientId, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
@@ -400,7 +400,7 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Lease expiration time in realtime microseconds"),
|
||||
SD_VARLINK_DEFINE_FIELD(ExpirationRealtimeUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
DHCPServer,
|
||||
SD_VARLINK_FIELD_COMMENT("Offset from the network address for the DHCP address pool"),
|
||||
SD_VARLINK_DEFINE_FIELD(PoolOffset, SD_VARLINK_INT, 0),
|
||||
@@ -411,7 +411,14 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Static DHCP leases configured for specific clients"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(StaticLeases, DHCPServerLease, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
BitRates,
|
||||
SD_VARLINK_FIELD_COMMENT("Transmit bitrate in bits per second"),
|
||||
SD_VARLINK_DEFINE_FIELD(TxBitRate, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Receive bitrate in bits per second"),
|
||||
SD_VARLINK_DEFINE_FIELD(RxBitRate, SD_VARLINK_INT, 0));
|
||||
|
||||
SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
Interface,
|
||||
SD_VARLINK_FIELD_COMMENT("Network interface index"),
|
||||
SD_VARLINK_DEFINE_FIELD(Index, SD_VARLINK_INT, 0),
|
||||
@@ -533,7 +540,9 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("DHCPv6 client configuration and lease information"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(DHCPv6Client, DHCPv6Client, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("LLDP transmit configuration for this interface"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(LLDP, LLDPNeighbor, SD_VARLINK_NULLABLE));
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(LLDP, LLDPNeighbor, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Current transmit/receive bitrates from speed meter"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(BitRates, BitRates, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD(
|
||||
Describe,
|
||||
@@ -593,6 +602,7 @@ 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_ERROR(AlreadyReloading);
|
||||
static SD_VARLINK_DEFINE_ERROR(StorageReadOnly);
|
||||
|
||||
SD_VARLINK_DEFINE_INTERFACE(
|
||||
@@ -604,6 +614,7 @@ SD_VARLINK_DEFINE_INTERFACE(
|
||||
&vl_method_GetLLDPNeighbors,
|
||||
&vl_method_SetPersistentStorage,
|
||||
&vl_type_Address,
|
||||
&vl_type_BitRates,
|
||||
&vl_type_DHCPLease,
|
||||
&vl_type_DHCPServer,
|
||||
&vl_type_DHCPServerLease,
|
||||
@@ -631,4 +642,5 @@ SD_VARLINK_DEFINE_INTERFACE(
|
||||
&vl_type_Route,
|
||||
&vl_type_RoutingPolicyRule,
|
||||
&vl_type_SIP,
|
||||
&vl_error_AlreadyReloading,
|
||||
&vl_error_StorageReadOnly);
|
||||
|
||||
@@ -7,3 +7,27 @@ extern const sd_varlink_interface vl_interface_io_systemd_Network;
|
||||
extern const sd_varlink_symbol vl_type_LinkAddressState;
|
||||
extern const sd_varlink_symbol vl_type_LinkOnlineState;
|
||||
extern const sd_varlink_symbol vl_type_LinkRequiredAddressFamily;
|
||||
extern const sd_varlink_symbol vl_type_LinkState;
|
||||
extern const sd_varlink_symbol vl_type_Route;
|
||||
extern const sd_varlink_symbol vl_type_NextHopGroup;
|
||||
extern const sd_varlink_symbol vl_type_NextHop;
|
||||
extern const sd_varlink_symbol vl_type_LLDPNeighbor;
|
||||
extern const sd_varlink_symbol vl_type_DNS;
|
||||
extern const sd_varlink_symbol vl_type_NTP;
|
||||
extern const sd_varlink_symbol vl_type_SIP;
|
||||
extern const sd_varlink_symbol vl_type_Domain;
|
||||
extern const sd_varlink_symbol vl_type_DNSSECNegativeTrustAnchor;
|
||||
extern const sd_varlink_symbol vl_type_DNSSetting;
|
||||
extern const sd_varlink_symbol vl_type_Pref64;
|
||||
extern const sd_varlink_symbol vl_type_NDisc;
|
||||
extern const sd_varlink_symbol vl_type_Address;
|
||||
extern const sd_varlink_symbol vl_type_Neighbor;
|
||||
extern const sd_varlink_symbol vl_type_DHCPLease;
|
||||
extern const sd_varlink_symbol vl_type_PrivateOption;
|
||||
extern const sd_varlink_symbol vl_type_DHCPv6ClientPD;
|
||||
extern const sd_varlink_symbol vl_type_DHCPv6ClientVendorOption;
|
||||
extern const sd_varlink_symbol vl_type_DHCPv6Client;
|
||||
extern const sd_varlink_symbol vl_type_DHCPServerLease;
|
||||
extern const sd_varlink_symbol vl_type_DHCPServer;
|
||||
extern const sd_varlink_symbol vl_type_BitRates;
|
||||
extern const sd_varlink_symbol vl_type_Interface;
|
||||
|
||||
Reference in New Issue
Block a user