/* SPDX-License-Identifier: LGPL-2.1+ */
-/***
- This file is part of systemd.
-
- Copyright 2015 Tom Gundersen
-
- systemd is free software; you can redistribute it and/or modify it
- under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2.1 of the License, or
- (at your option) any later version.
-
- systemd is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
#include "alloc-util.h"
+#include "bus-common-errors.h"
#include "bus-util.h"
+#include "networkd-link-bus.h"
#include "networkd-link.h"
#include "networkd-manager.h"
#include "parse-util.h"
#include "strv.h"
-static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState);
+BUS_DEFINE_PROPERTY_GET_ENUM(property_get_operational_state, link_operstate, LinkOperationalState);
+BUS_DEFINE_PROPERTY_GET_ENUM(property_get_carrier_state, link_carrier_state, LinkCarrierState);
+BUS_DEFINE_PROPERTY_GET_ENUM(property_get_address_state, link_address_state, LinkAddressState);
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_administrative_state, link_state, LinkState);
+static int property_get_bit_rates(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Link *link = userdata;
+ Manager *manager;
+ double interval_sec;
+ uint64_t tx, rx;
+
+ assert(bus);
+ assert(reply);
+ assert(userdata);
+
+ manager = link->manager;
+
+ if (!manager->use_speed_meter)
+ return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Speed meter is disabled.");
+
+ if (manager->speed_meter_usec_old == 0)
+ return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Speed meter is not active.");
+
+ if (!link->stats_updated)
+ return sd_bus_error_set(error, BUS_ERROR_SPEED_METER_INACTIVE, "Failed to measure bit-rates.");
+
+ assert(manager->speed_meter_usec_new > manager->speed_meter_usec_old);
+ interval_sec = (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);
+
+ return sd_bus_message_append(reply, "(tt)", tx, rx);
+}
+
const sd_bus_vtable link_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("OperationalState", "s", property_get_operational_state, offsetof(Link, operstate), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("CarrierState", "s", property_get_carrier_state, offsetof(Link, carrier_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("AddressState", "s", property_get_address_state, offsetof(Link, address_state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("AdministrativeState", "s", property_get_administrative_state, offsetof(Link, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("BitRates", "(tt)", property_get_bit_rates, 0, 0),
SD_BUS_VTABLE_END
};
-static char *link_bus_path(Link *link) {
+char *link_bus_path(Link *link) {
_cleanup_free_ char *ifindex = NULL;
char *p;
int r;
return 1;
}
-int link_send_changed(Link *link, const char *property, ...) {
+int link_send_changed_strv(Link *link, char **properties) {
_cleanup_free_ char *p = NULL;
- char **l;
assert(link);
assert(link->manager);
+ assert(properties);
if (!link->manager->bus)
- return 0; /* replace with assert when we have kdbus */
-
- l = strv_from_stdarg_alloca(property);
+ return 0;
p = link_bus_path(link);
if (!p)
link->manager->bus,
p,
"org.freedesktop.network1.Link",
- l);
+ properties);
+}
+
+int link_send_changed(Link *link, const char *property, ...) {
+ char **properties;
+
+ properties = strv_from_stdarg_alloca(property);
+
+ return link_send_changed_strv(link, properties);
}