]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/network/networkd-link-bus.c
Merge pull request #12762 from yuwata/network-introduce-carrier-and-network-state...
[thirdparty/systemd.git] / src / network / networkd-link-bus.c
index 532557ed6c5e628859b4e52b3d80ff6b0ba851b8..eda0325c2b94ff2c2560e2e52185fc874d5a1f14 100644 (file)
@@ -1,42 +1,77 @@
-/***
-  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/>.
-***/
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "alloc-util.h"
+#include "bus-common-errors.h"
 #include "bus-util.h"
+#include "networkd-link-bus.h"
 #include "networkd-link.h"
-#include "networkd.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;
@@ -81,8 +116,7 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
         }
 
         l[c] = NULL;
-        *nodes = l;
-        l = NULL;
+        *nodes = TAKE_PTR(l);
 
         return 1;
 }
@@ -116,17 +150,15 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void
         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)
@@ -136,5 +168,13 @@ int link_send_changed(Link *link, const char *property, ...) {
                         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);
 }