]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: introduce TrafficControlKind to prepare for supporting tc class
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 10 Feb 2020 11:53:00 +0000 (20:53 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 2 Mar 2020 06:46:28 +0000 (15:46 +0900)
src/network/meson.build
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-network.c
src/network/networkd-network.h
src/network/tc/qdisc.c
src/network/tc/qdisc.h
src/network/tc/tc.c [new file with mode: 0644]
src/network/tc/tc.h [new file with mode: 0644]

index 1f5175e053fce2371989a2e1b6b9e3eb0da4713d..ce0e7fb0ddd3152cd52166c3428e215d828379df 100644 (file)
@@ -125,6 +125,8 @@ sources = files('''
         tc/tbf.h
         tc/tc-util.c
         tc/tc-util.h
+        tc/tc.c
+        tc/tc.h
         tc/teql.c
         tc/teql.h
 '''.split())
index 3dca043d99c1a7a145dbd81fe379ba0f4f970abc..bd9d37aad206220b99cb7e24c2259f655b06a046 100644 (file)
@@ -34,7 +34,6 @@
 #include "networkd-radv.h"
 #include "networkd-routing-policy-rule.h"
 #include "networkd-wifi.h"
-#include "qdisc.h"
 #include "set.h"
 #include "socket-util.h"
 #include "stat-util.h"
@@ -42,6 +41,7 @@
 #include "string-table.h"
 #include "strv.h"
 #include "sysctl-util.h"
+#include "tc.h"
 #include "tmpfile-util.h"
 #include "udev-util.h"
 #include "util.h"
@@ -1116,7 +1116,7 @@ void link_check_ready(Link *link) {
         if (!link->routing_policy_rules_configured)
                 return;
 
-        if (!link->qdiscs_configured)
+        if (!link->tc_configured)
                 return;
 
         if (link_has_carrier(link) || !link->network->configure_without_carrier) {
@@ -2702,24 +2702,24 @@ static int link_configure_ipv4_dad(Link *link) {
         return 0;
 }
 
-static int link_configure_qdiscs(Link *link) {
-        QDisc *qdisc;
+static int link_configure_traffic_control(Link *link) {
+        TrafficControl *tc;
         Iterator i;
         int r;
 
-        link->qdiscs_configured = false;
-        link->qdisc_messages = 0;
+        link->tc_configured = false;
+        link->tc_messages = 0;
 
-        ORDERED_HASHMAP_FOREACH(qdisc, link->network->qdiscs_by_section, i) {
-                r = qdisc_configure(link, qdisc);
+        ORDERED_HASHMAP_FOREACH(tc, link->network->tc_by_section, i) {
+                r = traffic_control_configure(link, tc);
                 if (r < 0)
                         return r;
         }
 
-        if (link->qdisc_messages == 0)
-                link->qdiscs_configured = true;
+        if (link->tc_messages == 0)
+                link->tc_configured = true;
         else
-                log_link_debug(link, "Configuring queuing discipline (qdisc)");
+                log_link_debug(link, "Configuring traffic control");
 
         return 0;
 }
@@ -2731,7 +2731,7 @@ static int link_configure(Link *link) {
         assert(link->network);
         assert(link->state == LINK_STATE_INITIALIZED);
 
-        r = link_configure_qdiscs(link);
+        r = link_configure_traffic_control(link);
         if (r < 0)
                 return r;
 
index 59a510731130a7c648adb4d267f4b4d097c01547..3d07d882cda14a4d9cc6269a85aadbf142781657 100644 (file)
@@ -80,7 +80,7 @@ typedef struct Link {
         unsigned nexthop_messages;
         unsigned routing_policy_rule_messages;
         unsigned routing_policy_rule_remove_messages;
-        unsigned qdisc_messages;
+        unsigned tc_messages;
         unsigned enslaving;
 
         Set *addresses;
@@ -116,7 +116,7 @@ typedef struct Link {
         bool static_routes_ready:1;
         bool static_nexthops_configured:1;
         bool routing_policy_rules_configured:1;
-        bool qdiscs_configured:1;
+        bool tc_configured:1;
         bool setting_mtu:1;
         bool setting_genmode:1;
         bool ipv6_mtu_set:1;
index e6be07d9a194ac81c32ff4a0aa3476af83d6134c..5ca5ad32cd42f70a905eec50f0442ea83a02cdc7 100644 (file)
@@ -22,6 +22,7 @@
 #include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
+#include "tc.h"
 #include "util.h"
 
 /* Let's assume that anything above this number is a user misconfiguration. */
@@ -154,7 +155,7 @@ int network_verify(Network *network) {
         Prefix *prefix, *prefix_next;
         Route *route, *route_next;
         FdbEntry *fdb, *fdb_next;
-        QDisc *qdisc;
+        TrafficControl *tc;
         Iterator i;
 
         assert(network);
@@ -316,9 +317,9 @@ int network_verify(Network *network) {
                         routing_policy_rule_free(rule);
 
         bool has_root = false, has_clsact = false;
-        ORDERED_HASHMAP_FOREACH(qdisc, network->qdiscs_by_section, i)
-                if (qdisc_section_verify(qdisc, &has_root, &has_clsact) < 0)
-                        qdisc_free(qdisc);
+        ORDERED_HASHMAP_FOREACH(tc, network->tc_by_section, i)
+                if (traffic_control_section_verify(tc, &has_root, &has_clsact) < 0)
+                        traffic_control_free(tc);
 
         return 0;
 }
@@ -691,7 +692,7 @@ static Network *network_free(Network *network) {
         hashmap_free(network->prefixes_by_section);
         hashmap_free(network->route_prefixes_by_section);
         hashmap_free(network->rules_by_section);
-        ordered_hashmap_free_with_destructor(network->qdiscs_by_section, qdisc_free);
+        ordered_hashmap_free_with_destructor(network->tc_by_section, traffic_control_free);
 
         if (network->manager &&
             network->manager->duids_requesting_uuid)
index 66f010a7939fe4744d38673f38a34e412b7ad131..3ae1752acc86764caa3fa95aea6f65af4bb03886 100644 (file)
@@ -30,7 +30,6 @@
 #include "networkd-routing-policy-rule.h"
 #include "networkd-util.h"
 #include "ordered-set.h"
-#include "qdisc.h"
 #include "resolve-util.h"
 
 typedef enum IPv6PrivacyExtensions {
@@ -274,7 +273,7 @@ struct Network {
         Hashmap *prefixes_by_section;
         Hashmap *route_prefixes_by_section;
         Hashmap *rules_by_section;
-        OrderedHashmap *qdiscs_by_section;
+        OrderedHashmap *tc_by_section;
 
         /* All kinds of DNS configuration */
         struct in_addr_data *dns;
index 9f60888aa5cbb8e7787f8481d8953b97bb0c9e44..2168234a71c96086a7e031b5d2dccf84b3f39e51 100644 (file)
@@ -36,6 +36,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) {
                         return -ENOMEM;
 
                 *qdisc = (QDisc) {
+                        .meta.kind = TC_KIND_QDISC,
                         .family = AF_UNSPEC,
                         .parent = TC_H_ROOT,
                         .kind = kind,
@@ -45,6 +46,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) {
                 if (!qdisc)
                         return -ENOMEM;
 
+                qdisc->meta.kind = TC_KIND_QDISC,
                 qdisc->family = AF_UNSPEC;
                 qdisc->parent = TC_H_ROOT;
                 qdisc->kind = kind;
@@ -64,7 +66,8 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) {
 int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret) {
         _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
         _cleanup_(qdisc_freep) QDisc *qdisc = NULL;
-        QDisc *existing;
+        TrafficControl *existing;
+        QDisc *q = NULL;
         int r;
 
         assert(network);
@@ -76,15 +79,20 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns
         if (r < 0)
                 return r;
 
-        existing = ordered_hashmap_get(network->qdiscs_by_section, n);
+        existing = ordered_hashmap_get(network->tc_by_section, n);
         if (existing) {
-                if (existing->kind != _QDISC_KIND_INVALID &&
+                if (existing->kind != TC_KIND_QDISC)
+                        return -EINVAL;
+
+                q = TC_TO_QDISC(existing);
+
+                if (q->kind != _QDISC_KIND_INVALID &&
                     kind != _QDISC_KIND_INVALID &&
-                    existing->kind != kind)
+                    q->kind != kind)
                         return -EINVAL;
 
-                if (existing->kind == kind || kind == _QDISC_KIND_INVALID) {
-                        *ret = existing;
+                if (q->kind == kind || kind == _QDISC_KIND_INVALID) {
+                        *ret = q;
                         return 0;
                 }
         }
@@ -93,23 +101,23 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns
         if (r < 0)
                 return r;
 
-        if (existing) {
-                qdisc->family = existing->family;
-                qdisc->handle = existing->handle;
-                qdisc->parent = existing->parent;
-                qdisc->tca_kind = TAKE_PTR(existing->tca_kind);
+        if (q) {
+                qdisc->family = q->family;
+                qdisc->handle = q->handle;
+                qdisc->parent = q->parent;
+                qdisc->tca_kind = TAKE_PTR(q->tca_kind);
 
-                qdisc_free(ordered_hashmap_remove(network->qdiscs_by_section, n));
+                qdisc_free(q);
         }
 
         qdisc->network = network;
         qdisc->section = TAKE_PTR(n);
 
-        r = ordered_hashmap_ensure_allocated(&network->qdiscs_by_section, &network_config_hash_ops);
+        r = ordered_hashmap_ensure_allocated(&network->tc_by_section, &network_config_hash_ops);
         if (r < 0)
                 return r;
 
-        r = ordered_hashmap_put(network->qdiscs_by_section, qdisc->section, qdisc);
+        r = ordered_hashmap_put(network->tc_by_section, qdisc->section, TC(qdisc));
         if (r < 0)
                 return r;
 
@@ -122,7 +130,7 @@ void qdisc_free(QDisc *qdisc) {
                 return;
 
         if (qdisc->network && qdisc->section)
-                ordered_hashmap_remove(qdisc->network->qdiscs_by_section, qdisc->section);
+                ordered_hashmap_remove(qdisc->network->tc_by_section, qdisc->section);
 
         network_config_section_free(qdisc->section);
 
@@ -134,8 +142,8 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
         int r;
 
         assert(link);
-        assert(link->qdisc_messages > 0);
-        link->qdisc_messages--;
+        assert(link->tc_messages > 0);
+        link->tc_messages--;
 
         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
                 return 1;
@@ -147,9 +155,9 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
                 return 1;
         }
 
-        if (link->qdisc_messages == 0) {
-                log_link_debug(link, "QDisc configured");
-                link->qdiscs_configured = true;
+        if (link->tc_messages == 0) {
+                log_link_debug(link, "Traffic control configured");
+                link->tc_configured = true;
                 link_check_ready(link);
         }
 
@@ -206,7 +214,7 @@ int qdisc_configure(Link *link, QDisc *qdisc) {
                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
 
         link_ref(link);
-        link->qdisc_messages++;
+        link->tc_messages++;
 
         return 0;
 }
index 7d9e0ddb06e614d899e2a33022bbfd785238038b..f33939d197ac4c443f40077d1525f04320675215 100644 (file)
@@ -6,6 +6,7 @@
 #include "networkd-link.h"
 #include "networkd-network.h"
 #include "networkd-util.h"
+#include "tc.h"
 
 typedef enum QDiscKind {
         QDISC_KIND_CODEL,
@@ -21,6 +22,8 @@ typedef enum QDiscKind {
 } QDiscKind;
 
 typedef struct QDisc {
+        TrafficControl meta;
+
         NetworkConfigSection *section;
         Network *network;
 
@@ -66,6 +69,8 @@ int qdisc_section_verify(QDisc *qdisc, bool *has_root, bool *has_clsact);
 
 DEFINE_NETWORK_SECTION_FUNCTIONS(QDisc, qdisc_free);
 
+DEFINE_TC_CAST(QDISC, QDisc);
+
 CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_parent);
 CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle);
 
diff --git a/src/network/tc/tc.c b/src/network/tc/tc.c
new file mode 100644 (file)
index 0000000..e90ebf3
--- /dev/null
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "macro.h"
+#include "qdisc.h"
+#include "tc.h"
+
+void traffic_control_free(TrafficControl *tc) {
+        if (!tc)
+                return;
+
+        switch (tc->kind) {
+        case TC_KIND_QDISC:
+                qdisc_free(TC_TO_QDISC(tc));
+                break;
+        default:
+                assert_not_reached("Invalid traffic control type");
+        }
+}
+
+int traffic_control_configure(Link *link, TrafficControl *tc) {
+        assert(link);
+        assert(tc);
+
+        switch(tc->kind) {
+        case TC_KIND_QDISC:
+                return qdisc_configure(link, TC_TO_QDISC(tc));
+        default:
+                assert_not_reached("Invalid traffic control type");
+        }
+}
+
+int traffic_control_section_verify(TrafficControl *tc, bool *qdisc_has_root, bool *qdisc_has_clsact) {
+        assert(tc);
+
+        switch(tc->kind) {
+        case TC_KIND_QDISC:
+                return qdisc_section_verify(TC_TO_QDISC(tc), qdisc_has_root, qdisc_has_clsact);
+        default:
+                assert_not_reached("Invalid traffic control type");
+        }
+}
diff --git a/src/network/tc/tc.h b/src/network/tc/tc.h
new file mode 100644 (file)
index 0000000..defa0b7
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include "networkd-link.h"
+
+typedef enum TrafficControlKind {
+        TC_KIND_QDISC,
+        TC_KIND_TCLASS,
+        TC_KIND_FILTER,
+        _TC_KIND_MAX,
+        _TC_KIND_INVALID = -1,
+} TrafficControlKind;
+
+typedef struct TrafficControl {
+        TrafficControlKind kind;
+} TrafficControl;
+
+/* For casting a tc into the various tc kinds */
+#define DEFINE_TC_CAST(UPPERCASE, MixedCase)                           \
+        static inline MixedCase* TC_TO_##UPPERCASE(TrafficControl *tc) {                    \
+                if (_unlikely_(!tc || tc->kind != TC_KIND_##UPPERCASE))  \
+                        return NULL;                                      \
+                                                                          \
+                return (MixedCase*) tc;                                    \
+        }
+
+/* For casting the various tc kinds into a tc */
+#define TC(tc) (&(tc)->meta)
+
+void traffic_control_free(TrafficControl *tc);
+int traffic_control_configure(Link *link, TrafficControl *tc);
+int traffic_control_section_verify(TrafficControl *tc, bool *qdisc_has_root, bool *qdisc_has_clsact);