]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/tc: fix enumeration logic of traffic control classes
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 7 Oct 2023 05:24:34 +0000 (14:24 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 7 Oct 2023 12:35:16 +0000 (21:35 +0900)
TC class can be enumerated only per link.

src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/tc/tclass.c
src/network/tc/tclass.h

index ab5460db27ec9eb4cad25147f7af3640d735ef29..f597eb358b70e21e36de61c66144930b47ef5a90 100644 (file)
@@ -716,7 +716,7 @@ int manager_load_config(Manager *m) {
         return manager_build_dhcp_pd_subnet_ids(m);
 }
 
-static int manager_enumerate_internal(
+int manager_enumerate_internal(
                 Manager *m,
                 sd_netlink *nl,
                 sd_netlink_message *req,
@@ -775,17 +775,18 @@ static int manager_enumerate_qdisc(Manager *m) {
 }
 
 static int manager_enumerate_tclass(Manager *m) {
-        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
-        int r;
+        Link *link;
+        int r = 0;
 
         assert(m);
         assert(m->rtnl);
 
-        r = sd_rtnl_message_new_traffic_control(m->rtnl, &req, RTM_GETTCLASS, 0, 0, 0);
-        if (r < 0)
-                return r;
+        /* TC class can be enumerated only per link. See tc_dump_tclass() in net/sched/sched_api.c. */
+
+        HASHMAP_FOREACH(link, m->links_by_index)
+                RET_GATHER(r, link_enumerate_tclass(link, 0));
 
-        return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_tclass);
+        return r;
 }
 
 static int manager_enumerate_addresses(Manager *m) {
index a27137a8456a29f22b09a0cc3c4c04beeb8aa0a6..65bd5073a5f0dc42084df3bd6b2f3a90a5209489 100644 (file)
@@ -113,6 +113,11 @@ int manager_start(Manager *m);
 
 int manager_load_config(Manager *m);
 
+int manager_enumerate_internal(
+                Manager *m,
+                sd_netlink *nl,
+                sd_netlink_message *req,
+                int (*process)(sd_netlink *, sd_netlink_message *, Manager *));
 int manager_enumerate(Manager *m);
 
 int manager_set_hostname(Manager *m, const char *hostname);
index 9e6032b35a6d4d370e56cd84a9c99a60c1fb2888..4e31b819c83107889151f65339855512d50e342a 100644 (file)
@@ -505,6 +505,21 @@ int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, M
         return 1;
 }
 
+int link_enumerate_tclass(Link *link, uint32_t parent) {
+        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+        int r;
+
+        assert(link);
+        assert(link->manager);
+        assert(link->manager->rtnl);
+
+        r = sd_rtnl_message_new_traffic_control(link->manager->rtnl, &req, RTM_GETTCLASS, link->ifindex, 0, parent);
+        if (r < 0)
+                return r;
+
+        return manager_enumerate_internal(link->manager, link->manager->rtnl, req, manager_rtnl_process_tclass);
+}
+
 static int tclass_section_verify(TClass *tclass) {
         int r;
 
index f0ee318c76f2230829cd4ab77008e9d3b281678c..e73e23c97f6213aa7dbe4e54bfa0c46f181ede88 100644 (file)
@@ -67,6 +67,7 @@ int link_request_tclass(Link *link, TClass *tclass);
 void network_drop_invalid_tclass(Network *network);
 
 int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
+int link_enumerate_tclass(Link *link, uint32_t parent);
 
 DEFINE_SECTION_CLEANUP_FUNCTIONS(TClass, tclass_free);